DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Newsletter
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • Implementing LSM Trees in Golang: A Comprehensive Guide
  • Data Store Options for Operational Analytics/Data Engineering
  • Angular Component Tree With Tables in the Leaves and a Flexible JPA Criteria Backend
  • Popular JavaScript TreeGrid Components for Productive Data Management

Trending

  • Batching Strategies: Throughput vs Latency in Practice
  • Top Gen AI Frameworks for Go in 2026: A Hands-On Comparison
  • PWA on iOS, Part 3: Chrome on iPhone Is WebKit Too. How One Engine Sets the Rules for PWAs on iOS
  • The Window Closes: Why I Switched to Kotlin Before the Codebase Got Too Big

Draft This article hasn't been published, so readers can't see it.

In moderation This article is waiting for review, so readers can't see it yet.

Deleted This article has been deleted, so readers can't see it.

  1. DZone
  2. Data Engineering
  3. Databases
  4. Taking the New Swing Tree Table for a Spin

Taking the New Swing Tree Table for a Spin

By 
Geertjan Wielenga
·
Jun. 04, 08 · News
Post on X (opens in a new tab) Share on LinkedIn (opens in a new tab)
84.2K Views

Join the DZone community Save articles, join the discussion, and download Refcards and Trend Reports with a free account.

Join for free Already a member? Log in
Announcing the new Swing Tree Table yesterday, Tim Boudreau 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 some time 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. For the rest, I wasn't required to do anything with NetBeans, necessarily. I could have attached the JAR to a project in Eclipse or anywhere else. 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
}

}

The above could simply be set as a JTree's model and then you'd have a plain old standard JTree. It would work, no problems, it would be a normal JTree. However, it wouldn't be a tree table since you'd only have a tree, without a table. Therefore, let's now add two extra columns, via the new "org.netbeans.swing.outline.RowModel" class, which will enable the creation of a tree table instead of a tree:

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 NetBeans IDE 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 boolean 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);

}

Alternatively, without the NetBeans Matisse GUI Builder and NetBeans Palette Manager, i.e., simply using a standard Java class, you could do something like this:

private Outline outline;
public NewJFrame() {

setDefaultCloseOperation(EXIT_ON_CLOSE);

getContentPane().setLayout(new BorderLayout());

TreeModel treeMdl = new FileTreeModel(File.listRoots()[0]);

OutlineModel mdl = DefaultOutlineModel.createOutlineModel(
treeMdl, new FileRowModel(), true);

outline = new Outline();

outline.setRootVisible(false);

outline.setModel(mdl);

getContentPane().add(new JScrollPane(outline),BorderLayout.CENTER);

setBounds(20, 20, 700, 400);

}

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:

 

Database Tree (data structure) SPIN (software process)

Opinions expressed by DZone contributors are their own.

Related

  • Implementing LSM Trees in Golang: A Comprehensive Guide
  • Data Store Options for Operational Analytics/Data Engineering
  • Angular Component Tree With Tables in the Leaves and a Flexible JPA Criteria Backend
  • Popular JavaScript TreeGrid Components for Productive Data Management

Partner Resources

×

Comments

Loading comments

The comments didn't load

Please try again in a moment.

Likes

Loading

The next likes didn't load. Please try again.

The likes didn't load

Please try again in a moment.

See who liked this

Log in or join DZone for free to see who liked this article.

Log in Join for free
  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook