KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > openide > explorer > propertysheet > PropertySheet


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.explorer.propertysheet;
20
21 import java.awt.BorderLayout JavaDoc;
22 import java.awt.Color JavaDoc;
23 import java.awt.Component JavaDoc;
24 import java.awt.Dimension JavaDoc;
25 import java.awt.Font JavaDoc;
26 import java.awt.KeyboardFocusManager JavaDoc;
27 import java.awt.Point JavaDoc;
28 import java.awt.Toolkit JavaDoc;
29 import java.awt.event.ActionEvent JavaDoc;
30 import java.awt.event.FocusEvent JavaDoc;
31 import java.awt.event.FocusListener JavaDoc;
32 import java.awt.event.KeyEvent JavaDoc;
33 import java.beans.FeatureDescriptor JavaDoc;
34 import java.beans.PropertyChangeEvent JavaDoc;
35 import java.beans.PropertyChangeListener JavaDoc;
36 import java.beans.PropertyVetoException JavaDoc;
37 import java.lang.ref.Reference JavaDoc;
38 import java.lang.ref.WeakReference JavaDoc;
39 import java.lang.reflect.InvocationTargetException JavaDoc;
40 import java.lang.reflect.Method JavaDoc;
41 import java.util.ArrayList JavaDoc;
42 import java.util.Arrays JavaDoc;
43 import java.util.HashMap JavaDoc;
44 import java.util.HashSet JavaDoc;
45 import java.util.Iterator JavaDoc;
46 import java.util.List JavaDoc;
47 import java.util.Map JavaDoc;
48 import java.util.logging.Level JavaDoc;
49 import java.util.logging.Logger JavaDoc;
50 import javax.swing.AbstractAction JavaDoc;
51 import javax.swing.Action JavaDoc;
52 import javax.swing.BorderFactory JavaDoc;
53 import javax.swing.Icon JavaDoc;
54 import javax.swing.JCheckBoxMenuItem JavaDoc;
55 import javax.swing.JComponent JavaDoc;
56 import javax.swing.JMenuItem JavaDoc;
57 import javax.swing.JPanel JavaDoc;
58 import javax.swing.JPopupMenu JavaDoc;
59 import javax.swing.JRadioButtonMenuItem JavaDoc;
60 import javax.swing.JSeparator JavaDoc;
61 import javax.swing.KeyStroke JavaDoc;
62 import javax.swing.SwingUtilities JavaDoc;
63 import javax.swing.UIManager JavaDoc;
64 import javax.swing.event.ChangeEvent JavaDoc;
65 import javax.swing.event.ChangeListener JavaDoc;
66 import org.openide.nodes.Node;
67 import org.openide.nodes.Node.PropertySet;
68 import org.openide.nodes.NodeAdapter;
69 import org.openide.util.Exceptions;
70 import org.openide.util.HelpCtx;
71 import org.openide.util.Lookup;
72 import org.openide.util.Mutex;
73 import org.openide.util.NbBundle;
74 import org.openide.util.RequestProcessor;
75
76
77
78 /**
79  * Implements a property sheet for a set of nodes. Can be used as a
80  * standalone component (e.g. without a connection to {@link org.openide.explorer.ExplorerManager}).
81  * For example to display properties of a JavaBean one could use:
82  * <pre>
83  * Object bean = ...;
84  * JPanel container = ...;
85  * PropertySheet ps = new PropertySheet();
86  * ps.setNodes(new Node[] { new {@link org.openide.nodes.BeanNode}(bean) });
87  * container.add(ps);
88  * </pre>
89  *
90  * <strong>Note that this class should be final, but for backward compatibility,
91  * cannot be. Subclassing this class is strongly discouraged</strong>
92  *
93  * @author Tim Boudreau, Jan Jancura, Jaroslav Tulach
94  */

