Java/Swing JFC/Tree Model

Материал из Java эксперт
Перейти к: навигация, поиск

A tree model using the SortTreeModel with a File hierarchy as input

   <source lang="java">

/* 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);
 }

}


 </source>
   
  
 
  



implements TreeModel to create tree model

   <source lang="java">

/*

* 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);
 }

}


 </source>
   
  
 
  



implements TreeModel to display File in a Tree

   <source lang="java">

/*

* 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) {}

}


 </source>
   
  
 
  



Insert tree node

   <source lang="java">

/*

* 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();
 }

}


 </source>
   
  
 
  



JTree application, showing default tree contents

   <source lang="java">

/*

* 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();
 }

}


 </source>
   
  
 
  



TreeModel Support

   <source lang="java">
 

/*

* 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 addTreeModelListener().
    *
    * @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);
           }
       }
   }

}


 </source>