I l@ve RuBoard |
![]() ![]() |
17.6 Tree EventsTrees generate three types of events worth mentioning. Apart from the obvious selection events (TreeSelectionEvent, TreeSelectionListener), you can receive expansion events (TreeExpansionEvent, TreeExpansionListener, TreeWillExpandListener) from the graphical side, and you can catch structural changes to the model itself (TreeModelEvent, TreeModelListener). Figure 17-9 shows a simple program that uses the Every Event Listener (EEL) class (described in Chapter 3) to display all events that come from selecting, expanding, and editing a tree. (We use a tree built by the default JTree constructor.) For editing, you can change the text of a node or add and remove nodes so that you can monitor model events. Figure 17-9. The JTree events as reported by our EEL utility![]() Here's the source code required to hook up all the various events: // TreeEvents.java // import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; import javax.swing.tree.*; public class TreeEvents extends JFrame implements TreeSelectionListener { JButton addB, deleteB; JTree tree; DefaultMutableTreeNode leadSelection; public TreeEvents( ) { super("Tree Event Demo"); setSize(300,200); setDefaultCloseOperation(EXIT_ON_CLOSE); EEL eel = EEL.getInstance( ); eel.addGui( ); tree = new JTree( ); tree.setExpandsSelectedPaths(true); tree.setEditable(true); getContentPane( ).add(new JScrollPane(tree), BorderLayout.CENTER); tree.addTreeSelectionListener(eel); tree.addTreeSelectionListener(this); tree.addTreeExpansionListener(eel); tree.addTreeWillExpandListener(eel); tree.addPropertyChangeListener(eel); tree.getModel( ).addTreeModelListener(eel); addB = new JButton("Add a node"); deleteB = new JButton("Delete a node"); JPanel buttonP = new JPanel( ); buttonP.add(addB); buttonP.add(deleteB); getContentPane( ).add(buttonP, BorderLayout.SOUTH); addB.addActionListener(new ActionListener( ) { public void actionPerformed(ActionEvent ae) { String nodeName = JOptionPane.showInputDialog("New node name:"); if (leadSelection != null) { leadSelection.add(new DefaultMutableTreeNode(nodeName)); ((DefaultTreeModel)tree.getModel( )).reload(leadSelection); } else { JOptionPane.showMessageDialog(TreeEvents.this, "No Parent..."); } } }); deleteB.addActionListener(new ActionListener( ) { public void actionPerformed(ActionEvent ae) { if (leadSelection != null) { DefaultMutableTreeNode parent = (DefaultMutableTreeNode) leadSelection.getParent( ); if (parent == null) { JOptionPane.showMessageDialog(TreeEvents.this, "Can't delete root"); } else { parent.remove(leadSelection); leadSelection = null; ((DefaultTreeModel)tree.getModel( )).reload(parent); } } else { JOptionPane.showMessageDialog(TreeEvents.this, "No Selection..."); } } }); eel.showDialog( ); } public void valueChanged(TreeSelectionEvent e) { TreePath leadPath = e.getNewLeadSelectionPath( ); if (leadPath != null) { leadSelection = (DefaultMutableTreeNode)leadPath.getLastPathComponent( ); } } public static void main(String args[]) { TreeEvents te = new TreeEvents( ); te.setVisible(true); } } 17.6.1 The TreeModelEvent ClassThe TreeModelEvent class encapsulates model changes by specifying the path that has changed as well as information on the children of that path. 17.6.1.1 PropertiesThe TreeModelEvent has several properties as shown in Table 17-15. If the event contains information about the affected children of a node, you can retrieve the indices and the children themselves with the childIndices and children properties, respectively. The path and treePath properties provide access to the main node of the event. Whether you look at that node through a TreePath object or through an Object array depends on your program; both methods lead to the same node.
17.6.1.2 Constructors
17.6.2 The TreeModelListener InterfaceThe TreeModelListener interface requires that listeners implement the following methods:
We can use this class of events to monitor the state of the tree. For example, consider a tree that represents a filesystem. Any time we change the tree, we want to update the supporting filesystem. Listening for model changes would be the precise clue we need to perform the required updates. 17.6.3 The TreeSelectionEvent ClassSelection events occur whenever a user (or program, for that matter) changes the selection on a tree. For example, if you went through a directory tree and manually selected 12 discontiguous files, that would generate 12 selection events, each building on the last. If you were to pick 12 contiguous files by selecting the first file and using a modifier to pick the last, that would generate only two selection events. (Both of these examples assume that nothing was originally selected.) As with list selections, unselecting something also counts as a selection event. In many cases where more than one file can be selected, you shouldn't listen for selection events directly, but rather provide an OK button or some other means for the user to finalize the current selection. 17.6.3.1 PropertiesThe properties for TreeSelectionEvent are shown in Table 17-16. Not surprisingly, they are similar to the selection properties available for the JTree class.
17.6.3.2 Constructors
17.6.3.3 Methods
17.6.4 The TreeSelectionListener InterfaceThe TreeSelectionListener interface carries only one method:
17.6.5 The TreeExpansionEvent ClassNormally, the tree UI expands and collapses elements of a tree for you. However, if you want to listen for and react to these events, you can do so. The TreeExpansionEvent class covers both expanding and collapsing a tree node. 17.6.5.1 PropertyThe sole property for TreeExpansionEvent is shown in Table 17-17.
17.6.5.2 Constructor
17.6.6 The TreeExpansionListener InterfaceTo catch expansion or collapse events yourself, you can implement the TreeExpansionListener interface, which provides the following two methods:
17.6.7 Pending Expansion EventsJDK 1.2 introduced two classes that help you listen and react to expansion events before they occur. The TreeWillExpandListener interface allows you to register interest in pending expansion events. Implementations of this interface throw an ExpandVetoException if they decide that the expansion or collapse should not be allowed. 17.6.7.1 The TreeWillExpandListener interfaceThis interface gives you access to the expansion events (both expanding and collapsing) before the event takes place in the tree itself. The only reason you would want to hear about such an event rather than listening for the real expansion event is if you want to do something with the tree before it changes. The interface provides the following two methods:
17.6.7.2 The ExpandVetoException classThe most common reason for listening to pending expansion events is that you may want to stop them from occurring. If the user does not have permission to expand a folder in a filesystem, for example, you could have a listener check each expand event. If you find a case where an expansion or collapse should not occur, your listener can throw an ExpandVetoException. Each of the listener methods mentioned above can throw this exception. The JTree setExpandedState( ) method catches these exceptions, and, if one is thrown, the node is left alone, and the fireTreeExpanded( ) or fireTreeCollapsed( ) method is never called. ExpandVetoException's constructors are:
|
I l@ve RuBoard |
![]() ![]() |