如何在JavaFx中的TreeView的单个单元格项目中将对象的属性显示为控件?

时间:2016-12-25 21:45:54

标签: javafx data-binding combobox treeview controls

是否可以通过TreeView的单元格项中的Label,ComboBox(或更多控件)来表示Node的属性? 我想在每个树视图单元格中显示节点的名称,所选项目(如果可能,还有更多控件(例如复选框))。 有可能这样做吗?

根据Oracle教程(http://docs.oracle.com/javafx/2/ui_controls/tree-view.htm),CheckBoxTreeCell,ChoiceBoxTreeCell,ComboBoxTreeCell,TextFieldTreeCell类可用于类似目的,但我无法弄清楚如何使用其中的许多类单细胞,或如何为细胞制作可编辑的模板。

我的模型与此类似:

public enum Options {
    Option1, Option2, ... OptionN;
}

// I want to use this Node class as a TreeItem
public class Node {

    private Node parentNode;
    private List<Node> childNodes;

    // Data to be displayed and edited by using only the tree
    private String name;            // displayed as Label
    private Options selectedOption; // displayed as ComboBox
    // private boolean valid;       // displayed as Checkbox
    // these properties possibly should be JavaFX's ObjectProperty, StringProperty, ListProperty etc.

    // ...
}

我想要展示的内容与此类似:

Node0 [ComboBox: (selectedOption = Options.OptionI)]
|-- Node1 [ComboBox: (selectedOption = Options.OptionJ)]
|   |-- Node11 [ComboBox: (selectedOption = Options.OptionK)]
|-- Node2 [ComboBox: (selectedOption = Options.OptionK)]
    |-- Node21 [ComboBox: (selectedOption = Options.OptionL)]
    |-- Node22 [ComboBox: (selectedOption = Options.OptionJ)]

...用户可以通过编辑树的元素来设置Node的属性。 我应该使用什么方法来实现这个功能?

很抱歉,如果这是一个基本问题,我刚刚开始学习JavaFx。

1 个答案:

答案 0 :(得分:0)

您可能需要考虑使用TreeTableView。如果Control不符合您的需求,您可以使用自定义TreeCell

TreeView<Node> treeView = ...
treeView.setCellFactory(t -> new TreeCell<Node>() {

    private final ComboBox<Options> comboBox = new ComboBox<>(FXCollections.observableArrayList(Options.values()));
    private final CheckBox valid = new CheckBox("valid");
    private final VBox container = new VBox(comboBox, valid); // todo: add more controls for other properties

    private boolean swapping;

    {
        comboBox.valueProperty().addListener((observable, oldValue, newValue) -> {
            if (!swapping) {
                 getItem().setSelectedOption(newValue);
            }
        });
        valid.selectedProperty().addListener((observable, oldValue, newValue) -> {
            if (!swapping) {
                 getItem().setValid(newValue);
            }
        });

        // todo: listeners to other controls...

        setContentDisplay(ContentDisplay.BOTTOM);
    }

    @Override
    public void updateItem(Node item, boolean empty) {
        super.updateItem();
        if (empty) {
            setText("");
            setGraphic(null);
        } else {
            setText(item.getName());
            setGraphic(container);
            swapping = true;

            comboBox.setValue(item.getSelectedOption());
            valid.setSelected(item.isValid());
            // todo: initialize other nodes with item values

            swapping = false;
        }
    }
});
相关问题