Kev*_*ong 0 java data-binding model-view-controller treeview javafx
我有一个包含不同数据类型字段的对象:
public class MyObject{
     private String field1;
     private CustomObject field2;
     private int field3;
     ...
}
我想创建一个MyObject具有多个MyObject节点的树视图,每个节点都有字段(field1、field2、field3..etc )作为子节点。
我知道我可以制作一个字符串的 TreeView 并使用 addNode(MyObject obj) 方法自行填充它,在该方法中我将添加我需要的各个 TreeItems。但是,我使用 TableView 执行此操作,其中我能够将列与字段属性绑定。例如:
TableView<MyObject> table;
TableColumn<MyObject, String> myColumn;
myColumn.setCellValueFactory(new PropertyValueFactory<>("field1"));
有什么办法可以为 a 做类似的事情吗TreeView<MyObject>?我不反对创建一个扩展的子类TreeItem<?>
我正在寻找的最终结果将是这样的:
--> First My Object
    ->field1: "Value at Field 1"
    ->field2: "Value at Field 2"
    ->field3: 3
--> Second My Object
    ->field1: "Value at Field 1"
    ->field2: "Value at Field 2"
    ->field3: 3
几乎任何时候你TreeView在树的不同节点中使用不同类型的 a 时,你都需要在某处进行一些转换和/或类型检查。
这里一种可能的方法是子类化,TreeItem为要显示的属性提供一个字段,然后使用TreeCell显示该属性的字符串值的字段。
这是一个非常基本的例子:
import java.util.Arrays;
import java.util.List;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.TreeCell;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.stage.Stage;
public class TreeViewWithProperties extends Application {
    @Override
    public void start(Stage primaryStage) {
        List<SomeEntity> entities = Arrays.asList(
                new SomeEntity("First object", "String value 1", 42),
                new SomeEntity("Second object", "String value 2", 3)
        );
        TreeView<SomeEntity> tree = new TreeView<>();
        tree.setShowRoot(false);
        TreeItem<SomeEntity> treeRoot = new TreeItem<>();
        tree.setRoot(treeRoot);
        for (SomeEntity entity : entities) {
            TreeItem<SomeEntity> item = PropertyTreeItem.baseItem(entity);
            treeRoot.getChildren().add(item);
            item.getChildren().add(new PropertyTreeItem<String>(entity, entity.getStringField()));
            item.getChildren().add(new PropertyTreeItem<Integer>(entity, entity.getValue()));
        }
        tree.setCellFactory(tv -> new TreeCell<SomeEntity>() {
            @Override
            protected void updateItem(SomeEntity entity, boolean empty) {
                super.updateItem(entity, empty);
                PropertyTreeItem<?> item = (PropertyTreeItem<?>) getTreeItem();
                if (empty) {
                    setText(null);
                } else {
                    setText(item.getPropertyValue().toString());
                }
            }
        });
        Scene scene = new Scene(tree);
        primaryStage.setScene(scene);
        primaryStage.show();
    }
    public static class PropertyTreeItem<T> extends TreeItem<SomeEntity> {
        private final T propertyValue ;
        public PropertyTreeItem(SomeEntity entity, T value) {
            super(entity);
            this.propertyValue = value ;
        }
        public static PropertyTreeItem<SomeEntity> baseItem(SomeEntity entity) {
            return new PropertyTreeItem<>(entity, entity);
        }
        public T getPropertyValue() {
            return propertyValue ;
        }
    }
    public class SomeEntity {
        private String name ;
        private String stringField ;
        private int value ;
        public SomeEntity(String name, String stringField, int value) {
            this.name = name;
            this.stringField = stringField;
            this.value = value;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public String getStringField() {
            return stringField;
        }
        public void setStringField(String stringField) {
            this.stringField = stringField;
        }
        public int getValue() {
            return value;
        }
        public void setValue(int value) {
            this.value = value;
        }
        @Override
        public String toString() {
            return name ;
        }
    }
    public static void main(String[] args) {
        launch(args);
    }
}
当然,对此进行一些变化是可能的。如果您想在实体类中使用 JavaFX 属性,并且能够在树外部更改这些值,您可以将文本绑定到单元格中的属性,而不是简单地设置它。