KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > spi > palette > PaletteSwitch


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.spi.palette;
21
22 import java.beans.PropertyChangeEvent JavaDoc;
23 import java.beans.PropertyChangeListener JavaDoc;
24 import java.beans.PropertyChangeSupport JavaDoc;
25 import java.util.ArrayList JavaDoc;
26 import java.util.Iterator JavaDoc;
27 import java.util.Set JavaDoc;
28 import javax.swing.SwingUtilities JavaDoc;
29 import org.netbeans.api.editor.mimelookup.MimeLookup;
30 import org.netbeans.api.editor.mimelookup.MimePath;
31 import org.netbeans.modules.palette.ui.PalettePanel;
32 import org.openide.filesystems.FileObject;
33 import org.openide.loaders.DataObject;
34 import org.openide.loaders.DataShadow;
35 import org.openide.nodes.Node;
36 import org.openide.util.Lookup;
37 import org.openide.util.LookupEvent;
38 import org.openide.util.LookupListener;
39 import org.openide.windows.TopComponent;
40 import org.openide.windows.TopComponentGroup;
41 import org.openide.windows.WindowManager;
42
43 /**
44  * A class that listens to changes to the set of opened TopComponents and to the
45  * set of activated Nodes to show/hide the palette window when a TopComponent that
46  * supports the palette is activated/deactivated.
47  *
48  * @author S. Aubrecht
49  */

