KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > debug > internal > ui > viewers > model > TreeModelLabelProvider


1 /*******************************************************************************
2  * Copyright (c) 2006, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.debug.internal.ui.viewers.model;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.HashMap JavaDoc;
15 import java.util.Iterator JavaDoc;
16 import java.util.List JavaDoc;
17 import java.util.Map JavaDoc;
18
19 import org.eclipse.core.runtime.IAdaptable;
20 import org.eclipse.core.runtime.IProgressMonitor;
21 import org.eclipse.core.runtime.ISafeRunnable;
22 import org.eclipse.core.runtime.IStatus;
23 import org.eclipse.core.runtime.ListenerList;
24 import org.eclipse.core.runtime.PlatformObject;
25 import org.eclipse.core.runtime.SafeRunner;
26 import org.eclipse.core.runtime.Status;
27 import org.eclipse.debug.internal.ui.DebugUIPlugin;
28 import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider;
29 import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate;
30 import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
31 import org.eclipse.debug.internal.ui.views.launch.DebugElementAdapterFactory;
32 import org.eclipse.jface.resource.ImageDescriptor;
33 import org.eclipse.jface.viewers.ColumnLabelProvider;
34 import org.eclipse.jface.viewers.TreePath;
35 import org.eclipse.jface.viewers.ViewerCell;
36 import org.eclipse.jface.viewers.ViewerRow;
37 import org.eclipse.swt.graphics.Color;
38 import org.eclipse.swt.graphics.Font;
39 import org.eclipse.swt.graphics.FontData;
40 import org.eclipse.swt.graphics.Image;
41 import org.eclipse.swt.graphics.RGB;
42 import org.eclipse.swt.widgets.Display;
43 import org.eclipse.swt.widgets.TreeItem;
44 import org.eclipse.ui.progress.UIJob;
45
46 /**
47  * @since 3.3
48  */

