KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > api > nodes2looks > LookNode


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
20 package org.netbeans.api.nodes2looks;
21
22 import java.awt.Component JavaDoc;
23 import java.awt.Image JavaDoc;
24 import java.awt.datatransfer.Transferable JavaDoc;
25 import java.beans.BeanInfo JavaDoc;
26 import java.io.IOException JavaDoc;
27 import java.lang.ref.WeakReference JavaDoc;
28 import java.util.ArrayList JavaDoc;
29 import java.util.Enumeration JavaDoc;
30 import java.util.List JavaDoc;
31 import java.util.Collection JavaDoc;
32 import java.util.Iterator JavaDoc;
33 import javax.swing.Action JavaDoc;
34 import org.netbeans.modules.looks.LookListener;
35 import org.netbeans.modules.looks.LookEvent;
36 import org.netbeans.spi.looks.Look;
37 import org.netbeans.spi.looks.LookSelector;
38 import org.netbeans.spi.looks.Looks;
39 import org.netbeans.spi.looks.Selectors;
40 import org.openide.ErrorManager;
41 import org.openide.nodes.Children;
42 import org.openide.nodes.DefaultHandle;
43 import org.openide.nodes.Node;
44 import org.openide.cookies.InstanceCookie;
45 import org.openide.util.HelpCtx;
46 import org.openide.util.Lookup;
47 import org.openide.util.Utilities;
48 import org.openide.util.actions.SystemAction;
49 import org.openide.util.datatransfer.NewType;
50 import org.openide.util.datatransfer.PasteType;
51 import org.openide.util.lookup.AbstractLookup;
52
53 /**
54  * Node that represents an object using Looks.
55  *
56  * @author Petr Hrebejk
57  */

