AbstractTreeModel

I was told once in fishing forums it's a bad habit to call #. updateUI() #. revalidate() using abstractTableModel.

I pulled treemodelevents however the JTree object does not seem to respond to these events without back updateUI and revalidate? Why is this?


package Swing;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Observable;
import javax.swing.*;
import javax.swing.event.ListDataListener;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;
import javax.swing.table.*;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
//import com.sun.java.swing.tree.*;
//import com.sun.java.swing.event.*;
import java.util.*;



class TreeModelTest {

    public static void main(String[] args) {
        new GUI().createGui();
    }
}

class GUI  {
    private JTree tree;
    private PeopleTreeModel peopleModel = new PeopleTreeModel();


    public void createGui() {
        tree = new JTree(peopleModel);
        JPanel pane = new JPanel(new BorderLayout());
        pane.add(new JScrollPane(tree), BorderLayout.CENTER);
        pane.add(getButtonPanel(), BorderLayout.SOUTH);

        JFrame f = new JFrame("Abstract JTree Example");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.getContentPane().add(pane);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);

    }

    public JPanel getButtonPanel(){
        JPanel buttonPanel = new JPanel();

        JButton addPersonButton = new JButton("Add Person");
        addPersonButton.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                System.out.println("Adding Person");
                peopleModel.addPerson(new Person("New Person"));
                tree.updateUI();
                tree.revalidate();
            }
        });

        JButton removePersonButton = new JButton("Remove Person");
        removePersonButton.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                System.out.println("Remove Person");
                peopleModel.removePerson(0);
                tree.updateUI();
                tree.revalidate();
            }
        });

        JButton selectPersonButton = new JButton("Select Person");
        selectPersonButton.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                System.out.println("Select Person");
            }
        });

        buttonPanel.add(addPersonButton);
        buttonPanel.add(removePersonButton);
        buttonPanel.add(selectPersonButton);
        return buttonPanel;
    }
}







class PeopleTreeModel extends AbstractTreeModel  implements TreeModel {

    private ArrayList<Person> peopleArray = new ArrayList<Person>();


    public PeopleTreeModel() {
        super();
        peopleArray.add(new Person("Chris"));
        peopleArray.add(new Person("Hary"));
        peopleArray.add(new Person("Boris"));
        peopleArray.add(new Person("lucy"));
        peopleArray.add(new Person("char"));
        this.print();
    }

    public void addPerson(Person person){
        peopleArray.add(person);
        //here I want to fire tree event??
        Object[] path = {"people",person.getName()};
        this.fireTreeNodesInserted(new TreeModelEvent(person.getName(),path));


    }

    public void removePerson(int index){
        if(index<peopleArray.size()){
            peopleArray.remove(index);
            Object[] path = {"people",this.peopleArray.get(index).getName()};
            this.fireTreeNodesInserted(new TreeModelEvent(this.peopleArray.get(index).getName(),path));
            
        }
    }



    public ArrayList<Person> getPeopleArray() {
        return peopleArray;
    }

    public void setPeopleArray(ArrayList<Person> people) {
        this.peopleArray = people;
    }

    public void print() {
        System.out.println("\nPrinting People Array");
        for (int i = 0; i < peopleArray.size(); i++) {
            System.out.println(peopleArray.get(i).toString());
        }
    }

    public Object getRoot() {
        return "people";
    }

    public Object getChild(Object parent, int index) {
        if(parent.toString().equals("people")){
            return this.peopleArray.get(index);
        }else{
            return null;
        }
    }

    public int getChildCount(Object parent) {
        if(parent.toString().equals("people")){
            System.out.println("Returning size "+this.peopleArray.size());
            return this.peopleArray.size();
        }else{
            return 0;
        }
    }

    public boolean isLeaf(Object node) {
        if(node.toString().equals("people")){
            return false;
        }else{
            return true;
        }
    }

    public void valueForPathChanged(TreePath path, Object newValue) {
        System.out.println(path + ", "+ newValue);
    }

    public int getIndexOfChild(Object parent, Object child) {
        return this.peopleArray.indexOf(child);
    }
}





class Person {

    private String name;

    public Person() {
        this("Chris");
    }

    public Person(String name) {
        super();
        this.name = name;
    }

    @Override
    public String toString() {
        return name;
    }

    public String getName() {
        return name;
    }


    public void setName(String name) {
        this.name = name;
    }

}

// This class takes care of the event listener lists required by TreeModel.
// It also adds "fire" methods that call the methods in TreeModelListener.
// Look in TreeModelSupport for all of the pertinent code.
abstract class AbstractTreeModel extends TreeModelSupport implements TreeModel {
}


class TreeModelSupport {
   private Vector vector = new Vector();

   public void addTreeModelListener( TreeModelListener listener ) {
      if ( listener != null && !vector.contains( listener ) ) {
         vector.addElement( listener );
      }
   }

   public void removeTreeModelListener( TreeModelListener listener ) {
      if ( listener != null ) {
         vector.removeElement( listener );
      }
   }

   public void fireTreeNodesChanged( TreeModelEvent e ) {
      Enumeration listeners = vector.elements();
      while ( listeners.hasMoreElements() ) {
         TreeModelListener listener = (TreeModelListener)listeners.nextElement();
         listener.treeNodesChanged( e );
      }
   }

   public void fireTreeNodesInserted( TreeModelEvent e ) {
      Enumeration listeners = vector.elements();
      while ( listeners.hasMoreElements() ) {
         TreeModelListener listener = (TreeModelListener)listeners.nextElement();
         listener.treeNodesInserted( e );
      }
   }

   public void fireTreeNodesRemoved( TreeModelEvent e ) {
      Enumeration listeners = vector.elements();
      while ( listeners.hasMoreElements() ) {
         TreeModelListener listener = (TreeModelListener)listeners.nextElement();
         listener.treeNodesRemoved( e );
      }
   }

   public void fireTreeStructureChanged( TreeModelEvent e ) {
      Enumeration listeners = vector.elements();
      while ( listeners.hasMoreElements() ) {
         TreeModelListener listener = (TreeModelListener)listeners.nextElement();
         listener.treeStructureChanged( e );
      }
   }
}

847102 wrote:
After a bit more research, it does not work because JTree does not implement TreeModelListener. That's why you add manually the listener IE

This is not correct. JTree use an inner class as TreeModelListener and it works correctly for any model of tree.

The problem is that you do not send the correct events:
-to insert, you create a node changed event but calls the inserted node. Also the source would be better than the model of the tree.
-to remove them, do you the same (which will obviously not work). Also it will fail with an IndexOutOfBoundsException if you delete the last one.

I suggest you read the Javadoc for TreeModelEvent, especially the various manufacturers.

Tags: Java

Similar Questions

Maybe you are looking for