2

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

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

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

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

有谁知道是否有办法强制stopCellEditing()首先被调用,还是我应该为这个问题弥补一些变通方法?

4

2 回答 2

1

JTree中没有类似的客户端属性Swing。但是JXTree,来自JTree, in的派生类SwingX会:invokeStopEditing

如果你不能使用SwingX,你可以随时查看源代码,JXTree看看这个 StopEditing 机制是如何工作的:JXTree SwingX 1.0 API Documentation and Javadoc (go to Source tab)

特别是,从 line 开始974,创建一个监听器来监视“ permanentFocusOwner”等属性的变化KeyboardFocusManager......

于 2009-09-29T19:01:23.710 回答
0

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

但是,您还引用了与 a 上的单元格编辑有关的较早项目JTable,它失去了对外部组件的焦点,以及这对编辑单元格的影响。我认为这是一个暗示,你想要一个类似的解决方案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你按下 a 时的行为方式相同JButton

于 2009-10-04T02:09:53.667 回答