001 /*
002 * $Id: AbstractMutableTreeTableNode.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 package org.jdesktop.swingx.treetable;
022
023 import java.util.ArrayList;
024 import java.util.Collections;
025 import java.util.Enumeration;
026 import java.util.List;
027
028 import javax.swing.tree.TreeNode;
029
030 /**
031 * {@code AbstractMutableTreeTableNode} provides an implementation of most of
032 * the {@code MutableTreeTableNode} features.
033 *
034 * @author Karl Schaefer
035 */
036 public abstract class AbstractMutableTreeTableNode implements
037 MutableTreeTableNode {
038 /** this node's parent, or null if this node has no parent */
039 protected MutableTreeTableNode parent;
040
041 /**
042 * List of children, if this node has no children the list will be empty.
043 * This list will never be null.
044 */
045 protected final List<MutableTreeTableNode> children;
046
047 /** optional user object */
048 protected transient Object userObject;
049
050 protected boolean allowsChildren;
051
052 public AbstractMutableTreeTableNode() {
053 this(null);
054 }
055
056 public AbstractMutableTreeTableNode(Object userObject) {
057 this(userObject, true);
058 }
059
060 public AbstractMutableTreeTableNode(Object userObject,
061 boolean allowsChildren) {
062 this.userObject = userObject;
063 this.allowsChildren = allowsChildren;
064 children = createChildrenList();
065 }
066
067 /**
068 * Creates the list used to manage the children of this node.
069 * <p>
070 * This method is called by the constructor.
071 *
072 * @return a list; this list is guaranteed to be non-{@code null}
073 */
074 protected List<MutableTreeTableNode> createChildrenList() {
075 return new ArrayList<MutableTreeTableNode>();
076 }
077
078 public void add(MutableTreeTableNode child) {
079 insert(child, getChildCount());
080 }
081
082 /**
083 * {@inheritDoc}
084 */
085 public void insert(MutableTreeTableNode child, int index) {
086 if (!allowsChildren) {
087 throw new IllegalStateException("this node cannot accept children");
088 }
089
090 if (children.contains(child)) {
091 children.remove(child);
092 index--;
093 }
094
095 children.add(index, child);
096
097 if (child.getParent() != this) {
098 child.setParent(this);
099 }
100 }
101
102 /**
103 * {@inheritDoc}
104 */
105 public void remove(int index) {
106 children.remove(index).setParent(null);
107 }
108
109 /**
110 * {@inheritDoc}
111 */
112 public void remove(MutableTreeTableNode node) {
113 children.remove(node);
114 node.setParent(null);
115 }
116
117 /**
118 * {@inheritDoc}
119 */
120 public void removeFromParent() {
121 parent.remove(this);
122 }
123
124 /**
125 * {@inheritDoc}
126 */
127 public void setParent(MutableTreeTableNode newParent) {
128 if (newParent == null || newParent.getAllowsChildren()) {
129 if (parent != null && parent.getIndex(this) != -1) {
130 parent.remove(this);
131 }
132 } else {
133 throw new IllegalArgumentException(
134 "newParent does not allow children");
135 }
136
137 parent = newParent;
138
139 if (parent != null && parent.getIndex(this) == -1) {
140 parent.insert(this, parent.getChildCount());
141 }
142 }
143
144 /**
145 * Returns this node's user object.
146 *
147 * @return the Object stored at this node by the user
148 * @see #setUserObject
149 * @see #toString
150 */
151 public Object getUserObject() {
152 return userObject;
153 }
154
155 /**
156 * {@inheritDoc}
157 */
158 public void setUserObject(Object object) {
159 userObject = object;
160 }
161
162 /**
163 * {@inheritDoc}
164 */
165 public TreeTableNode getChildAt(int childIndex) {
166 return children.get(childIndex);
167 }
168
169 /**
170 * {@inheritDoc}
171 */
172 public int getIndex(TreeNode node) {
173 return children.indexOf(node);
174 }
175
176 /**
177 * {@inheritDoc}
178 */
179 public TreeTableNode getParent() {
180 return parent;
181 }
182
183 /**
184 * {@inheritDoc}
185 */
186 public Enumeration<? extends MutableTreeTableNode> children() {
187 return Collections.enumeration(children);
188 }
189
190 /**
191 * {@inheritDoc}
192 */
193 public boolean getAllowsChildren() {
194 return allowsChildren;
195 }
196
197 /**
198 * Determines whether or not this node is allowed to have children. If
199 * {@code allowsChildren} is {@code false}, all of this node's children are
200 * removed.
201 * <p>
202 * Note: By default, a node allows children.
203 *
204 * @param allowsChildren
205 * {@code true} if this node is allowed to have children
206 */
207 public void setAllowsChildren(boolean allowsChildren) {
208 this.allowsChildren = allowsChildren;
209
210 if (!this.allowsChildren) {
211 children.clear();
212 }
213 }
214
215 /**
216 * {@inheritDoc}
217 */
218 public int getChildCount() {
219 return children.size();
220 }
221
222 /**
223 * {@inheritDoc}
224 */
225 public boolean isLeaf() {
226 return getChildCount() == 0;
227 }
228
229 /**
230 * Determines whether the specified column is editable.
231 *
232 * @param column
233 * the column to query
234 * @return always returns {@code false}
235 */
236 public boolean isEditable(int column) {
237 return false;
238 }
239
240 /**
241 * Sets the value for the given {@code column}.
242 *
243 * @impl does nothing. It is provided for convenience.
244 * @param aValue
245 * the value to set
246 * @param column
247 * the column to set the value on
248 */
249 public void setValueAt(Object aValue, int column) {
250 // does nothing
251 }
252
253 /**
254 * Returns the result of sending <code>toString()</code> to this node's
255 * user object, or null if this node has no user object.
256 *
257 * @see #getUserObject
258 */
259 @Override
260 public String toString() {
261 if (userObject == null) {
262 return "";
263 } else {
264 return userObject.toString();
265 }
266 }
267 }