表格单元格中的 TreeView Java FX 8

aba*_*der 0 java javafx javafx-2 javafx-8

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

只是为了澄清,我试图在表格单元格上实现类似日期选择器或颜色选择器的功能,但使用我自己的项目列表作为树。

该表是这样定义的

private TableView<User> userTable;
Run Code Online (Sandbox Code Playgroud)

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

private TableColumn<User, TreeView> col4;
Run Code Online (Sandbox Code Playgroud)

我设置了像这样的 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
            }
    });
Run Code Online (Sandbox Code Playgroud)

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

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

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

        @Override
        public ObservableValue<TreeView> call(
                CellDataFeatures< User,TreeView> param)
        {
                     }
  }
Run Code Online (Sandbox Code Playgroud)

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

Jam*_*s_D 5

您需要区分您(及其)正在呈现的数据以及用于呈现这些数据的单元格。该对象确定如何从整行的值中获取特定列的值(即数据)。是一个对象,它确定如何获取向用户呈现数据的单元格。TableViewTableColumncellValueFactorycellFactory

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

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

TableView<User> userTable ;
TableColumn<User, Options> optionsCol ;
Run Code Online (Sandbox Code Playgroud)

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...
}
Run Code Online (Sandbox Code Playgroud)

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

public class Options {
    // properties etc
}
Run Code Online (Sandbox Code Playgroud)

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

optionsCol.setCellValueFactory(new PropertyValueFactory("options"));
Run Code Online (Sandbox Code Playgroud)

(或者在 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>
    );
Run Code Online (Sandbox Code Playgroud)

这在某种程度上更有效,因为它避免了使用的反射PropertyValueFactory,并且代码不多,特别是如果您省略 lambda 表达式的参数类型)。

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

我不太明白你的ComboBox适合位置,但这个答案应该足以让你根据需要进行工作。现在cellFactory只需返回一个TableCell使用 aTreeView来显示Options对象的 a :

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);
        }
    }
});
Run Code Online (Sandbox Code Playgroud)

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