001: package org.wingx.tree;
002:
003: import org.wingx.tree.LazyNode;
004:
005: import javax.swing.event.TreeExpansionEvent;
006: import javax.swing.event.TreeExpansionListener;
007: import javax.swing.tree.DefaultMutableTreeNode;
008: import javax.swing.tree.DefaultTreeModel;
009: import javax.swing.tree.MutableTreeNode;
010: import javax.swing.tree.TreeModel;
011:
012: /**
013: * basic node class
014: */
015: public abstract class XTreeNode extends DefaultMutableTreeNode
016: implements LazyNode {
017:
018: private TreeModel treeModel;
019:
020: /**
021: * Creates a tree node with no parent, no children, initialized with
022: * the specified user object. For default the XTreeTableNode doesn't
023: * allow children.
024: *
025: * @param userObject an Object provided by the user that constitutes
026: * the node's data
027: */
028: protected XTreeNode(Object userObject) {
029: super (userObject);
030: }
031:
032: /**
033: * construct the node with the tree model,
034: * the tree model must always be passed in the constructor,
035: * each node knows it's model from the start.
036: *
037: * @param treeModel
038: */
039: public XTreeNode(TreeModel treeModel, Object userObject,
040: boolean allowsChildren) {
041: super (userObject, allowsChildren);
042:
043: if (treeModel == null) {
044: throw new NullPointerException("no tree model");
045: }
046:
047: this .treeModel = treeModel;
048: }
049:
050: /**
051: * lazy initialization
052: */
053: public void initialize() {
054: if (!initialized) {
055: doInitialize();
056: initialized = true;
057: }
058: }
059:
060: private boolean initialized;
061:
062: /**
063: * do the initialization
064: */
065: protected abstract void doInitialize();
066:
067: /**
068: * reinitialize
069: */
070: public void reinitialize() {
071: removeAllChildrenNotify();
072: doInitialize();
073: initialized = true;
074: }
075:
076: /**
077: * @return Returns the initialized.
078: */
079: public boolean isInitialized() {
080: return this .initialized;
081: }
082:
083: public void setInitialized(boolean initialized) {
084: this .initialized = initialized;
085: }
086:
087: /**
088: * return the tree model
089: *
090: * @return
091: */
092: public TreeModel getTreeModel() {
093: XTreeNode ancestor = (XTreeNode) getParent();
094: while (treeModel == null && ancestor != null) {
095: treeModel = ancestor.getTreeModel();
096: }
097: return treeModel;
098: }
099:
100: /**
101: * Set the tree model as tree model of current
102: * node.
103: *
104: * @param treeModel The tree model of the whole
105: * tree.
106: */
107: public void setTreeModel(TreeModel treeModel) {
108: this .treeModel = treeModel;
109: }
110:
111: /**
112: * type cast the child ot an onode
113: *
114: * @param index
115: * @return
116: */
117: public XTreeNode getNodeChildAt(int index) {
118: return (XTreeNode) getChildAt(index);
119: }
120:
121: /**
122: * get the distance of this node from the root node
123: * the children of the root node have a depth of 1.
124: *
125: * @return Returns the depth.
126: */
127: public int getDepth() {
128: if (depth < 0) {
129: XTreeNode parent = (XTreeNode) getParent();
130: depth = (parent != null) ? parent.getDepth() + 1 : 0;
131: }
132: return this .depth;
133: }
134:
135: private int depth = -1;
136:
137: /**
138: * return the expanded state.
139: * the expanded state is held in the model
140: * because certain tree implementations perform
141: * expand / collapse at the model level.
142: *
143: * @return Returns the expanded.
144: */
145: public boolean isExpanded() {
146: return this .expanded;
147: }
148:
149: /**
150: * @param expanded The expanded to set.
151: */
152: public void setExpanded(boolean expanded) {
153: this .expanded = expanded;
154: }
155:
156: private boolean expanded;
157:
158: /**
159: * insert the child node,
160: * and notify the model if it is a default tree model
161: *
162: * @param newChild
163: * @param index
164: */
165: public void insertNotify(MutableTreeNode newChild, int index) {
166: if (getTreeModel() instanceof DefaultTreeModel) {
167: DefaultTreeModel model = (DefaultTreeModel) getTreeModel();
168: model.insertNodeInto(newChild, this , index);
169: } else {
170: insert(newChild, index);
171: }
172: }
173:
174: /**
175: * remove all children
176: */
177: public void removeAllChildrenNotify() {
178: if (getTreeModel() instanceof DefaultTreeModel) {
179: DefaultTreeModel model = (DefaultTreeModel) getTreeModel();
180: int count = getChildCount();
181: for (int i = count - 1; i >= 0; i--) {
182: model
183: .removeNodeFromParent((MutableTreeNode) getChildAt(i));
184: }
185: } else {
186: removeAllChildren();
187: }
188: }
189:
190: /**
191: * add the child node,
192: * and notify the model if it is a default tree model
193: *
194: * @param newChild
195: * @param parent
196: * @param index
197: */
198: public void addNotify(MutableTreeNode newChild) {
199: insertNotify(newChild, getChildCount());
200: }
201:
202: /**
203: * initialise the nodes when they are expanded
204: */
205: public static class InitializationListener implements
206: TreeExpansionListener {
207: public void treeExpanded(TreeExpansionEvent event) {
208: if (event.getPath() != null
209: && event.getPath().getLastPathComponent() != null) {
210: ((XTreeNode) event.getPath().getLastPathComponent())
211: .initialize();
212: }
213: }
214:
215: public void treeCollapsed(TreeExpansionEvent event) {
216: }
217: }
218:
219: }
|