95 public class PropertySheet extends JPanel JavaDoc {
96     /** generated Serialized Version UID */
97     static final long serialVersionUID = -7698351033045864945L;
98
99     // public constants ........................................................
100

101     /** Deprecated - no code outside the property sheet should be interested
102      * in how items are sorted.
103      *@deprecated Relic of the original property sheet implementation, will never be fired. */

104     public @Deprecated JavaDoc static final String JavaDoc PROPERTY_SORTING_MODE = "sortingMode"; // NOI18N
105

106     /** Property giving current value color.
107      *@deprecated Relic of the original property sheet implementation, will never be fired. */

108     public @Deprecated JavaDoc static final String JavaDoc PROPERTY_VALUE_COLOR = "valueColor"; // NOI18N
109

110     /** Property giving current disabled property color.
111      *@deprecated Relic of the original property sheet implementation, , will never be fired. */

112     public @Deprecated JavaDoc static final String JavaDoc PROPERTY_DISABLED_PROPERTY_COLOR = "disabledPropertyColor"; // NOI18N
113

114     /** Property with the current page index.
115      *@deprecated Relic of the original property sheet implementation, , will never be fired.*/

116     public @Deprecated JavaDoc static final String JavaDoc PROPERTY_CURRENT_PAGE = "currentPage"; // NOI18N
117

118     /** Property for plastic mode.
119      *@deprecated Relic of the original property sheet implementation, , will never be fired. */

120     public @Deprecated JavaDoc static final String JavaDoc PROPERTY_PLASTIC = "plastic"; // NOI18N
121

122     /** Property for the painting style.
123      *@deprecated Relic of the original property sheet implementation, will never be fired. */

124     public @Deprecated JavaDoc static final String JavaDoc PROPERTY_PROPERTY_PAINTING_STYLE = "propertyPaintingStyle"; // NOI18N
125

126     /** Property for whether only writable properties should be displayed.
127      *@deprecated Relic of the original property sheet implementation, will never be fired.*/

128     public @Deprecated JavaDoc static final String JavaDoc PROPERTY_DISPLAY_WRITABLE_ONLY = "displayWritableOnly"; // NOI18N
129

130     /** Constant for showing properties as a string always.
131      *@deprecated Relic of the original property sheet implementation, useless. */

132     public @Deprecated JavaDoc static final int ALWAYS_AS_STRING = 1;
133
134     /** Constant for preferably showing properties as string.
135      *@deprecated Relic of the original property sheet implementation, does useless. */

136     public @Deprecated JavaDoc static final int STRING_PREFERRED = 2;
137
138     /** Constant for preferably painting property values.
139      *@deprecated Relic of the original property sheet implementation, does useless. */

140     public @Deprecated JavaDoc static final int PAINTING_PREFERRED = 3;
141
142     /** Constant for unsorted sorting mode. */
143     public static final int UNSORTED = 0;
144
145     /** Constant for by-name sorting mode. */
146     public static final int SORTED_BY_NAMES = 1;
147
148     /** Constant for by-type sorting mode.
149      * @deprecated Not supported since NetBeans 3.6
150      **/

151     public @Deprecated JavaDoc static final int SORTED_BY_TYPES = 2;
152
153     /** Icon for the toolbar.
154      * @deprecated Presumably noone uses this variable. If you want to customize
155      * the property sheet look you can change the image files directly (or use your
156      * own).
157      */

158     static @Deprecated JavaDoc protected Icon JavaDoc iNoSort;
159
160     /** Icon for the toolbar.
161      * @deprecated Presumably noone uses this variable. If you want to customize
162      * the property sheet look you can change the image files directly (or use your
163      * own).
164      */

165     static @Deprecated JavaDoc protected Icon JavaDoc iAlphaSort;
166
167     /** Icon for the toolbar.
168      * @deprecated Presumably noone uses this variable. If you want to customize
169      * the property sheet look you can change the image files directly (or use your
170      * own).
171      */

172     static @Deprecated JavaDoc protected Icon JavaDoc iTypeSort;
173
174     /** Icon for the toolbar.
175      * @deprecated Presumably noone uses this variable. If you want to customize
176      * the property sheet look you can change the image files directly (or use your
177      * own).
178      */

179     static @Deprecated JavaDoc protected Icon JavaDoc iDisplayWritableOnly;
180
181     /** Icon for the toolbar.
182      * @deprecated Presumably noone uses this variable. If you want to customize
183      * the property sheet look you can change the image files directly (or use your
184      * own).
185      */

186     static @Deprecated JavaDoc protected Icon JavaDoc iCustomize;
187
188     /** Action command/input map key for popup menu invocation action */
189     private static final String JavaDoc ACTION_INVOKE_POPUP = "invokePopup"; //NOI18N
190

191     /** Action command/input map key for help invocation action */
192     private static final String JavaDoc ACTION_INVOKE_HELP = "invokeHelp"; //NOI18N
193

194     /** Init delay for second change of the selected nodes. */
195     private static final int INIT_DELAY = 70;
196
197     /** Maximum delay for repeated change of the selected nodes. */
198     private static final int MAX_DELAY = 150;
199
200     /**Debugging option to suppress all use of tabs */
201     private static final boolean neverTabs = Boolean.getBoolean("netbeans.ps.nevertabs"); //NOI18N
202
static final boolean forceTabs = Boolean.getBoolean("nb.ps.forcetabs");
203
204     /** Holds the sort mode for the property sheet */
205     private int sortingMode = UNSORTED;
206
207     /**Tracks whether the description area should be shown */
208     private boolean showDesc;
209
210     /** Temporary storage for the last selected node in the case the property
211      * sheet was removed temporarily from a container (winsys DnD) */

212     private Reference JavaDoc<Node> storedNode;
213
214     //Package private for unit tests
215
SheetTable table = new SheetTable();
216     PSheet psheet = new PSheet();
217     HelpAction helpAction = new HelpAction();
218
219     // delayed setting nodes (partly impl issue 27781)
220
private transient Node[] helperNodes;
221     private transient RequestProcessor.Task scheduleTask;
222     private transient RequestProcessor.Task initTask;
223     SheetPCListener pclistener = new SheetPCListener();
224
225     /** Create a new property sheet */
226     public PropertySheet() {
227         init();
228         initActions();
229     }
230
231     /** Install actions the property sheet will need */
232     private void initActions() {
233         Action JavaDoc invokePopupAction = new MutableAction(MutableAction.INVOKE_POPUP, this);
234
235         table.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_F10, KeyEvent.SHIFT_MASK), ACTION_INVOKE_POPUP);
236         table.getActionMap().put(ACTION_INVOKE_POPUP, invokePopupAction);
237
238         getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
239             KeyStroke.getKeyStroke(KeyEvent.VK_F10, KeyEvent.SHIFT_MASK), ACTION_INVOKE_POPUP
240         );
241         getActionMap().put(ACTION_INVOKE_POPUP, invokePopupAction);
242
243         getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
244             KeyStroke.getKeyStroke(KeyEvent.VK_F1, 0), ACTION_INVOKE_HELP
245         );
246         getActionMap().put(ACTION_INVOKE_HELP, helpAction);
247     }
248
249     public void addNotify() {
250         super.addNotify();
251
252         Node oldSelection = null;
253
254         if (storedNode != null) {
255             oldSelection = storedNode.get();
256         }
257
258         if (oldSelection != null) {
259             setCurrentNode(oldSelection);
260         }
261     }
262
263     public void updateUI() {
264         UIManager.get("nb.propertysheet"); //Causes default colors for the property sheet to be bootstrapped into
265
//UIDefaults - see core/swing/plaf
266

267         super.updateUI();
268     }
269
270     public void removeNotify() {
271         Node lastSel = null;
272
273         if (pclistener != null) {
274             //Save the last selection - if we're being transiently removed,
275
//i.e. because of drag and drop, we'll want to reset it on the
276
//next addNotify if it hasn't disappeared
277
lastSel = pclistener.detach();
278         }
279
280         doSetNodes(null);
281
282         if (lastSel != null) {
283             //Save the selected node in case we're re-added to a container
284
storedNode = new WeakReference JavaDoc<Node>(lastSel);
285         }
286
287         super.removeNotify();
288         table.getReusablePropertyEnv().setBeans(null);
289         table.getReusablePropertyEnv().setNode(null);
290         table.getReusablePropertyModel().setProperty(null);
291     }
292
293     /** Prepare the initial state of the property sheet */
294     private void init() {
295         Font JavaDoc f = UIManager.getFont("controlFont"); //NOI18N
296

297         if (f == null) {
298             //Aqua
299
f = UIManager.getFont("Tree.font"); //NOI18N
300
}
301
302         if (f != null) {
303             table.setFont(f);
304         }
305
306         showDesc = PropUtils.shouldShowDescription();
307         setLayout(new BorderLayout JavaDoc());
308         psheet.setBackground(table.getBackground());
309         setBackground(table.getBackground());
310         psheet.setMarginColor(PropUtils.getSetRendererColor());
311
312         psheet.add(table);
313         add(psheet, BorderLayout.CENTER);
314
315         table.setBorder(BorderFactory.createEmptyBorder());
316
317         setDescriptionVisible(showDesc);
318         setMinimumSize(new Dimension JavaDoc(100, 50));
319         psheet.setEmptyString(NbBundle.getMessage(PropertySheet.class, "CTL_NoProperties")); //NOI18N
320

321         TabSelectionListener listener = new TabSelectionListener();
322
323         psheet.addSelectionChangeListener(listener);
324
325         table.addChangeListener(listener);
326
327         try {
328             setSortingMode(PropUtils.getSavedSortOrder());
329         } catch (PropertyVetoException JavaDoc e) {
330             //Should never happen unless someone manually modifies
331
//backing storage
332
Exceptions.printStackTrace(e);
333         }
334     }
335
336     /** Enable/disable display of the description area */
337     void setDescriptionVisible(boolean val) {
338         if (isDescriptionVisible() != val) {
339             int state = psheet.getState();
340
341             if (!val) {
342                 int newState = ((state & PSheet.STATE_HAS_TABS) != 0) ? PSheet.STATE_HAS_TABS : 0;
343
344                 psheet.setState(newState);
345             } else {
346                 int newState = ((state & PSheet.STATE_HAS_TABS) != 0)
347                     ? (PSheet.STATE_HAS_TABS | PSheet.STATE_HAS_DESCRIPTION) : PSheet.STATE_HAS_DESCRIPTION;
348
349                 psheet.setState(newState);
350             }
351
352             PropUtils.saveShowDescription(val);
353         }
354     }
355
356     boolean isDescriptionVisible() {
357         return (psheet.getState() & PSheet.STATE_HAS_DESCRIPTION) != 0;
358     }
359
360     /** Overridden to route focus requests to the table */
361     public void requestFocus() {
362         if (table.getParent() != null) {
363             table.requestFocus();
364         } else {
365             super.requestFocus();
366         }
367     }
368
369     /** Overridden to route focus requests to the table */
370     public boolean requestFocusInWindow() {
371         if (table.getParent() != null) {
372             return table.requestFocusInWindow();
373         } else {
374             return super.requestFocusInWindow();
375         }
376     }
377
378     /**
379      * Set the nodes explored by this property sheet.
380      *
381      * @param nodes nodes to be explored
382      */

