001/* 002 * $Id: AbstractMutableTreeTableNode.java 3780 2010-09-09 16:17:41Z kschaefe $ 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 */ 021package org.jdesktop.swingx.treetable; 022 023import java.util.ArrayList; 024import java.util.Collections; 025import java.util.Enumeration; 026import java.util.List; 027 028import 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 */ 036public 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 @Override 086 public void insert(MutableTreeTableNode child, int index) { 087 if (!allowsChildren) { 088 throw new IllegalStateException("this node cannot accept children"); 089 } 090 091 if (children.contains(child)) { 092 children.remove(child); 093 index--; 094 } 095 096 children.add(index, child); 097 098 if (child.getParent() != this) { 099 child.setParent(this); 100 } 101 } 102 103 /** 104 * {@inheritDoc} 105 */ 106 @Override 107 public void remove(int index) { 108 children.remove(index).setParent(null); 109 } 110 111 /** 112 * {@inheritDoc} 113 */ 114 @Override 115 public void remove(MutableTreeTableNode node) { 116 children.remove(node); 117 node.setParent(null); 118 } 119 120 /** 121 * {@inheritDoc} 122 */ 123 @Override 124 public void removeFromParent() { 125 parent.remove(this); 126 } 127 128 /** 129 * {@inheritDoc} 130 */ 131 @Override 132 public void setParent(MutableTreeTableNode newParent) { 133 if (newParent == null || newParent.getAllowsChildren()) { 134 if (parent != null && parent.getIndex(this) != -1) { 135 parent.remove(this); 136 } 137 } else { 138 throw new IllegalArgumentException( 139 "newParent does not allow children"); 140 } 141 142 parent = newParent; 143 144 if (parent != null && parent.getIndex(this) == -1) { 145 parent.insert(this, parent.getChildCount()); 146 } 147 } 148 149 /** 150 * Returns this node's user object. 151 * 152 * @return the Object stored at this node by the user 153 * @see #setUserObject 154 * @see #toString 155 */ 156 @Override 157 public Object getUserObject() { 158 return userObject; 159 } 160 161 /** 162 * {@inheritDoc} 163 */ 164 @Override 165 public void setUserObject(Object object) { 166 userObject = object; 167 } 168 169 /** 170 * {@inheritDoc} 171 */ 172 @Override 173 public TreeTableNode getChildAt(int childIndex) { 174 return children.get(childIndex); 175 } 176 177 /** 178 * {@inheritDoc} 179 */ 180 @Override 181 public int getIndex(TreeNode node) { 182 return children.indexOf(node); 183 } 184 185 /** 186 * {@inheritDoc} 187 */ 188 @Override 189 public TreeTableNode getParent() { 190 return parent; 191 } 192 193 /** 194 * {@inheritDoc} 195 */ 196 @Override 197 public Enumeration<? extends MutableTreeTableNode> children() { 198 return Collections.enumeration(children); 199 } 200 201 /** 202 * {@inheritDoc} 203 */ 204 @Override 205 public boolean getAllowsChildren() { 206 return allowsChildren; 207 } 208 209 /** 210 * Determines whether or not this node is allowed to have children. If 211 * {@code allowsChildren} is {@code false}, all of this node's children are 212 * removed. 213 * <p> 214 * Note: By default, a node allows children. 215 * 216 * @param allowsChildren 217 * {@code true} if this node is allowed to have children 218 */ 219 public void setAllowsChildren(boolean allowsChildren) { 220 this.allowsChildren = allowsChildren; 221 222 if (!this.allowsChildren) { 223 children.clear(); 224 } 225 } 226 227 /** 228 * {@inheritDoc} 229 */ 230 @Override 231 public int getChildCount() { 232 return children.size(); 233 } 234 235 /** 236 * {@inheritDoc} 237 */ 238 @Override 239 public boolean isLeaf() { 240 return getChildCount() == 0; 241 } 242 243 /** 244 * Determines whether the specified column is editable. 245 * 246 * @param column 247 * the column to query 248 * @return always returns {@code false} 249 */ 250 @Override 251 public boolean isEditable(int column) { 252 return false; 253 } 254 255 /** 256 * Sets the value for the given {@code column}. 257 * 258 * @impl does nothing. It is provided for convenience. 259 * @param aValue 260 * the value to set 261 * @param column 262 * the column to set the value on 263 */ 264 @Override 265 public void setValueAt(Object aValue, int column) { 266 // does nothing 267 } 268 269 /** 270 * Returns the result of sending <code>toString()</code> to this node's 271 * user object, or null if this node has no user object. 272 * 273 * @see #getUserObject 274 */ 275 @Override 276 public String toString() { 277 if (userObject == null) { 278 return ""; 279 } else { 280 return userObject.toString(); 281 } 282 } 283}