Java Swing:如何在TreeListeners之前调用stopCellEditing():valueChanged?

时间:2009-08-14 08:55:38

标签: java swing jtable tablecelleditor event-dispatching

这是对这些早期问题的后续跟进:

当我使用terminateEditOnFocusLost属性时,如下所示,当表失去焦点时,我的CellEditor正确停止编辑:

jtable.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);

它也适用于我的JButtons。在处理按钮按下操作之前,为我的TableCellEditor 调用stopCellEditing()方法。但是当我将它与JTree一起使用,并且树选择发生变化时,TreeSelectionListener.valueChanged方法在 stopCellEditing()之前被称为

是否有人知道是否有办法强制stopCellEditing()首先被调用,或者我是否应该为这个问题做一些解决方法?

2 个答案:

答案 0 :(得分:1)

JTreeSwing中没有类似的客户端属性。 但JXTree中的JTree来自SwingX的派生类,invokeStopEditing执行:SwingX

如果您无法使用JXTree,则可以随时查看(go to Source tab)的源代码,了解此StopEditing机制如何运作:JXTree SwingX 1.0 API Documentation and Javadoc 974

特别是,从第permanentFocusOwner行开始,会创建一个监听器来监控KeyboardFocusManager等上的“{{1}}”属性更改...

答案 1 :(得分:0)

我不太清楚我理解你关于TreeSelectionListener的问题以及它与被调用的时间stopCellEditing()方法的关系。您是否正在创建自定义TreeCellEditor?如果是这样,有关此编辑器设置的更多信息将非常有用。

但是,您还引用了一个较早的项目,该项目涉及JTable上的单元格编辑,其对外部组件的焦点丢失以及此对编辑单元格的影响。我已经把它作为一个暗示你想要{​​{1}} ...

的类似解决方案

如上所述,JTree未实现开箱即用JTree的属性处理。这并不意味着你可以自己做。

查看"terminateEditOnFocusLost"的代码,非常简单。将一个类放在一起,其中唯一的工作是确定在焦点更改时JTable是否仍然具有焦点,如果没有,则调用JTree,如果失败,则调用stopEditing() 。在这里它适用于树:

cancelEditing()

您将注意到您的树必须以某种方式访问​​此课程。有几个设置调用要执行此操作:

class CellEditorRemover implements PropertyChangeListener {
    KeyboardFocusManager focusManager;
    public CellEditorRemover(KeyboardFocusManager fm) {
        this.focusManager = fm;
    }

    public void propertyChange(PropertyChangeEvent ev) {
        if (!tree.isEditing() || 
          tree.getClientProperty("terminateEditOnFocusLost") != Boolean.TRUE) 
        {
          return;
        }

        Component c = focusManager.getPermanentFocusOwner();
        while (c != null) {
            if (c == tree) { // focus remains inside the tree
                return;
            } else if ((c instanceof Window)
                        || (c instanceof Applet && c.getParent() == null)) 
            {
                if (c == SwingUtilities.getRoot(tree)) {
                    if (!tree.getCellEditor().stopCellEditing()) {
                        tree.getCellEditor().cancelCellEditing();
                    }
                }
                break;
            }
            c = c.getParent();
        }
    }
}

这应该有一个额外的好处,即当您按下tree.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE); KeyboardFocusManager fm = KeyboardFocusManager.getCurrentKeyboardFocusManager(); editorRemover = new CellEditorRemover(fm); fm.addPropertyChangeListener("permanentFocusOwner", editorRemover); 时,JTree的行为与JTable的行为方式相同。