001 package ui.model;
002
003 import javax.swing.tree.*;
004 import javax.swing.event.*;
005
006 /**
007 * @version 1.2 10/27/98
008 * An abstract implementation of the TreeTableModel interface, handling the list
009 * of listeners.
010 * @author Philip Milne
011 */
012 public abstract class AbstractTreeTableModel implements TreeTableModel {
013 protected Object root;
014 protected EventListenerList listenerList = new EventListenerList();
015
016 public AbstractTreeTableModel(Object root) {
017 this.root = root;
018 }
019
020 //
021 // Default implmentations for methods in the TreeModel interface.
022 //
023 public Object getRoot() {
024 return root;
025 }
026
027 public boolean isLeaf(Object node) {
028 return getChildCount(node) == 0;
029 }
030
031 public void valueForPathChanged(TreePath path, Object newValue) {}
032
033 // This is not called in the JTree's default mode: use a naive implementation.
034 public int getIndexOfChild(Object parent, Object child) {
035 for (int i = 0; i < getChildCount(parent); i++) {
036 if (getChild(parent, i).equals(child)) {
037 return i;
038 }
039 }
040 return -1;
041 }
042
043 public void addTreeModelListener(TreeModelListener l) {
044 listenerList.add(TreeModelListener.class, l);
045 }
046
047 public void removeTreeModelListener(TreeModelListener l) {
048 listenerList.remove(TreeModelListener.class, l);
049 }
050
051 /*
052 * Notify all listeners that have registered interest for
053 * notification on this event type. The event instance
054 * is lazily created using the parameters passed into
055 * the fire method.
056 * @see EventListenerList
057 */
058 protected void fireTreeNodesChanged(Object source, Object[] path, int[] childIndices, Object[] children) {
059 Object[] listeners = listenerList.getListenerList(); // Guaranteed to return a non-null array
060 TreeModelEvent e = null;
061 // Process the listeners last to first, notifying
062 // those that are interested in this event
063 for (int i = listeners.length-2; i>=0; i-=2) {
064 if (listeners[i]==TreeModelListener.class) {
065 // Lazily create the event:
066 if (e == null) e = new TreeModelEvent(source, path, childIndices, children);
067 ((TreeModelListener)listeners[i+1]).treeNodesChanged(e);
068 }
069 }
070 }
071
072 protected void fireTreeNodesInserted(Object source, Object[] path, int[] childIndices, Object[] children) {
073 Object[] listeners = listenerList.getListenerList();
074 TreeModelEvent e = null;
075 for (int i = listeners.length-2; i>=0; i-=2) {
076 if (listeners[i]==TreeModelListener.class) {
077 if (e == null) e = new TreeModelEvent(source, path, childIndices, children);
078 ((TreeModelListener)listeners[i+1]).treeNodesInserted(e);
079 }
080 }
081 }
082
083 protected void fireTreeNodesRemoved(Object source, Object[] path, int[] childIndices, Object[] children) {
084 Object[] listeners = listenerList.getListenerList();
085 TreeModelEvent e = null;
086 for (int i = listeners.length-2; i>=0; i-=2) {
087 if (listeners[i]==TreeModelListener.class) {
088 if (e == null) e = new TreeModelEvent(source, path, childIndices, children);
089 ((TreeModelListener)listeners[i+1]).treeNodesRemoved(e);
090 }
091 }
092 }
093
094 protected void fireTreeStructureChanged(Object source, Object[] path, int[] childIndices, Object[] children) {
095 Object[] listeners = listenerList.getListenerList();
096 TreeModelEvent e = null;
097 for (int i = listeners.length-2; i>=0; i-=2) {
098 if (listeners[i]==TreeModelListener.class) {
099 if (e == null) e = new TreeModelEvent(source, path, childIndices, children);
100 ((TreeModelListener)listeners[i+1]).treeStructureChanged(e);
101 }
102 }
103 }
104
105 //
106 // Default impelmentations for methods in the TreeTableModel interface.
107 //
108 public Class getColumnClass(int column) { return Object.class; }
109
110 /** By default, make the column with the Tree in it the only editable one.
111 * Making this column editable causes the JTable to forward mouse
112 * and keyboard events in the Tree column to the underlying JTree.
113 */
114 public boolean isCellEditable(Object node, int column) {
115 return getColumnClass(column) == TreeTableModel.class;
116 }
117
118 public void setValueAt(Object aValue, Object node, int column) {}
119
120
121 // Left to be implemented in the subclass:
122 /*
123 * public Object getChild(Object parent, int index)
124 * public int getChildCount(Object parent)
125 * public int getColumnCount()
126 * public String getColumnName(Object node, int column)
127 * public Object getValueAt(Object node, int column)
128 */
129 }