Change node name in JTree

I am trying to change the name of a node in my JTree. For this, I use the following code:

/** * Change the name of the currently selected node * @param newName Name to change the node too */ public void changeNodeName(String newName) { //get the path to the selected nod TreePath selectedPath = mainWindow.getStructureTree().getSelectionPath() ; //make sure there is no other node with this name DefaultMutableTreeNode node = (DefaultMutableTreeNode) selectedPath.getLastPathComponent(); //change its name node.setUserObject(newName); } 

This code is working fine. So say that I want to rename node b in the image below to c. The code does this correctly, as shown in the figures.

enter image description hereenter image description here

However, if I dragged the node and placed it somewhere else in the tree, its name will return to the original name b.

enter image description hereenter image description here

So, obviously, I'm not changing something right here. How do I or what do I change to change the value of the nodes?

thanks

EDIT:

I have a class that extends DefaultMutableTreeNode. Here is the source

 package Structure; import GUI.Window; import Logging.LogRunner; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.ArrayList; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JPopupMenu; import javax.swing.JSeparator; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreePath; /** * This class provides the basic functionality that all subclass of the structre * will need such as a pop up menu, and adding new nodes. * @author dvargo */ public abstract class BCStructure extends DefaultMutableTreeNode { /** * The root node to which this class belongs */ DefaultMutableTreeNode root; /** * Reference to the main window */ Window mainWindow; /** * Name of this node */ String name; /** * The pop up menu */ JPopupMenu Pmenu; /** * The pop up menu intems */ JMenuItem deleteMenuItem,renameMenuItem,newSectionMenuItem,newPageMenuItem; /** * What type of node this is */ String type; /** * Basic constructor that adds a pop up menu, sets the name, and initalizes values * @param newName - Name for this node * @param inWindow - Reference to the main window. */ public BCStructure(String newName,Window inWindow) { this(newName,inWindow,true); } /** * Returns the type of node this is * @return Page if the node is a page, Module if the node is a module, Section * if the node is a section */ public String getType() { return type; } /** * Returns a copy of this node * @return */ public abstract BCStructure copy(); /** * If this is a page, this constructor should be called, it will not allof a page to *have any children * @param newName - Name for the page * @param inWindow - Refernce to the main window * @param letChildren - False to disallow this node from having children */ public BCStructure(String newName,Window inWindow,boolean letChildren) { super(newName,letChildren); mainWindow = inWindow; name = newName; //add the popup menu addPopUp(); } /** * Updates a specific node * @param parentNode The parent node to update */ public void update(DefaultMutableTreeNode parentNode) { ((DefaultTreeModel)mainWindow.getStructureTree().getModel()).reload(parentNode); mainWindow.getStructureTree().repaint(); } /** * Returns the node that is currently selected (by being clicked on) in the tree * @return Node that is selected in the tree */ public DefaultMutableTreeNode getSelectedNode() { return (DefaultMutableTreeNode)mainWindow.getStructureTree().getLastSelectedPathComponent(); } /** * Returns the TreePath to this node * @return The TreePath to this node */ public TreePath getTreePath() { return new TreePath(this.getPath()); } /** * Sets the selected node in the tree * @param node The node to set selected in the tree */ public void setSelectedNode(BCStructure node) { mainWindow.getStructureTree().setSelectionPath(new TreePath(node.getPath())); update(node); } /** * Change the name of the currently selected node * @param newName Name to change the node too */ public void changeNodeName(String newName) { //get the path to the selected nod TreePath selectedPath = mainWindow.getStructureTree().getSelectionPath() ; //make sure there is no other node with this name DefaultMutableTreeNode node = (DefaultMutableTreeNode) selectedPath.getLastPathComponent(); DefaultMutableTreeNode nodeParent = (DefaultMutableTreeNode) node.getParent(); if(nodeParent != null) { for(int i = 0; i lt nodeParent.getChildCount(); i++) { DefaultMutableTreeNode currNode = (DefaultMutableTreeNode) nodeParent.getChildAt(i); if(currNode.getUserObject().equals(newName)) { JOptionPane.showMessageDialog(mainWindow,"Another page or section already has this name in this level. Please select another."); return; } } } //change its name node.setUserObject(newName); //mainWindow.getStructureTree().getModel().valueForPathChanged(selectedPath, newName); update(getSelectedNode()); } /** * Adds a new section node to the tree * @param newName Name for this node */ public void addNewSectionNode(String newName) { DefaultMutableTreeNode temp = getSelectedNode(); Section newNode = null; if(temp == null) { LogRunner.dialogMessage(this.getClass(),"Please select a node to add this section to."); } else { newNode = new Section(newName,mainWindow); try { temp.add(newNode); } catch(java.lang.IllegalStateException e) { LogRunner.getLogger().warning("You can not add a section to a page"); temp = (DefaultMutableTreeNode) temp.getParent(); temp.add(newNode); } } //set the selected node to the previously selected node update(temp); if(newNode != null) { mainWindow.getStructureTree().setSelectionPath(new TreePath(newNode.getPath())); } } /** * Adds a new page to this tree * @param newName Name for the node * @return The newly created page */ public Page addNewPageNode(String newName) { TreePath oldPath = mainWindow.getStructureTree().getSelectionPath(); //Section newSection = new Section(newSectionName); DefaultMutableTreeNode temp = getSelectedNode(); Page newPage = null; if(temp == null) { LogRunner.dialogMessage(this.getClass(),"Please select a module or section to add this section to."); } else { newPage = new Page(newName,mainWindow); try { temp.add(newPage); } catch(java.lang.IllegalStateException e) { LogRunner.getLogger().warning("You can not add any more nodes to a page."); temp = (DefaultMutableTreeNode) temp.getParent(); temp.add(newPage); } } update(temp); mainWindow.getStructureTree().setSelectionPath(oldPath); return newPage; } /** * Propmpts the user to entere a new name for a node that is selected */ private void rename() { String newname = JOptionPane.showInputDialog("New name?"); changeNodeName(newname); } /** * Deletes the selected node from the tree */ private void delete() { DefaultMutableTreeNode node = (DefaultMutableTreeNode)mainWindow.getStructureTree().getLastSelectedPathComponent(); if(node == null) return; DefaultMutableTreeNode parentNode = (DefaultMutableTreeNode)(node.getParent()); if(parentNode == null) return; //remove node parentNode.remove(node); ((DefaultTreeModel)mainWindow.getStructureTree().getModel()).reload(parentNode); } /** * Deletes a specific node from the tree * @param node The node to delete */ protected void delete(DefaultMutableTreeNode node) { if(node == null) return; DefaultMutableTreeNode parentNode = (DefaultMutableTreeNode)(node.getParent()); if(parentNode == null) return; //remove node parentNode.remove(node); ((DefaultTreeModel)mainWindow.getStructureTree().getModel()).reload(parentNode); } /** * Adds the popup menu functionality to the tree */ private void addPopUp() { Pmenu = new JPopupMenu(); newSectionMenuItem = new JMenuItem("Add New Section"); Pmenu.add(newSectionMenuItem); newPageMenuItem = new JMenuItem("Add New Page"); Pmenu.add(newPageMenuItem); Pmenu.add(new JSeparator()); deleteMenuItem = new JMenuItem("Delete"); Pmenu.add(deleteMenuItem); renameMenuItem = new JMenuItem("Rename"); Pmenu.add(renameMenuItem); //add actionlisteners to the menu items deleteMenuItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { delete();} } ); renameMenuItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { rename();} } ); newSectionMenuItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { mainWindow.createNewSectionPublicCall();} } ); newPageMenuItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { mainWindow.createNewPagePublicCall();} } ); //add action listener to the tree mainWindow.getStructureTree().addMouseListener(new MouseAdapter() { public void mouseReleased(MouseEvent Me) { if(Me.isPopupTrigger()) { Pmenu.show(Me.getComponent(), Me.getX(), Me.getY()); } } }); if(getClass().equals(Page.class)) { newSectionMenuItem.setEnabled(false); } } /** * Returns all the nodes in this tree from doing a left heavy recursive * traversal of the tree from the given root * @param root The root from which to start the search * @return A list of the nodes */ public ArrayList getAllNodesInOrder(BCStructure root) { ArrayList nodes = new ArrayList(); getAllNodesInOrderRec(root, nodes); return nodes; } /** * Recursive function that gets the nodes in the tree * @param currNode * @param theNodes */ private void getAllNodesInOrderRec(BCStructure currNode, ArrayList theNodes) { theNodes.add(currNode); for(int i = 0; i lt currNode.getChildCount(); i++) { currNode.getAllNodesInOrderRec((BCStructure) currNode.getChildAt(i), theNodes); } } }
package Structure; import GUI.Window; import Logging.LogRunner; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.ArrayList; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JPopupMenu; import javax.swing.JSeparator; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreePath; /** * This class provides the basic functionality that all subclass of the structre * will need such as a pop up menu, and adding new nodes. * @author dvargo */ public abstract class BCStructure extends DefaultMutableTreeNode { /** * The root node to which this class belongs */ DefaultMutableTreeNode root; /** * Reference to the main window */ Window mainWindow; /** * Name of this node */ String name; /** * The pop up menu */ JPopupMenu Pmenu; /** * The pop up menu intems */ JMenuItem deleteMenuItem,renameMenuItem,newSectionMenuItem,newPageMenuItem; /** * What type of node this is */ String type; /** * Basic constructor that adds a pop up menu, sets the name, and initalizes values * @param newName - Name for this node * @param inWindow - Reference to the main window. */ public BCStructure(String newName,Window inWindow) { this(newName,inWindow,true); } /** * Returns the type of node this is * @return Page if the node is a page, Module if the node is a module, Section * if the node is a section */ public String getType() { return type; } /** * Returns a copy of this node * @return */ public abstract BCStructure copy(); /** * If this is a page, this constructor should be called, it will not allof a page to *have any children * @param newName - Name for the page * @param inWindow - Refernce to the main window * @param letChildren - False to disallow this node from having children */ public BCStructure(String newName,Window inWindow,boolean letChildren) { super(newName,letChildren); mainWindow = inWindow; name = newName; //add the popup menu addPopUp(); } /** * Updates a specific node * @param parentNode The parent node to update */ public void update(DefaultMutableTreeNode parentNode) { ((DefaultTreeModel)mainWindow.getStructureTree().getModel()).reload(parentNode); mainWindow.getStructureTree().repaint(); } /** * Returns the node that is currently selected (by being clicked on) in the tree * @return Node that is selected in the tree */ public DefaultMutableTreeNode getSelectedNode() { return (DefaultMutableTreeNode)mainWindow.getStructureTree().getLastSelectedPathComponent(); } /** * Returns the TreePath to this node * @return The TreePath to this node */ public TreePath getTreePath() { return new TreePath(this.getPath()); } /** * Sets the selected node in the tree * @param node The node to set selected in the tree */ public void setSelectedNode(BCStructure node) { mainWindow.getStructureTree().setSelectionPath(new TreePath(node.getPath())); update(node); } /** * Change the name of the currently selected node * @param newName Name to change the node too */ public void changeNodeName(String newName) { //get the path to the selected nod TreePath selectedPath = mainWindow.getStructureTree().getSelectionPath() ; //make sure there is no other node with this name DefaultMutableTreeNode node = (DefaultMutableTreeNode) selectedPath.getLastPathComponent(); DefaultMutableTreeNode nodeParent = (DefaultMutableTreeNode) node.getParent(); if(nodeParent != null) { for(int i = 0; i lt nodeParent.getChildCount(); i++) { DefaultMutableTreeNode currNode = (DefaultMutableTreeNode) nodeParent.getChildAt(i); if(currNode.getUserObject().equals(newName)) { JOptionPane.showMessageDialog(mainWindow,"Another page or section already has this name in this level. Please select another."); return; } } } //change its name node.setUserObject(newName); //mainWindow.getStructureTree().getModel().valueForPathChanged(selectedPath, newName); update(getSelectedNode()); } /** * Adds a new section node to the tree * @param newName Name for this node */ public void addNewSectionNode(String newName) { DefaultMutableTreeNode temp = getSelectedNode(); Section newNode = null; if(temp == null) { LogRunner.dialogMessage(this.getClass(),"Please select a node to add this section to."); } else { newNode = new Section(newName,mainWindow); try { temp.add(newNode); } catch(java.lang.IllegalStateException e) { LogRunner.getLogger().warning("You can not add a section to a page"); temp = (DefaultMutableTreeNode) temp.getParent(); temp.add(newNode); } } //set the selected node to the previously selected node update(temp); if(newNode != null) { mainWindow.getStructureTree().setSelectionPath(new TreePath(newNode.getPath())); } } /** * Adds a new page to this tree * @param newName Name for the node * @return The newly created page */ public Page addNewPageNode(String newName) { TreePath oldPath = mainWindow.getStructureTree().getSelectionPath(); //Section newSection = new Section(newSectionName); DefaultMutableTreeNode temp = getSelectedNode(); Page newPage = null; if(temp == null) { LogRunner.dialogMessage(this.getClass(),"Please select a module or section to add this section to."); } else { newPage = new Page(newName,mainWindow); try { temp.add(newPage); } catch(java.lang.IllegalStateException e) { LogRunner.getLogger().warning("You can not add any more nodes to a page."); temp = (DefaultMutableTreeNode) temp.getParent(); temp.add(newPage); } } update(temp); mainWindow.getStructureTree().setSelectionPath(oldPath); return newPage; } /** * Propmpts the user to entere a new name for a node that is selected */ private void rename() { String newname = JOptionPane.showInputDialog("New name?"); changeNodeName(newname); } /** * Deletes the selected node from the tree */ private void delete() { DefaultMutableTreeNode node = (DefaultMutableTreeNode)mainWindow.getStructureTree().getLastSelectedPathComponent(); if(node == null) return; DefaultMutableTreeNode parentNode = (DefaultMutableTreeNode)(node.getParent()); if(parentNode == null) return; //remove node parentNode.remove(node); ((DefaultTreeModel)mainWindow.getStructureTree().getModel()).reload(parentNode); } /** * Deletes a specific node from the tree * @param node The node to delete */ protected void delete(DefaultMutableTreeNode node) { if(node == null) return; DefaultMutableTreeNode parentNode = (DefaultMutableTreeNode)(node.getParent()); if(parentNode == null) return; //remove node parentNode.remove(node); ((DefaultTreeModel)mainWindow.getStructureTree().getModel()).reload(parentNode); } /** * Adds the popup menu functionality to the tree */ private void addPopUp() { Pmenu = new JPopupMenu(); newSectionMenuItem = new JMenuItem("Add New Section"); Pmenu.add(newSectionMenuItem); newPageMenuItem = new JMenuItem("Add New Page"); Pmenu.add(newPageMenuItem); Pmenu.add(new JSeparator()); deleteMenuItem = new JMenuItem("Delete"); Pmenu.add(deleteMenuItem); renameMenuItem = new JMenuItem("Rename"); Pmenu.add(renameMenuItem); //add actionlisteners to the menu items deleteMenuItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { delete();} } ); renameMenuItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { rename();} } ); newSectionMenuItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { mainWindow.createNewSectionPublicCall();} } ); newPageMenuItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { mainWindow.createNewPagePublicCall();} } ); //add action listener to the tree mainWindow.getStructureTree().addMouseListener(new MouseAdapter() { public void mouseReleased(MouseEvent Me) { if(Me.isPopupTrigger()) { Pmenu.show(Me.getComponent(), Me.getX(), Me.getY()); } } }); if(getClass().equals(Page.class)) { newSectionMenuItem.setEnabled(false); } } /** * Returns all the nodes in this tree from doing a left heavy recursive * traversal of the tree from the given root * @param root The root from which to start the search * @return A list of the nodes */ public ArrayList getAllNodesInOrder(BCStructure root) { ArrayList nodes = new ArrayList(); getAllNodesInOrderRec(root, nodes); return nodes; } /** * Recursive function that gets the nodes in the tree * @param currNode * @param theNodes */ private void getAllNodesInOrderRec(BCStructure currNode, ArrayList theNodes) { theNodes.add(currNode); for(int i = 0; i lt currNode.getChildCount(); i++) { currNode.getAllNodesInOrderRec((BCStructure) currNode.getChildAt(i), theNodes); } } } 

And in the example above, the actual nodes you see are a subclass of BCStructure called Page. This is the actual class that I renamed.

 package Structure; import Components.BCFrame; import Components.Basic.BackGroundImage; import GUI.Window; import Logging.LogRunner; import XMLProcessing.XMLWriter; import java.awt.Color; import java.awt.Dimension; import java.util.ArrayList; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.tree.DefaultTreeCellRenderer; /** * This class is responcible for holding the components the make up a page and * is accessible through the tree structure. In other words, this class is what * actually makes up a page. It holds the componenets in an array, and since it * node in a tree, it can be notified when it has been clicked, and load the * compoenents it is holding. * @author dvargo */ public class Page extends BCStructure { /** * Holds all the componenets in the content pane so an action can be done on * all componenets. Also sets the added component to the current component. */ private ArrayList theComponents = new ArrayList() { @Override public boolean add(BCFrame e) { e.setPage(selfReference); return super.add(e); } }; /** * Self reference to this page */ private Page selfReference = this; /** * The dimensions of this page. It defualts to a medium page size */ private Dimension pageSize = Window.NORMAL; /** * This bages background; */ private BackGroundImage background; /** * Constructor that sets the node up in the tree and inializes values. * @param newName - Name for this node * @param inWindow - Reference to the main window * @param inRoot - The section or module that is the root for this page. */ public Page(String newName, Window inWindow) { super(newName, inWindow,false); DefaultTreeCellRenderer renderer = new DefaultTreeCellRenderer(); ImageIcon theImage = new ImageIcon(new JFrame().getToolkit().getImage(getClass().getResource("/GUI/fileIcon.png"))); renderer.setLeafIcon(theImage); //set the background color to white, there will always be a background background = new BackGroundImage(0,0,pageSize.width,pageSize.height,mainWindow); background.setColor(Color.WHITE); theComponents.add(background); //you must add this to the content pane to keep indexes correct. it will not display anything though mainWindow.getComponentContentPane().add(background,0); mainWindow.getContentPanePanel().repaint(); } /** * Loads all the componenets held in the arraylist to to the screen. */ public void loadPage() { //remove the background of the previous page mainWindow.getComponentContentPane().removeAll(); mainWindow.setPageSizeComboSeleted(pageSize); background.setSize(pageSize); mainWindow.getComponentContentPane().setPreferredSize(pageSize); mainWindow.getComponentContentPane().setSize(pageSize); for(BCFrame currentComp : theComponents) { mainWindow.getComponentContentPane().add(currentComp); currentComp.setVisible(true); currentComp.revalidate(); currentComp.repaint(); currentComp.setPage(this); } mainWindow.getComponentContentPane().repaint(); mainWindow.getComponentContentPane().revalidate(); } /** * Writes the componenets to file in XML. * @param filePath - The path and name of the file to write. */ public void save(String filePath) { XMLWriter theWriter = new XMLWriter(); for(int i = 0; i newComponents) { theComponents = newComponents; boolean backgroundExists = false; for(BCFrame curr : theComponents) { if(curr.getClass().equals(BackGroundImage.class)) { background = (BackGroundImage) curr; //make sure background isnt null backgroundExists = true; } curr.setPage(this); } if(backgroundExists) { return; } LogRunner.getLogger().severe("Could not find a background while setting the components, adding a new dfualt white one"); BackGroundImage bgi= new BackGroundImage(); bgi.setSize(pageSize); bgi.setColor(Color.WHITE); theComponents.add(bgi); background = bgi; } public ArrayList getComponents() { return theComponents; } }
package Structure; import Components.BCFrame; import Components.Basic.BackGroundImage; import GUI.Window; import Logging.LogRunner; import XMLProcessing.XMLWriter; import java.awt.Color; import java.awt.Dimension; import java.util.ArrayList; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.tree.DefaultTreeCellRenderer; /** * This class is responcible for holding the components the make up a page and * is accessible through the tree structure. In other words, this class is what * actually makes up a page. It holds the componenets in an array, and since it * node in a tree, it can be notified when it has been clicked, and load the * compoenents it is holding. * @author dvargo */ public class Page extends BCStructure { /** * Holds all the componenets in the content pane so an action can be done on * all componenets. Also sets the added component to the current component. */ private ArrayList theComponents = new ArrayList() { @Override public boolean add(BCFrame e) { e.setPage(selfReference); return super.add(e); } }; /** * Self reference to this page */ private Page selfReference = this; /** * The dimensions of this page. It defualts to a medium page size */ private Dimension pageSize = Window.NORMAL; /** * This bages background; */ private BackGroundImage background; /** * Constructor that sets the node up in the tree and inializes values. * @param newName - Name for this node * @param inWindow - Reference to the main window * @param inRoot - The section or module that is the root for this page. */ public Page(String newName, Window inWindow) { super(newName, inWindow,false); DefaultTreeCellRenderer renderer = new DefaultTreeCellRenderer(); ImageIcon theImage = new ImageIcon(new JFrame().getToolkit().getImage(getClass().getResource("/GUI/fileIcon.png"))); renderer.setLeafIcon(theImage); //set the background color to white, there will always be a background background = new BackGroundImage(0,0,pageSize.width,pageSize.height,mainWindow); background.setColor(Color.WHITE); theComponents.add(background); //you must add this to the content pane to keep indexes correct. it will not display anything though mainWindow.getComponentContentPane().add(background,0); mainWindow.getContentPanePanel().repaint(); } /** * Loads all the componenets held in the arraylist to to the screen. */ public void loadPage() { //remove the background of the previous page mainWindow.getComponentContentPane().removeAll(); mainWindow.setPageSizeComboSeleted(pageSize); background.setSize(pageSize); mainWindow.getComponentContentPane().setPreferredSize(pageSize); mainWindow.getComponentContentPane().setSize(pageSize); for(BCFrame currentComp : theComponents) { mainWindow.getComponentContentPane().add(currentComp); currentComp.setVisible(true); currentComp.revalidate(); currentComp.repaint(); currentComp.setPage(this); } mainWindow.getComponentContentPane().repaint(); mainWindow.getComponentContentPane().revalidate(); } /** * Writes the componenets to file in XML. * @param filePath - The path and name of the file to write. */ public void save(String filePath) { XMLWriter theWriter = new XMLWriter(); for(int i = 0; i newComponents) { theComponents = newComponents; boolean backgroundExists = false; for(BCFrame curr : theComponents) { if(curr.getClass().equals(BackGroundImage.class)) { background = (BackGroundImage) curr; //make sure background isnt null backgroundExists = true; } curr.setPage(this); } if(backgroundExists) { return; } LogRunner.getLogger().severe("Could not find a background while setting the components, adding a new dfualt white one"); BackGroundImage bgi= new BackGroundImage(); bgi.setSize(pageSize); bgi.setColor(Color.WHITE); theComponents.add(bgi); background = bgi; } public ArrayList getComponents() { return theComponents; } } 
+6
java swing jtree
source share
2 answers

I get it. If you notice in BCStructure, it has a value called a name. Whenever I change the name of a node, I have not updated this value. Then, if you notice in the copy () of the Page class, it uses this name variable. A copy is used in the drag and drop process. If the name was not updated, it would use the old value, so I saw the behavior I did. The view is simple but hard to explain. Thank you all for your help.

+2
source share

I do not see the code that you use to create the TreeModel, however, I assume that you are not using mutable nodes:

http://download.oracle.com/javase/1.5.0/docs/api/javax/swing/tree/MutableTreeNode.html#setUserObject%28java.lang.Object%29

+1
source share

All Articles