383     private void doSetNodes(Node[] nodes) {
384         if ((nodes == null) || (nodes.length == 0)) {
385             table.getPropertySetModel().setPropertySets(null);
386             table.getReusablePropertyEnv().clear();
387             return;
388         }
389
390         final Node n = (nodes.length == 1) ? nodes[0] : new ProxyNode(nodes);
391         setCurrentNode(n);
392     }
393
394     /**Set the nodes explored by this property sheet.
395      * @param nodes nodes to be explored or null to clear the sheet
396      */

397     public synchronized void setNodes(Node[] nodes) {
398         final boolean loggable = PropUtils.isLoggable(PropertySheet.class);
399
400         if (loggable) {
401             PropUtils.log(PropertySheet.class, "SetNodes " + Arrays.asList(nodes));
402         }
403
404         //Performance - check equality and avoid some extra repaints - repainting
405
//the property sheet can be expensive
406
if ((nodes != null) && (nodes.length > 0) && (pclistener != null)) {
407             if ((nodes.length == 1) && (nodes[0] == pclistener.getNode())) {
408                 if (loggable) {
409                     PropUtils.log(PropertySheet.class, " Same node selected as before; no redisplay needed");
410                 }
411
412                 return;
413             } else if (pclistener.getNode() instanceof ProxyNode) {
414                 if (loggable) {
415                     PropUtils.log(PropertySheet.class, " Selected node is a proxy node - comparing contents.");
416                 }
417
418                 Node[] currNodes = ((ProxyNode) pclistener.getNode()).getOriginalNodes();
419
420                 if (Arrays.asList(nodes).equals(Arrays.asList(currNodes))) {
421                     if (loggable) {
422                         PropUtils.log(
423                             PropertySheet.class,
424                             " Proxy node represents the same " + "nodes already showing. Showing: " +
425                             Arrays.asList(currNodes) + " requested " + Arrays.asList(nodes)
426                         );
427
428                         HashSet JavaDoc<Node> currs = new HashSet JavaDoc<Node>(Arrays.asList(currNodes));
429                         HashSet JavaDoc<Node> reqs = new HashSet JavaDoc<Node>(Arrays.asList(nodes));
430
431                         if (currs.size() != currNodes.length) {
432                             PropUtils.log(
433                                 PropertySheet.class,
434                                 " A hashSet of the current nodes does NOT have the same number " +
435                                 " of elements as the array of current nodes! Check " +
436                                 "your hashCode()/equals() contract. One or more nodes in " +
437                                 "the array are claiming to be the same node."
438                             );
439                         }
440
441                         if (reqs.size() != nodes.length) {
442                             PropUtils.log(
443                                 PropertySheet.class,
444                                 " A hashSet of the requested selected nodes does NOT have the same number " +
445                                 " of elements as the array of current nodes! Check your hashCode()/equals() contract" +
446                                 " One or more nodes in the array are claiming to be the same node."
447                             );
448                         }
449                     }
450
451                     return;
452                 }
453             }
454         } else if ((nodes == null) || (nodes.length == 0)) {
455             if (pclistener != null) {
456                 pclistener.detach();
457             }
458
459             if (SwingUtilities.isEventDispatchThread()) {
460                 if (loggable) {
461                     PropUtils.log(PropertySheet.class, " Nodes cleared on event queue. Emptying model.");
462                 }
463
464                 table.getPropertySetModel().setPropertySets(null);
465                 table.getReusablePropertyEnv().clear();
466             } else {
467                 SwingUtilities.invokeLater(
468                     new Runnable JavaDoc() {
469                         public void run() {
470                             if (loggable) {
471                                 PropUtils.log(
472                                     PropertySheet.class,
473                                     " Nodes " + "cleared off event queue. Empty model later on EQ."
474                                 );
475                             }
476
477                             table.getPropertySetModel().setPropertySets(null);
478                             table.getReusablePropertyEnv().clear();
479                         }
480                     }
481                 );
482             }
483
484             return;
485         }
486
487         RequestProcessor.Task task = getScheduleTask();
488         helperNodes = nodes;
489
490         //Clear any saved node if setNodes is called while we're offscreen
491
storedNode = null;
492
493         if (task.equals(initTask)) {
494             //if task is only init task then set nodes immediatelly
495
scheduleTask.schedule(0);
496             task.schedule(INIT_DELAY);
497         } else {
498             // in a task run then increase delay and reschedule task
499
int delay = task.getDelay() * 2;
500
501             if (delay > MAX_DELAY) {
502                 delay = MAX_DELAY;
503             }
504
505             if (delay < INIT_DELAY) {
506                 delay = INIT_DELAY;
507             }
508
509             if (loggable) {
510                 PropUtils.log(PropertySheet.class, " Scheduling delayed update of selected nodes.");
511             }
512
513             task.schedule(delay);
514         }
515     }
516
517     private synchronized RequestProcessor.Task getScheduleTask() {
518         if (scheduleTask == null) {
519             scheduleTask = RequestProcessor.getDefault().post(
520                     new Runnable JavaDoc() {
521                         public void run() {
522                             final Node[] nodes = helperNodes;
523                             SwingUtilities.invokeLater(
524                                 new Runnable JavaDoc() {
525                                     public void run() {
526                                         final boolean loggable = PropUtils.isLoggable(PropertySheet.class);
527
528                                         if (loggable) {
529                                             PropUtils.log(
530                                                 PropertySheet.class,
531                                                 "Delayed " + "updater setting nodes to " + Arrays.asList(nodes)
532                                             );
533                                         }
534
535                                         doSetNodes(nodes);
536                                     }
537                                 }
538                             );
539                         }
540                     }
541                 );
542             initTask = RequestProcessor.getDefault().post(new Runnable JavaDoc() {
543                         public void run() {
544                         }
545                     }
546                 );
547         }
548
549         // if none task runs then return initTask to wait for next changes
550
if (initTask.isFinished() && scheduleTask.isFinished()) {
551             return initTask;
552         }
553
554         // if some task runs then return schedule task which will set nodes
555
return scheduleTask;
556     }
557
558     // end of delayed
559

