1 /*
2  * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  *
23  */
24 
25 package sun.jvm.hotspot.ui.treetable;
26 
27 import javax.swing.tree.*;
28 import javax.swing.event.*;
29 
30 /**
31  * An abstract implementation of the TreeTableModel interface, handling the list
32  * of listeners.
33  * @author Philip Milne
34  */
35 
36 public abstract class AbstractTreeTableModel implements TreeTableModel {
37     protected Object root;
38     protected EventListenerList listenerList = new EventListenerList();
39 
AbstractTreeTableModel(Object root)40     public AbstractTreeTableModel(Object root) {
41         this.root = root;
42     }
43 
44     //
45     // Default implmentations for methods in the TreeModel interface.
46     //
47 
getRoot()48     public Object getRoot() {
49         return root;
50     }
51 
isLeaf(Object node)52     public boolean isLeaf(Object node) {
53         return getChildCount(node) == 0;
54     }
55 
valueForPathChanged(TreePath path, Object newValue)56     public void valueForPathChanged(TreePath path, Object newValue) {}
57 
58     // This is not called in the JTree's default mode: use a naive implementation.
getIndexOfChild(Object parent, Object child)59     public int getIndexOfChild(Object parent, Object child) {
60         for (int i = 0; i < getChildCount(parent); i++) {
61             if (getChild(parent, i).equals(child)) {
62                 return i;
63             }
64         }
65         return -1;
66     }
67 
addTreeModelListener(TreeModelListener l)68     public void addTreeModelListener(TreeModelListener l) {
69         listenerList.add(TreeModelListener.class, l);
70     }
71 
removeTreeModelListener(TreeModelListener l)72     public void removeTreeModelListener(TreeModelListener l) {
73         listenerList.remove(TreeModelListener.class, l);
74     }
75 
76     /*
77      * Notify all listeners that have registered interest for
78      * notification on this event type.  The event instance
79      * is lazily created using the parameters passed into
80      * the fire method.
81      * @see EventListenerList
82      */
fireTreeNodesChanged(Object source, Object[] path, int[] childIndices, Object[] children)83     protected void fireTreeNodesChanged(Object source, Object[] path,
84                                         int[] childIndices,
85                                         Object[] children) {
86         // Guaranteed to return a non-null array
87         Object[] listeners = listenerList.getListenerList();
88         TreeModelEvent e = null;
89         // Process the listeners last to first, notifying
90         // those that are interested in this event
91         for (int i = listeners.length-2; i>=0; i-=2) {
92             if (listeners[i]==TreeModelListener.class) {
93                 // Lazily create the event:
94                 if (e == null)
95                     e = new TreeModelEvent(source, path,
96                                            childIndices, children);
97                 ((TreeModelListener)listeners[i+1]).treeNodesChanged(e);
98             }
99         }
100     }
101 
102     /*
103      * Notify all listeners that have registered interest for
104      * notification on this event type.  The event instance
105      * is lazily created using the parameters passed into
106      * the fire method.
107      * @see EventListenerList
108      */
fireTreeNodesInserted(Object source, Object[] path, int[] childIndices, Object[] children)109     protected void fireTreeNodesInserted(Object source, Object[] path,
110                                         int[] childIndices,
111                                         Object[] children) {
112         // Guaranteed to return a non-null array
113         Object[] listeners = listenerList.getListenerList();
114         TreeModelEvent e = null;
115         // Process the listeners last to first, notifying
116         // those that are interested in this event
117         for (int i = listeners.length-2; i>=0; i-=2) {
118             if (listeners[i]==TreeModelListener.class) {
119                 // Lazily create the event:
120                 if (e == null)
121                     e = new TreeModelEvent(source, path,
122                                            childIndices, children);
123                 ((TreeModelListener)listeners[i+1]).treeNodesInserted(e);
124             }
125         }
126     }
127 
128     /*
129      * Notify all listeners that have registered interest for
130      * notification on this event type.  The event instance
131      * is lazily created using the parameters passed into
132      * the fire method.
133      * @see EventListenerList
134      */
fireTreeNodesRemoved(Object source, Object[] path, int[] childIndices, Object[] children)135     protected void fireTreeNodesRemoved(Object source, Object[] path,
136                                         int[] childIndices,
137                                         Object[] children) {
138         // Guaranteed to return a non-null array
139         Object[] listeners = listenerList.getListenerList();
140         TreeModelEvent e = null;
141         // Process the listeners last to first, notifying
142         // those that are interested in this event
143         for (int i = listeners.length-2; i>=0; i-=2) {
144             if (listeners[i]==TreeModelListener.class) {
145                 // Lazily create the event:
146                 if (e == null)
147                     e = new TreeModelEvent(source, path,
148                                            childIndices, children);
149                 ((TreeModelListener)listeners[i+1]).treeNodesRemoved(e);
150             }
151         }
152     }
153 
154     /*
155      * Notify all listeners that have registered interest for
156      * notification on this event type.  The event instance
157      * is lazily created using the parameters passed into
158      * the fire method.
159      * @see EventListenerList
160      */
fireTreeStructureChanged(Object source, Object[] path, int[] childIndices, Object[] children)161     protected void fireTreeStructureChanged(Object source, Object[] path,
162                                         int[] childIndices,
163                                         Object[] children) {
164         // Guaranteed to return a non-null array
165         Object[] listeners = listenerList.getListenerList();
166         TreeModelEvent e = null;
167         // Process the listeners last to first, notifying
168         // those that are interested in this event
169         for (int i = listeners.length-2; i>=0; i-=2) {
170             if (listeners[i]==TreeModelListener.class) {
171                 // Lazily create the event:
172                 if (e == null)
173                     e = new TreeModelEvent(source, path,
174                                            childIndices, children);
175                 ((TreeModelListener)listeners[i+1]).treeStructureChanged(e);
176             }
177         }
178     }
179 
180     //
181     // Default impelmentations for methods in the TreeTableModel interface.
182     //
183 
getColumnClass(int column)184     public Class getColumnClass(int column) { return Object.class; }
185 
186    /** By default, make the column with the Tree in it the only editable one.
187     *  Making this column editable causes the JTable to forward mouse
188     *  and keyboard events in the Tree column to the underlying JTree.
189     */
isCellEditable(Object node, int column)190     public boolean isCellEditable(Object node, int column) {
191          return getColumnClass(column) == TreeTableModel.class;
192     }
193 
setValueAt(Object aValue, Object node, int column)194     public void setValueAt(Object aValue, Object node, int column) {}
195 
196 
197     // Left to be implemented in the subclass:
198 
199     /*
200      *   public Object getChild(Object parent, int index)
201      *   public int getChildCount(Object parent)
202      *   public int getColumnCount()
203      *   public String getColumnName(Object node, int column)
204      *   public Object getValueAt(Object node, int column)
205      */
206 }
207