Animate JTree Drops #27
Chapter 3, Tables and Trees
|
145
HACK
The special rendering is a two-step process. First, getTreeCellRendererComponent( )
figures out if the cell to be rendered is the drop target, and if so, it sets a
local
boolean
. It sets another
boolean
to indicate that the drop target cell is a
leaf. Having set these
boolean
s, it returns the superclass’s implementation.
In short order, the renderer’s
paint( )
method is called. In the
paint( )
, you
can use the
boolean
s to apply special rendering. In this version, a drop tar-
get that is a leaf gets a line drawn in its top inset, suggesting that the
dropped item will be inserted before this node. If rendering a drop target
that is a branch—i.e., it’s not a leaf—then the special rendering puts a box
around the component.
Running the Code
The main method, shown in Example 3-17, builds a reorderable tree and
puts it in a
JFrame.
Example 3-17. Testing the drag-and-drop JTree
public static void main (String[] args) {
JTree tree = new DnDJTree( );
DefaultMutableTreeNode root = new DefaultMutableTreeNode("People");
DefaultMutableTreeNode set1 = new DefaultMutableTreeNode("Set 1");
DefaultMutableTreeNode set2 = new DefaultMutableTreeNode("Set 2");
DefaultMutableTreeNode set3 = new DefaultMutableTreeNode("Set 3");
set1.add (new DefaultMutableTreeNode ("Chris"));
set1.add (new DefaultMutableTreeNode ("Kelly"));
set1.add (new DefaultMutableTreeNode ("Keagan"));
set2.add (new DefaultMutableTreeNode ("Joshua"));
set2.add (new DefaultMutableTreeNode ("Kimi"));
set3.add (new DefaultMutableTreeNode ("Michael"));
set3.add (new DefaultMutableTreeNode ("Don"));
set3.add (new DefaultMutableTreeNode ("Daniel"));
root.add (set1);
root.add (set2);
set2.add (set3);
DefaultTreeModel mod = new DefaultTreeModel (root);
tree.setModel (mod);
// expand all
for (int i=0; i<tree.getRowCount( ); i++)
tree.expandRow (i);
// show tree
JScrollPane scroller =
new JScrollPane (tree,
ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
JFrame frame = new JFrame ("DnD JTree");
frame.getContentPane( ).add (scroller);
frame.pack( );
frame.setVisible(true);
}
146
|
Chapter 3, Tables and Trees
#27 Animate JTree Drops
HACK
Figure 3-12 shows the animation of a drag. In this case, the “Chris” node is
about to be dropped on top of the “Michael” node.
Because the drop is occurring over a leaf, the custom rendering shows a line
on top of the “Michael” node, meaning that “Chris” will be inserted before
“Michael”. The result of the drop is shown in Figure 3-13.
Figure 3-12. Dragging a node within a JTree
Figure 3-13. Dropping a node within a JTree
Animate JTree Drops #27
Chapter 3, Tables and Trees
|
147
HACK
In case that wasn’t such a good idea, Figure 3-14 shows the “Chris” node
being dragged back to where it was. In this case, the drag is over the “Set 1”
branch, which causes it to be drawn with a box around it, suggesting that
the drop will be “into” the branch.
The drop makes the dragged node the last child of the “Set 1” branch, as
shown in Figure 3-15.
Figure 3-14. Dragging a node to a branch
Figure 3-15. Dropping a node onto a branch
148
|
Chapter 3, Tables and Trees
#27 Animate JTree Drops
HACK
This code is primarily focused on making a single JTree reorderable. If you
want to make drag-and-drop work between widgets in your GUI, the big-
gest change you’ll need to make is to have the
drop( )
method not remove
the dragged node from the tree’s model, since you can’t assume that the
dragged item is even a node in this tree. A little bit of checking the event
source makes it easy enough to find what scenario you’re dealing with.

Get Swing Hacks now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.