Swing-based tree layouts with CheckboxTree

A configurable tree component with checkable nodes

CheckboxTree is an open source, Swing-based tree component with a checkbox in each of its nodes, similar to those commonly found in installers but missing from the Swing GUI toolkit. In this article creators Lorenzo Bigagli and Enrico Boldrini introduce CheckboxTree and demonstrate its standout features, namely four configurable check-propagation styles, grayed checkboxes, and a custom renderer that allows you to display radio buttons rather than checkboxes in your tree layouts. The article includes the source code for CheckboxTree, which you may use or extend for your Swing GUI development projects.

Installation GUIs and application preference windows often feature checkbox-enabled tree components, but you won't find such a component in the Swing GUI toolkit. Most developers either end up extending the Swing JTree ad-hoc or using one of the tree extensions available. We actually tried several of these components for a recent project but found that none of them had quite the features, simplicity or flexibility we needed.

Some components were part of an overly complicated widget library or required extending specific classes that disrupted our class hierarchy design. Some were not open source or relied on libraries that were not open source. Some had native dependencies. Most important, we needed a component that would support several checkbox propagation styles in a tree layout. We also wanted grayable checkboxes to indicate if descendants of a given node were in the opposite checking state from that node. So, like many developers before us, we created our CheckboxTree component from scratch.

CheckboxTree is a Swing JTree component with a checkbox in each of its nodes, as shown in Figure 1 (click the image for a live demonstration).

CheckboxTree is a Swing JTree with a checkbox in each of its nodes.
Figure 1. CheckboxTree: Checked, selected and grayed paths are visible

In this article we introduce CheckboxTree and explain its relationship to the Swing JTree classes. We also discuss its architecture and provide implementation details. Finally, we highlight some of the current limitations of CheckboxTree and note improvements that could be made to it in the future. CheckboxTree is available under the GPL license, so you are free to use it in your Swing development projects.

Background: JTree concepts and terminology

Before we begin describing CheckboxTree in detail, it might be helpful to quickly recall some Swing JTree concepts and terminology:

  • JTree, as described in the Swing documentation, is a "control that displays a set of hierarchical data as an outline."
  • A node is the basic unit of data displayed by a JTree. A specific node can be identified either by a TreePath or by its display row.
  • TreePath is an object that contains a JTree node and all its ancestors.
  • TreeModel is an object that manages the JTree data model based on the well-known MVC design pattern.
  • TreeSelectionModel is an object that manages user selections in a JTree, typically rendered by highlighting selected nodes.
  • TreeCellRenderer is used to style JTree nodes according to their content and status.

Using CheckboxTree

A key feature of CheckboxTree is that it does not require you to use tree nodes that implement a specific "checkable-node" interface (e.g., an interface with a method isChecked). You can continue to work with your preferred tree model, such as the default TreeModel or a custom one, which makes it easier to integrate CheckboxTree into your existing code.

You can use CheckboxTree by invoking one of the provided constructors, which are modeled after the standard JTree ones. The sample below shows how you would construct a CheckboxTree with a default TreeModel.

CheckboxTree checkboxTree = new CheckboxTree();

Here is how you would construct a CheckboxTree from an existing TreeNode:

TreeNode yourRoot = new DefaultMutableTreeNode("foo"); CheckboxTree checkboxTree = new CheckboxTree(yourRoot);

Here is how you would construct a CheckboxTree from an existing TreeModel:

Model yourTreeModel = new DefaultTreeModel(new DefaultMutableTreeNode("foo")); CheckboxTree checkboxTree = new CheckboxTree(yourTreeModel);

You could also set the data model at a later time, as shown here:

Model yourNewTreeModel = new DefaultTreeModel(new DefaultMutableTreeNode("bar")); checkboxTree.setModel(yourNewTreeModel);

Once constructed, your CheckboxTree is ready to listen for user input and respond.

1 2 3 4 Page 1
Page 1 of 4