add sortable tree node
authorDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Wed, 28 May 2008 21:04:25 +0000 (23:04 +0200)
committerDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Wed, 28 May 2008 21:04:25 +0000 (23:04 +0200)
src/net/pterodactylus/util/swing/SortableTreeNode.java [new file with mode: 0644]

diff --git a/src/net/pterodactylus/util/swing/SortableTreeNode.java b/src/net/pterodactylus/util/swing/SortableTreeNode.java
new file mode 100644 (file)
index 0000000..dbdeb68
--- /dev/null
@@ -0,0 +1,250 @@
+/*
+ * jSite2 - SortableMutableTreeNode.java -
+ * Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.util.swing;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Enumeration;
+import java.util.List;
+
+import javax.swing.tree.MutableTreeNode;
+import javax.swing.tree.TreeNode;
+
+/**
+ * {@link MutableTreeNode} subclass that allows to sort its children.
+ * 
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ */
+public class SortableTreeNode implements MutableTreeNode {
+
+       /** The parent node. */
+       private MutableTreeNode parentNode;
+
+       /** The user-defined object. */
+       private Object userObject;
+
+       /** Whether this node allows children. */
+       private boolean allowsChildren;
+
+       /** The children of this node. */
+       private List<MutableTreeNode> children = new ArrayList<MutableTreeNode>();
+
+       /**
+        * Creates a new sortable tree node.
+        * 
+        * @param allowsChildren
+        *            <code>true</code> if this node allows children,
+        *            <code>false</code> otherwise
+        */
+       public SortableTreeNode(boolean allowsChildren) {
+               this(null, allowsChildren);
+       }
+
+       /**
+        * Creates a new sortable tree node that contains the given user-defined
+        * object.
+        * 
+        * @param userObject
+        *            The user-defined object
+        */
+       public SortableTreeNode(Object userObject) {
+               this(userObject, true);
+       }
+
+       /**
+        * Creates a new sortable tree node that contains the given user-defined
+        * object.
+        * 
+        * @param userObject
+        *            The user-defined object
+        * @param allowsChildren
+        *            <code>true</code> if this node allows children,
+        *            <code>false</code> otherwise
+        */
+       public SortableTreeNode(Object userObject, boolean allowsChildren) {
+               this.allowsChildren = allowsChildren;
+               this.userObject = userObject;
+       }
+
+       //
+       // ACCESSORS
+       //
+
+       /**
+        * {@inheritDoc}
+        */
+       public boolean getAllowsChildren() {
+               return allowsChildren;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public TreeNode getChildAt(int childIndex) {
+               return children.get(childIndex);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public int getChildCount() {
+               return children.size();
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public int getIndex(TreeNode node) {
+               return children.indexOf(node);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public TreeNode getParent() {
+               return parentNode;
+       }
+
+       /**
+        * Returns the user-defined object.
+        * 
+        * @return The user-defined object
+        */
+       public Object getUserObject() {
+               return userObject;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public boolean isLeaf() {
+               return children.isEmpty();
+       }
+
+       //
+       // ACTIONS
+       //
+
+       /**
+        * Adds the given node to this node as a child.
+        * 
+        * @param child
+        *            The child node to add
+        */
+       public void add(MutableTreeNode child) {
+               children.add(child);
+               child.setParent(this);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void insert(MutableTreeNode child, int index) {
+               children.add(index, child);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void remove(int index) {
+               children.remove(index);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void remove(MutableTreeNode node) {
+               children.remove(node);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void removeFromParent() {
+               if (parentNode != null) {
+                       parentNode.remove(this);
+                       parentNode = null;
+               }
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void setParent(MutableTreeNode newParent) {
+               parentNode = newParent;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public void setUserObject(Object userObject) {
+               this.userObject = userObject;
+       }
+
+       /**
+        * Sorts the children of this node.
+        */
+       public void sort() {
+               Collections.sort(children, new Comparator<MutableTreeNode>() {
+
+                       /**
+                        * {@inheritDoc}
+                        */
+                       @SuppressWarnings( { "synthetic-access", "unchecked" })
+                       public int compare(MutableTreeNode firstNode, MutableTreeNode secondNode) {
+                               if (!(firstNode instanceof SortableTreeNode) || !(secondNode instanceof SortableTreeNode)) {
+                                       return 0;
+                               }
+                               SortableTreeNode firstSortableNode = (SortableTreeNode) firstNode;
+                               SortableTreeNode secondSortableNode = (SortableTreeNode) secondNode;
+                               if ((firstSortableNode.userObject == null) && (secondSortableNode.userObject == null)) {
+                                       return 0;
+                               }
+                               if ((firstSortableNode.userObject == null) && (secondSortableNode.userObject != null)) {
+                                       return -1;
+                               }
+                               if ((firstSortableNode.userObject != null) && (secondSortableNode.userObject == null)) {
+                                       return 1;
+                               }
+                               if (!(firstSortableNode.userObject instanceof Comparable) || !(secondSortableNode.userObject instanceof Comparable)) {
+                                       return 0;
+                               }
+                               return ((Comparable<Object>) firstSortableNode.userObject).compareTo(secondSortableNode.userObject);
+                       }
+               });
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public Enumeration<?> children() {
+               return Collections.enumeration(children);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       @Override
+       public String toString() {
+               return (userObject != null) ? userObject.toString() : null;
+       }
+
+}