【问题标题】:How do I restore a previous value in JavaFX TableColumn's onEditCommit?如何在 JavaFX TableColumn 的 onEditCommit 中恢复以前的值?
【发布时间】:2015-04-08 10:28:56
【问题描述】:

我有一个用 JavaFX 编写的表,用户可以选择编辑其中的一列。当对单元格进行编辑时,我尝试根据新文本重命名一些内部对象。如果重命名失败,我会发出通知 + 弹出错误对话框,然后我想将原始文本恢复到该字段中。出于某种原因,这让我陷入了无限循环的错误弹出窗口。

我目前从原作者那里得到的代码如下:

mNameColumn.setOnEditCommit(
    new EventHandler<TableColumn.CellEditEvent<StateDefinition, String>>() {
        @Override
        public void handle(TableColumn.CellEditEvent<StateDefinition, String> event) {
            try {
                someObject.rename(((StateDefinition) event.getTableView().getItems().get(event.getTablePosition().getRow())).getState(), event.getNewValue());
            } catch (MYException ex) {
                MyNotificationCollector.addNotification("Failed renaming: " + ex.getLocalizedMessage(), NotificationType.SYSTEM_WARNING);
                //popup error message code here
                // Need to revert the cell's text to the previous value here...
            }
        }
    });

知道我做错了什么吗?如何在不再次调用单元格编辑提交事件的情况下恢复旧值?

谢谢, 奥伦

【问题讨论】:

标签: java javafx tablecolumn


【解决方案1】:

尝试使用

TableColumn.CellEditEvent.getOldValue()

例如:

        try {
            someObject.rename(((StateDefinition) event.getTableView().getItems()
               .get(event.getTablePosition().getRow())).getState(), 
                   event.getNewValue());

        } catch (MYException ex) {
            MyNotificationCollector.addNotification("Failed renaming: " 
                + ex.getLocalizedMessage(), NotificationType.SYSTEM_WARNING);

            // popup error message code here
            // Revert the cell's text to the previous value here...

           someObject.rename(((StateDefinition) event.getTableView().getItems()
                .get(event.getTablePosition().getRow())).getState(),
                   event.getOldValue());

            // workaround for refreshing rendered view
            event.getTableView().getColumns().get(0).setVisible(false);
            event.getTableView().getColumns().get(0).setVisible(true);
        }

最后 2 行是用于刷新 tableview 渲染值的旧解决方法。

编辑:

如果抛出异常时支持的数据模型(tableview 的项目字段)未更改,则只需更新 catch 块中的 tableview 呈现:

} catch (MYException ex) {
            MyNotificationCollector.addNotification("Failed renaming: " 
                + ex.getLocalizedMessage(), NotificationType.SYSTEM_WARNING);

            // workaround for refreshing rendered view
            event.getTableView().getColumns().get(0).setVisible(false);
            event.getTableView().getColumns().get(0).setVisible(true);
        }

【讨论】:

  • 重命名本身失败,所以再次调用重命名是多余的。我所需要的只是恢复到旧值的 UI(表格)。我的问题只发生在涉及弹出窗口时,不知何故它会导致事件一次又一次地发生,我无法阻止它。
  • 所以我想我想做的是以某种方式调用取消编辑事件和/或强制单元格恢复其旧值。
  • @OrenSarid 查看更新。我无法告诉您有关您的弹出窗口的任何信息,因为没有关于它的信息。
  • 弹出窗口只是一个 JavaFX 对话框,我用 OK 按钮显示以引起用户的注意。但如果我使用它 - 事件会一次又一次地显示。无论如何,我尝试了您的解决方法,但它没有帮助,因为我得到的值有时是错误的(我更新为一个有效的名称,然后是一个无效的名称,然后我在刷新中得到第一个)。
  • @OrenSarid,首先,注释掉弹出逻辑,主要解决表格问题。接下来有两种方法,在验证用户承诺值时。 1)如果提交的值无效,它不会反映到数据模型中,所以上面描述的刷新就足够了。 2)如果提交的值无效但反映了,那么再次设置为已经验证的原始 getOldValue() 就足够了。
【解决方案2】:

这是一个bug in TableCell(实际上,所有单元格 - 尽管由于不同的原因,所有类型的单元格都不明显):如果自定义提交处理程序拒绝编辑的值(或在将其写回数据之前以任何方式更改它),就会发生这种情况)。技术原因是用 newValue 调用 updateItem

@Override 
public void commitEdit(T newValue) {
    // ... cell book-keeping
    // ... fire editCommitEvent to allow handler to save value
    // update the item within this cell, so that it represents the new value
    updateItem(newValue, false); // <-- assumes that the handler saves the new value as-is

在问题解决之前(希望很快;)我们可以通过重写方法来解决它,让它调用 super 然后强制进行完整更新:

@Override
public void commitEdit(T newValue) {
    super.commitEdit(newValue);
    updateIndex(getIndex());
}

【讨论】:

    猜你喜欢
    • 2013-11-25
    • 2013-12-14
    • 1970-01-01
    • 2019-05-27
    • 1970-01-01
    • 2018-07-21
    • 2017-11-25
    • 1970-01-01
    • 2014-07-21
    相关资源
    最近更新 更多