58 final class LookNode extends Node implements Node.Cookie, InstanceCookie.Of {
59
60     /** Use this constant for returning empty NewTypes. */
61     private static final NewType[] NO_NEW_TYPES = {};
62
63     /** Use this constant for returning empty PasteTypes. */
64     private static final PasteType[] NO_PASTE_TYPES = {};
65
66     /** Use this constant for returning empty PropertySets. */
67     private static final Node.PropertySet[] NO_PROPERTY_SETS = {};
68     
69     /** Use this constant for returning empty Actions. */
70     private static final Action JavaDoc[] NO_ACTIONS = {};
71
72     /** Name of the default icon 16x16 */
73     private static final String JavaDoc DEFAULT_ICON_16_NAME =
74         "org/netbeans/modules/looks/resources/defaultNode.gif"; // NOI18N
75

76     /** Name of the default icon 32x32 */
77     private static final String JavaDoc DEFAULT_ICON_32_NAME =
78         "org/netbeans/modules/looks/resources/defaultNode32.gif"; //NOI18N
79

80     // LookDescriptor for this node. Describes the Look used on this
81
// node and the LookSelector used for this node's children
82
// private Look look;
83

84     // LookSelector for this node
85
// private LookSelector lookSelector;
86

87     // Lookup provider
88
private LookNodeLookupProvider lookupProvider;
89
90     // Currently used firer
91
private FirerImpl firer;
92
93     // Persistence cache
94
private Cache cache;
95
96     /** Creates new LookNode with The {@link Selectors#defaultTypes() Looks.defaultTypes()}
97      * will be used for this node.
98      * as associated look.
99      * @see Look#attachTo(java.lang.Object)
100      * @param representedObject The object which the node will represent.
101      */

102     public LookNode( Object JavaDoc representedObject ) {
103         this (representedObject, null, null );
104     }
105
106     /** Creates new LookNode.
107      * @see Look#attachTo(java.lang.Object)
108      * @param representedObject The object which the node will represent.
109      * @param look Explicit look which will be set on the node.
110      */

111     public LookNode (Object JavaDoc representedObject, Look look ) {
112         this ( representedObject, look, null );
113     }
114
115     /** Creates new LookNode.
116      * @see Look#attachTo(java.lang.Object)
117      * @param representedObject The object which the node will represent.
118      * @param look Explicit look which will be set on the node.
119      */

120     public LookNode (Object JavaDoc representedObject, Look look, LookSelector lookSelector ) {
121         this ( representedObject, look, lookSelector, null );
122     }
123
124     /** Creates new LookNode.
125      * @see Look#attachTo(java.lang.Object)
126      * @param representedObject The object which the node will represent.
127      * @param look Explicit look which will be set on the node.
128      * @param handle Node.Handle which will take care of the persistence.
129      */

130     public LookNode(Object JavaDoc representedObject, Look look, LookSelector lookSelector, Node.Handle handle ) {
131         this ( create( representedObject, look, lookSelector ) );
132         
133         if (handle != null) {
134             this.cache = new Cache(handle);
135         }
136         else {
137             this.cache = new Cache();
138         }
139     }
140     
141     /** Constructor used by LookChildren.
142      */

143     LookNode( Object JavaDoc representedObject, Look look, LookSelector lookSelector, Cache cache ) {
144         this ( create( representedObject, look, lookSelector ) );
145         this.cache = cache;
146     }
147
148
149     /** Private constructor
150      * @param params
151      * representedObject, // [0]
152      * children, // [1]
153      * look, // [2]
154      * lookSelector, // [3]
155      * lookup, // [4]
156      * placeholderListener,// [5]
157      */

158     private LookNode( Object JavaDoc[] params ) {
159         super( (Children)params[1], (Lookup)params[4] );
160         ((LookNodeLookupProvider)params[4]).setLookNode( this );
161         this.lookupProvider = (LookNodeLookupProvider)params[4];
162         this.firer = new FirerImpl( this, (LookSelector)params[3], (Look)params[2], params[0] );
163         org.netbeans.modules.looks.Accessor.DEFAULT.changeLookListener( getLook(), getRepresentedObject(), (LookListener)params[5], firer ); // Change the placehoder-listener to real listener
164
org.netbeans.modules.looks.Accessor.DEFAULT.addSelectorListener( getLookSelector(), firer); // Attach firer to listen on selector
165
}
166
167     /** Computes imporatant parameters of the look node
168      * Used in LookNode constructors and in setLookDescriptor method
169      */

170     private static Object JavaDoc[] create( Object JavaDoc representedObject,
171                                     Look look,
172                                     LookSelector lookSelector ) {
173
174         if (lookSelector == null) {
175             // If lookSelector is not specified use the default one
176
ErrorManager.getDefault ().log ("LookSelector is null, DefaultSelector is used."); // NOI18N
177
lookSelector = Selectors.defaultTypes ();
178         }
179         
180         LookListener placehoderListener = new PlaceholderLookListener();
181         
182         if ( look != null ) {
183             Exception JavaDoc e = tryAttach( look, representedObject, placehoderListener );
184             if ( e != null ) {
185                 ErrorManager.getDefault().notify( ErrorManager.INFORMATIONAL, e );
186                 look = null;
187             }
188         }
189         else {
190             look = findFirstLook( lookSelector, representedObject, placehoderListener );
191         }
192
193             
194         if ( look == null ) {
195             // Either the exploicitly set look did not accept the object or
196
// we did not find any suitable look in the LookSelector.
197
// We have to use default beans look.
198
Exception JavaDoc e = tryAttach( Looks.bean(), representedObject, placehoderListener );
199             if ( e != null ) {
200                 // Thats really bad the beanLook does not accept this object
201
throw new IllegalStateException JavaDoc( "BeanLook has to accept all objects " + representedObject );
202             }
203             else {
204                 look = Looks.bean();
205             }
206         }
207         
208         
209         // Lookup
210
Lookup lookup = new LookNodeLookupProvider ();
211
212         // Children
213
Children children = look.isLeaf( representedObject, lookup ) ? Children.LEAF : new LookChildren();
214
215         // Create and fill the results array
216
Object JavaDoc results[] = new Object JavaDoc[] {
217             representedObject, // [0]
218
children, // [1]
219
look, // [2]
220
lookSelector, // [3]
221
lookup, // [4]
222
placehoderListener // [5]
223
};
224
225         return results;
226     }
227
228
229     // General methods ---------------------------------------------------------
230

231     /** Gets the LookSelector for this node. LookSelector is used for determining
232      * looks for the node's subnodes. This methods is useful when using
233      * UI for switching looks.
234      * @return The LookSelector this node currently uses.
235      */

236     public final LookSelector getLookSelector() {
237         return firer.lookSelector;
238     }
239
240     /** Returns represented object which this LookNode represents. This is the
241      * same object which can be accessed by calling
242      * @return The object represented by this node.
243      */

244     public synchronized Object JavaDoc getRepresentedObject() {
245         return firer.getRepresentedObject();
246     }
247
248     private final LookNodeLookupProvider getLookupProvider() {
249         return lookupProvider;
250     }
251
252     /** Sets the actual LookDescriptor for this node. After changing the
253      * LookDescriptor several property
254      * changes are fired:
255      * <CODE>PROP_COOKIE, PROP_NAME, PROP_NAME, PROP_DISPLAY_NAME, PROP_ICON,
256      * PROP_OPENED_ICON</CODE> and children are refreshed.
257      * @param look New LookDescriptor of the node.
258      */

259     public void setLook( Look look ) {
260
261         
262         
263         
264         // PENDING what to do when the selected look does not accept the object
265
synchronized ( this ) {
266             
267             LookListener placeholder = null;
268         
269             if ( look == null ) {
270                 // This means that we have to find new look in the selector
271
placeholder = new PlaceholderLookListener();
272                 look = findFirstLook( getLookSelector(), getRepresentedObject(), placeholder );
273                 if ( look == getLook() ) {
274                     org.netbeans.modules.looks.Accessor.DEFAULT.removeLookListener( getLook(), getRepresentedObject(), placeholder );
275                     return; // No need to do anything
276
}
277             }
278             
279             Object JavaDoc representedObject = getRepresentedObject();
280             FirerImpl oldFirer = firer;
281             LookSelector oldLookSelector = getLookSelector();
282             Look oldLook = getLook();
283                         
284             oldFirer.look = null; // Notify the old firer that i was
285
oldFirer.lookSelector = null; // explicitly removed from listeners lists
286
oldFirer.representedObject = null; // and look was detached
287
org.netbeans.modules.looks.Accessor.DEFAULT.removeSelectorListener( oldLookSelector, oldFirer );
288             org.netbeans.modules.looks.Accessor.DEFAULT.removeLookListener( oldLook, representedObject, oldFirer );
289
290             firer = new FirerImpl ( this, oldLookSelector, look, representedObject ); // Create new firer
291

292             this.lookupProvider.setDirty(); // Reset lookup on this node
293

294             if ( placeholder == null ) {
295                 org.netbeans.modules.looks.Accessor.DEFAULT.addLookListener( getLook(), getRepresentedObject(), firer ); // Attach the firer to listen on look
296
}
297             else {
298                 org.netbeans.modules.looks.Accessor.DEFAULT.changeLookListener( getLook(), getRepresentedObject(), placeholder, firer ); // Attach the firer to listen on look
299
}
300             org.netbeans.modules.looks.Accessor.DEFAULT.addSelectorListener ( getLookSelector(), firer);
301         }
302
303         // store the descriptor into the cache for pesistsnce
304
getCache().store( this );
305
306         // fire possible change notifications
307
fireCookieChange();
308         refreshChildren(true);
309         fireNameChange( null, null );
310         fireDisplayNameChange( null, null );
311         fireIconChange();
312         fireOpenedIconChange();
313     }
314
315     /** Utility method which gets the actual look from current LookDescriptor.
316      * @return Look set on this Node
317      */

318     public synchronized Look getLook() {
319         return firer.look;
320     }
321
322     /** Gets handle for the LookNode.
323      * @return the handle, or <code>null</code> if this node is not persistable
324      */

325     public Node.Handle getHandle() {
326         if ( cache!= null ) {
327             return cache;
328         }
329         else {
330             return DefaultHandle.createHandle (this);
331         }
332     }
333
334     /** Returns a node representing the same object as the original node. Looks
335      * passed in constructor and in setLook method are copied as well.
336      *
337      * @return LookNode representing the same object.
338      */

339     public Node cloneNode () {
340         return new LookNode( getRepresentedObject(), getLook(), getLookSelector(), cache );
341     }
342
343     // Additional methods for LookNode -----------------------------------------
344

345
346     final synchronized LookSelector getLookSelectorForChildren() {
347         Lookup lookup = getLookup();
348         LookSelector chLs = (LookSelector)lookup.lookup( LookSelector.class );
349         return chLs == null ? getLookSelector() : chLs;
350     }
351
352     /** Used to get Firer of this LookNode
353      */

354     final synchronized FirerImpl getFirer (){
355         return firer;
356     }
357
358     /** Refreshes children on the node */
359     void refreshChildren(boolean brutal) {
360
361         Children current = getChildren();
362         boolean isLeaf = getLook().isLeaf( getRepresentedObject(), getLookup() );
363
364         if ( isLeaf ) {
365             if ( current == Children.LEAF ) {
366                 return;
367             }
368             else {
369                 setChildren( Children.LEAF );
370                 return;
371             }
372         }
373
374         if ( current == Children.LEAF ) {
375             setChildren( new LookChildren() );
376         }
377         else {
378             ((LookChildren)current).refreshChildren( brutal );
379         }
380     }
381
382     Cache getCache() {
383         return cache;
384     }
385     
386     void setCache( Cache cache ) {
387         this.cache = cache;
388     }
389     
390     private static Look findFirstLook( LookSelector ls, Object JavaDoc ro, LookListener listener ) {
391
392         Enumeration JavaDoc descriptors = ls.getLooks( ro );
393
394         while (descriptors.hasMoreElements ()) {
395             Look look = (Look)descriptors.nextElement ();
396             
397             Exception JavaDoc e = tryAttach( look, ro, listener );
398             if ( e == null ) {
399                 return look;
400             }
401             
402             ErrorManager.getDefault().notify( ErrorManager.INFORMATIONAL, e );
403         }
404         
405         return null;
406     }
407     
408     private static Exception JavaDoc tryAttach( Look look, Object JavaDoc representedObject, LookListener listener ) {
409         try {
410             org.netbeans.modules.looks.Accessor.DEFAULT.addLookListener( look, representedObject, listener );
411             return null;
412         }
413         catch ( ClassCastException JavaDoc e ) {
414             return e;
415         }
416         catch ( IllegalArgumentException JavaDoc e ) {
417             return e;
418         }
419     }
420
421     private Lookup getLookupNoInit() {
422         return lookupProvider;
423     }
424     
425     // Methods for CHILDREN ----------------------------------------------------
426

427     final List JavaDoc getChildObjects() {
428         return getLook().getChildObjects( getRepresentedObject(), getLookupNoInit() );
429     }
430
431
432     // Methods for STYLE -------------------------------------------------------
433

434     /** Determines displayName by querying the Look.
435      * @return DisplayName provided by the Look or result
436      * of {@link #getName()}.
437      */

438     public String JavaDoc getDisplayName() {
439         String JavaDoc displayName = getLook().getDisplayName( getRepresentedObject(), getLookupNoInit() );
440         return displayName == null ? getName() : displayName;
441     }
442
443     /** Empty method, setting <CODE>displayName</CODE> on the
444      * <CODE>LookNode</CODE> has no effect. The <CODE>displayName</CODE> should
445      * be determined by associated <CODE>Look</CODE>.
446      * @param name Parameter is ignored.
447      */

448     public void setDisplayName( String JavaDoc name ) {
449     }
450
451     /** Determines name by querying the Look.
452      * @return Name provided by the Look or <CODE>null</CODE>.
453      */

454     public String JavaDoc getName() {
455         return getLook().getName( getRepresentedObject(), getLookupNoInit() );
456     }
457
458     /** Invoking this method on LookNode invokes method {@link Look#rename}
459      * @see org.netbeans.spi.looks.Look#rename(Object, String, Lookup)
460      * @param name The new name to be set.
461      */

462     public void setName( String JavaDoc name ) {
463         try {
464             getLook().rename( getRepresentedObject(), name, getLookupNoInit() );
465         }
466         catch ( IOException JavaDoc ex ) {
467             RuntimeException JavaDoc e = new IllegalArgumentException JavaDoc();
468             ErrorManager.getDefault().annotate (e, ex);
469             throw e;
470
471         }
472     }
473
474     /** Empty method, setting <CODE>shortDescription</CODE> on the
475      * <CODE>LookNode</CODE> has no effect. The <CODE>shortDescription</CODE>
476      * should be determined by associated <CODE>Look</CODE>.
477      * @param shortDescription Parameter is ignored.
478      */

479     public void setShortDescription( String JavaDoc shortDescription ) {
480     }
481
482     /** Determines shortDescription by querying the Look.
483      * @return Name provided by the Look or result of {@link #getDisplayName()}.
484      */

485     public String JavaDoc getShortDescription() {
486         String JavaDoc shortDescription = getLook().getShortDescription( getRepresentedObject(), getLookupNoInit() );
487         return shortDescription == null ? getDisplayName() : shortDescription;
488     }
489
490     /** Determines icon for closed state by querying the Look.
491      * @param type Icon type constant from {@link java.beans.BeanInfo}
492      * @return Icon provided by the Look
493      */

494     public Image JavaDoc getIcon( int type ) {
495         Image JavaDoc image = getLook().getIcon( getRepresentedObject(), type, getLookupNoInit() );
496
497         if ( image == null ) {
498             if ( type == BeanInfo.ICON_COLOR_32x32 || type == BeanInfo.ICON_MONO_32x32 ) {
499                 return Utilities.loadImage( DEFAULT_ICON_32_NAME );
500             }
501             return Utilities.loadImage( DEFAULT_ICON_16_NAME );
502         }
503         return image;
504     }
505
506     /** Determines icon for opened state by querying the Look.
507      * @param type Icon type constant from {@link java.beans.BeanInfo}
508      * @return Icon provided by the Look or the result of
509      * {@link #getIcon(int)}.
510      */

511     public Image JavaDoc getOpenedIcon( final int type ) {
512         Image JavaDoc image = getLook().getOpenedIcon( getRepresentedObject(), type, getLookupNoInit() );
513         return image == null ? getIcon( type ) : image;
514     }
515
516     /** Determines HelpCtx for opened state by querying the Look.
517      * @return HelpCtx provided by the Look.
518      */

519     public HelpCtx getHelpCtx () {
520         return getLook().getHelpCtx( getRepresentedObject(), getLookupNoInit() );
521     }
522
523     // Methods for ACTIONS & NEW TYPES -----------------------------------------
524

525     /** Determines NewTypes by querying the Look.
526      * @return NewTypes provided by the Look.
527      */

528     public NewType[] getNewTypes() {
529         NewType arr[] = getLook().getNewTypes( getRepresentedObject(), getLookupNoInit() );
530         return arr == null ? NO_NEW_TYPES : arr;
531     }
532
533     /** Get the set of actions associated with this node by asking the look
534      * @see org.openide.nodes.Node#getActions()
535      * @return system actions appropriate to the node
536      */

537     public SystemAction[] getActions() {
538         return toSA (getActions ( false ));
539     }
540
541     /** Implementation of the getActions command with the expected signature
542      * of a method that will be used in future
543      *
544      * @return the actions supported by this node
545      */

546     public Action JavaDoc[] getActions ( boolean context ) {
547
548         Action JavaDoc systemActions[];
549
550         if ( context ) {
551             systemActions = getLook().getContextActions( getRepresentedObject(), getLookupNoInit() );
552         }
553         else {
554             systemActions = getLook().getActions( getRepresentedObject(), getLookupNoInit() );
555         }
556
557         return systemActions == null ? NO_ACTIONS : systemActions;
558
559     }
560
561     /** Queries the look for special set of actions for situations when this
562      * node is displayed as a context.
563      * @see org.openide.nodes.Node#getContextActions()
564      * @return actions for a context. In the default implementation, same as {@link #getActions}.
565      */

566     public SystemAction [] getContextActions() {
567         return toSA (getActions ( true ));
568     }
569
570     /** Determines the default action for this node by asking the look.
571      * @see org.openide.nodes.Node#getDefaultAction()
572      * @return default action, or <code>null</code> if there should be none
573      */

574     public SystemAction getDefaultAction() {
575         Action JavaDoc a = getPreferredAction();
576         return a instanceof SystemAction ? (SystemAction)a : null;
577     }
578
579     /** Gets the preferred action for this node by asking the look.
580      * This action can but need not to be one from the action array returned
581      * from {@link #getActions(boolean)}.
582      * In case it is, the popup menu created from those actions
583      * is encouraged to highlight the preferred action.
584      * Override in subclasses accordingly.
585      *
586      * @return the preferred action instance of <code>null</code> if there is none.
587      * @since 3.29 */

588     public Action JavaDoc getPreferredAction() {
589         return getLook().getDefaultAction( getRepresentedObject(), getLookupNoInit() );
590     }
591
592     /** A convertor that takes array of Actions and return array of SystemActions
593      * @param arr array of Action
594      * @return array of SystemActions
595      */

596     private static SystemAction[] toSA (Action JavaDoc[] arr) {
597         SystemAction[] sa = new SystemAction[arr.length];
598
599         for (int i = 0; i < arr.length; i++) {
600             if (arr[i] instanceof SystemAction) {
601                 sa[i] = (SystemAction)arr[i];
602             }
603         }
604
605         return sa;
606     }
607
608
609     // Methods for PROPERTIES AND CUSTOMIZER -----------------------------------
610

611
612     /** Asks the look for the list of property sets for this node
613      * @see org.openide.nodes.Node#getPropertySets()
614      * @return the property sets
615      */

616     public Node.PropertySet[] getPropertySets() {
617
618         Node.PropertySet sets[] = getLook().getPropertySets( getRepresentedObject(), getLookupNoInit() );
619         return sets == null ? NO_PROPERTY_SETS : sets;
620
621     }
622
623     /** Gets the customizer component by consulting the look.
624      * @return the component, or <CODE>null</CODE> if there is no customizer
625      */

626     public Component JavaDoc getCustomizer() {
627         return getLook().getCustomizer( getRepresentedObject(), getLookupNoInit() );
628     }
629
630     /** Asks look whether there is a customizer for this node. If true,
631     * the customizer can be obtained via {@link #getCustomizer}. Result is
632     * @return <CODE>true</CODE> if there is a customizer
633     */

634     public boolean hasCustomizer () {
635         return getLook().hasCustomizer( getRepresentedObject(), getLookupNoInit() );
636     }
637
638     // Methods for CLIPBOARD OPERATIONS ----------------------------------------
639

640     /** Asks the look whether this node can be renamed.
641     * If true, one can use {@link #getName} to obtain the current name and
642     * {@link #setName} to change it.
643     * @return <code>true</code> if the node can be renamed
644     */

645     public boolean canRename() {
646         return getLook().canRename( getRepresentedObject(), getLookupNoInit() );
647     }
648
649     /** Asks the look whether this node can be deleted.
650      * @return <CODE>true</CODE> if the node can be deleted.
651      */

652     public boolean canDestroy() {
653         return getLook().canDestroy( getRepresentedObject(), getLookupNoInit() );
654     }
655
656     /** Asks the look whether this node permits copying.
657      * @return <code>true</code> if the node permits copying
658      */

659     public boolean canCopy() {
660         return getLook().canCopy( getRepresentedObject(), getLookupNoInit() );
661     }
662
663     /** Asks the look whether this node permits cutting.
664      * @return <code>true</code> if the node permits cutting
665      */

666     public boolean canCut() {
667         return getLook().canCut( getRepresentedObject(), getLookupNoInit() );
668     }
669
670     /** Consults the look to determine which paste operations are allowed when
671      * a given transferable is in the clipboard.
672      * @see org.openide.nodes.Node#getPasteTypes(java.awt.datatransfer.Transferable)
673      * @param t the transferable in the clipboard
674      * @return array of operations that are allowed
675      */

676     public PasteType[] getPasteTypes( Transferable JavaDoc t) {
677         PasteType arr[] = getLook().getPasteTypes( getRepresentedObject(), t, getLookupNoInit() );
678         return arr != null ? arr : NO_PASTE_TYPES;
679     }
680
681     /** Consults the look to determine if there is a paste operation that can
682      * be performed on provided transferable. Used by drag'n'drop code to check
683      * whether the drop is possible.
684      * @param t the transferable
685      * @param action the drag'n'drop action to do DnDConstants.ACTION_MOVE, ACTION_COPY, ACTION_LINK
686      * @param index index between children the drop occurred at or -1 if not specified
687      * @return null if the transferable cannot be accepted or the paste type
688      * to execute when the drop occurs
689      */

690     public PasteType getDropType( Transferable JavaDoc t, int action, int index) {
691         return getLook().getDropType( getRepresentedObject(), t, action, index, getLookupNoInit() );
692     }
693
694     /** Called when a node is to be copied to the clipboard. Look is responsible
695      * for handling the operation.
696      * @return the transferable object representing the content of the clipboard
697      * @exception IOException when the copy cannot be performed
698      */

699     public Transferable JavaDoc clipboardCopy() throws IOException JavaDoc {
700         return getLook().clipboardCopy( getRepresentedObject(), getLookupNoInit() );
701     }
702
703     /** Called when a node is to be cut to the clipboard. Look is responsible for
704      * handling the operation.
705      * @return the transferable object representing the content of the clipboard
706      * @exception IOException when the cut cannot be performed
707      */

708     public Transferable JavaDoc clipboardCut() throws IOException JavaDoc {
709         return getLook().clipboardCut( getRepresentedObject(), getLookupNoInit() );
710     }
711
712     /** Called when a drag is started with this node. Look is responsible
713      * for handling the operation.<BR>
714      * The node can attach a transfer listener to ExTransferable and
715      * will be then notified about progress of the drag (accept/reject).
716      * @return transferable to represent this node during a drag
717      * @exception IOException if a drag cannot be started
718      */

719     public Transferable JavaDoc drag() throws IOException JavaDoc {
720         return getLook().drag( getRepresentedObject(), getLookupNoInit() );
721     }
722
723     /** Call to this method removes the node from its parent and deletes it.
724      * The look is responsible for reflecting the destroy action in underlying
725      * data and for doing necessary cleanups.
726      * @exception IOException if something fails
727      */

728     public void destroy () throws IOException JavaDoc {
729         getLook().destroy( getRepresentedObject(), getLookupNoInit() );
730     }
731
732     // Implementation of InstanceCooke.Of --------------------------------------
733

734     public Class JavaDoc instanceClass() throws java.io.IOException JavaDoc, ClassNotFoundException JavaDoc {
735         return getRepresentedObject().getClass();
736     }
737     
738     public Object JavaDoc instanceCreate() throws java.io.IOException JavaDoc, ClassNotFoundException JavaDoc {
739         return getRepresentedObject();
740     }
741     
742     public String JavaDoc instanceName() {
743         return getRepresentedObject().getClass().getName();
744     }
745     
746     public boolean instanceOf( Class JavaDoc type ) {
747         return type.isInstance( getRepresentedObject() );
748     }
749     
750     public String JavaDoc toString() {
751         if (getRepresentedObject() != null) {
752             return super.toString();
753         } else {
754             return "LookNode<" + getLook().getName() + ";DEAD>"; // NOI18N
755
}
756     }
757     
758     // Firer innerclass -----------------------------------------------------
759

760     /** Class passed to the Look methods as parameter. Each LookNode contains
761      * exactly one instance of this class. Metods of the class allow access
762      * to the properties and methods od the node needed for the Look.
763      */

764     static final class FirerImpl extends WeakReference JavaDoc
765         implements Runnable JavaDoc, org.netbeans.modules.looks.SelectorListener, LookListener {
766
767         /** Represented object of the LookNode */
768         private Object JavaDoc representedObject;
769
770         private LookSelector lookSelector;
771         
772         // LookDescriptor the node. Describes the Look used on this
773
// node and the LookSelector used for this node's children
774
private Look look;
775
776         /** The constructor of the interior is private to prevent other classes
777          * than LookNode and Look from firing events on the node
778          */

779         FirerImpl( LookNode lookNode,
780                    LookSelector lookSelector,
781                    Look look,
782                    Object JavaDoc representedObject ) {
783             super( lookNode, Utilities.activeReferenceQueue() );
784             this.representedObject = representedObject;
785             this.look = look;
786             this.lookSelector = lookSelector;
787         }
788         
789         public LookNode getLookNode () {
790             return (LookNode)get();
791         }
792
793         /** Returns the object represented by the node
794          * @return Object represented by the node this interior belongs to.
795          */

796         public Object JavaDoc getRepresentedObject() {
797             return representedObject;
798         }
799
800         // Implementation of LookListener --------------------------------------
801

802         public void change( LookEvent evt ) {
803            
804             long mask = evt.getMask();
805             LookNode l = getLookNode();
806
807             if ( l != null ) {
808                 
809                 if ( ( mask & Look.GET_NAME ) > 0 ) {
810                     l.fireNameChange( null, null );
811                 }
812                 if ( ( mask & Look.GET_DISPLAY_NAME ) > 0 ) {
813                     l.fireDisplayNameChange( null, null );
814                 }
815                 if ( ( mask & Look.GET_ICON ) > 0 ) {
816                     l.fireIconChange();
817                 }
818                 if ( ( mask & Look.DESTROY ) > 0 ) {
819                     l.fireNodeDestroyed();
820                 }
821                 if ( ( mask & Look.GET_OPENED_ICON ) > 0 ) {
822                     l.fireOpenedIconChange();
823                 }
824                 if ( ( mask & Look.GET_PROPERTY_SETS ) > 0 ) {
825                     l.firePropertySetsChange( null, null );
826                 }
827                 if ( ( mask & Look.GET_CHILD_OBJECTS ) > 0 ) {
828                     l.refreshChildren(false);
829                 }
830                 if ( ( mask & Look.GET_SHORT_DESCRIPTION ) > 0 ) {
831                     l.fireShortDescriptionChange( null, null );
832                 }
833                 if ( ( mask & Look.GET_LOOKUP_ITEMS ) > 0 ) {
834                     l.getLookupProvider().setDirty();
835                 }
836             }
837         }
838
839         /** Notification of property change on given object
840          */

841         public void propertyChange( LookEvent evt ) {
842             LookNode l = getLookNode();
843             if (l != null) {
844                 l.firePropertyChange( evt.getPropertyName(), null, null );
845             }
846         }
847  
848         // Implementation of Runnable ------------------------------------------
849

850         public void run () {
851             
852             if ( lookSelector != null ) {
853                 org.netbeans.modules.looks.Accessor.DEFAULT.removeSelectorListener(lookSelector, this);
854             }
855             if ( look != null ) {
856                 org.netbeans.modules.looks.Accessor.DEFAULT.removeLookListener( look, representedObject, this );
857             }
858             
859             // Help GC:
860
representedObject = null;
861           
862         }
863
864         // Implementation of SelectorListener ----------------------------------
865

866         public void contentsChanged(org.netbeans.modules.looks.SelectorEvent evt) {
867             LookNode ln = getLookNode();
868
869             if ( evt.affectsObject(representedObject) && ln != null ) {
870                 ln.setLook( null );
871             }
872         }
873     } // end of FirerImpl
874

875     private static final class LookNodeLookupProvider extends org.openide.util.lookup.AbstractLookup {
876         private LookNode lookNode;
877         
878         protected void setLookNode (LookNode l) {
879             lookNode = l;
880         }
881         
882         protected void initialize() {
883             setDirty ();
884         }
885
886         // Implementation of Lookup.Provider -----------------------------------
887

888         public void setDirty() {
889             if ( lookNode == null ) {
890                 throw new IllegalStateException JavaDoc( "getLookupCalled before attached node" );
891             }
892
893             // We have to create new lookup - in order to fire changes properly
894

895             Look look = lookNode.getLook();
896             Collection JavaDoc lookupItems = look.getLookupItems( lookNode.getRepresentedObject(), this );
897
898             List JavaDoc pairs = new ArrayList JavaDoc( lookupItems == null ? 1 : 1 + lookupItems.size() );
899             pairs.add( ItemPair.wrap ( ( new NodeLookupItem( lookNode ) ) ) );
900             
901             
902             if ( lookupItems != null ) {
903                 for (Iterator JavaDoc it = lookupItems.iterator(); it.hasNext(); ) {
904                     pairs.add( ItemPair.wrap ((Lookup.Item)it.next()) );
905                 }
906             }
907
908             setPairs( pairs );
909         }
910     } // end of LookNodeLookupProvider
911

912     /** Pair that wraps an item */
913     private static final class ItemPair extends AbstractLookup.Pair {
914         
915         private AbstractLookup.Item item;
916         
917         private ItemPair (org.openide.util.lookup.AbstractLookup.Item i) {
918             this.item = i;
919         }
920
921         public static AbstractLookup.Pair wrap (Lookup.Item item) {
922             if (false/*XXX see #13779; doesn't work: item instanceof AbstractLookup.Pair*/) {
923                 return (AbstractLookup.Pair)item;
924             } else {
925                 return new ItemPair (item);
926             }
927         }
928
929         protected boolean creatorOf(Object JavaDoc obj) {
930             return item.getInstance() == obj;
931         }
932
933         public String JavaDoc getDisplayName() {
934             return item.getDisplayName ();
935         }
936
937         public String JavaDoc getId() {
938             return item.getId ();
939         }
940
941         public Object JavaDoc getInstance() {
942             return item.getInstance ();
943         }
944
945         public Class JavaDoc getType() {
946             return item.getType ();
947         }
948
949         protected boolean instanceOf(Class JavaDoc c) {
950             return c.isAssignableFrom (getType ());
951         }
952
953         public boolean equals (Object JavaDoc o) {
954             if (o instanceof ItemPair) {
955                 ItemPair p = (ItemPair)o;
956                 return item.equals (p.item);
957             }
958             return false;
959         }
960
961         public int hashCode () {
962             return item.hashCode ();
963         }
964     } // end of ItemPair
965

966     private static class NodeLookupItem extends Lookup.Item {
967         private LookNode ln;
968         
969         public NodeLookupItem( LookNode ln ) {
970             this.ln = ln;
971         }
972                 
973         public String JavaDoc getDisplayName() {
974             return getId();
975         }
976         
977         public String JavaDoc getId() {
978             return ln.toString();
979         }
980         
981         public Object JavaDoc getInstance() {
982             return ln;
983         }
984         
985         public Class JavaDoc getType() {
986             return ln.getClass();
987         }
988         
989     }
990     
991     // Serves as a placeholder for look listener, does nothing
992
private static class PlaceholderLookListener implements LookListener {
993         
994         public void change(LookEvent evt) {}
995         
996         public void propertyChange(LookEvent evt) {}
997                 
998     }
999     
1000}
1001
1002
Popular Tags