560     /** This has to be called from the AWT thread. */
561     void setCurrentNode(Node node) {
562         Node old = pclistener.getNode();
563
564         if (old != node) {
565             psheet.storeScrollAndTabInfo();
566         }
567
568         final boolean loggable = PropUtils.isLoggable(PropertySheet.class);
569
570         if (loggable) {
571             PropUtils.log(PropertySheet.class, "SetCurrentNode:" + node);
572         }
573
574         // table.setNode (node);
575
PropertySetModel psm = table.getPropertySetModel();
576         Node.PropertySet[] ps = node.getPropertySets();
577
578         //bloc below copied from original impl - is this common/needed?
579
if (ps == null) {
580             // illegal node behavior => log warning about it
581
Logger.getAnonymousLogger().warning("Node " + node + ": getPropertySets() returns null!"); // NOI18N
582
ps = new Node.PropertySet[] { };
583
584             //Prepare the reusable model/env's node
585
}
586
587         table.getReusablePropertyEnv().setNode(node);
588
589         assert noNullPropertyLists(ps) : "Node " + node + " returns null from getProperties() for one or " +
590         "more of its property sets"; //NOI18N
591

592         if (table.isEditing()) {
593             table.removeEditor();
594         }
595
596         boolean usingTabs = needTabs(node);
597
598         if (usingTabs) {
599             psheet.setState(psheet.getState() | PSheet.STATE_HAS_TABS);
600
601             TabInfo info = getTabItems(node);
602
603             psheet.setTabbedContainerItems(info.sets, info.titles);
604             psheet.manager().setCurrentNodeName(node.getName());
605             psm.setPropertySets(info.getSets(0));
606         } else {
607             psm.setPropertySets(ps);
608             psheet.setState(
609                 ((psheet.getState() & PSheet.STATE_HAS_DESCRIPTION) != 0) ? PSheet.STATE_HAS_DESCRIPTION : 0
610             );
611             psheet.setTabbedContainerItems(new Object JavaDoc[0], new String JavaDoc[0]);
612         }
613
614         psheet.adjustForName(node.getName());
615
616         table.setBeanName(node.getDisplayName());
617
618         String JavaDoc description = (String JavaDoc) node.getValue("nodeDescription"); //NOI18N
619

620         psheet.setDescription(node.getDisplayName(), (description == null) ? node.getShortDescription() : description);
621
622         pclistener.attach(node);
623
624         if (isDescriptionVisible()) {
625             helpAction.checkContext();
626         }
627     }
628
629     private boolean noNullPropertyLists(PropertySet[] ps) {
630         boolean result = true;
631
632         for (int i = 0; i < ps.length; i++) {
633             result &= (ps[i].getProperties() != null);
634
635             if (!result) {
636                 break;
637             }
638         }
639
640         return result;
641     }
642
643     /**Deprecated, does nothing.
644      * @param style Irrelevant
645      * @deprecated Relic of the original property sheet implementation. Does nothing.*/

646     public @Deprecated JavaDoc void setPropertyPaintingStyle(int style) {
647     }
648
649     /**Deprecated, returns no meaningful value.
650      * @return the mode
651      * @see #setPropertyPaintingStyle
652      * @deprecated Relic of the original property sheet implementation. Does nothing. */

653     public @Deprecated JavaDoc int getPropertyPaintingStyle() {
654         return 0;
655     }
656
657     /**
658      * Set the sorting mode.
659      * @param sortingMode one of {@link #UNSORTED} or {@link #SORTED_BY_NAMES}. {@link #SORTED_BY_TYPES} is
660      * no longer supported.
661      * @throws PropertyVetoException if a value other than one of the defined sorting modes is set
662      */

663     public void setSortingMode(int sortingMode) throws PropertyVetoException JavaDoc {
664         try {
665             table.getPropertySetModel().setComparator(PropUtils.getComparator(sortingMode));
666             this.sortingMode = sortingMode;
667             psheet.setMarginPainted(!PropUtils.neverMargin && (getSortingMode() == UNSORTED));
668             PropUtils.putSortOrder(sortingMode);
669         } catch (IllegalArgumentException JavaDoc iae) {
670             throw new PropertyVetoException JavaDoc(
671                 NbBundle.getMessage(PropertySheet.class, "EXC_Unknown_sorting_mode"),
672                 new PropertyChangeEvent JavaDoc(this, PROPERTY_SORTING_MODE, new Integer JavaDoc(0), new Integer JavaDoc(sortingMode))
673             ); //NOI18N
674
}
675     }
676
677     /**Get the sorting mode.
678      * @return the mode
679      * @see #setSortingMode */

