Link to home
Start Free TrialLog in
Avatar of SmileMagician
SmileMagician

asked on

Adding checkboxes to a JTree

I have a JTree that I am hoping to add checkboxes next to each child and then be able to check whether an individual checkbox is checked later  (by row number is fine). Here is the code I have outputting the folders and mp3 files on my hard drive into the tree:

  public void getList(DefaultMutableTreeNode node, File f) {
     if(!f.isDirectory()) {
         // We keep only MP3 files for display
         if (f.getName().endsWith("mp3")) {
            // System.out.println("FILE  -  " + f.getName());
            DefaultMutableTreeNode child = new DefaultMutableTreeNode(f);
            node.add(child);
            }
         }
     else {
         // Is a DIRECTORY  
         DefaultMutableTreeNode child = new DefaultMutableTreeNode(f);
         node.add(child);
         File fList[] = f.listFiles();
         for(int i = 0; i  < fList.length; i++)
             getList(child, fList[i]);
         }
    }

Thank you all so much!

SmileMagician  :)
SOLUTION
Avatar of sciuriware
sciuriware

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of SmileMagician
SmileMagician

ASKER

Ya, thats exactly what I want to do!  I am studying the three Java files but I don't know exactly what I need to add to my coding. Is this example creating the JTree in a different way than I am?  (I am just not finding any similar coding to my previous code snippet).
Look at the picture on that site.

;JOOP!
You use DefaultMutableTreeNode. You will need to use CheckNode instead. It extends extends DefaultMutableTreeNode.

The other things will remain almost the same. You will need to use a special Renderer and so on. Check the code as sciuriware said.

And see this: http://java.sun.com/docs/books/tutorial/uiswing/components/tree.html for the basics of customising a tree if you had not already seen it and if you just do not know the concept.
Heres a piece of the coding from that example that uses an array to build the tree. Since I am not using this array (but the coding above) to build my tree, I am having trouble combining my coding and theirs.      Also, is CheckNode its own class or do I replace DefaultMutableTreeNode completely?

    String[] strs = {"swing",     // 0
         "platf",     // 1
         "basic",     // 2
         "metal",     // 3
         "JTree"};    // 4
    CheckNode[] nodes = new CheckNode[strs.length];
    for (int i=0;i<strs.length;i++) {
      nodes[i] = new CheckNode(strs[i]);
    }
    nodes[0].add(nodes[1]);
    nodes[1].add(nodes[2]);
    nodes[1].add(nodes[3]);
    nodes[0].add(nodes[4]);
    nodes[3].setSelected(true);
    JTree tree = new JTree( nodes[0] );
    tree.setCellRenderer(new CheckRenderer());
    tree.getSelectionModel().setSelectionMode(
      TreeSelectionModel.SINGLE_TREE_SELECTION
    );
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
We have progress! =P   I've added the two other java files from the example plus your edited coding Venabili and now the tree outputs fine with the checkboxes next to each child, but get this: none of the checkboxes work.  they simply won't check. When I doubleclick them, it will expand or collapse that folder however.   any thoughts?
Yep -- See the CheckNodeTreeExample class in the site above.

You need to have also the Mouse listener

From the url:
You need one more class (make it an inner class as is done in http://www.objects.com.au/java/examples/swing/CheckBoxTreeCell.do - CheckNodeTreeExample .java so that you can reach all the variables):

class NodeSelectionListener extends MouseAdapter {
    JTree tree;
   
    NodeSelectionListener(JTree tree) {
      this.tree = tree;
    }
   
    public void mouseClicked(MouseEvent e) {
      int x = e.getX();
      int y = e.getY();
      int row = tree.getRowForLocation(x, y);
      TreePath  path = tree.getPathForRow(row);
      //TreePath  path = tree.getSelectionPath();
      if (path != null) {
        CheckNode node = (CheckNode)path.getLastPathComponent();
        boolean isSelected = ! (node.isSelected());
        node.setSelected(isSelected);
        if (node.getSelectionMode() == CheckNode.DIG_IN_SELECTION) {
          if ( isSelected ) {
            tree.expandPath(path);
          } else {
            tree.collapsePath(path);
          }
        }
        ((DefaultTreeModel)tree.getModel()).nodeChanged(node);
        // I need revalidate if node is root.  but why?
        if (row == 0) {
          tree.revalidate();
          tree.repaint();
        }
      }
    }
  }

And in the init method:
tree.addMouseListener(new NodeSelectionListener(tree));

I told you you may need to add something in the init code :)
Sure enough,  that was all I needed was the NodeSelectionListener class.  (thank you) the checkboxes are working.  All that I need now is to figure out how to check if a specific row's checkbox is selected.  I am brainstorming as we speak but I thought I'd ask since you'd probly get it much quicker than I.  =)
Modify the NodeSelectionListener class :)
int row = tree.getRowForLocation(x, y); for example returns this:)

I o not know what you need exactly but this is the place to be done NodeSelectionListener.mouseClicked

Play around with the values you can take there
Hey man, thank you so much, your quite brilliant.  :)   Everything is working beautifully!
Shouldn't this be a split?
sciuriware  gave you a start and I just guided you to make it working so he deserves points I think:)

By chance I am the Page Editor so I can reopen the question to allow split if you want to.

Venabili
Absolutely! I guess I wasn't aware I could split the answer. If you could allow me to do that that'd be great!

SmileMagician :)
Ah, very nice.  Thanks again guys!

SmileMagician  :)
Thanks for fixing this :)
Thanks for the split.

;JOOP!