Java Swing : How to invoke stopCellEditing() before TreeListeners:valueChanged?

怎甘沉沦 提交于 2019-12-11 03:56:01

问题


This is a follow-up to these earlier questions:

  • How to stop editing with DefaultCellEditor when a separate JBtton is pressed
  • Sun Bug 4724980: JTable: Add API to control what happens to edits when table loses focus.

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?


回答1:


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...




回答2:


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.



来源:https://stackoverflow.com/questions/1276769/java-swing-how-to-invoke-stopcellediting-before-treelistenersvaluechanged

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!