KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > editor > impl > CustomizableSideBar


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.modules.editor.impl;
21
22 import org.netbeans.modules.editor.*;
23 import java.awt.BorderLayout JavaDoc;
24 import java.io.IOException JavaDoc;
25 import java.util.ArrayList JavaDoc;
26 import java.util.Collection JavaDoc;
27 import java.util.HashMap JavaDoc;
28 import java.util.Iterator JavaDoc;
29 import java.util.List JavaDoc;
30 import java.util.Map JavaDoc;
31 import javax.swing.BoxLayout JavaDoc;
32 import javax.swing.JComponent JavaDoc;
33 import javax.swing.JPanel JavaDoc;
34 import javax.swing.event.ChangeEvent JavaDoc;
35 import javax.swing.event.ChangeListener JavaDoc;
36 import javax.swing.text.JTextComponent JavaDoc;
37 import org.netbeans.api.editor.mimelookup.MimeLookup;
38 import org.netbeans.api.editor.mimelookup.MimePath;
39 import org.netbeans.editor.SideBarFactory;
40 import org.netbeans.editor.WeakEventListenerList;
41 import org.netbeans.spi.editor.mimelookup.InstanceProvider;
42 import org.openide.ErrorManager;
43 import org.openide.cookies.InstanceCookie;
44 import org.openide.filesystems.FileObject;
45 import org.openide.loaders.DataObject;
46 import org.openide.loaders.DataObjectNotFoundException;
47 import org.openide.util.Lookup;
48 import org.openide.util.LookupEvent;
49 import org.openide.util.LookupListener;
50 import org.openide.util.WeakListeners;
51
52 /**
53  * Editor Customizable Side Bar.
54  * Contains components for particular MIME type as defined in XML layer.
55  *
56  * @author Martin Roskanin
57  */

