KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > openide > nodes > Sheet


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19 package org.openide.nodes;
20
21 import java.beans.PropertyChangeEvent JavaDoc;
22 import java.beans.PropertyChangeListener JavaDoc;
23 import java.beans.PropertyChangeSupport JavaDoc;
24
25 import java.util.*;
26
27
28 /** Support for creation of property sets. Allows easy
29 * addition, modification, and deletion of properties. Also
30 * permits listening on changes of contained properties.
31 *
32 * @author Jaroslav Tulach, Dafe Simonek
33 */

34 public final class Sheet extends Object JavaDoc {
35     /** Name for regular Bean property set. */
36     public static final String JavaDoc PROPERTIES = "properties"; // NOI18N
37

38     /** Name for expert Bean property set. */
39     public static final String JavaDoc EXPERT = "expert"; // NOI18N
40

41     /** list of sets (Sheet.Set) */
42     private ArrayList<Set> sets;
43
44     /** array of sets */
45     private Node.PropertySet[] array;
46
47     /** support for changes */
48     private PropertyChangeSupport JavaDoc supp = new PropertyChangeSupport JavaDoc(this);
49
50     /** change listener that is attached to each set added to this object */
51     private PropertyChangeListener JavaDoc propL = new PropertyChangeListener JavaDoc() {
52             public void propertyChange(PropertyChangeEvent JavaDoc ev) {
53                 supp.firePropertyChange(null, null, null);
54             }
55         };
56
57     /** Default constructor.
58     */

59     public Sheet() {
60         this(new ArrayList<Set>(2));
61     }
62
63     /** Copy constrcutor.
64     * @param ar array to use
65     */

66     private Sheet(ArrayList<Set> ar) {
67         sets = ar;
68     }
69
70     /** Obtain the array of property sets.
71     * @return the array
72     */

73     public final Node.PropertySet[] toArray() {
74         Node.PropertySet[] l = array;
75
76         if (l != null) {
77             return l;
78         }
79
80         synchronized (this) {
81             if (array != null) {
82                 return array;
83             }
84
85             array = new Node.PropertySet[sets.size()];
86             sets.toArray(array);
87
88             return array;
89         }
90     }
91
92     /** Create a deep copy of the sheet. Listeners are not copied.
93     * @return the cloned object */

94     public synchronized Sheet cloneSheet() {
95         int len = sets.size();
96         ArrayList<Set> l = new ArrayList<Set>(len);
97
98         for (int i = 0; i < len; i++) {
99             l.add(sets.get(i).cloneSet());
100         }
101
102         return new Sheet(l);
103     }
104
105     /** Find the property set with a given name.
106     * @param name name of the set
107     * @return the property set, or <code>null</code> if no such set exists
108     */

109     public synchronized Set get(String JavaDoc name) {
110         int indx = findIndex(name);
111
112         return (indx == -1) ? null : sets.get(indx);
113     }
114
115     /** Add a property set. If the set does not yet exist in the sheet,
116     * inserts a new set with the implied name. Otherwise the old set is replaced
117     * by the new one.
118     *
119     * @param set to add
120     * @return the previous set with the same name, or <code>null</code> if this is a fresh insertion
121     */

122     public synchronized Set put(Set set) {
123         int indx = findIndex(set.getName());
124         Set removed;
125
126         if (indx == -1) {
127             sets.add(set);
128             removed = null;
129         } else {
130             removed = sets.set(indx, set);
131         }
132
133         set.removePropertyChangeListener(propL);
134
135         if (removed == null) {
136             set.addPropertyChangeListener(propL);
137         }
138
139         refresh();
140
141         return removed;
142     }
143
144     /** Remove a property set from the sheet.
145     * @param set name of set to remove
146     * @return removed set, or <code>null</code> if the set could not be found
147     */

148     public synchronized Set remove(String JavaDoc set) {
149         int indx = findIndex(set);
150
151         if (indx != -1) {
152             Set s = sets.remove(indx);
153             s.removePropertyChangeListener(propL);
154             refresh();
155
156             return s;
157         } else {
158             return null;
159         }
160     }
161
162     /** Convenience method to create new sheet with only one empty set, named {@link #PROPERTIES}.
163     * Display name and hint are settable via the appropriate bundle.
164     *
165     * @return a new sheet with default property set
166     */

167     public static Sheet createDefault() {
168         Sheet newSheet = new Sheet();
169
170         // create default property set
171
newSheet.put(createPropertiesSet());
172
173         return newSheet;
174     }
175
176     /** Convenience method to create new sheet set named {@link #PROPERTIES}.
177     *
178     * @return a new properties sheet set
179     */

180     public static Sheet.Set createPropertiesSet() {
181         Sheet.Set ps = new Sheet.Set();
182         ps.setName(PROPERTIES);
183         ps.setDisplayName(Node.getString("Properties"));
184         ps.setShortDescription(Node.getString("HINT_Properties"));
185
186         return ps;
187     }
188
189     /** Convenience method to create new sheet set named {@link #EXPERT}.
190     *
191     * @return a new expert properties sheet set
192     */

193     public static Sheet.Set createExpertSet() {
194         Sheet.Set ps = new Sheet.Set();
195         ps.setExpert(true);
196         ps.setName(EXPERT);
197         ps.setDisplayName(Node.getString("Expert"));
198         ps.setShortDescription(Node.getString("HINT_Expert"));
199
200         return ps;
201     }
202
203     /** Add a change listener.
204     * @param l the listener */

205     public void addPropertyChangeListener(PropertyChangeListener JavaDoc l) {
206         supp.addPropertyChangeListener(l);
207     }
208
209     /** Remove a change listener.
210     * @param l the listener */

211     public void removePropertyChangeListener(PropertyChangeListener JavaDoc l) {
212         supp.removePropertyChangeListener(l);
213     }
214
215     /** Finds index for property set for given name.
216     * @param name of the property
217     * @return the index or -1 if not found
218     */

219     private int findIndex(String JavaDoc name) {
220         int s = sets.size();
221
222         for (int i = 0; i < s; i++) {
223             Node.PropertySet p = (Node.PropertySet) sets.get(i);
224
225             if (p.getName().equals(name)) {
226                 return i;
227             }
228         }
229
230         return -1;
231     }
232
233     /** Refreshes and fire info about the set
234     */

235     private void refresh() {
236         array = null;
237         supp.firePropertyChange(null, null, null);
238     }
239
240     /********* Inner classes **********/
241     /** A set of Bean properties.
242     */

243     public static final class Set extends Node.PropertySet {
244         /** list of properties (Node.Property) */
245         private List<Node.Property<?>> props;
246
247         /** array of properties */
248         private Node.Property<?>[] array;
249
250         /** change listeners listening on this set */
251         private PropertyChangeSupport JavaDoc supp = new PropertyChangeSupport JavaDoc(this);
252
253         /** Default constructor.
254         */

255         public Set() {
256             this(new ArrayList<Node.Property<?>>());
257         }
258
259         /** @param al array list to use for this property set
260         */

261         private Set(List<Node.Property<?>> al) {
262             props = al;
263         }
264
265         /** Clone the property set.
266         * @return the clone
267         */

268         public synchronized Set cloneSet() {
269             return new Set(new ArrayList<Node.Property<?>>(props));
270         }
271
272         /** Get a property by name.
273         * @param name name of the property
274         * @return the first property in the list that has this name, <code>null</code> if not found
275         */

276         public Node.Property<?> get(String JavaDoc name) {
277             int indx = findIndex(name);
278
279             return (indx == -1) ? null : props.get(indx);
280         }
281
282         /** Get all properties in this set.
283         * @return the properties
284         */

285         public Node.Property<?>[] getProperties() {
286             Node.Property<?>[] l = array;
287
288             if (l != null) {
289                 return l;
290             }
291
292             synchronized (this) {
293                 if (array != null) {
294                     return array;
295                 }
296
297                 array = new Node.Property<?>[props.size()];
298                 props.toArray(array);
299
300                 return array;
301             }
302         }
303
304         /** Add a property to this set, replacing any old one with the same name.
305         * @param p the property to add
306         * @return the property with the same name that was replaced, or <code>null</code> for a fresh insertion
307         */

308         public synchronized Node.Property<?> put(Node.Property<?> p) {
309             int indx = findIndex(p.getName());
310             Node.Property<?> removed;
311
312             if (indx != -1) {
313                 // replaces the original one
314
removed = props.set(indx, p);
315             } else {
316                 // adds this to the end
317
props.add(p);
318                 removed = null;
319             }
320
321             // clears computed array and fires into about change of properties
322
refresh();
323
324             return removed;
325         }
326
327         /** Add several properties to this set, replacing old ones with the same names.
328         *
329         * @param ar properties to add
330         */

331         public synchronized void put(Node.Property<?>[] ar) {
332             for (int i = 0; i < ar.length; i++) {
333                 Node.Property<?> p = ar[i];
334                 p = ar[i];
335
336                 int indx = findIndex(p.getName());
337
338                 if (indx != -1) {
339                     // replaces the original one
340
props.set(indx, p);
341                 } else {
342                     // adds this to the end
343
props.add(p);
344                 }
345             }
346
347             // clears computed array and fires into about change of properties
348
refresh();
349         }
350
351         /** Remove a property from the set.
352         * @param name name of the property to remove
353         * @return the removed property, or <code>null</code> if it was not there to begin with
354         */

355         public synchronized Node.Property<?> remove(String JavaDoc name) {
356             int indx = findIndex(name);
357
358             if (indx != -1) {
359                 try {
360                     return props.remove(indx);
361                 } finally {
362                     // clears computed array and fires into about change of properties
363
refresh();
364                 }
365             } else {
366                 return null;
367             }
368         }
369
370         /** Add a property change listener.
371         * @param l the listener to add */

372         public void addPropertyChangeListener(PropertyChangeListener JavaDoc l) {
373             supp.addPropertyChangeListener(l);
374         }
375
376         /** Remove a property change listener.
377         * @param l the listener to remove */

378         public void removePropertyChangeListener(PropertyChangeListener JavaDoc l) {
379             supp.removePropertyChangeListener(l);
380         }
381
382         /** Finds index for property with specified name.
383         * @param name of the property
384         * @return the index or -1 if not found
385         */

386         private int findIndex(String JavaDoc name) {
387             int s = props.size();
388
389             for (int i = 0; i < s; i++) {
390                 Node.Property<?> p = props.get(i);
391
392                 if (p.getName().equals(name)) {
393                     return i;
394                 }
395             }
396
397             return -1;
398         }
399
400         /** Notifies change of properties.
401         */

402         private void refresh() {
403             array = null;
404             supp.firePropertyChange(null, null, null);
405         }
406     }
407      // end of Set
408
}
409
Popular Tags