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 }