TreeSelectionListener reacts to selection events
- Creates a JSplitPane
- Creates a JTree, and places it in a JScrollPane
- Places the JScrollPane in the top half of the JSplitPane
- Displays Descriptive text, from html files, in the bottom half
|
|
public class TreeDemo extends JPanel implements TreeSelectionListener {
private JEditorPane htmlPane;
private JTree tree;
private URL helpURL;
private static boolean DEBUG = false;
public TreeDemo() {
super(new GridLayout(1,0));
//Create the nodes.
DefaultMutableTreeNode top = new DefaultMutableTreeNode("The Java Series");
createNodes(top); // call method to create nodes under root node
//Create a tree that allows one selection at a time.
tree = new JTree(top);
tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
//Listen for when the selection changes.
tree.addTreeSelectionListener(this);
//Create the scroll pane and add the tree to it.
JScrollPane treeView = new JScrollPane(tree);
//Create the HTML viewing pane.
htmlPane = new JEditorPane();
htmlPane.setEditable(false);
initHelp();
JScrollPane htmlView = new JScrollPane(htmlPane);
//Add the scroll panes to a split pane.
JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
splitPane.setTopComponent(treeView);
splitPane.setBottomComponent(htmlView);
Dimension minimumSize = new Dimension(100, 50);
htmlView.setMinimumSize(minimumSize);
treeView.setMinimumSize(minimumSize);
splitPane.setDividerLocation(100); //XXX: ignored in some releases
//of Swing. bug 4101306
//workaround for bug 4101306:
//treeView.setPreferredSize(new Dimension(100, 100));
splitPane.setPreferredSize(new Dimension(500, 300));
//Add the split pane to this panel.
add(splitPane);
}
User Object: the argument to the DefaultMutableTreeNode constructor
- An object that contains or points to the data associated with the tree node
- Can be a string
- Can be a custom object. If custom, implement its toString method so a string can be displayed for that node.
-
Example: BookInfo class a custom class that holds two pieces of data
- the name of a book
- the URL for an HTML file describing the book.
The toString method is implemented to return the book name.
private class BookInfo {
public String bookName;
public URL bookURL;
public BookInfo(String book, String filename) {
bookName = book;
bookURL = TreeDemo.class.getResource(filename);
if (bookURL == null) {
System.err.println("Couldn't find file: "
+ filename);
}
}
public String toString() {
return bookName;
}
}
Note: getResource is a method of java.lang.class, a subclass of java.lang.object.
From the API:
public URL getResource(String name)
Finds a resource with a given name. This method returns null if no resource with this name is found. The rules for searching resources associated with a given class are implemented by the * defining class loader of the class.
This method delegates the call to its class loader, after making these changes to the resource name: if the resource name starts with "/", it is unchanged; otherwise, the package name is prepended to the resource name after converting "." to "/". If this object was loaded by the bootstrap loader, the call is delegated to ClassLoader.getSystemResource.
Parameters:
name - name of the desired resource
Returns:
a java.net.URL object.
Since:
JDK1.1
See Also:
ClassLoader
TreeSelectionListener
- Used to respond to tree node selections. E.g.:
- Get default TreeSelectionModel for the tree
- Set TreeSelectionModel so at most one tree node at a time can be selected.
- Register an event handler on the tree:
- an object that implements the TreeSelectionListener interface.
- determines which node is selected by invoking the tree's getLastSelectedPathComponent method.
- Uses getUserObject method to get the data associated with the node.
/** Required by TreeSelectionListener interface. */
public void valueChanged(TreeSelectionEvent e) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode)
tree.getLastSelectedPathComponent(); // this method belongs to class JTree
if (node == null) return;
Object nodeInfo = node.getUserObject();
if (node.isLeaf()) {
BookInfo book = (BookInfo)nodeInfo;
displayURL(book.bookURL);
if (DEBUG) {
System.out.print(book.bookURL + ": \n ");
}
} else {
displayURL(helpURL);
}
if (DEBUG) {
System.out.println(nodeInfo.toString());
}
}
private void displayURL(URL url) {
try {
if (url != null) {
htmlPane.setPage(url); //a JEditorPane can diplay text/plain, text/html, text/rtf MIME types
} else { //null url
htmlPane.setText("File Not Found");
if (DEBUG) {
System.out.println("Attempted to display a null URL.");
}
}
} catch (IOException e) {
System.err.println("Attempted to read a bad URL: " + url);
}
}
where setPage() method belongs to the JEditorPane class. From the API:
public void setPage(URL page)
throws IOException
Sets the current URL being displayed. The content type of the pane is set, and if the editor kit for the pane is non-null, then a new default document is created and the URL is read into it.
Creating the Nodes
This method is passed the root node, an instance of DefaultMutableTreeNode
private void createNodes(DefaultMutableTreeNode top) {
DefaultMutableTreeNode category = null;
DefaultMutableTreeNode book = null;
category = new DefaultMutableTreeNode("Books for Java Programmers");
top.add(category);
//original Tutorial
book = new DefaultMutableTreeNode(new BookInfo
("The Java Tutorial: A Short Course on the Basics",
"tutorial.html"));
category.add(book);
//Tutorial Continued
book = new DefaultMutableTreeNode(new BookInfo
("The Java Tutorial Continued: The Rest of the JDK",
"tutorialcont.html"));
category.add(book);
//JFC Swing Tutorial
book = new DefaultMutableTreeNode(new BookInfo
("The JFC Swing Tutorial: A Guide to Constructing GUIs",
"swingtutorial.html"));
category.add(book);
//Bloch
book = new DefaultMutableTreeNode(new BookInfo
("Effective Java Programming Language Guide",
"bloch.html"));
category.add(book);
//Arnold/Gosling
book = new DefaultMutableTreeNode(new BookInfo
("The Java Programming Language", "arnold.html"));
category.add(book);
//Chan
book = new DefaultMutableTreeNode(new BookInfo
("The Java Developers Almanac",
"chan.html"));
category.add(book);
category = new DefaultMutableTreeNode("Books for Java Implementers");
top.add(category);
//VM
book = new DefaultMutableTreeNode(new BookInfo
("The Java Virtual Machine Specification",
"vm.html"));
category.add(book);
//Language Spec
book = new DefaultMutableTreeNode(new BookInfo
("The Java Language Specification",
"jls.html"));
category.add(book);
}
Changing the Icon in a JTree
- icon displayed by a node is determined by whether
- the node is a leaf
- whether the node is expanded.
- The specific icon depends on the look and feel implementation, but can be overridden by your program:
- first create an instance of DefaultTreeCellRenderer
- Next, specify the icons to use by invoking methods on the renderer:
- setLeafIcon (for leaf nodes)
- setOpenIcon (for expanded branch nodes)
- setClosedIcon (for collapsed branch nodes).
- Then use the tree's setCellRenderer method to specify that the DefaultTreeCellRenderer paint its nodes.
public class TreeIconDemo extends JPanel implements TreeSelectionListener {
private JEditorPane htmlPane;
private JTree tree;
private URL helpURL;
private static boolean DEBUG = false;
public TreeIconDemo() {
super(new GridLayout(1,0));
//Create the nodes.
DefaultMutableTreeNode top =
new DefaultMutableTreeNode("The Java Series");
createNodes(top);
//Create a tree that allows one selection at a time.
tree = new JTree(top);
tree.getSelectionModel().setSelectionMode
(TreeSelectionModel.SINGLE_TREE_SELECTION);
//Set the icon for leaf nodes.
ImageIcon leafIcon = createImageIcon("images/dukeWaveRed.gif");
if (leafIcon != null) {
DefaultTreeCellRenderer renderer = new DefaultTreeCellRenderer();
renderer.setLeafIcon(leafIcon);
tree.setCellRenderer(renderer);
} else {
System.err.println("Leaf icon missing; using default.");
}
// The rest of the code is the same as TreeDemo, except:
/** Returns an ImageIcon, or null if the path was invalid. */
protected static ImageIcon createImageIcon(String path) {
java.net.URL imgURL = TreeIconDemo2.class.getResource(path);
if (imgURL != null) {
return new ImageIcon(imgURL);
} else {
System.err.println("Couldn't find file: " + path);
return null;
}
}
Varying Node Icon
- Another example: TreeIconDemo2
- creates cell renderer that varies the leaf icon depending on whether the word "Tutorial" is in the node's text data.
- the renderer also specifies tool-tip text
public class TreeIconDemo2 extends JPanel
implements TreeSelectionListener {
private JEditorPane htmlPane;
private JTree tree;
private URL helpURL;
private static boolean DEBUG = false;
public TreeIconDemo2() {
super(new GridLayout(1,0));
//Create the nodes.
DefaultMutableTreeNode top =
new DefaultMutableTreeNode("The Java Series");
createNodes(top);
//Create a tree that allows one selection at a time.
tree = new JTree(top);
tree.getSelectionModel().setSelectionMode
(TreeSelectionModel.SINGLE_TREE_SELECTION);
//Enable tool tips. This lets us call setToolTipText() below.
ToolTipManager.sharedInstance().registerComponent(tree);
//Set the icon for leaf nodes.
ImageIcon tutorialIcon = createImageIcon("images/middle.gif");
if (tutorialIcon != null) {
tree.setCellRenderer(new MyRenderer(tutorialIcon));
} else {
System.err.println("Tutorial icon missing; using default.");
}
etc., as in TreeDemo.
Re: ToolTipManager, From the API:
public class ToolTipManager
extends MouseAdapter
implements MouseMotionListener
Finally:
private class MyRenderer extends DefaultTreeCellRenderer {
Icon tutorialIcon;
public MyRenderer(Icon icon) {
tutorialIcon = icon;
}
// override this method from DefaultTreeCellRenderer:
public Component getTreeCellRendererComponent(
JTree tree,
Object value,
boolean sel,
boolean expanded,
boolean leaf,
int row,
boolean hasFocus) {
super.getTreeCellRendererComponent(
tree, value, sel,
expanded, leaf, row,
hasFocus);
if (leaf && isTutorialBook(value)) {
setIcon(tutorialIcon);
setToolTipText("This book is in the Tutorial series.");
} else {
setToolTipText(null); //no tool tip
}
return this;
}
protected boolean isTutorialBook(Object value) {
DefaultMutableTreeNode node =
(DefaultMutableTreeNode)value;
BookInfo nodeInfo =
(BookInfo)(node.getUserObject());
String title = nodeInfo.bookName;
if (title.indexOf("Tutorial") >= 0) {
return true;
}
return false;
}