KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > internal > util > Descriptors


1 /*******************************************************************************
2  * Copyright (c) 2005, 2006 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.ui.internal.util;
12
13 import java.lang.reflect.InvocationTargetException JavaDoc;
14 import java.lang.reflect.Method JavaDoc;
15 import java.util.ArrayList JavaDoc;
16 import java.util.Iterator JavaDoc;
17 import java.util.List JavaDoc;
18
19 import org.eclipse.jface.resource.ColorDescriptor;
20 import org.eclipse.jface.resource.DeviceResourceDescriptor;
21 import org.eclipse.jface.resource.DeviceResourceException;
22 import org.eclipse.jface.resource.FontDescriptor;
23 import org.eclipse.jface.resource.ImageDescriptor;
24 import org.eclipse.jface.resource.JFaceResources;
25 import org.eclipse.jface.resource.ResourceManager;
26 import org.eclipse.swt.events.DisposeEvent;
27 import org.eclipse.swt.events.DisposeListener;
28 import org.eclipse.swt.graphics.Color;
29 import org.eclipse.swt.graphics.Font;
30 import org.eclipse.swt.graphics.Image;
31 import org.eclipse.swt.widgets.Button;
32 import org.eclipse.swt.widgets.Control;
33 import org.eclipse.swt.widgets.Item;
34 import org.eclipse.swt.widgets.Label;
35 import org.eclipse.swt.widgets.TableItem;
36 import org.eclipse.swt.widgets.ToolItem;
37 import org.eclipse.swt.widgets.Widget;
38 import org.eclipse.ui.internal.WorkbenchPlugin;
39
40 /**
41  * Contains a bunch of helper methods that allow JFace resource descriptors to be passed
42  * directly to SWT widgets without worrying about resource allocation. This class is internal,
43  * but it should be moved into JFace if the pattern is found generally useful. The current
44  * implementation uses a lot of reflection to save repeated code, but this could all be inlined
45  * (without reflection) if performance turns out to be a problem.
46  *
47  * <p>
48  * For example, an Image might be passed to a TableItem as follows:
49  * <p>
50  *
51  * <code>
52  * ImageDescriptor someDescriptor = ...;
53  * TableItem someTableItem = ...;
54  * ResourceManager manager = JFaceResources.getResources();
55  *
56  * Image actualImage = manager.createImage(someDescriptor);
57  * someTableItem.setImage(actualImage);
58  *
59  * // do something with the table item
60  *
61  * someTableItem.dispose();
62  * manager.destroyImage(someDescriptor);
63  * </code>
64  *
65  * <p>
66  * It is much more convenient to do the following:
67  * </p>
68  *
69  * <code>
70  * ImageDescriptor someDescriptor = ...;
71  * TableItem someTableItem = ...;
72  *
73  * Descriptors.setImage(someTableItem, someDescriptor);
74  *
75  * // do something with the table item
76  *
77  * someTableItem.dispose();
78  * </code>
79  *
80  * <p>
81  * This class tries to behave as if the table item itself had a set method that took a descriptor.
82  * Resource allocation and deallocation happens for free. All the methods are leakproof. That is,
83  * if any images, colors, etc. need to be allocated and passed to the SWT widget, they will be
84  * deallocated automatically when the widget goes away (the implementation hooks a dispose listener
85  * on the widget which cleans up as soon as the widget is disposed).
86  * </p>
87  *
88  * @since 3.1
89  */

