我的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的可观察值并仍显示字符串。
答案 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]类,因为它会变得有点冗长,而不是我在这里的匿名内部课程)。但这应该给你基本的结构。