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 org.netbeans.modules.debugger.ui.models;
043:
044: import java.beans.PropertyChangeEvent;
045: import java.beans.PropertyChangeListener;
046: import java.lang.ref.WeakReference;
047: import java.util.Vector;
048:
049: import org.netbeans.api.debugger.Watch;
050: import org.netbeans.api.debugger.DebuggerManager;
051: import org.netbeans.api.debugger.DebuggerManagerAdapter;
052: import org.netbeans.spi.viewmodel.ModelEvent;
053: import org.netbeans.spi.viewmodel.TreeModel;
054: import org.netbeans.spi.viewmodel.ModelListener;
055: import org.netbeans.spi.viewmodel.UnknownTypeException;
056:
057: /**
058: * @author Jan Jancura
059: */
060: public class WatchesTreeModel implements TreeModel {
061:
062: private Listener listener;
063: private Vector listeners = new Vector();
064:
065: /**
066: *
067: * @return threads contained in this group of threads
068: */
069: public Object getRoot() {
070: return ROOT;
071: }
072:
073: /**
074: *
075: * @return threads contained in this group of threads
076: */
077: public Object[] getChildren(Object parent, int from, int to)
078: throws UnknownTypeException {
079: if (parent == ROOT) {
080: Watch[] ws = DebuggerManager.getDebuggerManager()
081: .getWatches();
082: if (listener == null)
083: listener = new Listener(this );
084: to = Math.min(ws.length, to);
085: from = Math.min(ws.length, from);
086: Watch[] fws = new Watch[to - from];
087: System.arraycopy(ws, from, fws, 0, to - from);
088: return fws;
089: } else
090: throw new UnknownTypeException(parent);
091: }
092:
093: /**
094: * Returns number of children for given node.
095: *
096: * @param node the parent node
097: * @throws UnknownTypeException if this TreeModel implementation is not
098: * able to resolve children for given node type
099: *
100: * @return true if node is leaf
101: */
102: public int getChildrenCount(Object node)
103: throws UnknownTypeException {
104: if (node == ROOT) {
105: if (listener == null)
106: listener = new Listener(this );
107: // Performance, see issue #59058.
108: return Integer.MAX_VALUE;
109: //return DebuggerManager.getDebuggerManager ().getWatches ().length;
110: } else
111: throw new UnknownTypeException(node);
112: }
113:
114: public boolean isLeaf(Object node) throws UnknownTypeException {
115: if (node == ROOT)
116: return false;
117: if (node instanceof Watch)
118: return true;
119: throw new UnknownTypeException(node);
120: }
121:
122: public void addModelListener(ModelListener l) {
123: listeners.add(l);
124: }
125:
126: public void removeModelListener(ModelListener l) {
127: listeners.remove(l);
128: }
129:
130: private void fireTreeChanged() {
131: Vector v = (Vector) listeners.clone();
132: int i, k = v.size();
133: for (i = 0; i < k; i++)
134: ((ModelListener) v.get(i))
135: .modelChanged(new ModelEvent.NodeChanged(this ,
136: ROOT, ModelEvent.NodeChanged.CHILDREN_MASK));
137: }
138:
139: void fireWatchPropertyChanged(Watch b, String propertyName) {
140: Vector v = (Vector) listeners.clone();
141: int i, k = v.size();
142: for (i = 0; i < k; i++)
143: ((ModelListener) v.get(i)).modelChanged(
144: //new ModelEvent.TableValueChanged (this, b, "DefaultWatchesColumn")
145: new ModelEvent.NodeChanged(this , b));
146: }
147:
148: // innerclasses ............................................................
149:
150: private static class Listener extends DebuggerManagerAdapter
151: implements PropertyChangeListener {
152:
153: private WeakReference model;
154:
155: public Listener(WatchesTreeModel tm) {
156: model = new WeakReference(tm);
157: DebuggerManager.getDebuggerManager().addDebuggerListener(
158: DebuggerManager.PROP_WATCHES, this );
159: Watch[] ws = DebuggerManager.getDebuggerManager()
160: .getWatches();
161: int i, k = ws.length;
162: for (i = 0; i < k; i++)
163: ws[i].addPropertyChangeListener(this );
164: }
165:
166: private WatchesTreeModel getModel() {
167: WatchesTreeModel m = (WatchesTreeModel) model.get();
168: if (m == null) {
169: DebuggerManager.getDebuggerManager()
170: .removeDebuggerListener(
171: DebuggerManager.PROP_WATCHES, this );
172: Watch[] ws = DebuggerManager.getDebuggerManager()
173: .getWatches();
174: int i, k = ws.length;
175: for (i = 0; i < k; i++)
176: ws[i].removePropertyChangeListener(this );
177: }
178: return m;
179: }
180:
181: public void watchAdded(Watch watch) {
182: WatchesTreeModel m = getModel();
183: if (m == null)
184: return;
185: watch.addPropertyChangeListener(this );
186: m.fireTreeChanged();
187: }
188:
189: public void watchRemoved(Watch watch) {
190: WatchesTreeModel m = getModel();
191: if (m == null)
192: return;
193: watch.removePropertyChangeListener(this );
194: m.fireTreeChanged();
195: }
196:
197: public void propertyChange(PropertyChangeEvent evt) {
198: WatchesTreeModel m = getModel();
199: if (m == null)
200: return;
201: if (!(evt.getSource() instanceof Watch))
202: return;
203: Watch w = (Watch) evt.getSource();
204: m.fireWatchPropertyChanged(w, evt.getPropertyName());
205: }
206: }
207: }
|