X

Geertjan's Blog

  • June 3, 2008

Swing Outline Component

Geertjan Wielenga
Product Manager
Announcing the new Swing Tree Table today, Tim writes:

Usage is incredibly easy - you just provide a standard Swing TreeModel of whatever sort you like, and an additional RowModel that can be queried for the other columns contents, editability and so forth.

I found an example from sometime ago, by Tim, and have been playing with it to get used to this new development. The result is as follows:

To get started, I simply download the latest NetBeans IDE development build from netbeans.org and then attached the platform8/org-netbeans-swing-outline.jar to my Java SE project. Then I created a JFrame.

To work with this Swing tree table, you need to provide the new "org.netbeans.swing.outline.Outline" class with the new "org.netbeans.swing.outline.OutlineModel" which, in turn, is built from a plain old javax.swing.tree.TreeModel, together with the new "org.netbeans.swing.outline.RowModel". Optionally, to change the default rendering, you can use the new "org.netbeans.swing.outline.RenderDataProvider".

Let's first create a TreeModel for accessing files on disk. We will receive the root of the file system as a starting point:

private static class FileTreeModel implements TreeModel {
private File root;
public FileTreeModel(File root) {
this.root = root;
}
@Override
public void addTreeModelListener(javax.swing.event.TreeModelListener l) {
//do nothing
}
@Override
public Object getChild(Object parent, int index) {
File f = (File) parent;
return f.listFiles()[index];
}
@Override
public int getChildCount(Object parent) {
File f = (File) parent;
if (!f.isDirectory()) {
return 0;
} else {
return f.list().length;
}
}
@Override
public int getIndexOfChild(Object parent, Object child) {
File par = (File) parent;
File ch = (File) child;
return Arrays.asList(par.listFiles()).indexOf(ch);
}
@Override
public Object getRoot() {
return root;
}
@Override
public boolean isLeaf(Object node) {
File f = (File) node;
return !f.isDirectory();
}
@Override
public void removeTreeModelListener(javax.swing.event.TreeModelListener l) {
//do nothing
}
@Override
public void valueForPathChanged(javax.swing.tree.TreePath path, Object newValue) {
//do nothing
}
}

Next, let's introduce the RowModel class:

private class FileRowModel implements RowModel {
@Override
public Class getColumnClass(int column) {
switch (column) {
case 0:
return Date.class;
case 1:
return Long.class;
default:
assert false;
}
return null;
}
@Override
public int getColumnCount() {
return 2;
}
@Override
public String getColumnName(int column) {
return column == 0 ? "Date" : "Size";
}
@Override
public Object getValueFor(Object node, int column) {
File f = (File) node;
switch (column) {
case 0:
return new Date(f.lastModified());
case 1:
return new Long(f.length());
default:
assert false;
}
return null;
}
@Override
public boolean isCellEditable(Object node, int column) {
return false;
}
@Override
public void setValueFor(Object node, int column, Object value) {
//do nothing for now
}
}

Now, after dragging-and-dropping an Outline object onto your JFrame (which is possible after adding the beans from the JAR to the Palette Manager) which, in turn, automatically creates a JScrollPane as well, this is how you could code the JFrame's constructor:

public NewJFrame() {
//Initialize the ui generated by the Matisse GUI Builder, which,
//for example, adds the JScrollPane to the JFrame ContentPane:
initComponents();
//Here I am assuming we are not on Windows,
//otherwise use Utilities.isWindows() ? 1 : 0
//from the NetBeans Utilities API:
TreeModel treeMdl = new FileTreeModel(File.listRoots()[0]);
//Create the Outline's model, consisting of the TreeModel and the RowModel,
//together with two optional values: a boolen for something or other,
//and the display name for the first column:
OutlineModel mdl = DefaultOutlineModel.createOutlineModel(
treeMdl, new FileRowModel(), true, "File System");
//Initialize the Outline object:
outline1 = new Outline();
//By default, the root is shown, while here that isn't necessary:
outline1.setRootVisible(false);
//Assign the model to the Outline object:
outline1.setModel(mdl);
//Add the Outline object to the JScrollPane:
jScrollPane1.setViewportView(outline1);
}

At this point, you can run the JFrame, with this result:

So, we see a lot of superfluous info that doesn't look very nice. Let's implement "org.netbeans.swing.outline.RenderDataProvider", as follows:

