gpt4 book ai didi

java - 根据行项目创建CellFactory

转载 作者:行者123 更新时间:2023-11-30 03:18:23 25 4
gpt4 key购买 nike

我尝试创建TableColumnChoiceBoxTableCell 。选择在这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需要CallbackTableColumn<S,T>作为函数参数,并且无法在 CellFactory 内访问它。我可能可以做一些肮脏和丑陋的黑客来得到我想要的原因,但我很想有一些好的解决方案。

最佳答案

提醒一下基 native 制:cellFactory 用于为给定列创建任何 单元格。调用代码(即表皮肤实现深处的 VirtualFlow)不感兴趣或者根本不知道单元格是为哪一行创建的。而且,它会经常被重复使用——即设置一个新项目。总之,创建单元格的时刻并不是使用行相关数据配置单元格的正确时间。一旦知道了行,就必须稍后完成此操作:最明显的候选者是 updateItem(T, boolean)

现在回到具体的 ChoiceBoxTableCell:不幸的是,它的实现太愚蠢了,根本不支持其选择项的动态更新。因此,您需要一个支持动态的自定义扩展。好的一面是:ChoiceBoxTableCell 公开其项目,从而允许根据需要更改其内容。

正如代码注释中所指出的,事实证明,明显的钩子(Hook)并没有很好地工作。因此必须将配置移至 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));
}
}
}

附录:

no ideal, because items won't be updated when it is already expanded

如果您需要,您可以将 choiceBox 的项目绑定(bind)到提供程序返回的项目,而不是调用 setAll(provider.getItems()) 执行以下操作:

Bindings.bindContent(getItems(), provider.getItems());

关于java - 根据行项目创建CellFactory,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31959021/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com