49 public class TreeModelLabelProvider extends ColumnLabelProvider {
50     
51     private InternalTreeModelViewer fViewer;
52     private List JavaDoc fComplete;
53     
54     /**
55      * Cache of images used for elements in this label provider. Label updates
56      * use the method <code>getImage(...)</code> to cache images for
57      * image descriptors. The images are disposed with this label provider.
58      */

59     private Map JavaDoc fImageCache = new HashMap JavaDoc();
60
61     /**
62      * Cache of the fonts used for elements in this label provider. Label updates
63      * use the method <code>getFont(...)</code> to cache fonts for
64      * FontData objects. The fonts are disposed with this label provider.
65      */

66     private Map JavaDoc fFontCache = new HashMap JavaDoc();
67
68     /**
69      * Cache of the colors used for elements in this label provider. Label updates
70      * use the method <code>getColor(...)</code> to cache colors for
71      * RGB values. The colors are disposed with this label provider.
72      */

73     private Map JavaDoc fColorCache = new HashMap JavaDoc();
74     
75     /**
76      * Label listeners
77      */

78     private ListenerList fLabelListeners = new ListenerList();
79     
80     /**
81      * List of updates in progress
82      */

83     private List JavaDoc fUpdatesInProgress = new ArrayList JavaDoc();
84     
85     /**
86      * Constructs a new label provider on the given display
87      */

88     public TreeModelLabelProvider(InternalTreeModelViewer viewer) {
89         fViewer = viewer;
90     }
91     
92     /**
93      * Returns an image for the given image descriptor or <code>null</code>. Adds the image
94      * to a cache of images if it does not already exist.
95      *
96      * @param descriptor image descriptor or <code>null</code>
97      * @return image or <code>null</code>
98      */

99     protected Image getImage(ImageDescriptor descriptor) {
100         if (descriptor == null) {
101             return null;
102         }
103         Image image = (Image) fImageCache.get(descriptor);
104         if (image == null) {
105             image = new Image(getDisplay(), descriptor.getImageData());
106             fImageCache.put(descriptor, image);
107         }
108         return image;
109     }
110
111     /**
112      * Returns the display to use for resource allocation.
113      *
114      * @return display
115      */

116     private Display getDisplay() {
117         return fViewer.getControl().getDisplay();
118     }
119     
120     /**
121      * Returns a font for the given font data or <code>null</code>. Adds the font to the font
122      * cache if not yet created.
123      *
124      * @param fontData font data or <code>null</code>
125      * @return font font or <code>null</code>
126      */

127     protected Font getFont(FontData fontData) {
128         if (fontData == null) {
129             return null;
130         }
131         Font font = (Font) fFontCache.get(fontData);
132         if (font == null) {
133             font = new Font(getDisplay(), fontData);
134             fFontCache.put(fontData, font);
135         }
136         return font;
137     }
138     
139     /**
140      * Returns a color for the given RGB or <code>null</code>. Adds the color to the color
141      * cache if not yet created.
142      *
143      * @param rgb RGB or <code>null</code>
144      * @return color or <code>null</code>
145      */

146     protected Color getColor(RGB rgb) {
147         if (rgb == null) {
148             return null;
149         }
150         Color color = (Color) fColorCache.get(rgb);
151         if (color == null) {
152             color = new Color(getDisplay(), rgb);
153             fColorCache.put(rgb, color);
154         }
155         return color;
156     }
157
158     /* (non-Javadoc)
159      * @see org.eclipse.jface.viewers.BaseLabelProvider#dispose()
160      */

161     public void dispose() {
162         synchronized (fUpdatesInProgress) {
163             Iterator JavaDoc updatesInProgress = fUpdatesInProgress.iterator();
164             while (updatesInProgress.hasNext()) {
165                 ILabelUpdate currentUpdate = (ILabelUpdate) updatesInProgress.next();
166                 currentUpdate.cancel();
167             }
168         }
169         Iterator JavaDoc images = fImageCache.values().iterator();
170         while (images.hasNext()) {
171             Image image = (Image) images.next();
172             image.dispose();
173         }
174         fImageCache.clear();
175         
176         Iterator JavaDoc fonts = fFontCache.values().iterator();
177         while (fonts.hasNext()) {
178             Font font = (Font) fonts.next();
179             font.dispose();
180         }
181         fFontCache.clear();
182         
183         Iterator JavaDoc colors = fColorCache.values().iterator();
184         while (colors.hasNext()) {
185             Color color = (Color) colors.next();
186             color.dispose();
187         }
188         fColorCache.clear();
189
190         super.dispose();
191     }
192
193     public synchronized void update(ViewerCell cell) {
194         // NOT USED - the viewer updates each row instead
195
}
196     
197     public synchronized void update(TreePath elementPath, ViewerRow row) {
198         String JavaDoc[] visibleColumns = fViewer.getVisibleColumns();
199         Object JavaDoc element = elementPath.getLastSegment();
200         IElementLabelProvider presentation = getLabelAdapter(element);
201         if (presentation != null) {
202             presentation.update(new ILabelUpdate[]{new LabelUpdate(elementPath, (TreeItem) row.getItem(), this, visibleColumns, fViewer.getPresentationContext())});
203         } else if (element instanceof String JavaDoc) {
204             // for example, expression error messages
205
row.setText(0, (String JavaDoc)element);
206         }
207     }
208     
209     /**
210      * Returns the presentation context for this label provider.
211      *
212      * @return presentation context
213      */

214     protected IPresentationContext getPresentationContext() {
215         return fViewer.getPresentationContext();
216     }
217     
218     /**
219      * Returns the label provider for the given element or
220      * <code>null</code> if none.
221      *
222      * @param element
223      * element to retrieve adapter for
224      * @return label adapter or <code>null</code>
225      */

226     protected IElementLabelProvider getLabelAdapter(Object JavaDoc element) {
227         IElementLabelProvider adapter = null;
228         if (element instanceof IElementLabelProvider) {
229             adapter = (IElementLabelProvider) element;
230         } else if (element instanceof IAdaptable) {
231             IAdaptable adaptable = (IAdaptable) element;
232             adapter = (IElementLabelProvider) adaptable.getAdapter(IElementLabelProvider.class);
233             if (adapter == null && !(element instanceof PlatformObject)) {
234                 // for objects that don't properly subclass PlatformObject to inherit default
235
// adapters, just delegate to the adapter factory
236
adapter = (IElementLabelProvider) new DebugElementAdapterFactory().getAdapter(element, IElementLabelProvider.class);
237             }
238         }
239         return adapter;
240     }
241
242     /**
243      * A label update is complete.
244      *
245      * @param update
246      */

247     protected synchronized void complete(ILabelUpdate update) {
248         if (update.isCanceled()){
249             updateComplete(update);
250         } else {
251             if (fComplete == null) {
252                 fComplete = new ArrayList JavaDoc();
253                 UIJob job = new UIJob(getDisplay(), "Label Updates") { //$NON-NLS-1$
254
public IStatus runInUIThread(IProgressMonitor monitor) {
255                         LabelUpdate[] updates = null;
256                         synchronized (TreeModelLabelProvider.this) {
257                             updates = (LabelUpdate[]) fComplete.toArray(new LabelUpdate[fComplete.size()]);
258                             fComplete = null;
259                         }
260                         //System.out.println("Changed Labels: " + updates.length);
261
for (int i = 0; i < updates.length; i++) {
262                             updates[i].update();
263                         }
264                         return Status.OK_STATUS;
265                     }
266                 };
267                 job.setSystem(true);
268                 job.schedule(10L);
269             }
270             fComplete.add(update);
271         }
272     }
273     
274     void addLabelUpdateListener(ILabelUpdateListener listener) {
275         fLabelListeners.add(listener);
276     }
277     
278     void removeLabelUpdateListener(ILabelUpdateListener listener) {
279         fLabelListeners.remove(listener);
280     }
281     
282     /**
283      * Notification an update request has started
284      *
285      * @param update
286      */

287     void updateStarted(ILabelUpdate update) {
288         boolean begin = false;
289         synchronized (fUpdatesInProgress) {
290             begin = fUpdatesInProgress.isEmpty();
291             fUpdatesInProgress.add(update);
292         }
293         if (begin) {
294             if (ModelContentProvider.DEBUG_UPDATE_SEQUENCE) {
295                 System.out.println("LABEL SEQUENCE BEGINS"); //$NON-NLS-1$
296
}
297             notifyUpdate(ModelContentProvider.UPDATE_SEQUENCE_BEGINS, null);
298         }
299         if (ModelContentProvider.DEBUG_UPDATE_SEQUENCE) {
300             System.out.println("\tBEGIN - " + update); //$NON-NLS-1$
301
}
302         notifyUpdate(ModelContentProvider.UPDATE_BEGINS, update);
303     }
304     
305     /**
306      * Notification an update request has completed
307      *
308      * @param update
309      */

310     void updateComplete(ILabelUpdate update) {
311         boolean end = false;
312         synchronized (fUpdatesInProgress) {
313             fUpdatesInProgress.remove(update);
314             end = fUpdatesInProgress.isEmpty();
315         }
316         if (ModelContentProvider.DEBUG_UPDATE_SEQUENCE) {
317             System.out.println("\tEND - " + update); //$NON-NLS-1$
318
}
319         notifyUpdate(ModelContentProvider.UPDATE_COMPLETE, update);
320         if (end) {
321             if (ModelContentProvider.DEBUG_UPDATE_SEQUENCE) {
322                 System.out.println("LABEL SEQUENCE ENDS"); //$NON-NLS-1$
323
}
324             notifyUpdate(ModelContentProvider.UPDATE_SEQUENCE_COMPLETE, null);
325         }
326     }
327     
328     protected void notifyUpdate(final int type, final ILabelUpdate update) {
329         if (!fLabelListeners.isEmpty()) {
330             Object JavaDoc[] listeners = fLabelListeners.getListeners();
331             for (int i = 0; i < listeners.length; i++) {
332                 final ILabelUpdateListener listener = (ILabelUpdateListener) listeners[i];
333                 SafeRunner.run(new ISafeRunnable() {
334                     public void run() throws Exception JavaDoc {
335                         switch (type) {
336                             case ModelContentProvider.UPDATE_SEQUENCE_BEGINS:
337                                 listener.labelUpdatesBegin();
338                                 break;
339                             case ModelContentProvider.UPDATE_SEQUENCE_COMPLETE:
340                                 listener.labelUpdatesComplete();
341                                 break;
342                             case ModelContentProvider.UPDATE_BEGINS:
343                                 listener.labelUpdateStarted(update);
344                                 break;
345                             case ModelContentProvider.UPDATE_COMPLETE:
346                                 listener.labelUpdateComplete(update);
347                                 break;
348                         }
349                     }
350                     public void handleException(Throwable JavaDoc exception) {
351                         DebugUIPlugin.log(exception);
352                     }
353                 });
354             }
355         }
356     }
357
358 }
359
Popular Tags