Search code examples
javaswingmodeljtreeinvisible

Java Swing - JTree - setModel graphics bug on more then 2 chained branches


I tried to create my own JTree Model so I can update the graphics by calling: updateUI(); I ran into a problem when my JTree should display a tree with a depth over 2 branches.

I use a own class that has extended by java.util.Vector called: NamedVector.

Here's how the tree should look like:

ROOT
    Branch
        BranchInside
              Leaf
              Leaf
              ...
        OtherBranch
     AndOneMore
        ...
     ...

And here's how it looks like: http://imageshack.us/photo/my-images/39/fehlerqq.png/

enter image description here

Here's how I set the new TreeModel:

jTree1.setModel(new javax.swing.tree.TreeModel(){

        @Override
        public Object getRoot(){
            return core.Project.sharedInstance.getTranslationsTree();
        }

        @Override
        public Object getChild(Object parent, int index){
            if(parent instanceof String) return null;
            return ((core.NamedVector)parent).get(index);
        }

        @Override
        public int getChildCount(Object parent){
            if(parent instanceof String) return 0;
            return ((core.NamedVector)parent).size();
        }

        @Override
        public boolean isLeaf(Object node){
            if(node instanceof String) return true;
            return ((core.NamedVector)node).isEmpty();
        }

        @Override
        public int getIndexOfChild(Object parent, Object child){
            if(parent instanceof String) return -1;
            return ((core.NamedVector)parent).indexOf(child);
        }

        @Override
        public void valueForPathChanged(TreePath path, Object newValue){}
        @Override
        public void addTreeModelListener(TreeModelListener l){}
        @Override
        public void removeTreeModelListener(TreeModelListener l){}
    });

(core.Project.sharedInstance.getTranslationsTree() returns the root vector of my tree, when I print it in the console, it gives correct results.)

And here is my NamedVector class:

public class NamedVector extends java.util.Vector{
public String name;
public NamedVector(String name){
    this.name = name;
}
@Override
public String toString(){
    return name;
}
public static void dirToVector(java.io.File sourceLocation, NamedVector target){
    if(sourceLocation.isDirectory()){
        String[] children = sourceLocation.list();
        for(int i=0; i<children.length; i++){
            NamedVector vector = new NamedVector(children[i]);
            target.add(vector);
            dirToVector(new java.io.File(sourceLocation, children[i]),
                    vector);
        }
    }
}
public void print(){
    print("");
}
private void print(String pre){
    System.out.println(pre+name);
    pre+=" ";
    for(int i=0;i<this.size();i++){
        if(get(i) instanceof NamedVector){
            ((NamedVector)get(i)).print(pre);
        }else{
            System.out.println(pre+get(i).toString());
        }
    }
}}

This only happens when I use my own model on the tree, if I build it with DefaultMutableTreeNode it displays everything correct, but I would like to use a custom model.


Solution

  • My best guess, based on your comment

    But for DefaultTreeModel i have to add my nodes manually when i change my vector, i would like only changing my vector and calling the updateUI() method so my tree is builded by his own

    is that your TreeModel does not fire the correct events. So when a change occurs in your vector, the JTree is not informed. Afterwards, when it repaints/expands a node/... and asks the TreeModel for information, this information will be out of sync with the info the JTree received through the events, typically resulting in JTrees as shown in your pictures.

    Certainly if your model has empty implementations for the addTreeModelListener method