View Javadoc

1   /*
2    * %W% %E%
3    *
4    * Copyright 1997, 1998 Sun Microsystems, Inc. All Rights Reserved.
5    *
6    * Redistribution and use in source and binary forms, with or
7    * without modification, are permitted provided that the following
8    * conditions are met:
9    *
10   * - Redistributions of source code must retain the above copyright
11   *   notice, this list of conditions and the following disclaimer.
12   *
13   * - Redistribution in binary form must reproduce the above
14   *   copyright notice, this list of conditions and the following
15   *   disclaimer in the documentation and/or other materials
16   *   provided with the distribution.
17   *
18   * Neither the name of Sun Microsystems, Inc. or the names of
19   * contributors may be used to endorse or promote products derived
20   * from this software without specific prior written permission.
21   *
22   * This software is provided "AS IS," without a warranty of any
23   * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
24   * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
25   * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
26   * EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY
27   * DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT OF OR
28   * RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE OR
29   * ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE
30   * FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT,
31   * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
32   * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF
33   * THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS
34   * BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
35   *
36   * You acknowledge that this software is not designed, licensed or
37   * intended for use in the design, construction, operation or
38   * maintenance of any nuclear facility.
39   */
40  
41  package uk.ac.rdg.resc.jstyx.client.browser;
42  
43  import javax.swing.tree.*;
44  import javax.swing.event.*;
45  
46  /***
47   * An abstract implementation of the TreeTableModel interface, handling
48   * the list of listeners.
49   *
50   * @version %I% %G%
51   *
52   * @author Philip Milne
53   */
54  
55  public abstract class AbstractTreeTableModel implements TreeTableModel
56  {
57      protected Object root;
58      protected EventListenerList listenerList = new EventListenerList();
59      
60      /***
61       * Constructs the AbstractTreeTableModel. Must call setRoot() after this
62       * to set the root of the tree.
63       */
64      public AbstractTreeTableModel()
65      {
66      }
67      
68      //
69      // Default implmentations for methods in the TreeModel interface.
70      //
71      
72      public Object getRoot()
73      {
74          return root;
75      }
76      
77      public void setRoot(Object root)
78      {
79          this.root = root;
80      }
81      
82      public boolean isLeaf(Object node)
83      {
84          return getChildCount(node) == 0;
85      }
86      
87      public void valueForPathChanged(TreePath path, Object newValue)
88      {}
89      
90      // This is not called in the JTree's default mode: use a naive implementation.
91      public int getIndexOfChild(Object parent, Object child)
92      {
93          for (int i = 0; i < getChildCount(parent); i++)
94          {
95              if (getChild(parent, i).equals(child))
96              {
97                  return i;
98              }
99          }
100         return -1;
101     }
102     
103     public void addTreeModelListener(TreeModelListener l)
104     {
105         listenerList.add(TreeModelListener.class, l);
106     }
107     
108     public void removeTreeModelListener(TreeModelListener l)
109     {
110         listenerList.remove(TreeModelListener.class, l);
111     }
112     
113     /*
114      * Notify all listeners that have registered interest for
115      * notification on this event type.  The event instance
116      * is lazily created using the parameters passed into
117      * the fire method.
118      * @see EventListenerList
119      */
120     protected void fireTreeNodesChanged(Object source, Object[] path,
121     int[] childIndices,
122     Object[] children)
123     {
124         // Guaranteed to return a non-null array
125         Object[] listeners = listenerList.getListenerList();
126         TreeModelEvent e = null;
127         // Process the listeners last to first, notifying
128         // those that are interested in this event
129         for (int i = listeners.length-2; i>=0; i-=2)
130         {
131             if (listeners[i]==TreeModelListener.class)
132             {
133                 // Lazily create the event:
134                 if (e == null)
135                     e = new TreeModelEvent(source, path,
136                     childIndices, children);
137                 ((TreeModelListener)listeners[i+1]).treeNodesChanged(e);
138             }
139         }
140     }
141     
142     /*
143      * Notify all listeners that have registered interest for
144      * notification on this event type.  The event instance
145      * is lazily created using the parameters passed into
146      * the fire method.
147      * @see EventListenerList
148      */
149     protected void fireTreeNodesInserted(Object source, Object[] path,
150     int[] childIndices,
151     Object[] children)
152     {
153         // Guaranteed to return a non-null array
154         Object[] listeners = listenerList.getListenerList();
155         TreeModelEvent e = null;
156         // Process the listeners last to first, notifying
157         // those that are interested in this event
158         for (int i = listeners.length-2; i>=0; i-=2)
159         {
160             if (listeners[i]==TreeModelListener.class)
161             {
162                 // Lazily create the event:
163                 if (e == null)
164                     e = new TreeModelEvent(source, path,
165                     childIndices, children);
166                 ((TreeModelListener)listeners[i+1]).treeNodesInserted(e);
167             }
168         }
169     }
170     
171     /*
172      * Notify all listeners that have registered interest for
173      * notification on this event type.  The event instance
174      * is lazily created using the parameters passed into
175      * the fire method.
176      * @see EventListenerList
177      */
178     protected void fireTreeNodesRemoved(Object source, Object[] path,
179     int[] childIndices,
180     Object[] children)
181     {
182         // Guaranteed to return a non-null array
183         Object[] listeners = listenerList.getListenerList();
184         TreeModelEvent e = null;
185         // Process the listeners last to first, notifying
186         // those that are interested in this event
187         for (int i = listeners.length-2; i>=0; i-=2)
188         {
189             if (listeners[i]==TreeModelListener.class)
190             {
191                 // Lazily create the event:
192                 if (e == null)
193                     e = new TreeModelEvent(source, path,
194                     childIndices, children);
195                 ((TreeModelListener)listeners[i+1]).treeNodesRemoved(e);
196             }
197         }
198     }
199     
200     /*
201      * Notify all listeners that have registered interest for
202      * notification on this event type.  The event instance
203      * is lazily created using the parameters passed into
204      * the fire method.
205      * @see EventListenerList
206      */
207     protected void fireTreeStructureChanged(Object source, Object[] path,
208     int[] childIndices,
209     Object[] children)
210     {
211         // Guaranteed to return a non-null array
212         Object[] listeners = listenerList.getListenerList();
213         TreeModelEvent e = null;
214         // Process the listeners last to first, notifying
215         // those that are interested in this event
216         for (int i = listeners.length-2; i>=0; i-=2)
217         {
218             if (listeners[i]==TreeModelListener.class)
219             {
220                 // Lazily create the event:
221                 if (e == null)
222                     e = new TreeModelEvent(source, path,
223                     childIndices, children);
224                 ((TreeModelListener)listeners[i+1]).treeStructureChanged(e);
225             }
226         }
227     }
228     
229     //
230     // Default impelmentations for methods in the TreeTableModel interface.
231     //
232     
233     public Class getColumnClass(int column)
234     { return Object.class; }
235     
236     /*** By default, make the column with the Tree in it the only editable one.
237      *  Making this column editable causes the JTable to forward mouse
238      *  and keyboard events in the Tree column to the underlying JTree.
239      */
240     public boolean isCellEditable(Object node, int column)
241     {
242         return getColumnClass(column) == TreeTableModel.class;
243     }
244     
245     public void setValueAt(Object aValue, Object node, int column)
246     {}
247     
248     
249     // Left to be implemented in the subclass:
250     
251     /*
252      *   public Object getChild(Object parent, int index)
253      *   public int getChildCount(Object parent)
254      *   public int getColumnCount()
255      *   public String getColumnName(Object node, int column)
256      *   public Object getValueAt(Object node, int column)
257      */
258     
259 }
260