表格单元格Java FX 8中的TreeView

时间:2014-05-17 18:40:51

标签: java javafx javafx-2 javafx-8

我的UI中有一个TableView,它显示数据库中的用户列表。此表的其中一列是可编辑的,启用编辑后,此特定列的单元格将成为树视图,列出可以选择的各种选项。

为了澄清一点,我正在尝试在表格单元格上实现Datepicker或类似颜色的功能,但我将自己的项目列表作为树。

该表定义如下

private TableView<User> userTable;

显示树视图的特定列定义如下

private TableColumn<User, TreeView> col4;

我设置了这样的setcellFactory方法来显示树

col4.setCellFactory(new Callback<TableColumn<User,TreeView>, TableCell<User,TreeView>>() {

            @Override
            public TableCell<User, TreeView> call(
                    TableColumn<User, TreeView> param)
            {
                returns a comboboxtablecell which is filled with a tree
            }
    });

在表格中,在相应的列中,当我单击单元格时,单元格显示一个组合框,打开时的组合框显示树值。

但是当单元格处于不可编辑状态时,我不知道应该如何使用字符串值设置setcellValuefactory

col4.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<User,TreeView>, ObservableValue<TreeView>>() {

        @Override
        public ObservableValue<TreeView> call(
                CellDataFeatures< User,TreeView> param)
        {
                     }
  }

当单元格处于不可编辑状态时,我希望将树视图中的值显示为字符串。我不知道如何根据方法签名返回类型treeview的可观察值并仍显示字符串。

1 个答案:

答案 0 :(得分:3)

您需要区分TableView(及其TableColumn s)所呈现的数据,以及用于显示这些数据的单元格。 cellValueFactory是一个对象,它确定如何从整行的值中获取特定列的值(即数据)。 cellFactory是一个对象,用于确定如何获取向用户显示数据的单元格。

任何时候你写TableColumn<User, TreeView<...>>这样的东西(几乎总是)是个错误。类型参数中的第一个类型是表的每一行中对象的类型 - 这里很好 - 第二种是显示的数据类型。 TreeView不是数据类型:它是UI元素的类型,即用于显示数据的类型。

所以你想要这些东西。 (你在解释数据模型时没有太具体 - 这很好 - 但这可能不太正确;但它会给你这个想法。)

TableView<User> userTable ;
TableColumn<User, Options> optionsCol ;

User课程将有ObjectProperty<Options>

public class User {
    private final ObjectProperty<Options> options = new SimpleObjectProperty<>(this, "options", new Options());
    public final Options getOptions() {
        return options.get();
    }
    public final void setOptions(Options options) {
        this.options.set(options);
    }
    public ObjectProperty<Options> optionsProperty() {
        return options ;
    }

    // other properties, etc...
}

显然,这取决于封装该列中显示的数据的Options类:

public class Options {
    // properties etc
}

现在您只需使用默认的单元格值工厂:

optionsCol.setCellValueFactory(new PropertyValueFactory("options"));

(或者在JavaFX 8中,我更喜欢

    optionsCol.setCellValueFactory((TableColumn.cellDataFeatures<User, Options> data) -> 
        data.getValue()    // this is the User object
        .optionsProperty() // this is an ObjectProperty<Options>, which is an ObservableValue<Options>
    );

它更有效,因为它避免了PropertyValueFactory使用的反射,并且没有更多代码,特别是如果省略lambda表达式的参数类型。)

(您不必像这样设置。如果Options不是User的固有部分,那么您可以拥有Map<User, ObjectProperty<Options>>定义并使用它来返回与每个用户关联的ObjectProperty<Options>。我展示的方式只是最常见且最简单的方式。)

我真的不明白你的ComboBox适合哪里,但这个答案应该足以让你在你需要的时候工作。 cellFactory现在只需返回使用TableCell显示TreeView对象的Options

optionsCol.setCellFactory( col -> new TableCell<User, Options>() {
    private TreeView<...> treeView ;
    {
        treeView = new TreeView<>(...);
        // configure tree view, etc
    }
    @Override
    public void updateItem(Options options, boolean empty) {
        super.updateItem(options, empty) ;
        if (empty) {
            setGraphic(null);
        } else {
            // configure treeView with data from options, etc
            setGraphic(treeView);
        }
    }
});

你提到单元格是可编辑的,所以你需要连接单元格的所有编辑内容(你可能想要使用一个命名的[inner]类,因为它会变得有点冗长,而不是我在这里的匿名内部课程)。但这应该给你基本的结构。