AbstractTreeTableModel.java
001 /*
002  *  Copyright (c) 1995-2012, The University of Sheffield. See the file
003  *  COPYRIGHT.txt in the software or at http://gate.ac.uk/gate/COPYRIGHT.txt
004  *
005  *  This file is part of GATE (see http://gate.ac.uk/), and is free
006  *  software, licenced under the GNU Library General Public License,
007  *  Version 2, June 1991 (in the distribution as file licence.html,
008  *  and also available at http://gate.ac.uk/gate/licence.html).
009  *
010  *  Valentin Tablan 13/02/2001
011  *
012  *  $Id: AbstractTreeTableModel.java 17612 2014-03-10 08:51:17Z markagreenwood $
013  *
014  */
015 package gate.swing;
016 
017 import javax.swing.event.EventListenerList;
018 import javax.swing.event.TreeModelEvent;
019 import javax.swing.event.TreeModelListener;
020 import javax.swing.tree.TreePath;
021 
022 /**
023  * An abstract implementation of the TreeTableModel interface. Its main purpose
024  * is handling the list of listeners.
025  */
026 public abstract class AbstractTreeTableModel implements TreeTableModel {
027   /**
028    * The root of the tree.
029    */
030   protected Object root;
031 
032   /**
033    * The list of listeners.
034    */
035   protected EventListenerList listenerList = new EventListenerList();
036 
037   /**
038    * Constructor for a tree-table containing only one node: the root.
039    */
040   public AbstractTreeTableModel(Object root) {
041       this.root = root;
042   }
043 
044   //
045   // Default implmentations for methods in the TreeModel interface.
046   //
047 
048   /**
049    * Default implementation. Gets the root of the tree.
050    */
051   @Override
052   public Object getRoot() {
053       return root;
054   }
055 
056   /**
057    * Is this node a leaf?
058    */
059   @Override
060   public boolean isLeaf(Object node) {
061       return getChildCount(node== 0;
062   }
063 
064   @Override
065   public void valueForPathChanged(TreePath path, Object newValue) {}
066 
067   /**
068    * This method is not called by the current implementation of JTree.
069    * Implemented only for completion.
070    */
071   @Override
072   public int getIndexOfChild(Object parent, Object child) {
073     for (int i = 0; i < getChildCount(parent); i++){
074       if (getChild(parent, i).equals(child)){
075         return i;
076       }
077     }
078     return -1;
079   }
080 
081   /**
082    * Registers a new {@link javax.swing.event.TreeModelListener} with this
083    * model.
084    */
085   @Override
086   public void addTreeModelListener(TreeModelListener l) {
087     listenerList.add(TreeModelListener.class, l);
088   }
089 
090   /**
091    * Removes a {@link javax.swing.event.TreeModelListener} from the list of
092    * listeners registered with this model.
093    */
094   @Override
095   public void removeTreeModelListener(TreeModelListener l) {
096     listenerList.remove(TreeModelListener.class, l);
097   }
098 
099   /**
100    * Notify all listeners that have registered interest for
101    * notification on this event type.  The event instance
102    * is lazily created using the parameters passed into
103    * the fire method.
104    @see EventListenerList
105    */
106   protected void fireTreeNodesChanged(Object source, Object[] path,
107                                       int[] childIndices,
108                                       Object[] children) {
109     // Guaranteed to return a non-null array
110     Object[] listeners = listenerList.getListenerList();
111     TreeModelEvent e = null;
112     // Process the listeners last to first, notifying
113     // those that are interested in this event
114     for (int i = listeners.length-2; i>=0; i-=2) {
115       if (listeners[i]==TreeModelListener.class) {
116         // Lazily create the event:
117         if (e == nulle = new TreeModelEvent(source, path,
118                                               childIndices, children);
119         ((TreeModelListener)listeners[i+1]).treeNodesChanged(e);
120       }
121     }
122   }
123 
124   /**
125    * Notify all listeners that have registered interest for
126    * notification on this event type.  The event instance
127    * is lazily created using the parameters passed into
128    * the fire method.
129    @see EventListenerList
130    */
131   protected void fireTreeNodesInserted(Object source, Object[] path,
132                                       int[] childIndices,
133                                       Object[] children) {
134     // Guaranteed to return a non-null array
135     Object[] listeners = listenerList.getListenerList();
136     TreeModelEvent e = null;
137     // Process the listeners last to first, notifying
138     // those that are interested in this event
139     for (int i = listeners.length-2; i>=0; i-=2) {
140       if (listeners[i]==TreeModelListener.class) {
141         // Lazily create the event:
142         if (e == nulle = new TreeModelEvent(source, path,
143                                               childIndices, children);
144         ((TreeModelListener)listeners[i+1]).treeNodesInserted(e);
145       }
146     }
147   }
148 
149   /**
150    * Notify all listeners that have registered interest for
151    * notification on this event type.  The event instance
152    * is lazily created using the parameters passed into
153    * the fire method.
154    @see EventListenerList
155    */
156   protected void fireTreeNodesRemoved(Object source, Object[] path,
157                                       int[] childIndices,
158                                       Object[] children) {
159     // Guaranteed to return a non-null array
160     Object[] listeners = listenerList.getListenerList();
161     TreeModelEvent e = null;
162     // Process the listeners last to first, notifying
163     // those that are interested in this event
164     for (int i = listeners.length-2; i>=0; i-=2) {
165       if (listeners[i]==TreeModelListener.class) {
166         // Lazily create the event:
167         if (e == nulle = new TreeModelEvent(source, path,
168                                               childIndices, children);
169         ((TreeModelListener)listeners[i+1]).treeNodesRemoved(e);
170       }
171     }
172   }
173 
174   /**
175    * Notify all listeners that have registered interest for
176    * notification on this event type.  The event instance
177    * is lazily created using the parameters passed into
178    * the fire method.
179    @see EventListenerList
180    */
181   protected void fireTreeStructureChanged(Object source, Object[] path,
182                                       int[] childIndices,
183                                       Object[] children) {
184     // Guaranteed to return a non-null array
185     Object[] listeners = listenerList.getListenerList();
186     TreeModelEvent e = null;
187     // Process the listeners last to first, notifying
188     // those that are interested in this event
189     for (int i = listeners.length-2; i>=0; i-=2) {
190       if (listeners[i]==TreeModelListener.class) {
191         // Lazily create the event:
192         if (e == nulle = new TreeModelEvent(source, path,
193                                               childIndices, children);
194         ((TreeModelListener)listeners[i+1]).treeStructureChanged(e);
195       }
196     }
197   }
198 
199   /**
200    * Default implementation. Does nothing.
201    */
202   @Override
203   public void setValueAt(Object aValue, Object node, int column){}
204 
205   @Override
206   abstract public Class<?> getColumnClass(int column);
207   @Override
208   abstract public boolean isCellEditable(Object node, int column);
209   @Override
210   abstract public Object getChild(Object parent, int index);
211   @Override
212   abstract public int getChildCount(Object parent);
213   @Override
214   abstract public int getColumnCount();
215   @Override
216   abstract public String getColumnName(int column);
217   @Override
218   abstract public Object getValueAt(Object node, int column);
219 
220 }