58 public final class CustomizableSideBar extends JPanel JavaDoc {
59     
60     private static HashMap JavaDoc components = new HashMap JavaDoc(5);
61     private static HashMap JavaDoc lookupResults = new HashMap JavaDoc(5);
62     private static HashMap JavaDoc lookupListeners = new HashMap JavaDoc(5); //<kitClass, WeakListener>
63
private static HashMap JavaDoc changeListeners = new HashMap JavaDoc(5); //<kitClass, WeakEventListenerList>
64

65     /** List of the registered changes listeners */
66     //private static final WeakEventListenerList listenerList
67
// = new WeakEventListenerList();
68

69     
70     private CustomizableSideBar(List JavaDoc/*<JComponent>*/ components, SideBarPosition position){
71         BoxLayout JavaDoc bl = new javax.swing.BoxLayout JavaDoc(this, position.getAxis());
72         setLayout(bl);
73         
74         for (Iterator JavaDoc i = components.iterator(); i.hasNext(); ){
75             add((JComponent JavaDoc) i.next());
76         }
77     }
78
79     
80     private static WeakEventListenerList getListenerList(String JavaDoc mimeType){
81         WeakEventListenerList listenerList;
82         synchronized (changeListeners){
83             listenerList = (WeakEventListenerList)changeListeners.get(mimeType);
84         }
85         return listenerList;
86     }
87     
88     /** Add weak listener to listen to change of activity of documents or components.
89      * The caller must
90      * hold the listener object in some instance variable to prevent it
91      * from being garbage collected.
92      * @param l listener to add
93      */

94     public static void addChangeListener(String JavaDoc mimeType, ChangeListener JavaDoc l) {
95         WeakEventListenerList listenerList;
96         synchronized (changeListeners){
97             listenerList = (WeakEventListenerList)changeListeners.get(mimeType);
98             if (listenerList == null){
99                 listenerList = new WeakEventListenerList();
100             }
101             changeListeners.put(mimeType, listenerList);
102         }
103         
104         listenerList.add(ChangeListener JavaDoc.class, l);
105     }
106
107     /** Remove listener for changes in activity. It's optional
108      * to remove the listener. It would be done automatically
109      * if the object holding the listener would be garbage collected.
110      * @param l listener to remove
111      */

112     public static void removeChangeListener(String JavaDoc mimeType, ChangeListener JavaDoc l) {
113         WeakEventListenerList listenerList = getListenerList(mimeType);
114         if (listenerList == null){
115             return;
116         }
117         listenerList.remove(ChangeListener JavaDoc.class, l);
118     }
119
120     private static void fireChange(String JavaDoc mimeType) {
121         WeakEventListenerList listenerList = getListenerList(mimeType);
122         if (listenerList == null){
123             return;
124         }
125     ChangeListener JavaDoc[] listeners
126         = (ChangeListener JavaDoc[])listenerList.getListeners(ChangeListener JavaDoc.class);
127     ChangeEvent JavaDoc evt = new ChangeEvent JavaDoc(CustomizableSideBar.class);
128     for (int i = 0; i < listeners.length; i++) {
129         listeners[i].stateChanged(evt);
130     }
131     }
132     
133     
134     public static Map JavaDoc/*<SideBarPosition, JComponent>*/ createSideBars(JTextComponent JavaDoc target) {
135         Map JavaDoc/*<SideBarPosition, List<JComponent>>*/ components = getPanelComponents(target);
136         Map JavaDoc/*<SideBarPosition, JComponent>*/ result = new HashMap JavaDoc();
137         
138         for (Iterator JavaDoc entries = components.entrySet().iterator(); entries.hasNext(); ) {
139             Map.Entry JavaDoc entry = (Map.Entry JavaDoc) entries.next();
140             SideBarPosition position = (SideBarPosition) entry.getKey();
141             
142             result.put(position, new CustomizableSideBar((List JavaDoc) entry.getValue(), position));
143         }
144         
145         return result;
146     }
147         
148     private static Map JavaDoc/*<SideBarPosition, List>*/ getInstanceCookiesPerKitClass(String JavaDoc mimeType){
149         Map JavaDoc result = new HashMap JavaDoc();
150         if (mimeType == null) return result;
151         synchronized (components){
152             if (components.containsKey(mimeType)){
153                 return (Map JavaDoc)components.get(mimeType);
154             }else{
155                 Lookup lookup = MimeLookup.getLookup(MimePath.parse(mimeType));
156                 
157                 Lookup.Result lookupResult;
158                 synchronized (lookupResults){
159                     lookupResult = (Lookup.Result)lookupResults.get(mimeType);
160                     if (lookupResult == null){
161                         lookupResult = lookup.lookup(new Lookup.Template(SideBarFactoryProvider.class));
162                         lookupResults.put(mimeType, lookupResult);
163                     }
164                 }
165                     
166                 Collection JavaDoc instances = lookupResult.allInstances();
167                 if (instances.isEmpty()){
168                     return result; //empty
169
}
170                 
171                 SideBarFactoryProvider provider = (SideBarFactoryProvider) instances.iterator().next();
172
173                 synchronized (lookupListeners){
174                     LookupListener lookupListener = (LookupListener) lookupListeners.get(mimeType);
175                     if (lookupListener == null){
176                         lookupListener = new MyLookupListener(mimeType);
177                         LookupListener weakListener = (LookupListener) WeakListeners.create(
178                                                LookupListener.class, lookupListener, lookupResult);
179                         lookupResult.addLookupListener(weakListener);
180                         lookupListeners.put(mimeType, lookupListener);
181                     }
182                 }
183                 
184                 if (provider!=null){
185                     result = provider.getProviders();
186                 }
187                 
188                 if (result!=null){
189                     components.put(mimeType, result);
190                 }
191                 
192                 return result;
193             }
194         }
195     }
196     
197     private static Map JavaDoc/*<SideBarPosition, List<JComponent>>*/ getPanelComponents(JTextComponent JavaDoc target){
198         Map JavaDoc result = new HashMap JavaDoc();
199         Map JavaDoc icMap = getInstanceCookiesPerKitClass(NbEditorUtilities.getMimeType(target));
200
201         try{
202             for (Iterator JavaDoc entries = icMap.entrySet().iterator(); entries.hasNext(); ) {
203                 Map.Entry JavaDoc entry = (Map.Entry JavaDoc) entries.next();
204                 List JavaDoc icList = (List JavaDoc) entry.getValue();
205                 List JavaDoc retList = new ArrayList JavaDoc();
206                 
207                 for (int i = 0; i<icList.size(); i++){
208                     InstanceCookie ic = (InstanceCookie)icList.get(i);
209                     Object JavaDoc obj = ic.instanceCreate();
210                     JComponent JavaDoc sideBarObj = ((SideBarFactory)obj).createSideBar(target);
211                     if (sideBarObj!=null){
212                         retList.add(sideBarObj);
213                     }
214                 }
215                 result.put(entry.getKey(), retList);
216             }
217         }catch(IOException JavaDoc ioe){
218             ioe.printStackTrace();
219         }catch(ClassNotFoundException JavaDoc cnfe){
220             cnfe.printStackTrace();
221         }
222         
223         return result;
224     }
225     
226     public static final class SideBarPosition {
227         public static final int WEST = 1;
228         public static final int NORTH = 2;
229         public static final int SOUTH = 3;
230         public static final int EAST = 4;
231         
232         public static final String JavaDoc WEST_NAME = "West"; // NOI18N
233
public static final String JavaDoc NORTH_NAME = "North"; // NOI18N
234
public static final String JavaDoc SOUTH_NAME = "South"; // NOI18N
235
public static final String JavaDoc EAST_NAME = "East"; // NOI18N
236

237         private int position;
238         private boolean scrollable;
239         
240         SideBarPosition(FileObject fo) {
241             Object JavaDoc position = fo.getAttribute("position"); // NOI18N
242

243             if (position != null && position instanceof String JavaDoc) {
244                 String JavaDoc positionName = (String JavaDoc) position;
245                 
246                 if (WEST_NAME.equals(positionName)) {
247                     this.position = WEST;
248                 } else {
249                     if (NORTH_NAME.equals(positionName)) {
250                         this.position = NORTH;
251                     } else {
252                         if (SOUTH_NAME.equals(positionName)) {
253                             this.position = SOUTH;
254                         } else {
255                             if (EAST_NAME.equals(positionName)) {
256                                 this.position = EAST;
257                             } else {
258                                 if (ErrorManager.getDefault().isLoggable(ErrorManager.INFORMATIONAL))
259                                     ErrorManager.getDefault().log(ErrorManager.INFORMATIONAL, "Unsupported position: " + positionName);
260                                 
261                                 this.position = WEST;
262                             }
263                         }
264                     }
265                 }
266             } else {
267                 this.position = WEST;
268             }
269             
270             Object JavaDoc scrollable = fo.getAttribute("scrollable"); // NOI18N
271

272             if (scrollable != null && scrollable instanceof Boolean JavaDoc) {
273                 this.scrollable = ((Boolean JavaDoc) scrollable).booleanValue();
274             } else {
275                 this.scrollable = true;
276             }
277             
278             if (this.scrollable && (this.position == SOUTH || this.position == EAST)) {
279                 if (ErrorManager.getDefault().isLoggable(ErrorManager.INFORMATIONAL))
280                     ErrorManager.getDefault().log(ErrorManager.INFORMATIONAL, "Unsupported combination: scrollable == true, position=" + getBorderLayoutPosition());
281             }
282         }
283         
284         public int hashCode() {
285             return scrollable ? position : - position;
286         }
287         
288         public boolean equals(Object JavaDoc o) {
289             if (o instanceof SideBarPosition) {
290                 SideBarPosition p = (SideBarPosition) o;
291                 
292                 if (scrollable != p.scrollable)
293                     return false;
294                 
295                 if (position != p.position)
296                     return false;
297                 
298                 return true;
299             }
300             
301             return false;
302         }
303         
304         public int getPosition() {
305             return position;
306         }
307         
308         private static String JavaDoc[] borderLayoutConstants = new String JavaDoc[] {"", BorderLayout.WEST, BorderLayout.NORTH, BorderLayout.SOUTH, BorderLayout.EAST};
309         
310         public String JavaDoc getBorderLayoutPosition() {
311             return borderLayoutConstants[getPosition()];
312         }
313         
314         private static int[] axisConstants = new int[] {-1, BoxLayout.X_AXIS, BoxLayout.Y_AXIS, BoxLayout.Y_AXIS, BoxLayout.X_AXIS};
315         
316         private int getAxis() {
317             return axisConstants[getPosition()];
318         }
319         
320         public boolean isScrollable() {
321             return scrollable;
322         }
323         
324         public String JavaDoc toString() {
325             return "[SideBarPosition: scrollable=" + scrollable + ", position=" + position + "]"; // NOI18N
326
}
327     }
328
329     public static class SideBarFactoryProvider implements InstanceProvider{
330
331         List JavaDoc ordered;
332
333         public SideBarFactoryProvider(){
334         }
335
336         public SideBarFactoryProvider(List JavaDoc ordered){
337             this.ordered = ordered;
338         }
339
340         public Map JavaDoc getProviders(){
341             Map JavaDoc result = new HashMap JavaDoc();
342             for (int i = 0; i<ordered.size(); i++){
343                 FileObject fo = (FileObject) ordered.get(i);
344                 
345                 DataObject dob;
346                 try {
347                     dob = DataObject.find(fo);
348                 } catch (DataObjectNotFoundException dnfe) {
349                     // ignore
350
continue;
351                 }
352                 
353                 InstanceCookie ic = (InstanceCookie)dob.getCookie(InstanceCookie.class);
354                 if (ic!=null){
355                         try{
356                             if (SideBarFactory.class.isAssignableFrom(ic.instanceClass() )){
357                                 SideBarPosition position = new SideBarPosition(dob.getPrimaryFile());
358                                 
359                                 List JavaDoc retList = (List JavaDoc) result.get(position);
360                                 
361                                 if (retList == null) {
362                                     result.put(position, retList = new ArrayList JavaDoc());
363                                 }
364                                 
365                                 retList.add(ic);
366                             }
367                         }catch(IOException JavaDoc ioe){
368                             ioe.printStackTrace();
369                         }catch(ClassNotFoundException JavaDoc cnfe){
370                             cnfe.printStackTrace();
371                         }
372                 }
373             }
374             return result;
375         }
376
377         public Object JavaDoc createInstance(List JavaDoc ordered) {
378             return new SideBarFactoryProvider(ordered);
379         }
380     }
381     
382     private static class MyLookupListener implements LookupListener{
383         private String JavaDoc mimeType;
384         public MyLookupListener(String JavaDoc mimeType){
385             this.mimeType = mimeType;
386         }
387         
388         public void resultChanged(LookupEvent ev) {
389             synchronized (components){
390                 components.remove(mimeType);
391             }
392             fireChange(mimeType);
393         }
394     }
395
396 }
397
Popular Tags