Get edited TreeNode from CellEditorListener

I previously asked how to fire an event when a TreeNode was renamed ( here ). My question was answered, but I ran into another problem. I need to access a TreeNode that is being edited in the CellEditorListenerStopped edit event. This is the code I have to do:

package com.gamecreator; import javax.swing.event.CellEditorListener; import javax.swing.event.ChangeEvent; import javax.swing.tree.DefaultTreeCellEditor; public class CustomCellEditorListener implements CellEditorListener { public CustomCellEditorListener() { } public void editingCanceled(ChangeEvent e) { } public void editingStopped(ChangeEvent e) { DefaultTreeCellEditor editor = (DefaultTreeCellEditor) e.getSource(); //This gives me the error. CustomTreeNode node = //What do I put here???; node.getResource().setName((String) node.getUserObject()); //For debugging System.out.println(node.getResource().getName()); } } 

I get this error:

Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: javax.swing.tree.DefaultTreeCellEditor $ 1 cannot be thrown javax.swing.tree.DefaultTreeCellEditor

EDIT: In another attempt, I used this code in a CustomCellEditorListener

 public void editingStopped(ChangeEvent e) { TreePath path = ((CustomTreeCellEditor) e.getSource()).getLastPath(); //This gives me the error. CustomTreeNode node = (CustomTreeNode) path.getLastPathComponent(); node.getResource().setName((String) node.getUserObject()); //For debugging System.out.println(node.getResource().getName()); } 

and this code in CustomTreeCellEditor

 public TreePath getLastPath() { return lastPath; } 

I got the same error (I expected to be). What should work for me, so the only real question remains: “Why am I getting an error and how to fix it?”, But if someone has a better way to achieve this, I’m ready to listen.

EDIT 2: I made a small example of what I'm trying to accomplish, which can be found here (This is an Eclipse archive).

+3
source share
2 answers

I found a solution that was actually very simple. When a TreeNode is renamed, it becomes the only selected node in the tree. Because of this, I was able to use:

  CustomTreeNode node = (CustomTreeNode) tree.getLastSelectedPathComponent(); 
0
source

It seems you want to change the Resource name to DefaultMutableTreeNode . As you found, the ChangeEvent source ChangeEvent sent to editingStopped() not in DefaultTreeCellEditor ; this is an editor (anonymous) user interface delegate.

Instead, override getCellEditorValue() in DefaultTreeCellEditor , as shown below. DefaultTreeCellRenderer simply calls toString() via convertValueToText() , which accesses the user object DefaultMutableTreeNode .

Applications: note that isCellEditable() guarantees that only leaf nodes are edited.

As @kleopatra notes in the comments, the previous implementation of TreeCellEditor was invalid because it modified the editable node. In the version below, a new node is created with the updated name; A copy constructor would be useful in this context. The advantage is that userObject remains a Resource . See also this alternative approach .

image

 /** * @see /questions/890010/easy-and-fast-jtree-cell-editor/3184454#3184454 * @see https://stackoverflow.com/a/11639595/230513 * @see https://stackoverflow.com/a/11113648/230513 */ public class TreeEditDemo extends JPanel { private JTree tree; private DefaultMutableTreeNode root; private DefaultTreeCellEditor editor; private JLabel label = new JLabel(" ", JLabel.CENTER); public TreeEditDemo() { super(new BorderLayout()); root = new DefaultMutableTreeNode("Nodes"); root.add(new DefaultMutableTreeNode(new Resource("one"))); root.add(new DefaultMutableTreeNode(new Resource("two"))); root.add(new DefaultMutableTreeNode(new Resource("three"))); final DefaultTreeModel treeModel = new DefaultTreeModel(root); tree = new JTree(treeModel); tree.setEditable(true); editor = new MyTreeCellEditor(tree, (DefaultTreeCellRenderer) tree.getCellRenderer()); tree.setCellEditor(editor); tree.getInputMap().put( KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "startEditing"); this.add(new JScrollPane(tree)); this.add(label, BorderLayout.SOUTH); tree.addTreeSelectionListener(new TreeSelectionListener() { @Override public void valueChanged(TreeSelectionEvent e) { TreePath path = e.getNewLeadSelectionPath(); if (path != null) { DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent(); if (node.isLeaf()) { Resource user = (Resource) node.getUserObject(); label.setText(user.toString()); } else { label.setText(" "); } } } }); editor.addCellEditorListener(new CellEditorListener() { @Override public void editingStopped(ChangeEvent e) { label.setText(editor.getCellEditorValue().toString()); } @Override public void editingCanceled(ChangeEvent e) { } }); } private static class MyTreeCellEditor extends DefaultTreeCellEditor { public MyTreeCellEditor(JTree tree, DefaultTreeCellRenderer renderer) { super(tree, renderer); } @Override public Object getCellEditorValue() { String value = (String) super.getCellEditorValue(); return new Resource(value); } @Override public boolean isCellEditable(EventObject e) { return super.isCellEditable(e) && ((TreeNode) lastPath.getLastPathComponent()).isLeaf(); } } private static class Resource { String name; public Resource(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return getName(); } } private void display() { JFrame f = new JFrame("TreeEditorDemo"); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.add(this); f.pack(); f.setLocationRelativeTo(null); f.setVisible(true); } public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { @Override public void run() { new TreeEditDemo().display(); } }); } } 
+8
source

Source: https://habr.com/ru/post/889989/


All Articles