表格单元格中的TreeView Java FX 8



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

为了澄清,我正试图在表单元格上实现一个Datepicker或类似于colorpicker的功能,但我自己的项目列表是一个树。

该表的定义如下

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类型的可观测值,并且仍然显示字符串。

您需要区分TableView(及其TableColumns(正在显示的数据和用于显示这些数据的单元格。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);
        }
    }
});

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

最新更新