Inheriting from DefaultMutableTreeNode causes selection problems?

Hi all,

I've a class that represents a node of a JTree and, thus, that I've written on the base of the great DefaultMutableTreeNode adding a few methods that should not clash with the swing structure:

publicclass ContainerTreeNodeextends DefaultMutableTreeNode{

/**

* Defines if this node is a root node, that is have children.

*/

protectedboolean isRoot =false;

/**

* Defines which kind of root this node is.

*/

protected String rootType =null;

/**

* Returns the hashcode of this node. If the node contains a BaseKeyValue, then the

* hashcode of such value is returned, otherwise the DefaultMutableTreeNode is calculated.

*/

publicint hashCode(){

if( this.userObject !=null )return this.userObject.hashCode();

else

return super.hashCode();

}

/**

* Compares two nodes. Two nodes are equal if their values are.

*/

publicboolean equals(Object o){

if( o==null || (! (oinstanceof ContainerTreeNode)))returnfalse;

else{

Object userObject = ((ContainerTreeNode)o).userObject;

Object myObject= this.userObject;

if( userObjectinstanceof BaseKeyValue && myObjectinstanceof BaseKeyValue)

return userObject.equals(myObject);

else

returnfalse;

}

}

/**

* Builds up a tree node with the specified BaseKeyValue.

* @param keyValue the key value object to build up this node.

*/

public ContainerTreeNode(BaseKeyValue keyValue){

super(keyValue);

}

/**

* Builds a tree node with the specified string, used for description nodes.

* @param string the string to initialize this node with

*/

public ContainerTreeNode(String string){

super(string);

}

/**

* To print this element. The userobject is used for printing.

*/

public String toString(){

if( this.userObject !=null )return this.userObject.toString();

elsereturnnull;

}

/**

* Refreshes this node and, in the case, the children nodes. If this node contains a key-value object, then it is

* refreshed, otherwise nothing is done. After this, in any case, if the value of the flag is true, each node is

* forced to be refreshed simply calling this method on each node (that will call on each child node and so on).

* @param refreshChildren true if all the children must be forced to be updated, false otherwise.

*/

publicfinalvoid refreshNode(boolean refreshChildren){

// refresh myself

if( this.userObject !=null && this.userObjectinstanceof BaseKeyValue){

BaseKeyValue myKeyValue = (BaseKeyValue) this.userObject;

myKeyValue.refreshFromDatabase();

}

// if here I've got a basekeyvalue as user object, thus I can update the childs of this node.

if( refreshChildren ){

Enumeration children = this.children();

while (children !=null && children.hasMoreElements()){

ContainerTreeNode element = (ContainerTreeNode) children.nextElement();

element.refreshNode(refreshChildren);

}

}

}

/**

* @return the isRoot

*/

publicsynchronizedfinalboolean isRoot(){

return isRoot;

}

/**

* @param isRoot the isRoot to set

*/

publicsynchronizedfinalvoid setRoot(boolean isRoot){

this.isRoot = isRoot;

}

/**

* @return the rootType

*/

publicsynchronizedfinal String getRootType(){

return rootType;

}

/**

* @param rootType the rootType to set

*/

publicsynchronizedfinalvoid setRootType(String rootType){

this.rootType = rootType;

}

publicstaticvoid main(String argv[])throws Exception{

DefaultMutableTreeNode t1 =new ContainerTreeNode("t1");

DefaultMutableTreeNode t2 =new ContainerTreeNode("t2");

DefaultMutableTreeNode t3 =new ContainerTreeNode("t3");

DefaultMutableTreeNode t4 =new ContainerTreeNode("t4");

DefaultMutableTreeNode t5 =new ContainerTreeNode("t5");

t1.add(t2);

t2.add(t3);

t3.add(t4);

t4.add(t5);

DefaultTreeModel model =new DefaultTreeModel(t1);

JTree tree =new JTree(model);

JFrame f =new JFrame("prova");

f.setSize(300,300);

f.add(tree);

f.setVisible(true);

Thread.currentThread().sleep(5000);

TreePath path = tree.getSelectionModel().getSelectionPath();

t3.removeAllChildren();

t4.removeAllChildren();

t3.add(t5);

//model.reload(t2);

model.reload();

System.out.println("Nodo ricaricato " + path);

tree.getSelectionModel().setSelectionPath(path);

}

}

The problem is that the above main cannot re-select the node the user has clicked onto, while if I convert my nodes in DefaultMutableTreeNode it does. Anyone can explain me why?

Luca

[9221 byte] By [cat4hirea] at [2007-10-3 9:32:09]
# 1

Seems to be a problem with your "equals" method.

Try this one:

public boolean equals(Object o){

if( o==null || (! (o instanceof ContainerTreeNode))){

return false;

}

else{

Object userObject = ((ContainerTreeNode)o).userObject;

Object myObject= this.userObject;

if( userObject instanceof BaseKeyValue && myObject instanceof BaseKeyValue){

return userObject.equals(myObject);

}else{

return super.equals(o);

}

}

}

Andre_Uhresa at 2007-7-15 4:47:08 > top of Java-index,Desktop,Core GUI APIs...
# 2
It seems to work, thank you very much!Luca
cat4hirea at 2007-7-15 4:47:08 > top of Java-index,Desktop,Core GUI APIs...