我尝试使用TableColumn
创建ChoiceBoxTableCell
。此ChoiceBox
中的选项是基于与当前行关联的项目动态生成(并随时间更改)。我尝试了不同的方法,但似乎没有任何工作。
我想有这样的事情:
private DataProvider dataProvider;
private TableColumn<Phone, String> testColumn;
public void initialize() {
testColumn.setCellFactory(param, phone -> new ChoiceBoxTableCell<Phone, String>(dataProvicer.get(phone)));
}
其中:
public interface DataProvider {
ObservableList<String> get(Phone phone);
}
这是我希望拥有的理想代码,但正如您所知setCallFactory
以Callback
为TableColumn<S,T>
作为函数参数,没有办法在CellFactory
内访问它。我可能会做一些肮脏和丑陋的黑客来得到我想要的东西,但我希望有一个很好的解决方案。
答案 0 :(得分:3)
提醒基本机制:cellFactory用于为给定列创建任何单元格。调用代码(即表的皮肤实现深处的VirtualFlow)对事件不知道或不知道创建单元格的哪一行。此外,它将被重复使用 - 即设置一个新项目 - 经常。总之,创建单元格的时刻不是使用行相关数据配置单元格的正确时机。一旦知道了这一行,就必须在以后完成:最明显的候选者是updateItem(T, boolean)
。
现在回到具体的ChoiceBoxTableCell:遗憾的是,它的实现太愚蠢了,根本不支持其选择项的动态更新。因此,您需要一个支持动态的自定义扩展。好的一面是:ChoiceBoxTableCell公开了它的项目,因此可以根据需要更改其内容。
如代码注释中所述,事实证明,明显的钩子并没有很好地解决问题。所以必须将配置移动到startEdit方法。
一些代码:
public interface ChoiceItemProvider<S, T> {
ObservableList<T> getItems(S source);
}
public class DynamicChoiceBoxTableCell<S, T> extends ChoiceBoxTableCell<S, T> {
private ChoiceItemProvider<S, T> provider;
public DynamicChoiceBoxTableCell(ChoiceItemProvider<S, T> provider) {
super();
this.provider = provider;
}
/**
* Not so obvious hook: overridden to update the items of the
* choiceBox.
*/
@Override
public void startEdit() {
super.startEdit();
updateItems();
}
/**
* Obvious hook: override to update the items of the choiceBox.
* Not fully working - for some reason, the current item isn't
* selected after starting the edit.
*/
@Override
public void updateItem(T item, boolean empty) {
super.updateItem(item, empty);
// updateItems();
}
/**
* Dynamically updates the items to current rowItem.
*/
@SuppressWarnings("unchecked")
protected void updateItems() {
TableRow<S> tableRow = getTableRow();
S rowItem = tableRow != null ? tableRow.getItem() : null;
if (provider == null || rowItem == null) return;
if (provider != null) {
getItems().setAll(provider.getItems(rowItem));
}
}
}
补遗:
不理想,因为项目已经展开时不会更新
如果您需要,可以将choiceBox项目绑定到提供者返回的项目,而不是调用setAll(provider.getItems())
来执行:
Bindings.bindContent(getItems(), provider.getItems());
答案 1 :(得分:-1)
testColumn.setCellFactory(ChoiceBoxTableCell.forTableCoulmn(<dynamic list>));
这应该有用。