90 public final class Descriptors {
91     private static final String JavaDoc DISPOSE_LIST = "Descriptors.disposeList"; //$NON-NLS-1$
92

93     private Descriptors() {
94     }
95     
96     private static final class ResourceMethod {
97         ResourceMethod(Method JavaDoc m, String JavaDoc id) {
98             method = m;
99             this.id = id;
100         }
101         
102         Method JavaDoc method;
103         DeviceResourceDescriptor oldDescriptor;
104         String JavaDoc id;
105                 
106         public void invoke(Widget toCall, DeviceResourceDescriptor newDescriptor) {
107             if (newDescriptor == oldDescriptor) {
108                 return;
109             }
110             
111             ResourceManager mgr = JFaceResources.getResources(toCall.getDisplay());
112             
113             Object JavaDoc newResource;
114             try {
115                 newResource = newDescriptor == null? null : mgr.create(newDescriptor);
116             } catch (DeviceResourceException e1) {
117                 WorkbenchPlugin.log(e1);
118                 return;
119             }
120             
121             try {
122                 method.invoke(toCall, new Object JavaDoc[] {newResource});
123             } catch (IllegalArgumentException JavaDoc e) {
124                 throw e;
125             } catch (IllegalAccessException JavaDoc e) {
126                 WorkbenchPlugin.log(e);
127                 return;
128             } catch (InvocationTargetException JavaDoc e) {
129                 if (e.getTargetException() instanceof RuntimeException JavaDoc) {
130                     throw (RuntimeException JavaDoc)e.getTargetException();
131                 }
132                 WorkbenchPlugin.log(e);
133                 return;
134             }
135             
136             // Deallocate the old image
137
if (oldDescriptor != null) {
138                 // Dispose the image
139
mgr.destroy(oldDescriptor);
140             }
141             
142             // Remember the new image for next time
143

144             oldDescriptor = newDescriptor;
145         }
146
147         public void dispose() {
148             // Deallocate the old image
149
if (oldDescriptor != null) {
150                 ResourceManager mgr = JFaceResources.getResources();
151                 // Dispose the image
152
mgr.destroy(oldDescriptor);
153                 oldDescriptor = null;
154             }
155
156         }
157     }
158     
159     private static DisposeListener disposeListener = new DisposeListener() {
160         public void widgetDisposed(DisposeEvent e) {
161             doDispose(e.widget);
162         }
163     };
164     
165     // Item //////////////////////////////////////////////////////////////////////////////////
166

167     /**
168      * Sets the image on the given ToolItem. The image will be automatically allocated and
169      * disposed as needed.
170      *
171      * @since 3.1
172      *
173      * @param item
174      * @param descriptor
175      */

176     public static void setImage(Item item, ImageDescriptor descriptor) {
177         callMethod(item, "setImage", descriptor, Image.class); //$NON-NLS-1$
178
}
179     
180     // ToolItem //////////////////////////////////////////////////////////////////////////////
181

182     public static void setHotImage(ToolItem item, ImageDescriptor descriptor) {
183         callMethod(item, "setHotImage", descriptor, Image.class); //$NON-NLS-1$
184
}
185
186     public static void setDisabledImage(ToolItem item, ImageDescriptor descriptor) {
187         callMethod(item, "setDisabledImage", descriptor, Image.class); //$NON-NLS-1$
188
}
189
190     // TableItem //////////////////////////////////////////////////////////////////////////////
191

192     public static void setFont(TableItem item, FontDescriptor descriptor) {
193         callMethod(item, "setFont", descriptor, Font.class); //$NON-NLS-1$
194
}
195     
196     public static void setBackground(TableItem item, ColorDescriptor descriptor) {
197         callMethod(item, "setBackground", descriptor, Color.class); //$NON-NLS-1$
198
}
199
200     public static void setForeground(TableItem item, ColorDescriptor descriptor) {
201         callMethod(item, "setForeground", descriptor, Color.class); //$NON-NLS-1$
202
}
203     
204     // Control ///////////////////////////////////////////////////////////////////////////////
205

206     public static void setBackground(Control control, ColorDescriptor descriptor) {
207         callMethod(control, "setBackground", descriptor, Color.class); //$NON-NLS-1$
208
}
209     
210     public static void setForeground(Control control, ColorDescriptor descriptor) {
211         callMethod(control, "setForeground", descriptor, Color.class); //$NON-NLS-1$
212
}
213     
214     // Button ///////////////////////////////////////////////////////////////////////////////
215

216     public static void setImage(Button button, ImageDescriptor descriptor) {
217         callMethod(button, "setImage", descriptor, Image.class); //$NON-NLS-1$
218
}
219
220     public static void setImage(Label label, ImageDescriptor descriptor) {
221         callMethod(label, "setImage", descriptor, Image.class); //$NON-NLS-1$
222
}
223     
224     private static ResourceMethod getResourceMethod(Widget toCall, String JavaDoc methodName, Class JavaDoc resourceType) throws NoSuchMethodException JavaDoc {
225         Object JavaDoc oldData = toCall.getData(DISPOSE_LIST);
226         
227         if (oldData instanceof List JavaDoc) {
228             // Check for existing data
229
for (Iterator JavaDoc iter = ((List JavaDoc)oldData).iterator(); iter.hasNext();) {
230                 ResourceMethod method = (ResourceMethod) iter.next();
231                 
232                 if (method.id == methodName) {
233                     return method;
234                 }
235             }
236         } if (oldData instanceof ResourceMethod) {
237             if (((ResourceMethod)oldData).id == methodName) {
238                 return ((ResourceMethod)oldData);
239             }
240             
241             List JavaDoc newList = new ArrayList JavaDoc();
242             newList.add(oldData);
243             oldData = newList;
244             toCall.setData(DISPOSE_LIST, oldData);
245         }
246         
247         // At this point, the DISPOSE_LIST data is either null or points to an ArrayList
248

249         Class JavaDoc clazz = toCall.getClass();
250         
251         Method JavaDoc method;
252         try {
253             method = clazz.getMethod(methodName, new Class JavaDoc[] {resourceType});
254         } catch (SecurityException JavaDoc e) {
255             throw e;
256         }
257         
258         ResourceMethod result = new ResourceMethod(method, methodName);
259
260         if (oldData == null) {
261             toCall.setData(DISPOSE_LIST, result);
262             toCall.addDisposeListener(disposeListener);
263         } else {
264             ((List JavaDoc)oldData).add(result);
265         }
266         
267         return result;
268     }
269     
270     private static void callMethod(Widget toCall, String JavaDoc methodName, DeviceResourceDescriptor descriptor, Class JavaDoc resourceType) {
271         ResourceMethod method;
272         try {
273             method = getResourceMethod(toCall, methodName, resourceType);
274         } catch (NoSuchMethodException JavaDoc e) {
275             WorkbenchPlugin.log(e);
276             return;
277         }
278        
279         method.invoke(toCall, descriptor);
280     }
281     
282     private static void doDispose(Widget widget) {
283         Object JavaDoc oldData = widget.getData(DISPOSE_LIST);
284         
285         if (oldData instanceof ArrayList JavaDoc) {
286             ArrayList JavaDoc list = ((ArrayList JavaDoc)oldData);
287             ResourceMethod[] data = (ResourceMethod[]) list.toArray(new ResourceMethod[list.size()]);
288             
289             // Clear out the images
290
for (int i = 0; i < data.length; i++) {
291                 ResourceMethod method = data[i];
292
293                 method.dispose();
294             }
295         }
296         
297         if (oldData instanceof ResourceMethod) {
298             ((ResourceMethod)oldData).dispose();
299         }
300     }
301     
302 }
303
Popular Tags