[英]Create CellFactory based on row item
我尝试使用ChoiceBoxTableCell
创建TableColumn
。 此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
将TableColumn<S,T>
作为Callback
作为函数参数,并且无法在CellFactory
访问它。 我可能会做一些肮脏和丑陋的骇客来了解我想要的原因,但我希望有一些不错的解决方案。
提醒基本机制: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));
}
}
}
附录re:
不理想,因为已经扩展的项目不会被更新
如果需要,可以将choiceBox的项目绑定到提供程序返回的项目,而不是调用setAll(provider.getItems())
来做:
Bindings.bindContent(getItems(), provider.getItems());
testColumn.setCellFactory(ChoiceBoxTableCell.forTableCoulmn(<dynamic list>));
这应该工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.