680     public int getSortingMode() {
681         return sortingMode;
682     }
683
684     /** Deprecated. Does nothing.
685      * @param index index of the page to select
686      * @deprecated Relic of the original property sheet implementation. Does nothing.
687      */

688     public @Deprecated JavaDoc void setCurrentPage(int index) {
689     }
690
691     /**
692      * Deprecated. Does nothing.
693      * @deprecated Relic of the original property sheet implementation. Does nothing.
694      * @param str name of the tab to select
695      * @return always returns false
696      */

697     public @Deprecated JavaDoc boolean setCurrentPage(String JavaDoc str) {
698         return false;
699     }
700
701     /**Deprecated. Does nothing.
702      * @return index of currently selected page
703      * @deprecated Relic of the original property sheet implementation. Does nothing. */

704     public @Deprecated JavaDoc int getCurrentPage() {
705         // return pages.getSelectedIndex ();
706
return 0;
707     }
708
709     /**Deprecated. Does nothing.
710      * @param plastic true if so
711      * @deprecated Relic of the original property sheet implementation. Display of properties
712      * is handled by the look and feel.
713      */

714     public @Deprecated JavaDoc void setPlastic(boolean plastic) {
715     }
716
717     /**Test whether buttons in sheet are plastic.
718      * @return <code>true</code> if so
719      * @deprecated Relic of the original property sheet implementation. Does nothing.*/

720     public @Deprecated JavaDoc boolean getPlastic() {
721         return false;
722     }
723
724     /**Deprecated. Does nothing.
725      * @param color the new color
726      * @deprecated Relic of the original property sheet implementation. Display of properties
727      * is handled by the look and feel. */

728     public @Deprecated JavaDoc void setValueColor(Color JavaDoc color) {
729     }
730
731     /**Deprecated. Does nothing.
732      * @deprecated Relic of the original property sheet implementation. Display of properties
733      * is handled by the look and feel.
734      * @return the color */

735     public @Deprecated JavaDoc Color JavaDoc getValueColor() {
736         return Color.BLACK;
737     }
738
739     /**Deprecated. Does nothing.
740      * @deprecated Relic of the original property sheet implementation. Does nothing.
741      * @param color the new color */

742     public @Deprecated JavaDoc void setDisabledPropertyColor(Color JavaDoc color) {
743     }
744
745     /**Deprecated. Does not return a meaningful value.
746      * @deprecated Relic of the original property sheet implementation. Display of properties
747      * is handled by the look and feel.
748      * @return the color */

749     public @Deprecated JavaDoc Color JavaDoc getDisabledPropertyColor() {
750         return Color.GRAY;
751     }
752
753     /**Deprecated. Does nothing.
754      * @param b <code>true</code> if this is desired
755      * @deprecated Relic of the original property sheet implementation. Does nothing.*/

756     public @Deprecated JavaDoc void setDisplayWritableOnly(boolean b) {
757     }
758
759     /**Deprecated. Does not return a meaningful value.
760      * @deprecated Relic of the original property sheet implementation. Does nothing.
761      * @return <code>true</code> if so */

