Добавить индикатор выполнения в TreeTableView (возвращая значение Double в Observable <Double>)

1

Я экспериментирую с JavaFX, и я пытаюсь добавить индикатор выполнения в таблицу дерева. Есть ли способ связать значения зарплаты с индикатором прогресса.

Мой код - это модифицированная версия Oracle TreeTableView. Пример:

public class TreeTableViewSample extends Application implements Runnable {

List<Employee> employees = Arrays.<Employee>asList(
        new Employee("Ethan Williams", 30.0),
        new Employee("Emma Jones", 10.0),
        new Employee("Michael Brown", 70.0),
        new Employee("Anna Black", 50.0),
        new Employee("Rodger York", 20.0),
        new Employee("Susan Collins", 70.0));

/*  private final ImageView depIcon = new ImageView (
 new Image(getClass().getResourceAsStream("department.png"))
 );
 */
final CheckBoxTreeItem<Employee> root
        = new CheckBoxTreeItem<>(new Employee("Sales Department", 0.0));
final CheckBoxTreeItem<Employee> root2
        = new CheckBoxTreeItem<>(new Employee("Departments", 0.0));

public static void main(String[] args) {
    Application.launch(TreeTableViewSample.class, args);
}

@Override
public void start(Stage stage) {
    root.setExpanded(true);
    employees.stream().forEach((employee) -> {
        CheckBoxTreeItem<Employee> cbt=new CheckBoxTreeItem<>(employee);
        cbt.selectedProperty().addListener((ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) -> {
                if (newValue) {
                    System.out.println("Slected employ name is "+cbt.getValue().getName()); 
                }
            });

        root.getChildren().add(cbt);
    });
    stage.setTitle("Tree Table View Sample");
    final Scene scene = new Scene(new Group(), 400, 400);
    scene.setFill(Color.LIGHTGRAY);
    Group sceneRoot = (Group) scene.getRoot();

    TreeTableColumn<Employee, String> empColumn
            = new TreeTableColumn<>("Employee");
    empColumn.setPrefWidth(150);
    empColumn.setCellValueFactory(
            (TreeTableColumn.CellDataFeatures<Employee, String> param)
            -> new ReadOnlyStringWrapper(param.getValue().getValue().getName())
    );

    TreeTableColumn<Employee, Double> salaryColumn
            = new TreeTableColumn<>("Salary");
    salaryColumn.setPrefWidth(190);
    salaryColumn.setCellValueFactory(new Callback<CellDataFeatures<Employee, Double>, ObservableValue<Double>>() {
  @Override
  public ObservableValue<Double> call(CellDataFeatures<Employee, Double> p)          {
// p.getValue() returns the Employee instance for a particular TableView row
      return p.getValue().getValue().getSalary();
 }
 });
    salaryColumn.setCellFactory(ProgressBarTreeTableCell.<Employee>forTreeTableColumn());
    root2.getChildren().add(root);

    TreeTableView<Employee> treeTableView = new TreeTableView<>(root2);
    treeTableView.getColumns().setAll(empColumn, salaryColumn);
    treeTableView.setRowFactory(f -> new CheckBoxTreeTableRowHack<>());
    sceneRoot.getChildren().add(treeTableView);
    stage.setScene(scene);
    stage.show();
    ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1);
    executorService.scheduleAtFixedRate(this, 3, 10, TimeUnit.SECONDS);

}

@Override
public void run() {
    root2.getValue().setSalary(calcSalary(root));
}

public double calcSalary(TreeItem<Employee> t) {
    Double salary = 0.0;
    if (!t.isLeaf()) {

        ObservableList<TreeItem<Employee>> al = t.getChildren();
        for (int i = 0; i < al.size(); i++) {
            TreeItem<Employee> get = al.get(i);
            salary += calcSalary(get);
        }
        t.getValue().setSalary(salary);
    }
    return salary += t.getValue().getSalary();
}

public class Employee {

    private SimpleStringProperty name;
    private SimpleDoubleProperty salary;

    public SimpleStringProperty nameProperty() {
        if (name == null) {
            name = new SimpleStringProperty(this, "name");
        }
        return name;
    }

    public SimpleDoubleProperty salaryProperty() {
        if (salary == null) {
            salary = new SimpleDoubleProperty(this, "salary");
        }
        return salary;
    }

    private Employee(String name, Double salary) {
        this.name = new SimpleStringProperty(name);
        this.salary = new SimpleDoubleProperty(salary);
    }

    public String getName() {
        return name.get();
    }

    public void setName(String fName) {
        name.set(fName);
    }

    public Double getSalary() {
        return salary.get();
    }

    public void setSalary(Double fName) {
        salary.set(fName);
    }
}
}

Я получаю ошибку при return p.getValue().getValue().getSalary(); он говорит Incompatible Types: Double cannot be converted to ObservableValue<Double>. Поскольку я знаю, что вы должны вернуть ObservableValue в возврате метода вызова. Но, как новичок, я не могу найти способ отличить значение. Установка строки проста.

До сих пор я попытался return new ReadOnlyDoubleWrapper(p.getValue().getValue().getSalary()); но это тоже не получилось для меня.

Я использую JavaFx 8.

Я пытаюсь создать Salary Bars, который также может использоваться как индикатор выполнения задачи и ее подзадач. (Просто игра с пользовательским интерфейсом). Но не знаю, как связать их с реальными значениями Employee, так как я предполагаю, что обычный вид таблицы отличается от представления таблицы дерева. Благодаря ! :)

  • 0
    @ItachiUchiha Как я могу установить зарплату для индикатора выполнения в соответствии с вашим кодом. Мои извинения, я работаю постоянно, поэтому, возможно, мне становится трудно понять код: P. Это не просто, как setCellValueFactory( new PropertyValueFactory<Employee, Double>("salary") );
Теги:
progress-bar
javafx-8
treetableview

1 ответ

2
Лучший ответ

Это по существу то же самое, что и свойства JavaFX в TableView: salaryProperty не ObservableValue<Double> а ObservableValue<Number>.

Вам нужно сделать столбец TreeTableColumn<Employee, Number>. Затем вы можете просто вернуть salaryProperty для сотрудника:

TreeTableColumn<Employee, Number> salaryColumn
        = new TreeTableColumn<>("Salary");
salaryColumn.setCellValueFactory(p -> p.getValue().getValue().salaryProperty());

Другой вариант - использовать salaryProperty().asObject() который возвращает ObjectProperty<Double> связанный двунаправленно с salaryProperty():

TreeTableColumn<Employee, Double> salaryColumn
        = new TreeTableColumn<>("Salary");
salaryColumn.setCellValueFactory(p -> 
    p.getValue().getValue().salaryProperty().asObject());
  • 0
    Спасибо :), Второй работал, но прогрессбар не показывает, как я ожидал. Все индикаторы заполнены, я хотел установить максимальное значение индикатора прогресса родительского контроля, а остальные - в соответствии с этим (промежуточное значение). Например, если Parent ProgressBar равен 100 и, допустим, сумма дочерних элементов ProgressBars должна быть равна 100 (например, 10,20,30,40 могут быть значениями дочерних элементов progressBar). Это достижимо?
  • 1
    ProgressBar принимает значения для progress между 0 и 1 . Чтобы получить правильное отображение для других диапазонов, необходимо создать подкласс TreeTableCell и установить значение напрямую.
Показать ещё 4 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню