AbstractTreeTableModel.java
上传用户:zhengdagz
上传日期:2014-03-06
资源大小:1956k
文件大小:13k
源码类别:

xml/soap/webservice

开发平台:

Java

  1. /*
  2.  * $Id: AbstractTreeTableModel.java,v 1.3 2005/10/10 18:01:37 rbair Exp $
  3.  *
  4.  * Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle,
  5.  * Santa Clara, California 95054, U.S.A. All rights reserved.
  6.  *
  7.  * This library is free software; you can redistribute it and/or
  8.  * modify it under the terms of the GNU Lesser General Public
  9.  * License as published by the Free Software Foundation; either
  10.  * version 2.1 of the License, or (at your option) any later version.
  11.  * 
  12.  * This library is distributed in the hope that it will be useful,
  13.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15.  * Lesser General Public License for more details.
  16.  * 
  17.  * You should have received a copy of the GNU Lesser General Public
  18.  * License along with this library; if not, write to the Free Software
  19.  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  20.  */
  21. package org.jdesktop.swingx.treetable;
  22. import java.util.EventListener;
  23. import javax.swing.event.EventListenerList;
  24. import javax.swing.event.TreeModelEvent;
  25. import javax.swing.event.TreeModelListener;
  26. import javax.swing.tree.TreeNode;
  27. import javax.swing.tree.TreePath;
  28. // There is no javax.swing.tree.AbstractTreeModel; There ought to be one.
  29. /**
  30.  * AbstractTreeTableModel provides an implementation of
  31.  * {@link org.jdesktop.swingx.treetable.TreeTableModel} as a convenient starting
  32.  * point in defining custom data models for {@link org.jdesktop.swingx.JXTreeTable}.
  33.  *
  34.  * @author Ramesh Gupta
  35.  */
  36. public abstract class AbstractTreeTableModel implements TreeTableModel {
  37.     /**
  38.      * Value returned by {@link org.jdesktop.swingx.treetable.TreeTableModel#getColumnClass(int) getColumnClass}
  39.      * for the {@link org.jdesktop.swingx.JXTreeTable#isHierarchical(int) hierarchical} column.
  40.      */
  41. public final static Class hierarchicalColumnClass = TreeTableModel.class;
  42.     /**
  43.      * Root node of the model
  44.      */
  45.     protected Object root;
  46.     /**
  47.      * Event listener list
  48.      */
  49.     protected EventListenerList listenerList = new EventListenerList();
  50.     /**
  51.      * Constructs an <code>AbstractTreeTableModel</code> with a null root node
  52.      */
  53.     public AbstractTreeTableModel() {
  54.         this(null);
  55.     }
  56.     /**
  57.      * Constructs an <code>AbstractTreeTableModel</code> with the specified node
  58.      * as the root node.
  59.      *
  60.      * @param root root node
  61.      */
  62.     public AbstractTreeTableModel(Object root) {
  63.         this.root = root;
  64.     }
  65.     /**
  66.      * {@inheritDoc}
  67.      */
  68.     public Class getColumnClass(int column) {
  69.         // Assume that the first column will contain hierarchical nodes.
  70.         return column == 0 ? hierarchicalColumnClass : Object.class;
  71.     }
  72.     /**
  73.      * {@inheritDoc}
  74.      */
  75.     public String getColumnName(int column) {
  76.         return "Column " + column; // Cheap implementation
  77.     }
  78.     /**
  79.      * {@inheritDoc}
  80.      */
  81.     public Object getRoot() { // From the TreeNode interface
  82.         return root;
  83.     }
  84.     /**
  85.      * Returns the child of <I>parent</I> at index <I>index</I> in the parent's
  86.      * child array.  <I>parent</I> must be a node previously obtained from
  87.      * this data source. This should not return null if <i>index</i>
  88.      * is a valid index for <i>parent</i> (that is <i>index</i> >= 0 &&
  89.      * <i>index</i> < getChildCount(<i>parent</i>)).
  90.      *
  91.      * @param   parent  a node in the tree, obtained from this data source
  92.      * @return  the child of <I>parent</I> at index <I>index</I>, or null if the
  93.      * specified parent node is not a <code>TreeNode</code>.
  94.      */
  95.     public Object getChild(Object parent, int index) {
  96.         // meant to be overridden
  97.         try {
  98.             return ((TreeNode) parent).getChildAt(index);
  99.         }
  100.         catch (ClassCastException ex) { // not a TreeNode?
  101.             return null;
  102.         }
  103.     }
  104.     /**
  105.      * Returns the number of children in the specified parent node.
  106.      *
  107.      * @param parent node whose child count is being requested
  108.      * @return the number of children in the specified parent node
  109.      */
  110.     public int getChildCount(Object parent) {
  111.         // meant to be overridden
  112.         try {
  113.             return ((TreeNode) parent).getChildCount();
  114.         }
  115.         catch (ClassCastException ex) { // not a TreeNode?
  116.             return 0;
  117.         }
  118.     }
  119.     /**
  120.      * {@inheritDoc}
  121.      */
  122.     public int getColumnCount() {
  123.         // meant to be overridden
  124.         return 1; // Cheap (and woefully inadequate) implementation
  125.     }
  126.     /**
  127.      * Returns the index of child in parent.
  128.      * If either the parent or child is <code>null</code>, returns -1.
  129.      * @param parent a note in the tree, obtained from this data source
  130.      * @param child the node we are interested in
  131.      * @return the index of the child in the parent, or -1
  132.      *    if either the parent or the child is <code>null</code>
  133.      */
  134.     public int getIndexOfChild(Object parent, Object child) {
  135.         if (parent == null || child == null)
  136.             return -1;
  137.         try {
  138.             return ((TreeNode) parent).getIndex((TreeNode) child);
  139.         }
  140.         catch (ClassCastException ex) { // not a TreeNode?
  141.             // This is not called in the JTree's default mode.
  142.             // Use a naive implementation.
  143.             for (int i = 0; i < getChildCount(parent); i++) {
  144.                 if (getChild(parent, i).equals(child)) {
  145.                     return i;
  146.                 }
  147.             }
  148.             return -1;
  149.         }
  150.     }
  151.     /**
  152.      * {@inheritDoc}
  153.      */
  154.     public boolean isCellEditable(Object node, int column) {
  155. // RG: Fix Issue 49 -- Cell not editable, by default.
  156. // Subclasses might override this to return true.
  157.         return false;
  158.     }
  159.     /**
  160.      * Returns true if the specified node is a leaf node; false otherwise.
  161.      *
  162.      * @param node node to test
  163.      * @return true if the specified node is a leaf node; false otherwise
  164.      */
  165.     public boolean isLeaf(Object node) {
  166.         try {
  167.             return ((TreeNode) node).isLeaf();
  168.         }
  169.         catch (ClassCastException ex) { // not a TreeNode?
  170.             return getChildCount(node) == 0;
  171.         }
  172.     }
  173.     /**
  174.      * Called when value for the item identified by path has been changed.
  175.      * If newValue signifies a truly new value the model should
  176.      * post a <code>treeNodesChanged</code> event.
  177.      *
  178.      * @param path path to the node that has changed
  179.      * @param newValue the new value from the <code>TreeCellEditor</code>
  180.      */
  181.     public void valueForPathChanged(TreePath path, Object newValue) {
  182.         /**@todo Implement this javax.swing.tree.TreeModel method*/
  183.     }
  184.     public void addTreeModelListener(TreeModelListener l) {
  185.         listenerList.add(TreeModelListener.class, l);
  186.     }
  187.     public void removeTreeModelListener(TreeModelListener l) {
  188.         listenerList.remove(TreeModelListener.class, l);
  189.     }
  190.     public TreeModelListener[] getTreeModelListeners() {
  191.         return (TreeModelListener[]) listenerList.getListeners(
  192.             TreeModelListener.class);
  193.     }
  194.     /*
  195.      * Notify all listeners that have registered interest for
  196.      * notification on this event type.  The event instance
  197.      * is lazily created using the parameters passed into
  198.      * the fire method.
  199.      * @see EventListenerList
  200.      */
  201.     protected void fireTreeNodesChanged(Object source, Object[] path,
  202.                                         int[] childIndices, Object[] children) {
  203.         // Guaranteed to return a non-null array
  204.         Object[] listeners = listenerList.getListenerList();
  205.         TreeModelEvent e = null;
  206.         // Process the listeners last to first, notifying
  207.         // those that are interested in this event
  208.         for (int i = listeners.length - 2; i >= 0; i -= 2) {
  209.             if (listeners[i] == TreeModelListener.class) {
  210.                 // Lazily create the event:
  211.                 if (e == null)
  212.                     e = new TreeModelEvent(source, path,
  213.                                            childIndices, children);
  214.                 ((TreeModelListener) listeners[i + 1]).treeNodesChanged(e);
  215.             }
  216.         }
  217.     }
  218.     /*
  219.      * Notify all listeners that have registered interest for
  220.      * notification on this event type.  The event instance
  221.      * is lazily created using the parameters passed into
  222.      * the fire method.
  223.      * @see EventListenerList
  224.      */
  225.     protected void fireTreeNodesInserted(Object source, Object[] path,
  226.                                          int[] childIndices, Object[] children) {
  227.         // Guaranteed to return a non-null array
  228.         Object[] listeners = listenerList.getListenerList();
  229.         TreeModelEvent e = null;
  230.         // Process the listeners last to first, notifying
  231.         // those that are interested in this event
  232.         for (int i = listeners.length - 2; i >= 0; i -= 2) {
  233.             if (listeners[i] == TreeModelListener.class) {
  234.                 // Lazily create the event:
  235.                 if (e == null)
  236.                     e = new TreeModelEvent(source, path,
  237.                                            childIndices, children);
  238.                 ((TreeModelListener) listeners[i + 1]).treeNodesInserted(e);
  239.             }
  240.         }
  241.     }
  242.     /*
  243.      * Notify all listeners that have registered interest for
  244.      * notification on this event type.  The event instance
  245.      * is lazily created using the parameters passed into
  246.      * the fire method.
  247.      * @see EventListenerList
  248.      */
  249.     protected void fireTreeNodesRemoved(Object source, Object[] path,
  250.                                         int[] childIndices, Object[] children) {
  251.         // Guaranteed to return a non-null array
  252.         Object[] listeners = listenerList.getListenerList();
  253.         TreeModelEvent e = null;
  254.         // Process the listeners last to first, notifying
  255.         // those that are interested in this event
  256.         for (int i = listeners.length - 2; i >= 0; i -= 2) {
  257.             if (listeners[i] == TreeModelListener.class) {
  258.                 // Lazily create the event:
  259.                 if (e == null)
  260.                     e = new TreeModelEvent(source, path,
  261.                                            childIndices, children);
  262.                 ((TreeModelListener) listeners[i + 1]).treeNodesRemoved(e);
  263.             }
  264.         }
  265.     }
  266.     /*
  267.      * Notify all listeners that have registered interest for
  268.      * notification on this event type.  The event instance
  269.      * is lazily created using the parameters passed into
  270.      * the fire method.
  271.      * @see EventListenerList
  272.      */
  273.     protected void fireTreeStructureChanged(Object source, Object[] path,
  274.                                             int[] childIndices,
  275.                                             Object[] children) {
  276.         // Guaranteed to return a non-null array
  277.         Object[] listeners = listenerList.getListenerList();
  278.         TreeModelEvent e = null;
  279.         // Process the listeners last to first, notifying
  280.         // those that are interested in this event
  281.         for (int i = listeners.length - 2; i >= 0; i -= 2) {
  282.             if (listeners[i] == TreeModelListener.class) {
  283.                 // Lazily create the event:
  284.                 if (e == null) {
  285.                     e = new TreeModelEvent(source, path,
  286.                                            childIndices, children);
  287.                 }
  288.                 ((TreeModelListener) listeners[i + 1]).treeStructureChanged(e);
  289.             }
  290.         }
  291.     }
  292.     /**
  293.      * Returns an array of all the objects currently registered
  294.      * as <code><em>Foo</em>Listener</code>s
  295.      * upon this model.
  296.      * <code><em>Foo</em>Listener</code>s are registered using the
  297.      * <code>add<em>Foo</em>Listener</code> method.
  298.      *
  299.      * <p>
  300.      *
  301.      * You can specify the <code>listenerType</code> argument
  302.      * with a class literal,
  303.      * such as
  304.      * <code><em>Foo</em>Listener.class</code>.
  305.      * For example, you can query a
  306.      * <code>DefaultTreeModel</code> <code>m</code>
  307.      * for its tree model listeners with the following code:
  308.      *
  309.      * <pre>TreeModelListener[] tmls = (TreeModelListener[])(m.getListeners(TreeModelListener.class));</pre>
  310.      *
  311.      * If no such listeners exist, this method returns an empty array.
  312.      *
  313.      * @param listenerType the type of listeners requested; this parameter
  314.      *          should specify an interface that descends from
  315.      *          <code>java.util.EventListener</code>
  316.      * @return an array of all objects registered as
  317.      *          <code><em>Foo</em>Listener</code>s on this component,
  318.      *          or an empty array if no such
  319.      *          listeners have been added
  320.      * @exception ClassCastException if <code>listenerType</code>
  321.      *          doesn't specify a class or interface that implements
  322.      *          <code>java.util.EventListener</code>
  323.      *
  324.      * @see #getTreeModelListeners
  325.      *
  326.      * @since 1.3
  327.      */
  328.     public EventListener[] getListeners(Class listenerType) {
  329.         return listenerList.getListeners(listenerType);
  330.     }
  331.     // Left to be implemented in the subclass:
  332.     /**
  333.      * public Object getChild(Object parent, int index)
  334.      * public int getChildCount(Object parent)
  335.      * public int getColumnCount()
  336.      * public String getColumnName(int column)
  337.      * public Object getValueAt(Object node, int column)
  338.      * public void setValueAt(Object value, Object node, int column)
  339.      */
  340. }