whitespace fixups
[jSite2.git] / src / net / pterodactylus / util / swing / SortableTreeNode.java
1 /*
2  * jSite2 - SortableMutableTreeNode.java -
3  * Copyright © 2008 David Roden
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18  */
19
20 package net.pterodactylus.util.swing;
21
22 import java.util.ArrayList;
23 import java.util.Collections;
24 import java.util.Comparator;
25 import java.util.Enumeration;
26 import java.util.List;
27
28 import javax.swing.tree.MutableTreeNode;
29 import javax.swing.tree.TreeNode;
30
31 /**
32  * {@link MutableTreeNode} subclass that allows to sort its children.
33  *
34  * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
35  */
36 public class SortableTreeNode implements MutableTreeNode {
37
38         /** The parent node. */
39         private MutableTreeNode parentNode;
40
41         /** The user-defined object. */
42         private Object userObject;
43
44         /** Whether this node allows children. */
45         private boolean allowsChildren;
46
47         /** The children of this node. */
48         private List<MutableTreeNode> children = new ArrayList<MutableTreeNode>();
49
50         /**
51          * Creates a new sortable tree node.
52          *
53          * @param allowsChildren
54          *            <code>true</code> if this node allows children,
55          *            <code>false</code> otherwise
56          */
57         public SortableTreeNode(boolean allowsChildren) {
58                 this(null, allowsChildren);
59         }
60
61         /**
62          * Creates a new sortable tree node that contains the given user-defined
63          * object.
64          *
65          * @param userObject
66          *            The user-defined object
67          */
68         public SortableTreeNode(Object userObject) {
69                 this(userObject, true);
70         }
71
72         /**
73          * Creates a new sortable tree node that contains the given user-defined
74          * object.
75          *
76          * @param userObject
77          *            The user-defined object
78          * @param allowsChildren
79          *            <code>true</code> if this node allows children,
80          *            <code>false</code> otherwise
81          */
82         public SortableTreeNode(Object userObject, boolean allowsChildren) {
83                 this.allowsChildren = allowsChildren;
84                 this.userObject = userObject;
85         }
86
87         //
88         // ACCESSORS
89         //
90
91         /**
92          * {@inheritDoc}
93          */
94         public boolean getAllowsChildren() {
95                 return allowsChildren;
96         }
97
98         /**
99          * {@inheritDoc}
100          */
101         public TreeNode getChildAt(int childIndex) {
102                 return children.get(childIndex);
103         }
104
105         /**
106          * {@inheritDoc}
107          */
108         public int getChildCount() {
109                 return children.size();
110         }
111
112         /**
113          * {@inheritDoc}
114          */
115         public int getIndex(TreeNode node) {
116                 return children.indexOf(node);
117         }
118
119         /**
120          * {@inheritDoc}
121          */
122         public TreeNode getParent() {
123                 return parentNode;
124         }
125
126         /**
127          * Returns the user-defined object.
128          *
129          * @return The user-defined object
130          */
131         public Object getUserObject() {
132                 return userObject;
133         }
134
135         /**
136          * {@inheritDoc}
137          */
138         public boolean isLeaf() {
139                 return children.isEmpty();
140         }
141
142         /**
143          * {@inheritDoc}
144          */
145         public Enumeration<?> children() {
146                 return Collections.enumeration(children);
147         }
148
149         //
150         // ACTIONS
151         //
152
153         /**
154          * Adds the given node to this node as a child.
155          *
156          * @param child
157          *            The child node to add
158          */
159         public void add(MutableTreeNode child) {
160                 children.add(child);
161                 child.setParent(this);
162         }
163
164         /**
165          * {@inheritDoc}
166          */
167         public void insert(MutableTreeNode child, int index) {
168                 children.add(index, child);
169                 child.setParent(this);
170         }
171
172         /**
173          * {@inheritDoc}
174          */
175         public void remove(int index) {
176                 children.remove(index).setParent(null);
177         }
178
179         /**
180          * {@inheritDoc}
181          */
182         public void remove(MutableTreeNode node) {
183                 children.remove(node);
184                 node.setParent(null);
185         }
186
187         /**
188          * {@inheritDoc}
189          */
190         public void removeFromParent() {
191                 if (parentNode != null) {
192                         parentNode.remove(this);
193                         parentNode = null;
194                 }
195         }
196
197         /**
198          * Removes all children of this node.
199          */
200         public void removeAll() {
201                 for (MutableTreeNode childNode : children) {
202                         childNode.setParent(null);
203                 }
204                 children.clear();
205         }
206
207         /**
208          * {@inheritDoc}
209          */
210         public void setParent(MutableTreeNode newParent) {
211                 parentNode = newParent;
212         }
213
214         /**
215          * {@inheritDoc}
216          */
217         public void setUserObject(Object userObject) {
218                 this.userObject = userObject;
219         }
220
221         /**
222          * Sorts the children of this node.
223          */
224         public void sort() {
225                 Collections.sort(children, new Comparator<MutableTreeNode>() {
226
227                         /**
228                          * {@inheritDoc}
229                          */
230                         @SuppressWarnings( { "synthetic-access", "unchecked" })
231                         public int compare(MutableTreeNode firstNode, MutableTreeNode secondNode) {
232                                 if (!(firstNode instanceof SortableTreeNode) || !(secondNode instanceof SortableTreeNode)) {
233                                         return 0;
234                                 }
235                                 SortableTreeNode firstSortableNode = (SortableTreeNode) firstNode;
236                                 SortableTreeNode secondSortableNode = (SortableTreeNode) secondNode;
237                                 if ((firstSortableNode.userObject == null) && (secondSortableNode.userObject == null)) {
238                                         return 0;
239                                 }
240                                 if ((firstSortableNode.userObject == null) && (secondSortableNode.userObject != null)) {
241                                         return -1;
242                                 }
243                                 if ((firstSortableNode.userObject != null) && (secondSortableNode.userObject == null)) {
244                                         return 1;
245                                 }
246                                 if (!(firstSortableNode.userObject instanceof Comparable) || !(secondSortableNode.userObject instanceof Comparable)) {
247                                         return 0;
248                                 }
249                                 return ((Comparable<Object>) firstSortableNode.userObject).compareTo(secondSortableNode.userObject);
250                         }
251                 });
252         }
253
254         /**
255          * {@inheritDoc}
256          */
257         @Override
258         public String toString() {
259                 return (userObject != null) ? userObject.toString() : null;
260         }
261
262 }