Java/Swing JFC/Tree Model
Содержание
A tree model using the SortTreeModel with a File hierarchy as input
/*
Java Swing, 2nd Edition
By Marc Loy, Robert Eckstein, Dave Wood, James Elliott, Brian Cole
ISBN: 0-596-00408-7
Publisher: O"Reilly
*/
// SortTreeDemo.java
//This class creates a tree model using the SortTreeModel with
//a File hierarchy as input.
//
import java.io.File;
import java.util.ruparator;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.MutableTreeNode;
import javax.swing.tree.TreeNode;
public class SortTreeDemo extends JFrame {
public SortTreeDemo(String startDir) {
super("SortTreeModel Demonstration");
setSize(300, 400);
setDefaultCloseOperation(EXIT_ON_CLOSE);
PrettyFile f = new PrettyFile(startDir);
DefaultMutableTreeNode root = new DefaultMutableTreeNode(f);
SortTreeModel model = new SortTreeModel(root,
new TreeStringComparator());
fillModel(model, root);
JTree tree = new JTree(model);
getContentPane().add(new JScrollPane(tree));
}
protected void fillModel(SortTreeModel model, DefaultMutableTreeNode current) {
PrettyFile pf = (PrettyFile) current.getUserObject();
File f = pf.getFile();
if (f.isDirectory()) {
String files[] = f.list();
// ignore "." files
for (int i = 0; i < files.length; i++) {
if (files[i].startsWith("."))
continue;
PrettyFile tmp = new PrettyFile(pf, files[i]);
DefaultMutableTreeNode node = new DefaultMutableTreeNode(tmp);
model.insertNodeInto(node, current);
if (tmp.getFile().isDirectory()) {
fillModel(model, node);
}
}
}
}
public class PrettyFile {
File f;
public PrettyFile(String s) {
f = new File(s);
}
public PrettyFile(PrettyFile pf, String s) {
f = new File(pf.f, s);
}
public File getFile() {
return f;
}
public String toString() {
return f.getName();
}
}
public static void main(String args[]) {
SortTreeDemo demo = new SortTreeDemo(args.length == 1 ? args[0] : ".");
demo.setVisible(true);
}
}
//SortTreeModel.java
//This class is similar to the DefaultTreeModel, but it keeps
//a node"s children in alphabetical order.
//
class SortTreeModel extends DefaultTreeModel {
private Comparator comparator;
public SortTreeModel(TreeNode node, Comparator c) {
super(node);
comparator = c;
}
public SortTreeModel(TreeNode node, boolean asksAllowsChildren, Comparator c) {
super(node, asksAllowsChildren);
comparator = c;
}
public void insertNodeInto(MutableTreeNode child, MutableTreeNode parent) {
int index = findIndexFor(child, parent);
super.insertNodeInto(child, parent, index);
}
public void insertNodeInto(MutableTreeNode child, MutableTreeNode par, int i) {
// The index is useless in this model, so just ignore it.
insertNodeInto(child, par);
}
// Perform a recursive binary search on the children to find the right
// insertion point for the next node.
private int findIndexFor(MutableTreeNode child, MutableTreeNode parent) {
int cc = parent.getChildCount();
if (cc == 0) {
return 0;
}
if (cc == 1) {
return comparator.rupare(child, parent.getChildAt(0)) <= 0 ? 0 : 1;
}
return findIndexFor(child, parent, 0, cc - 1); // First & last index
}
private int findIndexFor(MutableTreeNode child, MutableTreeNode parent,
int i1, int i2) {
if (i1 == i2) {
return comparator.rupare(child, parent.getChildAt(i1)) <= 0 ? i1
: i1 + 1;
}
int half = (i1 + i2) / 2;
if (comparator.rupare(child, parent.getChildAt(half)) <= 0) {
return findIndexFor(child, parent, i1, half);
}
return findIndexFor(child, parent, half + 1, i2);
}
}
//TreeStringComparator.java
//This class compares the contents of the userObject as strings.
//It"s case-insensitive.
//
class TreeStringComparator implements Comparator {
public int compare(Object o1, Object o2) {
if (!(o1 instanceof DefaultMutableTreeNode && o2 instanceof DefaultMutableTreeNode)) {
throw new IllegalArgumentException(
"Can only compare DefaultMutableTreeNode objects");
}
String s1 = ((DefaultMutableTreeNode) o1).getUserObject().toString();
String s2 = ((DefaultMutableTreeNode) o2).getUserObject().toString();
return s1.rupareToIgnoreCase(s2);
}
}
implements TreeModel to create tree model
/*
* Copyright (c) 2000 David Flanagan. All rights reserved.
* This code is from the book Java Examples in a Nutshell, 2nd Edition.
* It is provided AS-IS, WITHOUT ANY WARRANTY either expressed or implied.
* You may study, use, and modify it for any non-commercial purpose.
* You may distribute it non-commercially as long as you retain this notice.
* For a commercial use license, or to purchase the book (recommended),
* visit http://www.davidflanagan.ru/javaexamples2.
*/
import java.awt.BorderLayout;
import java.awt.ruponent;
import java.awt.Container;
import java.awt.Font;
import java.awt.Point;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.event.TreeModelListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.TreeCellRenderer;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
/**
* This class is a JTree subclass that displays the tree of AWT or Swing
* component that make up a GUI.
*/
public class ComponentTree extends JTree {
/**
* All this constructor method has to do is set the TreeModel and
* TreeCellRenderer objects for the tree. It is these classes (defined
* below) that do all the real work.
*/
public ComponentTree(Component c) {
super(new ComponentTreeModel(c));
setCellRenderer(new ComponentCellRenderer(getCellRenderer()));
}
/**
* The TreeModel class puts hierarchical data in a form that the JTree can
* display. This implementation interprets the containment hierarchy of a
* Component for display by the ComponentTree class. Note that any kind of
* Object can be a node in the tree, as long as the TreeModel knows how to
* handle it.
*/
static class ComponentTreeModel implements TreeModel {
Component root; // The root object of the tree
// Constructor: just remember the root object
public ComponentTreeModel(Component root) {
this.root = root;
}
// Return the root of the tree
public Object getRoot() {
return root;
}
// Is this node a leaf? (Leaf nodes are displayed differently by JTree)
// Any node that isn"t a container is a leaf, since they cannot have
// children. We also define containers with no children as leaves.
public boolean isLeaf(Object node) {
if (!(node instanceof Container))
return true;
Container c = (Container) node;
return c.getComponentCount() == 0;
}
// How many children does this node have?
public int getChildCount(Object node) {
if (node instanceof Container) {
Container c = (Container) node;
return c.getComponentCount();
}
return 0;
}
// Return the specified child of a parent node.
public Object getChild(Object parent, int index) {
if (parent instanceof Container) {
Container c = (Container) parent;
return c.getComponent(index);
}
return null;
}
// Return the index of the child node in the parent node
public int getIndexOfChild(Object parent, Object child) {
if (!(parent instanceof Container))
return -1;
Container c = (Container) parent;
Component[] children = c.getComponents();
if (children == null)
return -1;
for (int i = 0; i < children.length; i++) {
if (children[i] == child)
return i;
}
return -1;
}
// This method is only required for editable trees, so it is not
// implemented here.
public void valueForPathChanged(TreePath path, Object newvalue) {
}
// This TreeModel never fires any events (since it is not editable)
// so event listener registration methods are left unimplemented
public void addTreeModelListener(TreeModelListener l) {
}
public void removeTreeModelListener(TreeModelListener l) {
}
}
/**
* A TreeCellRenderer displays each node of a tree. The default renderer
* displays arbitrary Object nodes by calling their toString() method. The
* Component.toString() method returns long strings with extraneous
* information. Therefore, we use this "wrapper" implementation of
* TreeCellRenderer to convert nodes from Component objects to useful String
* values before passing those String values on to the default renderer.
*/
static class ComponentCellRenderer implements TreeCellRenderer {
TreeCellRenderer renderer; // The renderer we are a wrapper for
// Constructor: just remember the renderer
public ComponentCellRenderer(TreeCellRenderer renderer) {
this.renderer = renderer;
}
// This is the only TreeCellRenderer method.
// Compute the string to display, and pass it to the wrapped renderer
public Component getTreeCellRendererComponent(JTree tree, Object value,
boolean selected, boolean expanded, boolean leaf, int row,
boolean hasFocus) {
String newvalue = value.getClass().getName(); // Component type
String name = ((Component) value).getName(); // Component name
if (name != null)
newvalue += " (" + name + ")"; // unless null
// Use the wrapped renderer object to do the real work
return renderer.getTreeCellRendererComponent(tree, newvalue,
selected, expanded, leaf, row, hasFocus);
}
}
/**
* This main() method demonstrates the use of the ComponentTree class: it
* puts a ComponentTree component in a Frame, and uses the ComponentTree to
* display its own GUI hierarchy. It also adds a TreeSelectionListener to
* display additional information about each component as it is selected
*/
public static void main(String[] args) {
// Create a frame for the demo, and handle window close requests
JFrame frame = new JFrame("ComponentTree Demo");
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
// Create a scroll pane and a "message line" and add them to the
// center and bottom of the frame.
JScrollPane scrollpane = new JScrollPane();
final JLabel msgline = new JLabel(" ");
frame.getContentPane().add(scrollpane, BorderLayout.CENTER);
frame.getContentPane().add(msgline, BorderLayout.SOUTH);
// Now create the ComponentTree object, specifying the frame as the
// component whose tree is to be displayed. Also set the tree"s font.
JTree tree = new ComponentTree(frame);
tree.setFont(new Font("SansSerif", Font.BOLD, 12));
// Only allow a single item in the tree to be selected at once
tree.getSelectionModel().setSelectionMode(
TreeSelectionModel.SINGLE_TREE_SELECTION);
// Add an event listener for notifications when
// the tree selection state changes.
tree.addTreeSelectionListener(new TreeSelectionListener() {
public void valueChanged(TreeSelectionEvent e) {
// Tree selections are referred to by "path"
// We only care about the last node in the path
TreePath path = e.getPath();
Component c = (Component) path.getLastPathComponent();
// Now we know what component was selected, so
// display some information about it in the message line
if (c.isShowing()) {
Point p = c.getLocationOnScreen();
msgline.setText("x: " + p.x + " y: " + p.y + " width: "
+ c.getWidth() + " height: " + c.getHeight());
} else {
msgline.setText("component is not showing");
}
}
});
// Now that we"ve set up the tree, add it to the scrollpane
scrollpane.setViewportView(tree);
// Finally, set the size of the main window, and pop it up.
frame.setSize(600, 400);
frame.setVisible(true);
}
}
implements TreeModel to display File in a Tree
/*
* This example is from the book "Java Foundation Classes in a Nutshell".
* Written by David Flanagan. Copyright (c) 1999 by O"Reilly & Associates.
* You may distribute this source code for non-commercial purposes only.
* You may study, modify, and use this example for any purpose, as long as
* this notice is retained. Note that this example is provided "as is",
* WITHOUT WARRANTY of any kind either expressed or implied.
*/
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.tree.*;
import java.io.File;
public class FileTreeDemo {
public static void main(String[] args) {
// Figure out where in the filesystem to start displaying
File root;
if (args.length > 0) root = new File(args[0]);
else root = new File(System.getProperty("user.home"));
// Create a TreeModel object to represent our tree of files
FileTreeModel model = new FileTreeModel(root);
// Create a JTree and tell it to display our model
JTree tree = new JTree();
tree.setModel(model);
// The JTree can get big, so allow it to scroll.
JScrollPane scrollpane = new JScrollPane(tree);
// Display it all in a window and make the window appear
JFrame frame = new JFrame("FileTreeDemo");
frame.getContentPane().add(scrollpane, "Center");
frame.setSize(400,600);
frame.setVisible(true);
}
}
/**
* The methods in this class allow the JTree component to traverse
* the file system tree, and display the files and directories.
**/
class FileTreeModel implements TreeModel {
// We specify the root directory when we create the model.
protected File root;
public FileTreeModel(File root) { this.root = root; }
// The model knows how to return the root object of the tree
public Object getRoot() { return root; }
// Tell JTree whether an object in the tree is a leaf or not
public boolean isLeaf(Object node) { return ((File)node).isFile(); }
// Tell JTree how many children a node has
public int getChildCount(Object parent) {
String[] children = ((File)parent).list();
if (children == null) return 0;
return children.length;
}
// Fetch any numbered child of a node for the JTree.
// Our model returns File objects for all nodes in the tree. The
// JTree displays these by calling the File.toString() method.
public Object getChild(Object parent, int index) {
String[] children = ((File)parent).list();
if ((children == null) || (index >= children.length)) return null;
return new File((File) parent, children[index]);
}
// Figure out a child"s position in its parent node.
public int getIndexOfChild(Object parent, Object child) {
String[] children = ((File)parent).list();
if (children == null) return -1;
String childname = ((File)child).getName();
for(int i = 0; i < children.length; i++) {
if (childname.equals(children[i])) return i;
}
return -1;
}
// This method is only invoked by the JTree for editable trees.
// This TreeModel does not allow editing, so we do not implement
// this method. The JTree editable property is false by default.
public void valueForPathChanged(TreePath path, Object newvalue) {}
// Since this is not an editable tree model, we never fire any events,
// so we don"t actually have to keep track of interested listeners.
public void addTreeModelListener(TreeModelListener l) {}
public void removeTreeModelListener(TreeModelListener l) {}
}
Insert tree node
/*
* Copyright (c) Ian F. Darwin, http://www.darwinsys.ru/, 1996-2002.
* All rights reserved. Software written by Ian F. Darwin and others.
* $Id: LICENSE,v 1.8 2004/02/09 03:33:38 ian Exp $
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS""
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Java, the Duke mascot, and all variants of Sun"s Java "steaming coffee
* cup" logo are trademarks of Sun Microsystems. Sun"s, and James Gosling"s,
* pioneering role in inventing and promulgating (and standardizing) the Java
* language and environment is gratefully acknowledged.
*
* The pioneering role of Dennis Ritchie and Bjarne Stroustrup, of AT&T, for
* inventing predecessor languages C and C++ is also gratefully acknowledged.
*/
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
/**
* Simple JFC JTree demo
*
* @version $Id: JTreeDemo.java,v 1.4 2002/08/25 01:31:29 ian Exp $
*/
public class JTreeDemo extends JFrame {
JButton addButton, quitButton;
JTree myTree;
DefaultMutableTreeNode root, child;
/** "main program" method - construct and show */
public static void main(String[] av) {
// create a JTreeDemo object, tell it to show up
new JTreeDemo().setVisible(true);
}
/** Construct the object including its GUI */
public JTreeDemo() {
super("JTreeDemo");
Container cp = getContentPane();
cp.setLayout(new BorderLayout());
root = new DefaultMutableTreeNode("root");
child = new DefaultMutableTreeNode("Colors");
root.add(child);
child.add(new DefaultMutableTreeNode("Cyan"));
child.add(new DefaultMutableTreeNode("Magenta"));
child.add(new DefaultMutableTreeNode("Yellow"));
child.add(new DefaultMutableTreeNode("Black"));
myTree = new JTree(root);
// cp.add(BorderLayout.CENTER, myTree);
//JScrollPane scroller = new JScrollPane();
//scroller.getViewport().add(myTree);
JScrollPane scroller = new JScrollPane(myTree);
cp.add(BorderLayout.CENTER, scroller);
cp.add(BorderLayout.NORTH, addButton = new JButton("Add"));
addButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// Insert more nodes into the tree
child = new DefaultMutableTreeNode("Flavors");
child.add(new DefaultMutableTreeNode("Java"));
child.add(new DefaultMutableTreeNode("Espresso"));
child.add(new DefaultMutableTreeNode("Hey Joe!"));
child.add(new DefaultMutableTreeNode("Charcoal"));
child.add(new DefaultMutableTreeNode("Paint Remover"));
// Notify the model, which will add it and create an event, and
// send it up the tree...
((DefaultTreeModel) myTree.getModel()).insertNodeInto(child,
root, 0);
}
});
cp.add(BorderLayout.SOUTH, quitButton = new JButton("Exit"));
quitButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
setVisible(false);
dispose();
System.exit(0);
}
});
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
setVisible(false);
dispose();
System.exit(0);
}
});
pack();
}
}
JTree application, showing default tree contents
/*
* Copyright (c) Ian F. Darwin, http://www.darwinsys.ru/, 1996-2002.
* All rights reserved. Software written by Ian F. Darwin and others.
* $Id: LICENSE,v 1.8 2004/02/09 03:33:38 ian Exp $
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS""
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Java, the Duke mascot, and all variants of Sun"s Java "steaming coffee
* cup" logo are trademarks of Sun Microsystems. Sun"s, and James Gosling"s,
* pioneering role in inventing and promulgating (and standardizing) the Java
* language and environment is gratefully acknowledged.
*
* The pioneering role of Dennis Ritchie and Bjarne Stroustrup, of AT&T, for
* inventing predecessor languages C and C++ is also gratefully acknowledged.
*/
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTree;
/**
* Simple JFC JTree Simple application, showing default tree contents. Note that
* the JTree will display a silly demo with not Model provided.
*
* @version $Id: JTreeSimple.java,v 1.2 2004/02/23 03:39:22 ian Exp $
*/
public class JTreeSimple extends JFrame {
JButton addButton, quitButton;
JTree myTree;
/** "main program" method - construct and show */
public static void main(String[] av) {
// create a JTreeSimple object, tell it to show up
new JTreeSimple().setVisible(true);
}
/** Construct the object including its GUI */
public JTreeSimple() {
super("JTreeSimple");
Container cp = getContentPane();
cp.setLayout(new BorderLayout());
myTree = new JTree();
JScrollPane scroller = new JScrollPane(myTree);
cp.add(BorderLayout.CENTER, scroller);
cp.add(BorderLayout.SOUTH, quitButton = new JButton("Exit"));
quitButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
setVisible(false);
dispose();
System.exit(0);
}
});
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
}
}
TreeModel Support
/*
* Copyright 2002 Sun Microsystems, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistribution in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* Neither the name of Sun Microsystems, Inc. or the names of
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any
* kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
* WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
* EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY
* DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT OF OR
* RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE OR
* ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE
* FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT,
* SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF
* THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS
* BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that this software is not designed, licensed or
* intended for use in the design, construction, operation or
* maintenance of any nuclear facility.
*/
import javax.swing.event.EventListenerList;
import javax.swing.event.TreeModelListener;
import javax.swing.event.TreeModelEvent;
import javax.swing.tree.TreeModel;
/**
* A Class that implements the listener registration and event fire methods for
* a TreeModel. This class gets the implementation from DefaultTreeModel
*
* @version %I% %G%
* @author Mark Davidson
*/
public abstract class TreeModelSupport implements TreeModel {
protected EventListenerList listenerList = new EventListenerList();
/**
* Adds a listener for the TreeModelEvent posted after the tree changes.
*
* @see #removeTreeModelListener
* @param l the listener to add
*/
public void addTreeModelListener(TreeModelListener l) {
listenerList.add(TreeModelListener.class, l);
}
/**
* Removes a listener previously added with <B>addTreeModelListener()</B>.
*
* @see #addTreeModelListener
* @param l the listener to remove
*/
public void removeTreeModelListener(TreeModelListener l) {
listenerList.remove(TreeModelListener.class, l);
}
/*
* Notify all listeners that have registered interest for
* notification on this event type. The event instance
* is lazily created using the parameters passed into
* the fire method.
* @see EventListenerList
*/
protected void fireTreeNodesChanged(Object source, Object[] path,
int[] childIndices,
Object[] children) {
// Guaranteed to return a non-null array
Object[] listeners = listenerList.getListenerList();
TreeModelEvent e = null;
// Process the listeners last to first, notifying
// those that are interested in this event
for (int i = listeners.length-2; i>=0; i-=2) {
if (listeners[i]==TreeModelListener.class) {
// Lazily create the event:
if (e == null)
e = new TreeModelEvent(source, path,
childIndices, children);
((TreeModelListener)listeners[i+1]).treeNodesChanged(e);
}
}
}
/*
* Notify all listeners that have registered interest for
* notification on this event type. The event instance
* is lazily created using the parameters passed into
* the fire method.
* @see EventListenerList
*/
protected void fireTreeNodesInserted(Object source, Object[] path,
int[] childIndices,
Object[] children) {
// Guaranteed to return a non-null array
Object[] listeners = listenerList.getListenerList();
TreeModelEvent e = null;
// Process the listeners last to first, notifying
// those that are interested in this event
for (int i = listeners.length-2; i>=0; i-=2) {
if (listeners[i]==TreeModelListener.class) {
// Lazily create the event:
if (e == null)
e = new TreeModelEvent(source, path,
childIndices, children);
((TreeModelListener)listeners[i+1]).treeNodesInserted(e);
}
}
}
/*
* Notify all listeners that have registered interest for
* notification on this event type. The event instance
* is lazily created using the parameters passed into
* the fire method.
* @see EventListenerList
*/
protected void fireTreeNodesRemoved(Object source, Object[] path,
int[] childIndices,
Object[] children) {
// Guaranteed to return a non-null array
Object[] listeners = listenerList.getListenerList();
TreeModelEvent e = null;
// Process the listeners last to first, notifying
// those that are interested in this event
for (int i = listeners.length-2; i>=0; i-=2) {
if (listeners[i]==TreeModelListener.class) {
// Lazily create the event:
if (e == null)
e = new TreeModelEvent(source, path,
childIndices, children);
((TreeModelListener)listeners[i+1]).treeNodesRemoved(e);
}
}
}
protected void fireTreeNodesRemoved(TreeModelEvent evt) {
// Guaranteed to return a non-null array
Object[] listeners = listenerList.getListenerList();
// Process the listeners last to first, notifying
// those that are interested in this event
for (int i = listeners.length-2; i>=0; i-=2) {
if (listeners[i]==TreeModelListener.class) {
((TreeModelListener)listeners[i+1]).treeStructureChanged(evt);
}
}
}
/*
* Notify all listeners that have registered interest for
* notification on this event type. The event instance
* is lazily created using the parameters passed into
* the fire method.
* @see EventListenerList
*/
protected void fireTreeStructureChanged(Object source, Object[] path,
int[] childIndices,
Object[] children) {
// Guaranteed to return a non-null array
Object[] listeners = listenerList.getListenerList();
TreeModelEvent e = null;
// Process the listeners last to first, notifying
// those that are interested in this event
for (int i = listeners.length-2; i>=0; i-=2) {
if (listeners[i]==TreeModelListener.class) {
// Lazily create the event:
if (e == null)
e = new TreeModelEvent(source, path,
childIndices, children);
((TreeModelListener)listeners[i+1]).treeStructureChanged(e);
}
}
}
}