首先我必须道歉,因为英语不是我的母语,但我会尽量在我问什么我清楚。
我有一组在的tableview行,每一行都有每一列diferent comboboxs。 因此,组合框之间的互动必须是每行。 如果在ComboBox A1,我选择第1项,在下拉列表A2的ITEMLIST将被更新。 我的问题是,每一个组合框A2,B2,C2等是否正在按照A1中的选择... ...与B1,C1的组合框同样的事情更新。 我需要更新的仅仅是A2,根据A1。 根据B1 B2等
我通过cellfactory设置的组合框,因为我不得不从后面的数据保存在一个序列化对象。
希望是明确的。
问候。
这是非常痛苦......
从TableCell
,你可以观察到TableRow
通过它的tableRowProperty()
从TableRow
,您可以在该行中观察的项目,通过表行的itemProperty()
当然,从该行中的项目,你可以观察你的模型类中定义的任何属性,并相应地更新在组合框中的项目列表。
痛苦的是,这些价值就可以了,会在某个点的变化。 所以,你需要的东西来观察不断变化,你必须管理添加和删除监听器发生这种情况。
该Bindings.select方法应该是帮助管理这样的事情,但是作为JavaFX的8,它打印巨大的堆栈跟踪到输出的警告每当遇到一个空值,它经常做。 因此,我建议,直到固定做你自己的监听器管理。 (出于某种原因,JavaFX的团队似乎并不认为这是一个大问题,即使在一个Bindings.select定义的路径遇到空值在API文档中明确支持。)
这只是为了稍微不愉快时, getTableRow()
在方法TableCell<S,T>
返回TableRow
,而不是更明显TableRow<S>
(有可能是为了这个,我不能明白了一个道理,但是,嗯...)。 所以,你的代码另外被蒙上散落。
我创建了一个例子的作品:它道歉是基于美国的地理位置,但我有很多已经写好的例子。 我真的希望我失去了一些东西,并且有更容易的方法可以做到这一点,请随时提出的东西,如果任何人有更好的想法。
在最后一个音符:在EasyBind库可以提供结合到一起的任意路径属性简单的方法。
作为@ James_D的例子不再由于链路腐烂运行,而我处理这个同样的问题,这里就是我想通了,要产生这种效果。
这里查看完整的测试用例。
我延长内置ComboBoxTableCell<S, T>
以暴露必要的字段。 定制TableCell
具有Supplier<S> tableValue = (S) this.getTableRow().getItem();
用于访问数据适用对象。 此外,我反射性地检索和存储于电池的参考ComboBox
。 因为它是在超懒洋洋地实例化,我也有通过反射来设置它之前,我可以得到它。 最后,我必须初始化ComboBox
为好,因为这将是在javafx.scene.control.cell.CellUtils.createComboBox
,因为我手动创建。 它揭露这些人好像是很重要的:
在列的CellFactory,我们完成初始化ComboBoxCell。 我们只需要创建我们自定义的新实例ComboBoxTableCell
,然后当显示首次下拉框中(例如,我们可以肯定的是,我们有与电池相关的数据对象),我们将绑定ComboBox#itemsProperty
到Bindings.When
返回适当ObservableList
的情况。
CellFactory:
column1.setCellFactory(c -> {
TransparentComboBoxTableCell<Data, Enum> tcbtc = new TransparentComboBoxTableCell<>();
tcbtc.comboBox.setOnShown(e -> {
if (!tcbtc.comboBox.itemsProperty().isBound()) tcbtc.comboBox.itemsProperty().bind(
Bindings.when(tcbtc.tableValue.get().base.isEqualTo(BASE.EVEN)).then(evens).otherwise(
Bindings.when(tcbtc.tableValue.get().base.isEqualTo(BASE.ODD)).then(odds).otherwise(
FXCollections.emptyObservableList()
))
);
});
return tcbtc;
});
定制ComboBoxTableCell:
public static class TransparentComboBoxTableCell<S, T> extends ComboBoxTableCell<S, T> {
public TransparentComboBoxTableCell() {
this(FXCollections.observableArrayList());
}
public TransparentComboBoxTableCell(ObservableList<T> startingItems) {
super(startingItems);
try {
Field f = ComboBoxTableCell.class.getDeclaredField("comboBox");
f.setAccessible(true);
f.set(this, new ComboBox<>());
comboBox = (ComboBox<T>) f.get(this);
// Setup out of javafx.scene.control.cell.CellUtils.createComboBox
// comboBox.converterProperty().bind(converter);
comboBox.setMaxWidth(Double.MAX_VALUE);
comboBox.getSelectionModel().selectedItemProperty().addListener((ov, oldValue, newValue) -> {
if (this.isEditing()) {
this.commitEdit((T) newValue);
}
});
} catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException ex) {
Logger.getLogger(FXMLDocumentController.class.getName()).log(Level.SEVERE, null, ex);
throw new Error("Error extracting 'comboBox' from ComboBoxTableCell", ex);
}
tableValue = () -> (S) this.getTableRow().getItem();
}
public final ComboBox<T> comboBox;
public final Supplier<S> tableValue;
}