This may be a good time to look at the old JTreeTable code that will give you the tree displayed in the first column, and the freedom to display the cells for each column to the right of the node tree as you wish, in your case, check boxes and labels, as well as the ability to use TableCellEditors with your JTable, as you are used to. The warning is that while the code in this link works, it is a bit confusing.
There is an alternative. I demonstrated below the implementation of a tree table that should be better, called Outline , provided by NetBeans (although you do not need to develop using the NetBeans IDE, you just need a jar). This article shows how easy it is to get started.
I managed to mock up a quick example of an Outline tree table in Eclipse (using org-netbeans-swing-outline.jar imported into my project) after about 30 minutes (I slowly print):
private void buildFrame() { frame = new JFrame("Demo"); frame.setSize(300, 300); addStuffToFrame(); frame.setVisible(true); } private void addStuffToFrame() { MyTreeNode top = new MyTreeNode("top"); createNodes(top); DefaultTreeModel model = new DefaultTreeModel(top); //here are the netBeans tree table classes OutlineModel outlineModel = DefaultOutlineModel.createOutlineModel(model, new MyRowModel()); Outline outline = new Outline(); outline.setRootVisible(true); outline.setModel(outlineModel); frame.getContentPane().add(new JScrollPane(outline)); } private void createNodes(MyTreeNode top) { MyTreeNode child = new MyTreeNode("child 2"); top.add(new MyTreeNode("child 1")); child.add(new MyTreeNode("g-child1")); child.add(new MyTreeNode("g-child2")); child.add(new MyTreeNode("g-child3")); top.add(child); top.add(new MyTreeNode("child3")); top.add(new MyTreeNode("child4")); }
I am creating a TreeNode to store a Boolean that will interact well with the built-in JTable displaying mechnanism.
public class MyTreeNode extends DefaultMutableTreeNode { Boolean data1 = null; Boolean data2 = null; String name = null; MyTreeNode (String name) { this.name=name; } void setData1(Boolean val) {data1=val;} void setData2(Boolean val) {data2=val;} Boolean getData1() {return data1;} Boolean getData2() {return data2;} String getName() {return name;} }
NetBeans RowModel is the key to creating this table instead of a simple JTree:
public class MyRowModel implements RowModel { public Class getColumnClass(int col) { switch (col) { case 0: return String.class; case 1: return Boolean.class; //these return class definitions will case 2: return Boolean.class; //trigger the checkbox rendering default:return null; } } public int getColumnCount() { return 3; } public String getColumnName(int col) { return ""; } public Object getValueFor(Object node, int col) { MyTreeNode n = (MyTreeNode)node; switch (col) { case 0: return n.getName(); case 1: return n.getData1(); case 2: return n.getData2(); default:return null; } } public boolean isCellEditable(Object node, int col) { return col > 0; } public void setValueFor(Object node, int col, Object val) { MyTreeNode n = (MyTreeNode)node; if (col == 1) {n.setData1((Boolean)val);} else if (col == 2) {n.setData2((Boolean)val);} //EDIT: here is a recursive method to set all children // selected for one of the two checkboxes as it is // checked by the parent for (Enumeration children = n.children(); children.hasMoreElements(); ) { MyTreeNode child = (MyTreeNode) children.nextElement(); setValueFor(child, col, val); } } }
here is the finished, albeit simplified, product:
alt text http://img17.imageshack.us/img17/6643/picture1hz.png
I updated the setValueFor method to iterate over the children of the node and check the boxes as selected or deselected when the parent was changed.