50 final class PaletteSwitch implements Runnable JavaDoc, LookupListener {
51     
52     static final String JavaDoc PROP_PALETTE_CONTENTS = "component_palette_contents"; //NOI18N
53

54     private static PaletteSwitch theInstance;
55     
56     private PropertyChangeListener JavaDoc registryListener;
57     
58     private PropertyChangeSupport JavaDoc propertySupport;
59     
60     private PaletteController currentPalette;
61     private boolean isGroupOpen = false;
62     private Lookup.Result lookupRes;
63     
64     /** Creates a new instance of PaletteSwitcher */
65     private PaletteSwitch() {
66         
67         propertySupport = new PropertyChangeSupport JavaDoc( this );
68         currentPalette = findPalette();
69     }
70     
71     public synchronized static PaletteSwitch getDefault() {
72         if( null == theInstance ) {
73             theInstance = new PaletteSwitch();
74         }
75         return theInstance;
76     }
77     
78     public void startListening() {
79         synchronized( theInstance ) {
80             if( null == registryListener ) {
81                 registryListener = createRegistryListener();
82                 TopComponent.getRegistry().addPropertyChangeListener( registryListener );
83                 switchLookupListener();
84                 run();
85             }
86         }
87     }
88     
89     public void stopListening() {
90         synchronized( theInstance ) {
91             if( null != registryListener ) {
92                 TopComponent.getRegistry().removePropertyChangeListener( registryListener );
93                 registryListener = null;
94                 currentPalette = null;
95             }
96         }
97     }
98
99     public void addPropertyChangeListener( PropertyChangeListener JavaDoc l ) {
100         propertySupport.addPropertyChangeListener( l );
101     }
102
103     public void removePropertyChangeListener( PropertyChangeListener JavaDoc l ) {
104         propertySupport.removePropertyChangeListener( l );
105     }
106     
107     public PaletteController getCurrentPalette() {
108         return currentPalette;
109     }
110     
111     public void run() {
112         if( !SwingUtilities.isEventDispatchThread() ) {
113             SwingUtilities.invokeLater( this );
114             return;
115         }
116         final PaletteController oldPalette = currentPalette;
117         currentPalette = findPalette();
118
119         showHidePaletteTopComponent( oldPalette, currentPalette );
120
121         propertySupport.firePropertyChange( PROP_PALETTE_CONTENTS, oldPalette, currentPalette );
122     }
123     
124     private PaletteController findPalette() {
125         TopComponent.Registry registry = TopComponent.getRegistry();
126         
127         PaletteController palette;
128         TopComponent activeTc = registry.getActivated();
129         palette = getPaletteFromTopComponent( activeTc, true );
130         
131         ArrayList JavaDoc<PaletteController> availablePalettes = new ArrayList JavaDoc<PaletteController>(3);
132         if( null == palette ) {
133             Set JavaDoc openedTcs = registry.getOpened();
134             for( Iterator JavaDoc i=openedTcs.iterator(); i.hasNext(); ) {
135                 TopComponent tc = (TopComponent)i.next();
136                 
137                 palette = getPaletteFromTopComponent( tc, true );
138                 if( null != palette ) {
139                     availablePalettes.add( palette );
140                 }
141             }
142             if( null != currentPalette && (availablePalettes.contains( currentPalette ) || isPaletteMaximized()) )
143                 palette = currentPalette;
144             else if( availablePalettes.size() > 0 )
145                 palette = availablePalettes.get( 0 );
146         }
147         return palette;
148     }
149     
150     private boolean isPaletteMaximized() {
151         boolean isMaximized = true;
152         boolean currentPaletteStillAvailable = false;
153         TopComponent.Registry registry = TopComponent.getRegistry();
154         Set JavaDoc openedTcs = registry.getOpened();
155         for( Iterator JavaDoc i=openedTcs.iterator(); i.hasNext(); ) {
156             TopComponent tc = (TopComponent)i.next();
157
158             if( tc.isShowing() && !(tc instanceof PaletteTopComponent) ) {
159                 //other window(s) than the Palette are showing
160
isMaximized = false;
161                 break;
162             }
163             if( !currentPaletteStillAvailable ) {
164                 //check whether the window with the current palette controller wasn't closed
165
PaletteController palette = getPaletteFromTopComponent( tc, false );
166                 if( null != palette && palette == currentPalette ) {
167                     currentPaletteStillAvailable = true;
168                 }
169             }
170         }
171         return isMaximized && currentPaletteStillAvailable;
172     }
173     
174     PaletteController getPaletteFromTopComponent( TopComponent tc, boolean mustBeShowing ) {
175         if( null == tc || (!tc.isShowing() && mustBeShowing) )
176             return null;
177         
178         PaletteController pc = (PaletteController)tc.getLookup().lookup( PaletteController.class );
179         if( null == pc && WindowManager.getDefault().isEditorTopComponent( tc ) ) {
180             //check if there's any palette assigned to TopComponent's mime type
181
Node[] activeNodes = tc.getActivatedNodes();
182             if( null != activeNodes && activeNodes.length > 0 ) {
183                 DataObject dob = activeNodes[0].getLookup().lookup( DataObject.class );
184                 if( null != dob ) {
185                     while( dob instanceof DataShadow ) {
186                         dob = ((DataShadow)dob).getOriginal();
187                     }
188                     FileObject fo = dob.getPrimaryFile();
189                     if( !fo.isVirtual() ) {
190                         String JavaDoc mimeType = fo.getMIMEType();
191                         pc = getPaletteFromMimeType( mimeType );
192                     }
193                 }
194             }
195         }
196         return pc;
197     }
198     
199     /**
200      * Finds appropriate PaletteController for given mime type.
201      *
202      * @param mimeType Mime type to check for associated palette content.
203      *
204      * @return PaletteController that is associated with the given mime type and that should
205      * be displayed in the Common Palette when an editor window with the given mime type is activated.
206      * @since 1.10
207      */

208     PaletteController getPaletteFromMimeType( String JavaDoc mimeType ) {
209         MimePath path = MimePath.get( mimeType );
210         Lookup lkp = MimeLookup.getLookup( path );
211         return lkp.lookup( PaletteController.class );
212     }
213     
214     private void showHidePaletteTopComponent( PaletteController prevPalette, PaletteController newPalette ) {
215         if( prevPalette == newPalette && null != newPalette )
216             return;
217         
218         WindowManager wm = WindowManager.getDefault();
219         final TopComponentGroup group = wm.findTopComponentGroup( "commonpalette" ); // NOI18N
220
if( null == group )
221             return; // group not found (should not happen)
222

223         if( null == prevPalette && null != newPalette ) {
224             group.open();
225             isGroupOpen = true;
226         } else if( ((null != prevPalette && null == newPalette)
227             || (null == prevPalette && null == newPalette))
228             && isGroupOpen ) {
229             PalettePanel.getDefault().setContent( null, null, null );
230             group.close();
231             isGroupOpen = false;
232         }
233     }
234     
235     /**
236      * multiview components do not fire events when switching their inner tabs
237      * so we have to listen to changes in lookup contents
238      */

239     private void switchLookupListener() {
240         TopComponent active = TopComponent.getRegistry().getActivated();
241         if( null != lookupRes ) {
242             lookupRes.removeLookupListener( PaletteSwitch.this );
243             lookupRes = null;
244         }
245         if( null != active ) {
246             lookupRes = active.getLookup().lookup( new Lookup.Template<PaletteController>( PaletteController.class ) );
247             lookupRes.addLookupListener( PaletteSwitch.this );
248             lookupRes.allItems();
249         }
250     }
251     
252     private PropertyChangeListener JavaDoc createRegistryListener() {
253         return new PropertyChangeListener JavaDoc() {
254             public void propertyChange( PropertyChangeEvent JavaDoc evt ) {
255                 if( TopComponent.Registry.PROP_CURRENT_NODES.equals( evt.getPropertyName() )
256                     || TopComponent.Registry.PROP_OPENED.equals( evt.getPropertyName() )
257                     || TopComponent.Registry.PROP_ACTIVATED.equals( evt.getPropertyName() ) ) {
258
259                     if( TopComponent.Registry.PROP_ACTIVATED.equals( evt.getPropertyName() ) ) {
260                         //switch lookup listener for the activated TC
261
switchLookupListener();
262                     }
263                     run();
264                 }
265             }
266         };
267     }
268
269     public void resultChanged(LookupEvent ev) {
270         run();
271     }
272 }
273
Popular Tags