762     public @Deprecated JavaDoc boolean getDisplayWritableOnly() {
763         return false;
764     }
765
766     final void showPopup(Point JavaDoc p) {
767         JMenuItem JavaDoc helpItem = new JMenuItem JavaDoc();
768         JRadioButtonMenuItem JavaDoc sortNamesItem = new JRadioButtonMenuItem JavaDoc();
769         JRadioButtonMenuItem JavaDoc unsortedItem = new JRadioButtonMenuItem JavaDoc();
770         JCheckBoxMenuItem JavaDoc descriptionItem = new JCheckBoxMenuItem JavaDoc();
771         JMenuItem JavaDoc defaultValueItem = new JMenuItem JavaDoc();
772         JPopupMenu JavaDoc popup = new JPopupMenu JavaDoc();
773
774         unsortedItem.setSelected(getSortingMode() == UNSORTED);
775         sortNamesItem.setSelected(getSortingMode() == SORTED_BY_NAMES);
776         helpAction.checkContext();
777         helpItem.setAction(helpAction);
778         sortNamesItem.setAction(new MutableAction(MutableAction.SORT_NAMES, this));
779         unsortedItem.setAction(new MutableAction(MutableAction.UNSORT, this));
780         descriptionItem.setAction(new MutableAction(MutableAction.SHOW_DESCRIPTION, this));
781         descriptionItem.setSelected(isDescriptionVisible());
782         defaultValueItem.setAction(new MutableAction(MutableAction.RESTORE_DEFAULT, this));
783
784         FeatureDescriptor JavaDoc fd = table.getSelection();
785         defaultValueItem.setEnabled(PropUtils.shallBeRDVEnabled(fd));
786
787         popup.add(unsortedItem);
788         popup.add(sortNamesItem);
789         popup.add(new JSeparator JavaDoc());
790         popup.add(descriptionItem);
791         popup.add(new JSeparator JavaDoc());
792         popup.add(defaultValueItem);
793         popup.add(new JSeparator JavaDoc());
794         popup.add(helpItem);
795         popup.show(psheet, p.x, p.y);
796     }
797
798     Node[] getCurrentNodes() {
799         Node n = pclistener.getNode();
800
801         if (n != null) {
802             if (n instanceof ProxyNode) {
803                 return ((ProxyNode) n).getOriginalNodes();
804             } else {
805                 return new Node[] { n };
806             }
807         }
808
809         return new Node[0];
810     }
811
812     private static final boolean needTabs(Node n) {
813         boolean needTabs = true;
814
815         if (forceTabs) {
816             return true;
817         }
818
819         if (n instanceof ProxyNode) {
820             Node[] nodes = ((ProxyNode) n).getOriginalNodes();
821
822             for (int i = 0; i < nodes.length; i++) {
823                 assert nodes[i] != n : "Proxy node recursively references itself"; //NOI18N
824
needTabs &= needTabs(nodes[i]);
825
826                 if (!needTabs) {
827                     break;
828                 }
829             }
830         } else {
831             PropertySet[] ps = n.getPropertySets();
832             needTabs = forceTabs ? (ps.length > 1) : (neverTabs ? false : false);
833
834             //neverTabs is a debugging option to force tab use one tab per property set
835
if (!neverTabs) {
836                 for (int i = 0; (i < ps.length) && !needTabs; i++) {
837                     needTabs |= (ps[i].getValue("tabName") != null); //NOI18N
838
}
839             }
840         }
841
842         return needTabs;
843     }
844
845     private static final TabInfo getTabItems(Node n) {
846         Map JavaDoc<String JavaDoc, List JavaDoc<PropertySet>> titlesToContents = new HashMap JavaDoc<String JavaDoc, List JavaDoc<PropertySet>>();
847         ArrayList JavaDoc<String JavaDoc> order = new ArrayList JavaDoc<String JavaDoc>();
848
849         PropertySet[] sets = n.getPropertySets();
850
851         for (int i = 0; i < sets.length; i++) {
852             String JavaDoc currTab = (String JavaDoc) sets[i].getValue("tabName"); //NOI18N
853

854             if (currTab == null) {
855                 currTab = PropUtils.basicPropsTabName();
856             }
857
858             List JavaDoc<PropertySet> l = titlesToContents.get(currTab);
859
860             if (l == null) {
861                 l = new ArrayList JavaDoc<PropertySet>();
862                 l.add(sets[i]);
863                 titlesToContents.put(currTab, l);
864             } else {
865                 l.add(sets[i]);
866             }
867
868             if (!order.contains(currTab)) {
869                 order.add(currTab);
870             }
871         }
872
873         String JavaDoc[] titles = new String JavaDoc[order.size()];
874         Object JavaDoc[] setSets = new Object JavaDoc[order.size()];
875         int count = 0;
876
877         for (Iterator JavaDoc<String JavaDoc> i = order.iterator(); i.hasNext();) {
878             titles[count] = i.next();
879
880             List JavaDoc<PropertySet> currSets = titlesToContents.get(titles[count]);
881             setSets[count] = new PropertySet[currSets.size()];
882             setSets[count] = currSets.toArray((PropertySet[]) setSets[count]);
883             count++;
884         }
885
886         return new TabInfo(titles, setSets);
887     }
888
889     public void firePropertyChange(String JavaDoc propertyName, boolean oldValue, boolean newValue) {
890         super.firePropertyChange(propertyName, oldValue, newValue);
891         // on macos we get this hint about focus lost..
892
if ("MACOSX".equals(propertyName)) {
893             this.table.focusLostCancel();
894         }
895     }
896
897     private class TabSelectionListener implements ChangeListener JavaDoc, FocusListener JavaDoc {
898         public void stateChanged(ChangeEvent JavaDoc e) {
899             helpAction.checkContext();
900
901             if (e.getSource() instanceof SheetTable) {
902                 SheetTable tbl = (SheetTable) e.getSource();
903                 FeatureDescriptor JavaDoc fd = tbl.getSelection();
904                 Component JavaDoc focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getPermanentFocusOwner();
905
906                 if ((focusOwner != tbl) && !tbl.isKnownComponent(focusOwner) && !isAncestorOf(focusOwner)) {
907                     fd = null;
908                 }
909
910                 if (fd != null) {
911                     String JavaDoc ttl = fd.getDisplayName();
912                     String JavaDoc desc = fd.getShortDescription();
913                     psheet.setDescription(ttl, desc);
914                 } else {
915                     Node n = pclistener.getNode();
916
917                     if (n != null) {
918                         String JavaDoc ttl = n.getDisplayName();
919                         String JavaDoc desc = (String JavaDoc) n.getValue("nodeDescription"); //NOI18N
920

921                         if (desc == null) {
922                             desc = n.getShortDescription();
923                         }
924
925                         psheet.setDescription(ttl, desc);
926                     } else {
927                         psheet.setDescription(null, null);
928                     }
929                 }
930             } else {
931                 if (!psheet.isAdjusting()) {
932                     psheet.storeScrollAndTabInfo();
933                 }
934
935                 PropertySet[] sets = (PropertySet[]) psheet.getTabbedContainerSelection();
936
937                 if (sets != null) {
938                     table.getPropertySetModel().setPropertySets(sets);
939
940                     if ((sets.length > 0) && !psheet.isAdjusting()) {
941                         String JavaDoc tab = (String JavaDoc) sets[0].getValue("tabName"); //NOI18N
942
tab = (tab == null) ? PropUtils.basicPropsTabName() : tab;
943                         psheet.manager().storeLastSelectedGroup(tab);
944                         psheet.adjustForName(tab);
945                     }
946                 }
947             }
948         }
949
950         public void focusGained(FocusEvent JavaDoc e) {
951             ChangeEvent JavaDoc ce = new ChangeEvent JavaDoc(table);
952             stateChanged(ce);
953         }
954
955         public void focusLost(FocusEvent JavaDoc e) {
956             focusGained(e);
957         }
958     }
959
960     final class HelpAction extends AbstractAction JavaDoc {
961         HelpCtx.Provider provider = null;
962
963         //XXX MERGE THIS CLASS WITH PROXYHELPPROVIDER
964
private boolean wasEnabled = false;
965
966         public HelpAction() {
967             super(NbBundle.getMessage(PropertySheet.class, "CTL_Help")); //NOI18N
968
checkContext();
969         }
970
971         public void checkContext() {
972             HelpCtx ctx = getContext();
973             boolean enabled = ctx != null;
974
975             if (enabled != wasEnabled) {
976                 firePropertyChange(
977                     "enabled", enabled ? Boolean.FALSE : Boolean.TRUE, enabled ? Boolean.TRUE : Boolean.FALSE
978                 ); //NOI18N
979
}
980
981             wasEnabled = enabled;
982             psheet.setHelpEnabled(enabled);
983         }
984
985         public boolean isEnabled() {
986             return getContext() != null;
987         }
988
989         public void actionPerformed(ActionEvent JavaDoc e) {
990             HelpCtx ctx = getContext();
991
992             if (ctx == null) {
993                 Toolkit.getDefaultToolkit().beep();
994
995                 return;
996             }
997
998             try {
999                 //Copied from original property sheet implementation
1000
Class JavaDoc<?> c = Lookup.getDefault().lookup(ClassLoader JavaDoc.class).loadClass(
1001                        "org.netbeans.api.javahelp.Help"
1002                    ); // NOI18N
1003

1004                Object JavaDoc o = Lookup.getDefault().lookup(c);
1005
1006                if (o != null) {
1007                    Method JavaDoc m = c.getMethod("showHelp", // NOI18N
1008
new Class JavaDoc[] { HelpCtx.class }
1009                        );
1010
1011                    if (m != null) { //Unit tests
1012
m.invoke(o, new Object JavaDoc[] { ctx });
1013                    }
1014
1015                    return;
1016                }
1017            } catch (ClassNotFoundException JavaDoc cnfe) {
1018                // ignore - maybe javahelp module is not installed, not so strange
1019
} catch (Exception JavaDoc ee) {
1020                // potentially more serious
1021
Logger.getLogger(PropertySheet.class.getName()).log(Level.WARNING, null, ee);
1022            }
1023
1024            // Did not work.
1025
Toolkit.getDefaultToolkit().beep();
1026        }
1027
1028        public HelpCtx getContext() {
1029            FeatureDescriptor JavaDoc fd = (FeatureDescriptor JavaDoc) table.getSelection();
1030            String JavaDoc id = null;
1031
1032            //First look on the individual property
1033
if ((fd != null) && fd instanceof Node.Property) {
1034                id = (String JavaDoc) fd.getValue("helpID"); //NOI18N
1035
}
1036
1037            if (id == null) {
1038                if ((psheet.getState() & PSheet.STATE_HAS_TABS) != 0) {
1039                    //If we're in a tabbed pane, we want the first visible
1040
//property set's help id
1041
Node.PropertySet[] ps = (Node.PropertySet[]) psheet.getTabbedContainerSelection();
1042
1043                    if ((ps != null) && (ps.length > 0)) {
1044                        id = (String JavaDoc) ps[0].getValue("helpID"); //NOI18N
1045
}
1046                } else if ((id == null) && (pclistener != null)) {
1047                    //Otherwise, look for the first property set on the node
1048
Node n = pclistener.getNode();
1049
1050                    if (n == null) {
1051                        return null;
1052                    }
1053
1054                    Node.PropertySet[] ps = n.getPropertySets();
1055
1056                    if ((fd != null) && (ps != null) && (ps.length > 0)) {
1057                        for (int i = 0; i < ps.length; i++) {
1058                            if ((ps[i] == fd) || Arrays.asList(ps[i].getProperties()).contains(fd)) {
1059                                id = (String JavaDoc) ps[i].getValue("helpID"); //NOI18N
1060

1061                                break;
1062                            }
1063                        }
1064                    }
1065                }
1066
1067                //Then look on the first property set
1068
if ((id == null) && (pclistener != null)) {
1069                    Node[] nodes = getCurrentNodes();
1070
1071                    if ((nodes != null) && (nodes.length > 0)) {
1072                        for (int i = 0; i < nodes.length; i++) {
1073                            // Then try to find a property-sheet specific id on
1074
// the Node
1075
id = (String JavaDoc) nodes[i].getValue("propertiesHelpID"); //NOI18N
1076

1077                            if (id != null) {
1078                                break;
1079                            }
1080
1081                            // Then try to find if node doesn't return help
1082
// context directly
1083
HelpCtx ctx = nodes[i].getHelpCtx();
1084
1085                            if ((ctx != null) && (ctx != HelpCtx.DEFAULT_HELP)) {
1086                                return ctx;
1087                            }
1088                        }
1089                    }
1090                }
1091            }
1092
1093            if ((id != null) && !HelpCtx.DEFAULT_HELP.getHelpID().equals(id)) {
1094                return new HelpCtx(id);
1095            } else {
1096                return null;
1097            }
1098        }
1099    }
1100
1101    /**
1102     * Convenience action class to eliminate a few action subclasses.
1103     */

