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