private class RenderData implements RenderDataProvider {
@Override
public java.awt.Color getBackground(Object o) {
return null;
}
@Override
public String getDisplayName(Object o) {
return ((File) o).getName();
}
@Override
public java.awt.Color getForeground(Object o) {
File f = (File) o;
if (!f.isDirectory() && !f.canWrite()) {
return UIManager.getColor("controlShadow");
}
return null;
}
@Override
public javax.swing.Icon getIcon(Object o) {
return null;
}
@Override
public String getTooltipText(Object o) {
File f = (File) o;
return f.getAbsolutePath();
}
@Override
public boolean isHtmlDisplayName(Object o) {
return false;
}
}

Now, back in the constructor, add the renderer to the outline:

outline1.setRenderDataProvider(new RenderData());

Run the JFrame again and the result should be the same as in the first screenshot above. Look again at the rendering code and note that, for example, you have tooltips:

Join the discussion

Comments ( 34 )
  • Casper Bang Tuesday, June 3, 2008

    I wonder why Sun sponsors two distinct yet so similar components as the JXTreeTable from SwingLabs (by Jeannette and Karl) and this NetBeans one (by Tim Bray?).

    They appear equally powerful although admittedly I know very little about the NetBeans one, but both appear to revolve around javax.swing.tree.TreeModel.


  • Geertjan Tuesday, June 3, 2008

    Not Tim Bray, but Tim Boudreau. And, secondly, I'm pretty sure the two tree tables are pretty different, Tim's one is probably more suited to the NetBeans Platform, but that's just a guess.


  • Jon W Wednesday, June 4, 2008

    Cool, I might be using this for an upcoming project of mine.

    This tutorial gave me a nice headstart, thx!


  • Saeven Friday, June 6, 2008

    JIDE has one of these too that works really well. So is this going to make its way into javax.swing? Seems that such a component would be a logical fit into the stock Swing family.


  • Jay Monday, June 9, 2008

    I was using jxtreetable in my current project; and by following your example, I was able to hack an alternate version in Outline. Pretty impressive. Haven't played much, but sure to say the two do share certain similarity, which is good thing. No documentation on Outline has been a real pain. Still have no clue as how to make a tree fully expanded in a treetable via code.

    Wish the two will merge and become a better one.


  • Montechristos Monday, June 16, 2008

    How about tooltips/highlighters that JXTreeTable provides?


  • Jeanette Winzenburg Monday, June 16, 2008

    Just started to evaluate Outline (naturally from my SwingX biased perspective :-) and started a discussion thread over at SwingLabs forum <p>

    <a href="http://forums.java.net/jive/thread.jspa?threadID=42470&tstart=0">JXTreeTable vs. Outline</a> <p>

    Cheers

    Jeanette


  • guest Monday, June 16, 2008

    hmm ... no way to edit a post? The link looks busted, trying again:

    http://forums.java.net/jive/thread.jspa?threadID=42470&tstart=0


  • battery Thursday, June 26, 2008

    […] former peeps over at Yahoo just released 10 more components, 3 Flash and 5 Flex components. The also fixed some of the bugs […]


  • valentin Thursday, June 26, 2008

    Hi,

    Can anybody tell when org-netbeans-swing-outline.jar will be available into final NetBeans 6.1?


  • valentin Thursday, June 26, 2008

    Can you tell me please how to build org-netbeans-swing-outline.jar from sources?


  • Geertjan Thursday, June 26, 2008

    It will be part of 6.5 Milestone 1. You can already get it if you download a development build from netbeans.org. No need to build it from sources, just get the JAR.


  • Ivan Tuesday, July 29, 2008

    Is it possible to use custom renderer/editor for the cells ? Namely I'de like to use ComboBox to edit values in the table part


  • Josep Monday, August 4, 2008

    I have installed the Netbeans 6.5M1 in a virtual machine and copied the JAR into my 6.1 folders.

    Following your examples it has been easy to implement.

    Thanks a lot!


  • Jos&eacute; Renato Tuesday, August 19, 2008

    Hi,

    I'm using this amazing component, and I'm having some trouble to enable the DnD support for my data structure.

    When I'm using a JTree, I have the getSelectedPaths method to know exactly which objects are selected per node.

    Using the OutLine component, How do I do that? Because, the SelectionModel that is accept in this component is a ListSelectionModel and not a TreeSelectionModel.

    Thanks..


  • pfoomer Saturday, August 30, 2008

    Having spent two hours trying to get an JXTreeTable working , the demo's too convoluted, Outline up in 15 mins, now modifying for my project.

    Cheers Tom


  • Froed Tuesday, November 18, 2008

    under which license is the outline.jar released? Can we use this binary in our commercial application without problems to our license terms (e.g. like we have with GPL and/or lgpl licenses)

    Thanks for your help

    Froed


  • thorsten Thursday, November 20, 2008

    Is there a JavaDoc anywherethat describes Outline, RowModel etc.?


  • Francisco Martins Tuesday, August 18, 2009

    how to implement the expansion and collapse of the object JTree using the outline?


  • Anatoliy Friday, August 28, 2009

    In Fedora, Outline doesn't paint expand/collapse icons for the tree elements as well as doesn't put any gap for the descendants

    Does anybody have any idea why and maybe some workaround?

    Thanks in advance.


  • Samyak Thursday, September 10, 2009

    Where can I get the sources for the 'org-netbeans-swing-outline.jar' that comes bundled with NetBeans 6.5 installation? I need it as it would help me while debugging my application which uses Outline component. Can somebody point me to the sources archive?

    Thanks in advance.


  • hootoo Monday, December 7, 2009

    Is it possible to use custom renderer/editor for the cells ? Namely I'de like to use ComboBox to edit values in the table part


  • NetBeans Newbie Wednesday, March 3, 2010

    Hi Geertjan,

    Love your tutorial and writeups all over the netbeans.org site and internet. Can you show how to build a Tree with each tree node having an image of its own?

    Thanks,


  • Xue li Shen Thursday, May 20, 2010

    Thanks for the great work. But looks like I have some problem when I set asksAllowsChildren to false. What I am doing is

    - Build the tree table

    - add some nodes under an empty node, then fireTreeNodesInserted event. The node collapse icon is not updated.

    - add some nodes under an empty node, then fireTreeNodesInserted event and fireTreeNodesChanged event. The node collapse icon is updated. But when I click the collapse icon, it does not expend.

    Is there some way to fix the problem? Thanks.


  • aquiles Tuesday, March 1, 2011

    Thanks for that comments, is very usefull.


  • Jaime Tuesday, October 4, 2011

    I understand that when you call the setValueFor method that you change the value for a single cell of the table. In a chase where you have that value modify other cells of the table (summations for example) how would you force the entire table to update after such a change? In a normal table you can force a data update by calling fireTableDataChanged() but here I don't see where you have that capibility.


  • dave Irving Tuesday, March 31, 2015

    Has anyone had any experience of getting more columns into the Etable level than is easily viewed. (i.e. how do you get the horizontal scroll bar to become visible). as whenever I add columns they just become smaller and smaller.

    I need to be able to add lots of columns, but keep their width?

    Any ideas? I cannot sort this one.


  • Geertjan Wednesday, April 1, 2015

    Put it into a JScrollPane probably.


  • Dave Irving Wednesday, April 1, 2015

    the panel already is extended from ScrollPane. The columns resize to fit the box.

    Actually - just found out - turn off Auto-resize on columns

    The table is then allowed to grow beyond the bounds of the View.


  • guest Wednesday, January 6, 2016

    Any one can you help I am added all system files like C,D,E,F folders into the JFilechooser with jtree and Jcheckbox format.When click on particular check box there will display the corresponding file size.These is the requirement how to do Can you people help me?


  • guest Tuesday, January 12, 2016

    I am done these for all folders.your solution for only one folder whether D or C

    Drives only.But all drives not possible.


  • guest Tuesday, January 12, 2016

    I am have another requirement that is when ever click on jtree check box inside jFilechooser dialog box its can be show inside file name field of jfilechooser.

    Actually I think these is complex task.

    Can you people help me as soon as possible?


  • Geertjan Tuesday, January 12, 2016

    No one will help you until you check code into GitHub so that others can take a look at it and advise you how to implement the features you need. Create a small application that sets up the application, add the components you need, put some comments in there stating what you'd like and what's missing. Also, join a mailing list instead of leaving entries at the end of a blog entry -- e.g., dev at platform dot netbeans dot org and ask your questions there.


  • Patrick Lucas Tuesday, April 18, 2017

    Hi

    I am using the NetBeans version of this outline ad it does just what I want but I am hitting a brick wall when adding data to the data structure on which the model is based.

    How can I get the outline to update and show the new data without losing the tree's state?

    Any help would be greatly appreciated.

    All the best

    Patrick


Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.