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

发布于 2024-08-02 02:06:28 字数 843 浏览 9 评论 0原文

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

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

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

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

有谁知道是否有一种方法可以强制首先调用 stopCellEditing() ,或者我应该为这个问题找到一些解决方法?

This is a follow-up to these earlier questions:

When I use the terminateEditOnFocusLost property, like below, my CellEditor correctly stops editing when the table loses focus:

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

It also works with my JButtons. The stopCellEditing() method is called for my TableCellEditor before the button press action is processed. But when I use it with a JTree, and the tree selection changes, the TreeSelectionListener.valueChanged method is called before stopCellEditing().

Does any one know if there is a way to force stopCellEditing() to be invoked first, or should I just make up some work-around for this issue?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

最冷一天 2024-08-09 02:06:28

JTreeSwing 中没有类似的客户端属性。
但是 SwingXJXTree(从 JTree 派生的类)执行以下操作:invokeStopEditing

如果您无法使用 SwingX,您可以随时查看 JXTree 的源代码,看看这个 StopEditing 机制是如何工作的:JXTree SwingX 1.0 API 文档和 Javadoc (转至源选项卡)

特别地,从第 974 行开始,创建一个侦听器来监视 KeyboardFocusManager 等上的“permanentFocusOwner”属性更改...

JTree does not have similar client property in Swing.
But JXTree, a derived class from JTree, in SwingX does: invokeStopEditing.

If you can't use SwingX, you can always look at the source code of JXTree and see how this StopEditing mecanism works: JXTree SwingX 1.0 API Documentation and Javadoc (go to Source tab)

Specially, starting from line 974, a listener is created to monitor "permanentFocusOwner" property change on the KeyboardFocusManager etc...

等往事风中吹 2024-08-09 02:06:28

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

但是,您还引用了之前的一项,该项目涉及 JTable 上的单元格编辑、其对外部组件的焦点丢失以及这对编辑单元格的影响。 我将此视为您希望为 JTree 提供类似的解决方案的暗示...


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

查看 JTable 的代码,它非常简单。 一个类放在一起,其唯一的工作是在焦点更改时确定 JTree 是否仍然具有焦点,如果没有,则调用 stopEditing() ,如果没有,则调用 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 时的行为相同。代码>JButton。

I am not quite sure I understand your question with regards to the TreeSelectionListener and how it relates to the timing stopCellEditing() method being called. Are you creating a custom TreeCellEditor? If so, some more info on the setup of this editor would be useful.

However, you also referenced an earlier item which pertained to cell editing on a JTable, its loss of focus to an outside component, and the affect of this on the editing cell. I have taken that as a hint that you would like a similiar solution for JTree...


As noted, JTree does not implement the handling of the property for "terminateEditOnFocusLost" out of the box. This doesn't mean that you can do it yourself.

Looking at the code for JTable, it is pretty straight forward. A class is put together whose only job is to identify if the JTree still has focus when there is a focus change, and if not, it calls stopEditing() and if that fails it calls cancelEditing(). Here it is, adapted for a tree:

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();
        }
    }
}

You will note that your tree has to be accessible somehow to this class. There are a couple setup calls to perform to make this work:

tree.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
KeyboardFocusManager fm = 
                KeyboardFocusManager.getCurrentKeyboardFocusManager();
editorRemover = new CellEditorRemover(fm);
fm.addPropertyChangeListener("permanentFocusOwner", editorRemover);

This should have the added benefit of making your JTree behave the same way that your JTable behaves when you press a JButton.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文