001 /* JAPI - (Yet another (hopefully) useful) Java API
002 *
003 * Copyright (C) 2004-2006 Christian Hujer
004 *
005 * This program is free software; you can redistribute it and/or
006 * modify it under the terms of the GNU General Public License as
007 * published by the Free Software Foundation; either version 2 of the
008 * License, or (at your option) any later version.
009 *
010 * This program is distributed in the hope that it will be useful, but
011 * WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013 * General Public License for more details.
014 *
015 * You should have received a copy of the GNU General Public License
016 * along with this program; if not, write to the Free Software
017 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
018 * 02111-1307, USA.
019 */
020
021 package net.sf.japi.swing.treetable;
022
023 import javax.swing.event.EventListenerList;
024 import javax.swing.event.TreeModelEvent;
025 import javax.swing.event.TreeModelListener;
026
027 /** Abstract base implementation of TreeTableModel.
028 * @author <a href="mailto:chris@riedquat.de">Christian Hujer</a>
029 */
030 public abstract class AbstractTreeTableModel<R, T> implements TreeTableModel<R, T> {
031
032 /** The tree root node content object. */
033 private final R root;
034
035 /** The Event listener list for registering TreeModelListeners. */
036 private final EventListenerList listenerList = new EventListenerList();
037
038 /** Create an AbstractTreeTableModel.
039 * @param root tree root node content object
040 */
041 protected AbstractTreeTableModel(final R root) {
042 this.root = root;
043 }
044
045 /** {@inheritDoc} */
046 public R getRoot() {
047 return root;
048 }
049
050 /** {@inheritDoc} */
051 public boolean isLeaf(final T node) {
052 return getChildCount(node) == 0;
053 }
054
055 /** {@inheritDoc} */
056 public int getIndexOfChild(final T parent, final T child) {
057 for (int i = 0; i < getChildCount(parent); i++) {
058 if (getChild(parent, i).equals(child)) {
059 return i;
060 }
061 }
062 return -1;
063 }
064
065 /** {@inheritDoc} */
066 public void addTreeModelListener(final TreeModelListener l) {
067 listenerList.add(TreeModelListener.class, l);
068 }
069
070 /** {@inheritDoc} */
071 public void removeTreeModelListener(final TreeModelListener l) {
072 listenerList.remove(TreeModelListener.class, l);
073 }
074
075 /** {@inheritDoc} */
076 public Class<?> getColumnClass(final int column) {
077 return Object.class;
078 }
079
080 /** {@inheritDoc} */
081 public boolean isCellEditable(final T node, final int column) {
082 //noinspection ObjectEquality
083 return getColumnClass(column) == TreeTableModel.class;
084 }
085
086 /** {@inheritDoc} */
087 public void setValueAt(final Object value, final T node, final int column) {
088 // The basic implementation does nothing
089 }
090
091 /** Informs all registered listeners of a change.
092 * @param source
093 * @param path
094 * @param childIndices
095 * @param children
096 */
097 protected void fireTreeNodesChanged(final Object source, final T[] path, final int[] childIndices, final T[] children) {
098 final Object[] listeners = listenerList.getListenerList();
099 final TreeModelEvent e = new TreeModelEvent(source, path, childIndices, children);
100 for (int i = listeners.length - 2; i >= 0; i -= 2) {
101 //noinspection ObjectEquality
102 if (listeners[i] == TreeModelListener.class) {
103 ((TreeModelListener)listeners[i+1]).treeNodesChanged(e);
104 }
105 }
106 }
107
108 /** Informs all registered listeners of an insertion.
109 * @param source
110 * @param path
111 * @param childIndices
112 * @param children
113 */
114 protected void fireTreeNodesInserted(final Object source, final Object[] path, final int[] childIndices, final Object[] children) {
115 final Object[] listeners = listenerList.getListenerList();
116 final TreeModelEvent e = new TreeModelEvent(source, path, childIndices, children);
117 for (int i = listeners.length - 2; i >= 0; i -= 2) {
118 //noinspection ObjectEquality
119 if (listeners[i] == TreeModelListener.class) {
120 ((TreeModelListener)listeners[i + 1]).treeNodesInserted(e);
121 }
122 }
123 }
124
125 /** Informs all registered listeners of a removal.
126 * @param source
127 * @param path
128 * @param childIndices
129 * @param children
130 */
131 protected void fireTreeNodesRemoved(final Object source, final Object[] path, final int[] childIndices, final Object[] children) {
132 final Object[] listeners = listenerList.getListenerList();
133 final TreeModelEvent e = new TreeModelEvent(source, path, childIndices, children);
134 for (int i = listeners.length - 2; i >= 0; i -= 2) {
135 //noinspection ObjectEquality
136 if (listeners[i] == TreeModelListener.class) {
137 ((TreeModelListener)listeners[i + 1]).treeNodesRemoved(e);
138 }
139 }
140 }
141
142 /** Informs all registered listeners of a structural change.
143 * @param source
144 * @param path
145 * @param childIndices
146 * @param children
147 */
148 protected void fireTreeStructureChanged(final Object source, final Object[] path, final int[] childIndices, final Object[] children) {
149 final Object[] listeners = listenerList.getListenerList();
150 final TreeModelEvent e = new TreeModelEvent(source, path, childIndices, children);
151 for (int i = listeners.length - 2; i >= 0; i -= 2) {
152 //noinspection ObjectEquality
153 if (listeners[i] == TreeModelListener.class) {
154 ((TreeModelListener)listeners[i + 1]).treeStructureChanged(e);
155 }
156 }
157 }
158
159 } // class AbstractTreeTableModel