gpt4 book ai didi

java - 如何为 TableView/TreeTableView 启用 focusLost 提交?

转载 作者:搜寻专家 更新时间:2023-10-30 19:56:40 24 4
gpt4 key购买 nike

是否有任何简单的方法让 TreeTableView(或 TableView)尝试在失去焦点时提交值?

不幸的是,我没有成功使用 javafx TableCellFactories 的任何默认实现,这就是为什么我尝试了我自己的 TreeTableCell 实现以及一些不同的 tableCell 实现,例如来自 Graham Smith 的实现。 ,这似乎是最直接的,因为它已经为失去焦点实现了一个钩子(Hook),但是该值从未提交并且用户更改被重置为原始值。

我的猜测是,每当失去焦点时,受影响的 Cell 的 editingProperty 始终已经为 false,这导致 Cell 永远不会在 focusLost 上提交值。这里是原始 (oracle-)TreeTableCell 实现 (8u20ea) 的相关部分,这导致我的方法失败:

 @Override public void commitEdit(T newValue) {
if (! isEditing()) return; // <-- here my approaches are blocked, because on focus lost its not editing anymore.

final TreeTableView<S> table = getTreeTableView();
if (table != null) {
@SuppressWarnings("unchecked")
TreeTablePosition<S,T> editingCell = (TreeTablePosition<S,T>) table.getEditingCell();

// Inform the TableView of the edit being ready to be committed.
CellEditEvent<S,T> editEvent = new CellEditEvent<S,T>(
table,
editingCell,
TreeTableColumn.<S,T>editCommitEvent(),
newValue
);

Event.fireEvent(getTableColumn(), editEvent);
}

// inform parent classes of the commit, so that they can switch us
// out of the editing state.
// This MUST come before the updateItem call below, otherwise it will
// call cancelEdit(), resulting in both commit and cancel events being
// fired (as identified in RT-29650)
super.commitEdit(newValue);

// update the item within this cell, so that it represents the new value
updateItem(newValue, false);

if (table != null) {
// reset the editing cell on the TableView
table.edit(-1, null);

// request focus back onto the table, only if the current focus
// owner has the table as a parent (otherwise the user might have
// clicked out of the table entirely and given focus to something else.
// It would be rude of us to request it back again.
ControlUtils.requestFocusOnControlOnlyIfCurrentFocusOwnerIsChild(table);
}
}

我成功地覆盖了这个方法并在调用原始 commitEdit() 方法之前“手动”提交了值,但这会导致像 enter 这样的键上的提交提交值两次(在键上 + 在焦点丢失时)。此外,我根本不喜欢我的方法,所以我想知道是否还有其他人以“更好”的方式解决了这个问题?

最佳答案

经过一些挖掘,结果是罪魁祸首(又名:在 textField 失去焦点之前取消编辑的合作者)是处理 mousePressed 的 TableCellBehaviour/Base:

  • mousePressed 调用 simpleSelect(..)
  • 在检测到单击时调用 edit(-1, null)
  • 在 TableView 上调用相同的方法
  • 将其 editingCell 属性设置为 null
  • tableCell 监听该属性并通过取消自己的编辑使用react

不幸的是,一个 hackaround 需要 3 个合作者

  • 带有附加 API 的 TableView 以终止编辑
  • 具有重写的 simpleSelect(...) 的 TableCellBehaviour,它在调用 super 之前调用额外的 api(而不是 edit(-1..))
  • 配置了扩展行为的 TableCell并且知道表的扩展属性

一些代码片段(full code):

// on XTableView:
public void terminateEdit() {
if (!isEditing()) return;
// terminatingCell is a property that supporting TableCells can listen to
setTerminatingCell(getEditingCell());
if (isEditing()) throw new IllegalStateException(
"expected editing to be terminated but was " + getEditingCell());
setTerminatingCell(null);
}

// on XTableCellBehaviour: override simpleSelect
@Override
protected void simpleSelect(MouseEvent e) {
TableCell<S, T> cell = getControl();
TableView<S> table = cell.getTableColumn().getTableView();
if (table instanceof XTableView) {
((XTableView<S>) table).terminateEdit();
}
super.simpleSelect(e);
}

// on XTextFieldTableCell - this method is called from listener
// to table's terminatingCell property
protected void terminateEdit(TablePosition<S, ?> newPosition) {
if (!isEditing() || !match(newPosition)) return;
commitEdit();
}

protected void commitEdit() {
T edited = getConverter().fromString(myTextField.getText());
commitEdit(edited);
}

/**
* Implemented to create XTableCellSkin which supports terminating edits.
*/
@Override
protected Skin<?> createDefaultSkin() {
return new XTableCellSkin<S, T>(this);
}

注意:TableCellBehaviour 的实现在 jdk8u5 和 jdk8u20 之间发生了巨大变化(黑客的乐趣 - 不适合生产使用 ;-) - 在后者中覆盖的方法是 handleClicks(..)

顺便说一句:大量投票给 JDK-8089514 (在旧的 jira 中是 RT-18492)可能会加速核心修复。不幸的是,至少需要作者角色才能在新跟踪器中投票/评论错误。

关于java - 如何为 TableView/TreeTableView 启用 focusLost 提交?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24694616/

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