001 /*
002 * $Id: AbstractTreeTableModel.java 3100 2008-10-14 22:33:10Z rah003 $
003 *
004 * Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle,
005 * Santa Clara, California 95054, U.S.A. All rights reserved.
006 *
007 * This library is free software; you can redistribute it and/or
008 * modify it under the terms of the GNU Lesser General Public
009 * License as published by the Free Software Foundation; either
010 * version 2.1 of the License, or (at your option) any later version.
011 *
012 * This library is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015 * Lesser General Public License for more details.
016 *
017 * You should have received a copy of the GNU Lesser General Public
018 * License along with this library; if not, write to the Free Software
019 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
020 */
021
022 package org.jdesktop.swingx.treetable;
023
024 import javax.swing.event.TreeModelListener;
025 import javax.swing.tree.TreePath;
026
027 import org.jdesktop.swingx.tree.TreeModelSupport;
028
029 // There is no javax.swing.tree.AbstractTreeModel; There ought to be one.
030
031 /**
032 * AbstractTreeTableModel provides an implementation of
033 * {@link org.jdesktop.swingx.treetable.TreeTableModel} as a convenient starting
034 * point in defining custom data models for
035 * {@link org.jdesktop.swingx.JXTreeTable}. It takes care of listener
036 * management and contains convenience methods for creating and dispatching
037 * {@code TreeModelEvent}s. To create a concreate instance of
038 * {@code TreeTableModel} you need only to provide implementations for the
039 * following methods:
040 *
041 * <pre>
042 * public int getColumnCount();
043 * public Object getValueAt(Object node, int column);
044 * public Object getChild(Object parent, int index);
045 * public int getChildCount(Object parent);
046 * public int getIndexOfChild(Object parent, Object child);
047 * public boolean isLeaf(Object node);
048 * </pre>
049 *
050 * @author Ramesh Gupta
051 * @author Karl Schaefer
052 */
053 public abstract class AbstractTreeTableModel implements TreeTableModel {
054
055 /**
056 * Root node of the model
057 */
058 protected Object root;
059
060 /**
061 * Provides support for event dispatching.
062 */
063 protected TreeModelSupport modelSupport;
064
065 /**
066 * Constructs an {@code AbstractTreeTableModel} with a {@code null} root
067 * node.
068 */
069 public AbstractTreeTableModel() {
070 this(null);
071 }
072
073 /**
074 * Constructs an {@code AbstractTreeTableModel} with the specified root
075 * node.
076 *
077 * @param root
078 * root node
079 */
080 public AbstractTreeTableModel(Object root) {
081 this.root = root;
082 this.modelSupport = new TreeModelSupport(this);
083 }
084
085 /**
086 * {@inheritDoc}
087 */
088 public Class<?> getColumnClass(int column) {
089 return Object.class;
090 }
091
092 /**
093 * {@inheritDoc}
094 */
095 public String getColumnName(int column) {
096 //Copied from AbstractTableModel.
097 //Should use same defaults when possible.
098 String result = "";
099
100 for (; column >= 0; column = column / 26 - 1) {
101 result = (char) ((char) (column % 26) + 'A') + result;
102 }
103
104 return result;
105 }
106
107 /**
108 * {@inheritDoc}
109 */
110 public int getHierarchicalColumn() {
111 if (getColumnCount() == 0) {
112 return -1;
113 }
114
115 return 0;
116 }
117
118 /**
119 * {@inheritDoc}
120 */
121 public Object getRoot() {
122 return root;
123 }
124
125 /**
126 * {@inheritDoc}
127 */
128 public boolean isCellEditable(Object node, int column) {
129 // RG: Fix Issue 49 -- Cell not editable, by default.
130 // Subclasses might override this to return true.
131 return false;
132 }
133
134 /**
135 * Returns <code>true</code> if <code>node</code> is a leaf.
136 *
137 * @impl {@code true} if {@code getChildCount(node) == 0}
138 * @param node a node in the tree, obtained from this data source
139 * @return true if <code>node</code> is a leaf
140 */
141 public boolean isLeaf(Object node) {
142 return getChildCount(node) == 0;
143 }
144
145 /**
146 * Sets the value for the {@code node} at {@code columnIndex} to
147 * {@code value}.
148 *
149 * @impl is no-op; provided for convenience for uneditable models
150 * @param value
151 * the new value
152 * @param node
153 * the node whose value is to be changed
154 * @param column
155 * the column whose value is to be changed
156 * @see #getValueAt
157 * @see #isCellEditable
158 * @see javax.swing.table.TableModel#setValueAt(Object, int, int)
159 */
160 public void setValueAt(Object value, Object node, int column) {
161 //does nothing
162 }
163
164 /**
165 * Called when value for the item identified by path has been changed. If
166 * newValue signifies a truly new value the model should post a
167 * {@code treeNodesChanged} event.
168 * <p>
169 *
170 * @impl is no-op. A {@code JXTreeTable} does not usually edit the node directly.
171 * @param path
172 * path to the node that has changed
173 * @param newValue
174 * the new value from the <code>TreeCellEditor</code>
175 */
176 public void valueForPathChanged(TreePath path, Object newValue) {
177 //does nothing
178 }
179
180 /**
181 * {@inheritDoc}
182 */
183 public void addTreeModelListener(TreeModelListener l) {
184 modelSupport.addTreeModelListener(l);
185 }
186
187 /**
188 * {@inheritDoc}
189 */
190 public void removeTreeModelListener(TreeModelListener l) {
191 modelSupport.removeTreeModelListener(l);
192 }
193
194 /**
195 * Returns an array of all the <code>TreeModelListener</code>s added
196 * to this JXTreeTable with addTreeModelListener().
197 *
198 * @return all of the <code>TreeModelListener</code>s added or an empty
199 * array if no listeners have been added
200 */
201 public TreeModelListener[] getTreeModelListeners() {
202 return modelSupport.getTreeModelListeners();
203 }
204 }