001: /*--------------------------------------------------------------------------*
002: | Copyright (C) 2006 Christopher Kohlhaas |
003: | |
004: | This program is free software; you can redistribute it and/or modify |
005: | it under the terms of the GNU General Public License as published by the |
006: | Free Software Foundation. A copy of the license has been included with |
007: | these distribution in the COPYING file, if not go to www.fsf.org |
008: | |
009: | As a special exception, you are granted the permissions to link this |
010: | program with every library, which license fulfills the Open Source |
011: | Definition as published by the Open Source Initiative (OSI). |
012: *--------------------------------------------------------------------------*/
013: package org.rapla.gui.toolkit;
014:
015: import javax.swing.tree.TreeNode;
016: import javax.swing.JTree;
017: import javax.swing.tree.TreePath;
018: import java.util.Enumeration;
019:
020: /** Node object that is used to show recursive structures like the categories */
021: public abstract class RecursiveNode implements TreeNode {
022: protected Object userObject;
023: RecursiveNode[] childNodes;
024: protected TreeNode parent;
025:
026: public RecursiveNode(TreeNode parent, Object userObject) {
027: this .parent = parent;
028: this .userObject = userObject;
029: }
030:
031: abstract protected Object[] getChildObjects();
032:
033: abstract protected RecursiveNode createChildNode(Object userObject);
034:
035: public int getIndexOfUserObject(Object object) {
036: Object[] childNodes = getChildNodes();
037: for (int i = 0; i < childNodes.length; i++) {
038: if (((RecursiveNode) childNodes[i]).getUserObject().equals(
039: object))
040: return i;
041: }
042: return -1;
043: }
044:
045: public Object getUserObject() {
046: return userObject;
047: }
048:
049: public TreeNode getParent() {
050: return parent;
051: }
052:
053: public int countParents() { // Count the parents
054: TreeNode tmp = this ;
055: int parentCount = 0;
056: while (tmp.getParent() != null) {
057: tmp = tmp.getParent();
058: parentCount++;
059: }
060: return parentCount;
061: }
062:
063: public boolean isLeaf() {
064: return getChildCount() == 0;
065: }
066:
067: public int getChildCount() {
068: return getChildNodes().length;
069: }
070:
071: public boolean getAllowsChildren() {
072: return true;
073: }
074:
075: public Enumeration children() {
076: return new Enumeration() {
077: int i = 0;
078:
079: public boolean hasMoreElements() {
080: return (i + 1 < childNodes.length);
081: }
082:
083: public Object nextElement() {
084: if (i + 1 < childNodes.length)
085: return childNodes[i++];
086: else
087: return null;
088: }
089: };
090: }
091:
092: /** Selects a row in a tree wich TreeNodePath corresponds to the
093: * given path of userObjects.*/
094: static public void selectUserObjects(JTree tree,
095: Object[] userObjects) {
096: int size = userObjects.length;
097: RecursiveNode[] nodes = new RecursiveNode[size + 1];
098: nodes[0] = (RecursiveNode) tree.getModel().getRoot();
099: for (int i = 1; i <= size; i++) {
100: Object obj = userObjects[size - i];
101: int index = nodes[i - 1].getIndexOfUserObject(obj);
102: if (index < 0) {
103: tree.setSelectionRow(-1);
104: return;
105: }
106: nodes[i] = (RecursiveNode) nodes[i - 1].getChildAt(index);
107: }
108: /*
109: System.out.print("TreePath: " );
110: for (int i=0;i<=size ;i++)
111: System.out.print("[" + i + "]" + nodes[i].getUserObject());
112: System.out.println();*/
113: TreePath treePath = new TreePath(nodes);
114: if (nodes.length > 1) {
115: RecursiveNode[] nodes2 = new RecursiveNode[nodes.length - 1];
116: System.arraycopy(nodes, 0, nodes2, 0, nodes.length - 1);
117: tree.expandPath(new TreePath(nodes2));
118: }
119: tree.setSelectionPath(treePath);
120: tree.scrollPathToVisible(treePath);
121: }
122:
123: /* returns the path from the root to the node*/
124: public TreeNode[] getPath() {
125: int parentCount = countParents();
126: TreeNode[] path = new TreeNode[parentCount + 1];
127: for (int i = parentCount; i > 0; i--) {
128: if (i == parentCount)
129: path[i - 1] = getParent();
130: else
131: path[i - 1] = path[i].getParent();
132: }
133: path[parentCount] = this ;
134: return path;
135: }
136:
137: /* returns the path from the root to the node*/
138: public TreePath getTreePath() {
139: Object[] nodes = getPath();
140: return new TreePath(nodes);
141: }
142:
143: public int getIndex(TreeNode treeNode) {
144: Object[] childNodes = getChildNodes();
145: for (int i = 0; i < childNodes.length; i++) {
146: if (childNodes[i].equals(treeNode))
147: return i;
148: }
149: return -1;
150: }
151:
152: public TreeNode getChildAt(int index) {
153: return getChildNodes()[index];
154: }
155:
156: public RecursiveNode findNodeFor(Object obj) {
157: Object userObject = getUserObject();
158: if (userObject != null && userObject.equals(obj))
159: return this ;
160: RecursiveNode[] childs = getRecursiveNodes();
161: for (int i = 0; i < childs.length; i++) {
162: RecursiveNode result = childs[i].findNodeFor(obj);
163: if (result != null) {
164: return result;
165: }
166: }
167: return null;
168:
169: }
170:
171: public TreeNode[] getChildNodes() {
172: return getRecursiveNodes();
173: }
174:
175: private RecursiveNode[] getRecursiveNodes() {
176: Object[] newChildren = getChildObjects();
177: // Check if the childrens have changed
178: if (childNodes != null
179: && childNodes.length == newChildren.length) {
180: boolean bChanged = false;
181: for (int i = 0; i < childNodes.length; i++) {
182: if (childNodes[i].getUserObject() != newChildren[i]) {
183: bChanged = true;
184: break;
185: }
186: }
187: // No changes, we can return the chached ones;
188: if (!bChanged)
189: return childNodes;
190: }
191:
192: childNodes = new RecursiveNode[newChildren.length];
193: for (int i = 0; i < newChildren.length; i++) {
194: childNodes[i] = createChildNode(newChildren[i]);
195: }
196: return childNodes;
197: }
198:
199: public boolean equals(Object obj) {
200: if (obj instanceof RecursiveNode && getUserObject() != null) {
201: return getUserObject().equals(
202: ((RecursiveNode) obj).getUserObject());
203: }
204: return false;
205: }
206: }
|