Igor
Igor

Reputation: 1592

Adding nodes to programmatically created JTrees in Java

I'm creating this app that creates tabs and JTrees on button click events. The problem is when I try to add ne node to a JTree it doesn't refresh the JTree ( or it doesn't add the node to it ... I don't really know).

This is the functions that creates the tabs and trees:

jTabbedPane1.add(st,jSplitpane10);
int count = jTabbedPane1.getTabCount();
jTabbedPane1.setSelectedIndex(count-1);

DefaultMutableTreeNode root = new DefaultMutableTreeNode("All Notebooks");
DefaultMutableTreeNode notebook1 = new DefaultMutableTreeNode("Notebook 1");
root.add(notebook1);

// Create tree
JTree tree = new JTree(root);
//Create Scroll Pane for the tree
JScrollPane sp = new JScrollPane(tree);

Global.trees.add(tree);

And this is the code that is supposed to add new node "Green" to a tree in the selected tab:

int i = jTabbedPane1.getSelectedIndex();
DefaultTreeModel model = (DefaultTreeModel)Global.trees.get(i).getModel();

// Find node to which new node is to be added
int startRow = 0;
String prefix = "J";
TreePath path = Global.trees.get(i).getNextMatch(prefix, startRow, Position.Bias.Forward);
MutableTreeNode node = (MutableTreeNode)path.getLastPathComponent();

// Create new node
MutableTreeNode newNode = new DefaultMutableTreeNode("green");

// Insert new node as last child of node
model.insertNodeInto(newNode, node, node.getChildCount());
model.reload(newNode);

Here's also the declaration of the global list of JTrees:

public class Global {
    public java.util.List<JTree> trees = new ArrayList<JTree>();
}Global Global;

Any ideas why new nodes aren't showing in the trees???

Upvotes: 0

Views: 7678

Answers (3)

improgrammer
improgrammer

Reputation: 572

Here is some code to add JTree programmatically:

Source:http://sickprogrammersarea.blogspot.in/2014/03/add-jtree-programmatically-in-java-swing.html

import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.tree.*;
public class MyTree extends JApplet
{
  JTree t;
  JLabel l1;
  String lang[]={"C","C++","JAVA","PYTHON","AJAX","PHP"};
  public void init()
  {
    try
    {
     SwingUtilities.invokeAndWait(new Runnable() {
       public void run()
       {
          makeGUI();
       }
    });
    } catch(Exception e){
       System.out.println("Sorry some error occured "+e);
    }
}
private void makeGUI()
{
   DefaultMutableTreeNode top=new DefaultMutableTreeNode("Language");
   DefaultMutableTreeNode a=new DefaultMutableTreeNode("Programming");
   top.add(a);
   DefaultMutableTreeNode a1=new DefaultMutableTreeNode("C");
   a.add(a1);
   DefaultMutableTreeNode a2=new DefaultMutableTreeNode("Java");
   a.add(a2);
   DefaultMutableTreeNode b=new DefaultMutableTreeNode("Web Based");
   top.add(b);
   DefaultMutableTreeNode b1=new DefaultMutableTreeNode("PHP");
   b.add(b1);
   DefaultMutableTreeNode b2=new DefaultMutableTreeNode("JSP");
   b.add(b2);
   t=new JTree(top);
   JScrollPane scr=new JScrollPane(t);
   add(scr);
   setLayout(new  FlowLayout());
   l1=new JLabel("Choose a language");
   add(l1,BorderLayout.SOUTH);
   t.addTreeSelectionListener(new TreeSelectionListener () {
    public void valueChanged(TreeSelectionEvent ae) { 
      l1.setText(ae.getPath()+" is selected");
    }
  });
 }
}

Upvotes: 1

Duncan Jones
Duncan Jones

Reputation: 69339

I produced a small example application to test your issue. I found that the node was being added correctly, but not expanding. Also, the call to model.reload seems unnecessary.

I added a call to expandPath on the tree to cause the display to show the new node. You may need to double check this doesn't expand too much of the tree:

public class Example extends JFrame {

  private JTree tree;

  public Example() {
    DefaultMutableTreeNode root = new DefaultMutableTreeNode("All Notebooks");
    DefaultMutableTreeNode notebook1 = new DefaultMutableTreeNode("Notebook 1");
    root.add(notebook1);

    tree = new JTree(root);
    JScrollPane sp = new JScrollPane(tree);

    setLayout(new BorderLayout());
    add(sp, BorderLayout.CENTER);
    add(new JButton("Go") {
    {
      addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
          Example.this.addNode();
        }
      });
    }}, BorderLayout.SOUTH);

    setDefaultCloseOperation(EXIT_ON_CLOSE);
    pack();
  }


  private void addNode() {
    DefaultTreeModel model = (DefaultTreeModel) tree.getModel();

    // Find node to which new node is to be added
    int startRow = 0;
    String prefix = "N";
    TreePath path = tree.getNextMatch(prefix, startRow,
        Position.Bias.Forward);
    MutableTreeNode node = (MutableTreeNode) path.getLastPathComponent();

    // Create new node
    MutableTreeNode newNode = new DefaultMutableTreeNode("green");

    // Insert new node as last child of node
    model.insertNodeInto(newNode, node, node.getChildCount());
    tree.expandPath(path);
  }


  public static void main(String[] args) {    
    EventQueue.invokeLater(new Runnable() {      
      @Override
      public void run() {
        new Example().setVisible(true);
      }
    });
  }
}

Upvotes: 0

user529543
user529543

Reputation:

JTree and JTable are the most complex Swing components.

I think is reloaded, but not expanded. The JTree root node has many settings: how handler or not show root node or not and so on.

I am using a debug console listing where I dump the model data as text ( override the toString() in nodes too) and I can see easily,, what is there, but if you have just a few nodes not needed, it is enough with the Netbeans's debugger.

Also try to expand all rows in tree to have it visible.

Your code is good:

// Create new node
MutableTreeNode newNode = new DefaultMutableTreeNode("green");

// Insert new node as last child of node
model.insertNodeInto(newNode, node, node.getChildCount());
model.reload(newNode);

but probably it is not visible, you need to expand, how to do it, that is another question

Upvotes: 1

Related Questions