001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package threaddemo.views.looktree;
043:
044: import java.util.Enumeration;
045: import java.util.List;
046: import org.netbeans.modules.looks.Accessor;
047: import org.netbeans.modules.looks.LookEvent;
048: import org.netbeans.modules.looks.LookListener;
049: import org.netbeans.spi.looks.Look;
050: import org.netbeans.spi.looks.LookSelector;
051: import org.openide.util.Lookup;
052:
053: /**
054: * One node in a tree of looks.
055: * @author Jesse Glick
056: */
057: abstract class LookTreeNode implements LookListener {
058:
059: public static LookTreeNode createRoot(Object o, LookSelector s,
060: LookTreeModel m) {
061: return new RootLookTreeNode(findLook(o, s), o, s, m);
062: }
063:
064: private final Object representedObject;
065: private final Look look;
066: // private Map<Object,LookTreeNode> children = null;
067: private LookTreeNode[] children;
068: private List childrenList;
069: protected int index = -1;
070:
071: private static final class RootLookTreeNode extends LookTreeNode {
072: private final LookSelector s;
073: private final LookTreeModel m;
074:
075: public RootLookTreeNode(Look l, Object o, LookSelector s,
076: LookTreeModel m) {
077: super (l, o);
078: this .s = s;
079: this .m = m;
080: }
081:
082: protected LookSelector getSelector() {
083: return s;
084: }
085:
086: protected void fireDisplayChange(LookTreeNode source) {
087: m.fireDisplayChange(source);
088: }
089:
090: protected void fireChildrenChange(LookTreeNode source) {
091: m.fireChildrenChange(source);
092: }
093:
094: public void lookupItemsChanged(LookEvent evt) {
095: }
096:
097: }
098:
099: private static final class ChildLookTreeNode extends LookTreeNode {
100: private final LookTreeNode p;
101:
102: public ChildLookTreeNode(Look l, Object o, LookTreeNode p,
103: int index) {
104: super (l, o);
105: this .p = p;
106: this .index = index;
107: }
108:
109: protected LookSelector getSelector() {
110: return p.getSelector();
111: }
112:
113: protected void fireDisplayChange(LookTreeNode source) {
114: p.fireDisplayChange(source);
115: }
116:
117: protected void fireChildrenChange(LookTreeNode source) {
118: p.fireChildrenChange(source);
119: }
120:
121: public void lookupItemsChanged(LookEvent evt) {
122: }
123:
124: }
125:
126: private LookTreeNode(Look l, Object o) {
127: this .representedObject = o;
128: this .look = l;
129: Accessor.DEFAULT.addLookListener(l, representedObject, this );
130: }
131:
132: private static Look findLook(Object o, LookSelector s) {
133: Enumeration e = s.getLooks(o);
134: while (e.hasMoreElements()) {
135: Object x = e.nextElement();
136: if (x instanceof Look) {
137: return (Look) x;
138: }
139: }
140: throw new IllegalArgumentException("No look found for " + o
141: + " with selector " + s);
142: }
143:
144: protected abstract LookSelector getSelector();
145:
146: protected abstract void fireDisplayChange(LookTreeNode source);
147:
148: protected abstract void fireChildrenChange(LookTreeNode source);
149:
150: public Look getLook() {
151: return look;
152: }
153:
154: void forgetChildren() {
155: /*
156: if (children != null) {
157: for (LookTreeNode child : children) {
158: child.forgetEverything();
159: }
160: children = null;
161: }
162: */
163: childrenList = null;
164: children = null;
165: }
166:
167: void forgetEverything() {
168: forgetChildren();
169: //FirerSupport.DEFAULT.unregisterSubstitute(n);
170: }
171:
172: @SuppressWarnings("unchecked")
173: private List getChildrenList() {
174: if (childrenList == null) {
175: childrenList = getLook().getChildObjects(representedObject,
176: getLookup());
177: assert childrenList != null : "null kids from " + getLook()
178: + " on " + representedObject;
179: children = new LookTreeNode[childrenList.size()];
180: }
181: return childrenList;
182: }
183:
184: public LookTreeNode getParent() {
185: if (this instanceof ChildLookTreeNode) {
186: return ((ChildLookTreeNode) this ).p;
187: } else {
188: return null;
189: }
190: }
191:
192: public Object getData() {
193: return representedObject;
194: }
195:
196: public Lookup getLookup() {
197: return Lookup.EMPTY; // PENDING
198: }
199:
200: public String toString() {
201: return "LookTreeNode<" + representedObject + ">";
202: }
203:
204: // Methods for TreeModel ---------------------------------------------------
205:
206: public LookTreeNode getChild(int index) {
207:
208: if (children == null || children[index] == null) {
209: Object o = getChildrenList().get(index);
210: LookTreeNode ltn = new ChildLookTreeNode(findLook(o,
211: getSelector()), o, this , index);
212: children[index] = ltn;
213: }
214:
215: return children[index];
216: }
217:
218: public int getChildCount() {
219: return getChildrenList().size();
220: }
221:
222: public int getIndexOfChild(LookTreeNode child) {
223: // XXX this is not very nice for performance
224:
225: if (child.index == -1) {
226: System.out.println("Uggly: find " + child + " in " + this );
227: for (int i = 0; i < children.length; i++) {
228: if (children[i] == child)
229: return i;
230: }
231: throw new IllegalStateException("Can't find LookTreeNode "
232: + child + " in " + this );
233: } else {
234: return child.index;
235: }
236: }
237:
238: @SuppressWarnings("unchecked")
239: public boolean isLeaf() {
240: return getLook().isLeaf(representedObject, getLookup());
241: }
242:
243: // Implementation of LookListener ------------------------------------------
244:
245: public void change(LookEvent evt) {
246: long mask = evt.getMask();
247:
248: // XXX Look.GET_PROPERTY_SETS not impl.
249:
250: if ((mask & (Look.GET_NAME | Look.GET_DISPLAY_NAME
251: | Look.GET_ICON | Look.GET_OPENED_ICON | Look.GET_SHORT_DESCRIPTION)) > 0) {
252:
253: fireDisplayChange(this );
254: }
255:
256: if ((mask & Look.GET_CHILD_OBJECTS) > 0) {
257: forgetChildren();
258: fireChildrenChange(this );
259: }
260: }
261:
262: public void propertyChange(LookEvent evt) {
263: // XXX prop sets not impl
264: }
265:
266: }
|