0

I am learning how to implement TreeTable in SwingX. For a start I have a table model:

import java.util.ArrayList;
import java.util.List;

import org.jdesktop.swingx.treetable.AbstractTreeTableModel;
import org.jdesktop.swingx.treetable.DefaultTreeTableModel;

public class MyTreeTableModel extends AbstractTreeTableModel 
{
    private MyTreeNode myroot;
    //here we add new children
    public MyTreeTableModel()
    {
        myroot = new MyTreeNode( "root", "Root of the tree" );


        myroot.getChildren().add( new MyTreeNode( "Empty Child 1", "This is an empty child" ) );

        MyTreeNode subtree = new MyTreeNode( "Sub Tree", "This is a subtree (it has children)" );
        subtree.getChildren().add( new MyTreeNode( "EmptyChild 1, 1", "This is an empty child of a subtree" ) );
        subtree.getChildren().add( new MyTreeNode( "EmptyChild 1, 2", "This is an empty child of a subtree" ) );
        myroot.getChildren().add( subtree );

        myroot.getChildren().add( new MyTreeNode( "Empty Child 2", "This is an empty child" ) );    

    }

    public void addChildren(){
        myroot.getChildren().add( new MyTreeNode( "Empty Child 1", "This is an empty child" ) );
    }

    //get colunmcount
    public int getColumnCount() 
    {
        return 4;
    }

    @Override
    public String getColumnName( int column )
    {
        switch( column )
        {
        case 0: return "Description";
        case 1: return "Amount";
        case 2: return "Date";
        case 3: return "Paid";

        default: return "Unknown";
        }
    }

    public Object getValueAt( Object node, int column ) 
    {
        System.out.println( "getValueAt: " + node + ", " + column );
        MyTreeNode treenode = ( MyTreeNode )node;
        switch( column )
        {
        case 0: return treenode.getName();
        case 1: return treenode.getDescription();
        case 2: return treenode.getChildren().size();
        default: return "Unknown";
        }
    }

    public Object getChild( Object node, int index ) 
    {
        MyTreeNode treenode = ( MyTreeNode )node;
        return treenode.getChildren().get( index );
    }

    public int getChildCount( Object parent ) 
    {
        MyTreeNode treenode = ( MyTreeNode )parent;
        return treenode.getChildren().size();
    }

    public int getIndexOfChild( Object parent, Object child ) 
    {
        MyTreeNode treenode = ( MyTreeNode )parent;
        for( int i=0; i>treenode.getChildren().size(); i++ )
        {
            if( treenode.getChildren().get( i ) == child )
            {
                return i;
            }
        }

        // TODO Auto-generated method stub
        return 0;
    }

     public boolean isLeaf( Object node )
     {
         MyTreeNode treenode = ( MyTreeNode )node;
         if( treenode.getChildren().size() > 0 )
         {
             return false;
         }
         return true;
     }

     @Override
     public Object getRoot()
     {
         return myroot;
     }
     }

class MyTreeNode
{
    private String name;
    private String description;
    private List<MyTreeNode> children = new ArrayList<MyTreeNode>();

    public MyTreeNode() 
    {
    }

    public MyTreeNode( String name, String description ) 
    {
        this.name = name;
        this.description = description;
    }

    public String getName() 
    {
        return name;
    }

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

    public String getDescription() 
    {
        return description;
    }

    public void setDescription(String description) 
    {
        this.description = description;
    }

    public List<MyTreeNode> getChildren() 
    {
        return children;
    }

    public String toString()
    {
        return "MyTreeNode: " + name + ", " + description;
    }

And here I trying to run it:

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;

import models.ExpenseModel;

import org.jdesktop.swingx.JXTreeTable;


public class SwingXExample extends JFrame 
{
    private JTabbedPane tabs = new JTabbedPane();

    private MyTreeTableModel treeTableModel = new MyTreeTableModel();
    private JXTreeTable treeTable = new JXTreeTable( treeTableModel );

    public SwingXExample()
    {
        super( "SwingX Examples" );

        // Build the tree table panel
        JPanel treeTablePanel = new JPanel( new BorderLayout() );
        treeTablePanel.add( new JScrollPane( treeTable ) );
        tabs.addTab( "JXTreeTable", treeTablePanel );


        JButton add_button = new JButton("+");
        JPanel buttonsPanel = new JPanel();
        buttonsPanel.setBounds(10, 260, 300, 30);
        getContentPane().add(buttonsPanel);
        buttonsPanel.setLayout(new GridLayout(0, 3, 0, 0));
        buttonsPanel.add(add_button);  
        add_button.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                // Get active table
                treeTableModel.addChildren();
            }
        });

        // Add the tabs to the JFrame

        add( tabs );

        setSize( 1024, 768 );
        Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
        setLocation( d.width / 2 - 512, d.height/2 - 384 );
        setVisible( true );
        setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
    }


    public static void main( String[] args )
    {
        AppStarter starter = new AppStarter( args );
        SwingUtilities.invokeLater( starter );
    }
}

class AppStarter extends Thread
{
    private String[] args;

    public AppStarter( String[] args )
    {
        this.args = args;
    }

    public void run()
    {
        SwingXExample example = new SwingXExample();
    }

}

The problem is, that my method, addChildren doesn't work at all, table is not updating when i push the button. In addition, I wonder how can i delete something from the table. If anyone knows what I am doing wrong here, please help me.

Ophelia
  • 549
  • 1
  • 5
  • 26

1 Answers1

0

After some digging around the JavaDocs, I was disappointed within not finding a fireXxx method...

So I started digging around the source code of DefaultTreeTableModel, because it has a insertNodeInto method...

public void insertNodeInto(MutableTreeTableNode newChild,
        MutableTreeTableNode parent, int index) {
    parent.insert(newChild, index);

    modelSupport.fireChildAdded(new TreePath(getPathToRoot(parent)), index,
            newChild);
}

So, there is another class which is been used to provide support for event notification, awesome...now, how do we get access to it??

After following the code back, I found...

public abstract class AbstractTreeTableModel implements TreeTableModel {

    /**
     * Provides support for event dispatching.
     */
    protected TreeModelSupport modelSupport;

So, modelSupport is defined in AbstractTreeTableModel as protected! Not the way I would like to have done it, but there it is.

So, in your addChildren method, you need to fire an event telling the view that a new node was inserted...

public void addChildren(){
    MyTreeNode newChild = new MyTreeNode( "Empty Child 1", "This is an empty child" );
    myroot.getChildren().add(newChild);
    modelSupport.fireChildAdded(
        new TreePath(getPathToRoot(myroot)), 
        myroot.getChildren().size() - 1,
        newChild);
}

or some such...

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • hmmm, it says that The method fireChildAdded(TreePath, int, Object) in the type TreeModelSupport is not applicable for the arguments (TreePath, int, MyTreeNode) AND for some reason treepath cannot be resolved as a type0_o – Ophelia Feb 26 '15 at 23:48
  • Well, [`javax.swing.tree.TreePath`](http://docs.oracle.com/javase/7/docs/api/javax/swing/tree/TreePath.html) is part of the Swing API...(and I didn't test the code, I just hobbled it together) – MadProgrammer Feb 26 '15 at 23:50
  • ok, with importing treepath this problem was solved, but now it doesnt seem to know the method getPathtoRoot – Ophelia Feb 27 '15 at 00:29