1104    private static class MutableAction extends AbstractAction JavaDoc {
1105        private static final int SORT_NAMES = 0;
1106        private static final int UNSORT = 1;
1107        private static final int INVOKE_POPUP = 2;
1108        private static final int SHOW_DESCRIPTION = 3;
1109        private static final int SHOW_HELP = 4;
1110        private static final int RESTORE_DEFAULT = 5;
1111        private final int id;
1112        private final PropertySheet sheet;
1113
1114        public MutableAction(int id, PropertySheet sheet) {
1115            this.id = id;
1116            this.sheet = sheet;
1117
1118            String JavaDoc nameKey = null;
1119
1120            switch (id) {
1121            case SORT_NAMES:
1122                nameKey = "CTL_AlphaSort"; //NOI18N
1123

1124                break;
1125
1126            case UNSORT:
1127                nameKey = "CTL_NoSort"; //NOI18N
1128

1129                break;
1130
1131            case INVOKE_POPUP:
1132                break;
1133
1134            case SHOW_DESCRIPTION:
1135                nameKey = "CTL_ShowDescription"; //NOI18N
1136

1137                break;
1138
1139            case SHOW_HELP:
1140                break;
1141
1142            case RESTORE_DEFAULT:
1143                nameKey = "CTL_RestoreDefaultValue"; //NOI18N
1144

1145                break;
1146
1147            default:
1148                throw new IllegalArgumentException JavaDoc(Integer.toString(id));
1149            }
1150
1151            if (nameKey != null) {
1152                putValue(Action.NAME, NbBundle.getMessage(PropertySheet.class, nameKey));
1153            }
1154        }
1155
1156        public void actionPerformed(ActionEvent JavaDoc ae) {
1157            switch (id) {
1158            case SORT_NAMES:
1159
1160                try {
1161                    sheet.setSortingMode(SORTED_BY_NAMES);
1162                } catch (PropertyVetoException JavaDoc pve) {
1163                    //can't happen
1164
}
1165
1166                break;
1167
1168            case UNSORT:
1169
1170                try {
1171                    sheet.setSortingMode(UNSORTED);
1172                } catch (PropertyVetoException JavaDoc pve) {
1173                    //can't happen
1174
}
1175
1176                break;
1177
1178            case INVOKE_POPUP:
1179                sheet.showPopup(new Point JavaDoc(0, 0));
1180
1181                break;
1182
1183            case SHOW_DESCRIPTION:
1184                sheet.setDescriptionVisible(!sheet.isDescriptionVisible());
1185
1186                break;
1187
1188            case SHOW_HELP:
1189                break;
1190
1191            case RESTORE_DEFAULT:
1192
1193                try {
1194                    // no need to use instanceof check since this action is
1195
// not accessible if a selection is not a Node.Property
1196
// instance
1197
((Node.Property) sheet.table.getSelection()).restoreDefaultValue();
1198                } catch (IllegalAccessException JavaDoc iae) {
1199                    throw (IllegalStateException JavaDoc) new IllegalStateException JavaDoc("Error restoring default value").initCause(iae);
1200                } catch (InvocationTargetException JavaDoc ite) {
1201                    throw (IllegalStateException JavaDoc) new IllegalStateException JavaDoc("Error restoring defaul value").initCause(ite);
1202                }
1203
1204                break;
1205
1206            default:
1207                throw new IllegalArgumentException JavaDoc(Integer.toString(id));
1208            }
1209        }
1210
1211        public boolean isEnabled() {
1212            if ((id == INVOKE_POPUP) && Boolean.TRUE.equals(sheet.getClientProperty("disablePopup"))) {
1213                return false;
1214            }
1215
1216            return super.isEnabled();
1217        }
1218    }
1219
1220    private final class SheetPCListener extends NodeAdapter {
1221        private PropertyChangeListener JavaDoc inner;
1222
1223        /** Cache the current node locally only in the listener */
1224        private Node currNode;
1225
1226        public SheetPCListener() {
1227            inner = new PCL();
1228        }
1229
1230        /** Attach to a node, detaching from the last one if non-null. */
1231        public void attach(Node n) {
1232            if (currNode != n) {
1233                if (currNode != null) {
1234                    detach();
1235                }
1236
1237                if (n != null) {
1238                    n.addPropertyChangeListener(inner);
1239                    n.addNodeListener(this);
1240
1241                    if (PropUtils.isLoggable(PropertySheet.class)) {
1242                        PropUtils.log(PropertySheet.class, "Now listening for changes on " + n);
1243                    }
1244                }
1245
1246                currNode = n;
1247            }
1248        }
1249
1250        public Node getNode() {
1251            return currNode;
1252        }
1253
1254        public Node detach() {
1255            Node n = currNode;
1256
1257            if (n != null) {
1258                if (PropUtils.isLoggable(PropertySheet.class)) {
1259                    PropUtils.log(PropertySheet.class, "Detaching listeners from " + n);
1260                }
1261
1262                n.removePropertyChangeListener(inner);
1263                n.removeNodeListener(this);
1264
1265                //clear the reference
1266
currNode = null;
1267            }
1268
1269            return n;
1270        }
1271
1272        /** Receives property change events directed to the NodeListener */
1273        public void propertyChange(PropertyChangeEvent JavaDoc evt) {
1274            String JavaDoc nm = evt.getPropertyName();
1275
1276            if (Node.PROP_PROPERTY_SETS.equals(nm)) {
1277                final Node n = (Node) evt.getSource();
1278                Mutex.EVENT.readAccess(
1279                    new Runnable JavaDoc() {
1280                        public void run() {
1281                            attach(n);
1282                            setCurrentNode(n);
1283                        }
1284                    }
1285                );
1286            } else if (
1287                Node.PROP_COOKIE.equals(nm) || //weed out uninteresting property changes
1288
Node.PROP_ICON.equals(nm) || Node.PROP_PARENT_NODE.equals(nm) || Node.PROP_OPENED_ICON.equals(nm) ||
1289                    Node.PROP_LEAF.equals(nm)
1290            ) {
1291                return;
1292            } else if (
1293                isDescriptionVisible() &&
1294                    (Node.PROP_DISPLAY_NAME.equals(nm) || Node.PROP_SHORT_DESCRIPTION.equals(nm))
1295            ) {
1296                //XXX SHOULD NOT BE FIRED TO NODELISTENERS
1297
Node n = (Node) evt.getSource();
1298
1299                /* fallbackTitle = n.getDisplayName();
1300                                fallbackDescription = n.getShortDescription();
1301                                if (infoPanel != null) {
1302                                    table.fireChange();
1303                                    infoPanel.getBottomComponent().repaint();
1304                                }
1305                                */

1306            }
1307             /*else {
1308              if (evt.getPropertyName() == null) {
1309                  //Trigger rebuilding the entire list of properties, probably
1310                  //one has been added or removed
1311                  setCurrentNode(currNode);
1312              }
1313            }
1314             */

1315        }
1316
1317        public void nodeDestroyed(org.openide.nodes.NodeEvent ev) {
1318            detach();
1319            Mutex.EVENT.readAccess(
1320                new Runnable JavaDoc() {
1321                    public void run() {
1322                        doSetNodes(null);
1323                    }
1324                }
1325            );
1326        }
1327
1328        private final class PCL implements PropertyChangeListener JavaDoc {
1329            /** Receives property change events directed to PropertyChangeListeners,
1330             * not NodeListeners */

1331            public void propertyChange(final PropertyChangeEvent JavaDoc evt) {
1332                SwingUtilities.invokeLater(new Runnable JavaDoc() {
1333                    public void run() {
1334                        String JavaDoc nm = evt.getPropertyName();
1335                        /*
1336                        if (Node.PROP_COOKIE.equals(nm) || // weed out frequently abused property changes
1337                                Node.PROP_ICON.equals(nm) || Node.PROP_PARENT_NODE.equals(nm) ||
1338                                Node.PROP_OPENED_ICON.equals(nm) || Node.PROP_LEAF.equals(nm)) {
1339                            ErrorManager.getDefault().log(
1340                                    ErrorManager.WARNING,
1341                                    "Recived bogus property change " + nm + " from " + evt.getSource() + // NOI18N
1342                                    ". This should ony be fired to" + // NOI18N
1343                                    "NodeListeners, not general property change listeners"); // NOI18N
1344                        } else if (isDescriptionVisible() &&
1345                                (Node.PROP_DISPLAY_NAME.equals(nm) || Node.PROP_SHORT_DESCRIPTION.equals(nm))) {
1346                            Node n = (Node) evt.getSource();
1347                            /*
1348                            fallbackTitle = n.getDisplayName();
1349                            fallbackDescription = n.getShortDescription();
1350                            if (infoPanel != null) {
1351                                table.fireChange();
1352                                infoPanel.getBottomComponent().repaint();
1353                            }
1354                            
1355                        } else
1356                         */

1357                        if (nm == null) {
1358                            if (currNode != null) {
1359                                setCurrentNode(currNode);
1360                            }
1361                        } else {
1362                            table.repaintProperty(nm);
1363                        }
1364                    }
1365                });
1366            }
1367        }
1368    }
1369    
1370    private static final class TabInfo {
1371        public String JavaDoc[] titles;
1372        public Object JavaDoc[] sets;
1373
1374        public TabInfo(String JavaDoc[] titles, Object JavaDoc[] sets) {
1375            this.titles = titles;
1376            this.sets = sets;
1377        }
1378
1379        public PropertySet[] getSets(int i) {
1380            return (PropertySet[]) sets[i];
1381        }
1382    }
1383}
1384
Popular Tags