problem with jtree selection
Hi all,
I've got a JTree that represents a sort of data that I'm going to change dynamically in my application. I'd like to reset the selection of the user to the leaf she has selected before the change to the tree structure.
First of all my tree uses DefaultMutableTreeNode to build each node, and each DefaultMutableTreeNode contains a SingleKeyValue object, that is a key-value object (two strings) and that has an hashcode defined as follows:
publicclass SingleKeyValueextends BaseKeyValue{
/**
* The key of the database object.
*/
protected String key =null;
/**
* The description of this object.
*/
protected String value =null;
publicint hashCode(){
return this.key.hashCode();
}
I hope the hashcode can help me finding the right object even when its value changes (but the key is the same). The construction of the tree is the following:
DefaultMutableTreeNode root =new DefaultMutableTreeNode("The root");
// iterate and build each node
SingleKeyValue object =new SingleKeyValue("key","value");
DefaultMutableTreeNode node =new DefaultMutableTreeNode(object);
root.add(node);
DefaultTreeModel model =new DefaultTreeModel(root);
JTree tree =new JTree(model);
so the tree is associated to a DefaultTreeModel. Then, when I need to change something in the tree I rebuild the tree and all leafs (with the SingleKeyValues) and rebuild the model:
TreeModel treeModel = this.myTree.getModel();
TreeSelectionModel selectionModel = this.myTree.getSelectionModel();
DefaultTreeModel defaultTreeModel =null;
DefaultTreeSelectionModel defaultTreeSelectionModel =null;
TreePath selectedPath =null;
TreeNode root =null;
Logger.info("SimpleTreePanel.refreshDatabaseView: treemodel "+treeModel +" selectionModel " + selectionModel);
if( treeModel !=null && treeModelinstanceof DefaultTreeModel ){
defaultTreeModel = (DefaultTreeModel) treeModel;
root = this.getRoot();
// get the selection
if( selectionModel !=null && selectionModelinstanceof DefaultTreeSelectionModel ){
defaultTreeSelectionModel = (DefaultTreeSelectionModel) selectionModel;
selectedPath = defaultTreeSelectionModel.getSelectionPath();
Logger.warn("Selection path of the tree: "+selectedPath);
}
// rebuild the tree
defaultTreeModel.setRoot(root);
// set the selected element
defaultTreeSelectionModel.setSelectionPath(selectedPath);
The problem is that after the above code the tree is all closed, no leaf are selected. I guess the problem is with the SingleKeyValueObject because I've tried the default model and it works with, for example, simple strings. Any idea about?
Thanks,
Luca
[4195 byte] By [
cat4hirea] at [2007-10-3 8:36:16]

Are you actually rebuilding the tree and all the nodes (like calling new DefaultMutableTreeNode(singleKeyValue) or just resetting its root?
Did you try DefaultTreeModel#reload ?
Here's a complete test program that creates a few SingleKeyValue objetcs (objects with a key and a description) and that then places them into a JTree using the DefaultMutableTreeNode. After that, the selection of user is took and one node is changed, but while the selection is working, the reload/refresh of the tree is not.
Any idea about how to work on it?
public class SingleKeyValue extends BaseKeyValue{
/**
* The key of the database object.
*/
protected String key = null;
/**
* The description of this object.
*/
protected String value = null;
// constants related to the type of the table this object refers to
public static final String COMPETENCE = "competenza";
public static final String FAMILY= "famiglia_competenza";
public static final String ROLE = "ruolo";
public static final String PROVINCE= "provincia";
public static final String KNOWLEDGE = "titolo_studio";
public final static String OBJECTIVE= "obiettivo";
public final static String PERSON = "persona";
public SingleKeyValue( String key, String value, String table){
super();
this.key = key;
this.value = value;
this.SQLTable = table;
}
/**
* @return the key
*/
public final String getKey() {
return key;
}
/**
* @param key the key to set
*/
public final void setKey(String key) {
this.key = key;
}
/**
* @return the value
*/
public final String getValue() {
return value;
}
/**
* @param value the value to set
*/
public final void setValue(String value) {
this.value = value;
}
/**
* Shows this element.
*/
public String toString(){
String ret;
if( this.showKey ){
ret = this.label + this.key +" { "+ this.value +" }";
}
else
ret = this.label + this.value;
// trim the string
if( ret.length() > this.maxLength )
return ret.substring(0 , this.maxLength);
else
return ret;
}
/**
* The hash code of this object is the hash code of the key.
* @return the hash code of the key of the object
*/
public int hashCode() {
return this.key.hashCode();
}
/**
* Returns true if the object passed is a single key value equals (i.e., with the same key) of this one.
*/
public boolean equals(Object o){
if( o== null || (! (o instanceof SingleKeyValue) ) )return false;
else
return (this.hashCode() == o.hashCode());
}
public static void main(String argv[]) throws Exception{
SingleKeyValue skv1 = new SingleKeyValue("Key1","Description1", SingleKeyValue.COMPETENCE);
SingleKeyValue skv2 = new SingleKeyValue("Key1a","Description1a", SingleKeyValue.COMPETENCE);
SingleKeyValue skv3 = new SingleKeyValue("Key1b","Description1b", SingleKeyValue.COMPETENCE);
SingleKeyValue skv4 = new SingleKeyValue("Key2","Description2", SingleKeyValue.COMPETENCE);
SingleKeyValue skv5 = new SingleKeyValue("Key2a","Description2a", SingleKeyValue.COMPETENCE);
SingleKeyValue skv6 = new SingleKeyValue("Key2b","Description2b", SingleKeyValue.COMPETENCE);
DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode("root");
DefaultMutableTreeNode node1 = new DefaultMutableTreeNode(skv1);
DefaultMutableTreeNode node2 = new DefaultMutableTreeNode(skv2);
DefaultMutableTreeNode node3 = new DefaultMutableTreeNode(skv3);
DefaultMutableTreeNode node4 = new DefaultMutableTreeNode(skv4);
DefaultMutableTreeNode node5 = new DefaultMutableTreeNode(skv5);
DefaultMutableTreeNode node6 = new DefaultMutableTreeNode(skv6);
rootNode.add(node1);
node1.add(node2);
node1.add(node3);
rootNode.add(node4);
node4.add(node5);
node4.add(node6);
JTree tree = new JTree(rootNode);
JFrame f = new JFrame("Tree try");
f.add( new JScrollPane(tree) );
f.setSize(300,300);
f.setVisible(true);
System.out.println("Please select a node within 10 seconds");
Thread.sleep(10000);
// now get the user selection
TreeModel treeModel = tree.getModel();
TreeSelectionModel selectionModel = tree.getSelectionModel();
DefaultTreeModel defaultTreeModel = null;
DefaultTreeSelectionModel defaultTreeSelectionModel = null;
TreePath selectedPath = null;
TreeNode root = null;
if( treeModel != null && treeModel instanceof DefaultTreeModel ) {
defaultTreeModel = (DefaultTreeModel) treeModel;
// get the selection
if( selectionModel != null && selectionModel instanceof DefaultTreeSelectionModel ){
defaultTreeSelectionModel = (DefaultTreeSelectionModel) selectionModel;
selectedPath = defaultTreeSelectionModel.getSelectionPath();
}
// rebuild the tree
node1.setUserObject(new SingleKeyValue("key20","key changed",SingleKeyValue.FAMILY));
defaultTreeModel.reload();
// set the selected element
defaultTreeSelectionModel.setSelectionPath(selectedPath);
}
}
}
cannot find symbolsymbol: class BaseKeyValue
Sorry, I forgot the base class, that just adds a few variables and method for utility services:
public abstract class BaseKeyValue {
/**
* Should this object show the key when the toString method is called?
*/
protected boolean showKey = false;
/**
* A generic label for this object, used when the toString method is called.
*/
protected String label = "";
/**
* The sql table this value is referred to. It's a kind of "type" for this object.
*/
protected String SQLTable = null;
/**
* The maximum length for this key-value string to display.
*/
protected int maxLength = 50;
/**
* Specifies if this element must present the key in the toString method.
* @return the showKey
*/
public final boolean isShowKey() {
return showKey;
}
/**
* Sets the showKey attribute, that specifies if the toString method must show the key or not.
* @param showKey the showKey to set
*/
public final void setShowKey(boolean showKey) {
this.showKey = showKey;
}
/**
* The max length of the string to be shown when this element is print.
* @return the maxLength
*/
public final int getMaxLength() {
return maxLength;
}
/**
* The max length of the string to be shown when this element is print.
* @param maxLength the maxLength to set
*/
public final void setMaxLength(int maxLength) {
this.maxLength = maxLength;
}
/**
* The type of this key-value element.
* @return the sQLTable
*/
public final String getSQLTable() {
return SQLTable;
}
/**
* Sets the type for this kind of key-value object.
* @param table the sQLTable to set
*/
public final void setSQLTable(String table) {
SQLTable = table;
}
/**
* The type of this key-value is the SQL Table it has been associated to.
* @return the SQLTable of this element
*/
public final String getType(){
return this.getSQLTable();
}
/**
* Sets the sql table associated to this object (formerly the type of the object).
* @param type the type (i.e., the sql table name)
*/
public final void setType(String type){
this.SQLTable = type;
}
/**
* Compares this object kind with another string.
* @param type the sql table (type to compare to
* @return true if the object is registered as belonging to the specified table
*/
public final boolean isKind(String type){
if( type == null || this.SQLTable == null)return false;
elsereturn this.SQLTable.equals(type);
}
Your code works for me: the selected node remains selected.(Using jdk 1.5.0_08)Message was edited by: Andre_Uhres
Now the node selection works for me too, but it does not work the refresh of the tree displaied data. After I changed node1 I cannot see the new data displaied in the tree.Any clue?Luca
> ..it does not work the refresh of the tree displaied data.
> After I changed node1 I cannot see the new data displaied in the tree.
The code works for me also in that respect: after 10 seconds the first node is labeled "key changed".
I have no idea about your problem for the moment..
****!At the moment I'm using linux with jdk1.5, which platform have you tested it? Could it be a problem of Linux-refreshing? I've tried also forcing a repaint of the window but I cannot see anything.Luca
I use Windows XPI have no possibility for testing on Linux, sorry.
Very strange: running it into eclipse 3.2 on Linux I cannot see the tree changing, running it from the console I can see it changing!Anybody experiencing similar problems?Luca
I found that, in eclipse, changing the Run->JRE configuration from Project JRE (that is j2se5) to execution evnrionment (selection j2se5) it works. I will discover what such setting is....By the way, thanks everybody for the help.Luca