1 package com
.swtdesigner
;
2 import java
.io
.BufferedInputStream
;
3 import java
.io
.FileInputStream
;
4 import java
.io
.InputStream
;
5 import java
.util
.HashMap
;
6 import java
.util
.Iterator
;
8 import org
.eclipse
.swt
.SWT
;
9 import org
.eclipse
.swt
.graphics
.Color
;
10 import org
.eclipse
.swt
.graphics
.Cursor
;
11 import org
.eclipse
.swt
.graphics
.Font
;
12 import org
.eclipse
.swt
.graphics
.FontData
;
13 import org
.eclipse
.swt
.graphics
.GC
;
14 import org
.eclipse
.swt
.graphics
.Image
;
15 import org
.eclipse
.swt
.graphics
.ImageData
;
16 import org
.eclipse
.swt
.graphics
.Point
;
17 import org
.eclipse
.swt
.graphics
.RGB
;
18 import org
.eclipse
.swt
.graphics
.Rectangle
;
19 import org
.eclipse
.swt
.widgets
.Canvas
;
20 import org
.eclipse
.swt
.widgets
.Control
;
21 import org
.eclipse
.swt
.widgets
.CoolBar
;
22 import org
.eclipse
.swt
.widgets
.CoolItem
;
23 import org
.eclipse
.swt
.widgets
.Display
;
26 * Utility class for managing OS resources associated with SWT controls such as
27 * colors, fonts, images, etc.
29 * !!! IMPORTANT !!! Application code must explicitly invoke the <code>dispose()</code>
30 * method to release the operating system resources managed by cached objects
31 * when those objects and OS resources are no longer needed (e.g. on
32 * application shutdown)
34 * This class may be freely distributed as part of any application or plugin.
36 * Copyright (c) 2003 - 2005, Instantiations, Inc. <br>All Rights Reserved
41 public class SWTResourceManager
{
44 * Dispose of cached objects and their underlying OS resources. This should
45 * only be called when the cached objects are no longer needed (e.g. on
46 * application shutdown)
48 public static void dispose() {
55 //////////////////////////////
57 //////////////////////////////
60 * Maps RGB values to colors
62 private static HashMap
<RGB
, Color
> m_ColorMap
= new HashMap
<RGB
, Color
>();
65 * Returns the system color matching the specific ID
66 * @param systemColorID int The ID value for the color
67 * @return Color The system color matching the specific ID
69 public static Color
getColor(int systemColorID
) {
70 Display display
= Display
.getCurrent();
71 return display
.getSystemColor(systemColorID
);
75 * Returns a color given its red, green and blue component values
76 * @param r int The red component of the color
77 * @param g int The green component of the color
78 * @param b int The blue component of the color
79 * @return Color The color matching the given red, green and blue componet values
81 public static Color
getColor(int r
, int g
, int b
) {
82 return getColor(new RGB(r
, g
, b
));
86 * Returns a color given its RGB value
87 * @param rgb RGB The RGB value of the color
88 * @return Color The color matching the RGB value
90 public static Color
getColor(RGB rgb
) {
91 Color color
= m_ColorMap
.get(rgb
);
93 Display display
= Display
.getCurrent();
94 color
= new Color(display
, rgb
);
95 m_ColorMap
.put(rgb
, color
);
101 * Dispose of all the cached colors
103 public static void disposeColors() {
104 for (Iterator
<Color
> iter
= m_ColorMap
.values().iterator(); iter
.hasNext();)
105 iter
.next().dispose();
109 //////////////////////////////
111 //////////////////////////////
114 * Maps image names to images
116 private static HashMap
<String
, Image
> m_ClassImageMap
= new HashMap
<String
, Image
>();
119 * Maps images to image decorators
121 private static HashMap
<Image
, HashMap
<Image
, Image
>> m_ImageToDecoratorMap
= new HashMap
<Image
, HashMap
<Image
, Image
>>();
124 * Returns an image encoded by the specified input stream
125 * @param is InputStream The input stream encoding the image data
126 * @return Image The image encoded by the specified input stream
128 protected static Image
getImage(InputStream is
) {
129 Display display
= Display
.getCurrent();
130 ImageData data
= new ImageData(is
);
131 if (data
.transparentPixel
> 0)
132 return new Image(display
, data
, data
.getTransparencyMask());
133 return new Image(display
, data
);
137 * Returns an image stored in the file at the specified path
138 * @param path String The path to the image file
139 * @return Image The image stored in the file at the specified path
141 public static Image
getImage(String path
) {
142 return getImage("default", path
); //$NON-NLS-1$
146 * Returns an image stored in the file at the specified path
147 * @param section The section to which belongs specified image
148 * @param path String The path to the image file
149 * @return Image The image stored in the file at the specified path
151 public static Image
getImage(String section
, String path
) {
152 String key
= section
+ '|' + SWTResourceManager
.class.getName() + '|' + path
;
153 Image image
= m_ClassImageMap
.get(key
);
156 FileInputStream fis
= new FileInputStream(path
);
157 image
= getImage(fis
);
158 m_ClassImageMap
.put(key
, image
);
160 } catch (Exception e
) {
161 image
= getMissingImage();
162 m_ClassImageMap
.put(key
, image
);
169 * Returns an image stored in the file at the specified path relative to the specified class
170 * @param clazz Class The class relative to which to find the image
171 * @param path String The path to the image file
172 * @return Image The image stored in the file at the specified path
174 public static Image
getImage(Class
<?
> clazz
, String path
) {
175 String key
= clazz
.getName() + '|' + path
;
176 Image image
= m_ClassImageMap
.get(key
);
179 if (path
.length() > 0 && path
.charAt(0) == '/') {
180 String newPath
= path
.substring(1, path
.length());
181 image
= getImage(new BufferedInputStream(clazz
.getClassLoader().getResourceAsStream(newPath
)));
183 image
= getImage(clazz
.getResourceAsStream(path
));
185 m_ClassImageMap
.put(key
, image
);
186 } catch (Exception e
) {
187 image
= getMissingImage();
188 m_ClassImageMap
.put(key
, image
);
194 private static final int MISSING_IMAGE_SIZE
= 10;
195 private static Image
getMissingImage() {
196 Image image
= new Image(Display
.getCurrent(), MISSING_IMAGE_SIZE
, MISSING_IMAGE_SIZE
);
198 GC gc
= new GC(image
);
199 gc
.setBackground(getColor(SWT
.COLOR_RED
));
200 gc
.fillRectangle(0, 0, MISSING_IMAGE_SIZE
, MISSING_IMAGE_SIZE
);
207 * Style constant for placing decorator image in top left corner of base image.
209 public static final int TOP_LEFT
= 1;
211 * Style constant for placing decorator image in top right corner of base image.
213 public static final int TOP_RIGHT
= 2;
215 * Style constant for placing decorator image in bottom left corner of base image.
217 public static final int BOTTOM_LEFT
= 3;
219 * Style constant for placing decorator image in bottom right corner of base image.
221 public static final int BOTTOM_RIGHT
= 4;
224 * Returns an image composed of a base image decorated by another image
225 * @param baseImage Image The base image that should be decorated
226 * @param decorator Image The image to decorate the base image
227 * @return Image The resulting decorated image
229 public static Image
decorateImage(Image baseImage
, Image decorator
) {
230 return decorateImage(baseImage
, decorator
, BOTTOM_RIGHT
);
234 * Returns an image composed of a base image decorated by another image
235 * @param baseImage Image The base image that should be decorated
236 * @param decorator Image The image to decorate the base image
237 * @param corner The corner to place decorator image
238 * @return Image The resulting decorated image
240 public static Image
decorateImage(final Image baseImage
, final Image decorator
, final int corner
) {
241 HashMap
<Image
, Image
> decoratedMap
= m_ImageToDecoratorMap
.get(baseImage
);
242 if (decoratedMap
== null) {
243 decoratedMap
= new HashMap
<Image
, Image
>();
244 m_ImageToDecoratorMap
.put(baseImage
, decoratedMap
);
246 Image result
= decoratedMap
.get(decorator
);
247 if (result
== null) {
248 Rectangle bid
= baseImage
.getBounds();
249 Rectangle did
= decorator
.getBounds();
250 result
= new Image(Display
.getCurrent(), bid
.width
, bid
.height
);
251 GC gc
= new GC(result
);
252 gc
.drawImage(baseImage
, 0, 0);
254 if (corner
== TOP_LEFT
) {
255 gc
.drawImage(decorator
, 0, 0);
256 } else if (corner
== TOP_RIGHT
) {
257 gc
.drawImage(decorator
, bid
.width
- did
.width
- 1, 0);
258 } else if (corner
== BOTTOM_LEFT
) {
259 gc
.drawImage(decorator
, 0, bid
.height
- did
.height
- 1);
260 } else if (corner
== BOTTOM_RIGHT
) {
261 gc
.drawImage(decorator
, bid
.width
- did
.width
- 1, bid
.height
- did
.height
- 1);
265 decoratedMap
.put(decorator
, result
);
271 * Dispose all of the cached images
273 public static void disposeImages() {
274 for (Iterator
<Image
> I
= m_ClassImageMap
.values().iterator(); I
.hasNext();)
276 m_ClassImageMap
.clear();
278 for (Iterator
<HashMap
<Image
, Image
>> I
= m_ImageToDecoratorMap
.values().iterator(); I
.hasNext();) {
279 HashMap
<Image
, Image
> decoratedMap
= I
.next();
280 for (Iterator
<Image
> J
= decoratedMap
.values().iterator(); J
.hasNext();) {
281 Image image
= J
.next();
288 * Dispose cached images in specified section
289 * @param section the section do dispose
291 public static void disposeImages(String section
) {
292 for (Iterator
<String
> I
= m_ClassImageMap
.keySet().iterator(); I
.hasNext();) {
293 String key
= I
.next();
294 if (!key
.startsWith(section
+ '|'))
296 Image image
= m_ClassImageMap
.get(key
);
302 //////////////////////////////
304 //////////////////////////////
307 * Maps font names to fonts
309 private static HashMap
<String
, Font
> m_FontMap
= new HashMap
<String
, Font
>();
312 * Maps fonts to their bold versions
314 private static HashMap
<Font
, Font
> m_FontToBoldFontMap
= new HashMap
<Font
, Font
>();
317 * Returns a font based on its name, height and style
318 * @param name String The name of the font
319 * @param height int The height of the font
320 * @param style int The style of the font
321 * @return Font The font matching the name, height and style
323 public static Font
getFont(String name
, int height
, int style
) {
324 return getFont(name
, height
, style
, false, false);
329 * Returns a font based on its name, height and style.
330 * Windows-specific strikeout and underline flags are also supported.
331 * @param name String The name of the font
332 * @param size int The size of the font
333 * @param style int The style of the font
334 * @param strikeout boolean The strikeout flag (warning: Windows only)
335 * @param underline boolean The underline flag (warning: Windows only)
336 * @return Font The font matching the name, height, style, strikeout and underline
338 public static Font
getFont(String name
, int size
, int style
, boolean strikeout
, boolean underline
) {
339 String fontName
= name
+ '|' + size
+ '|' + style
+ '|' + strikeout
+ '|' + underline
;
340 Font font
= m_FontMap
.get(fontName
);
342 FontData fontData
= new FontData(name
, size
, style
);
343 if (strikeout
|| underline
) {
345 Class
<?
> logFontClass
= Class
.forName("org.eclipse.swt.internal.win32.LOGFONT"); //$NON-NLS-1$
346 Object logFont
= FontData
.class.getField("data").get(fontData
); //$NON-NLS-1$
347 if (logFont
!= null && logFontClass
!= null) {
349 logFontClass
.getField("lfStrikeOut").set(logFont
, new Byte((byte) 1)); //$NON-NLS-1$
352 logFontClass
.getField("lfUnderline").set(logFont
, new Byte((byte) 1)); //$NON-NLS-1$
355 } catch (Throwable e
) {
357 "Unable to set underline or strikeout" + " (probably on a non-Windows platform). " + e
); //$NON-NLS-1$ //$NON-NLS-2$
360 font
= new Font(Display
.getCurrent(), fontData
);
361 m_FontMap
.put(fontName
, font
);
368 * Return a bold version of the give font
369 * @param baseFont Font The font for whoch a bold version is desired
370 * @return Font The bold version of the give font
372 public static Font
getBoldFont(Font baseFont
) {
373 Font font
= m_FontToBoldFontMap
.get(baseFont
);
375 FontData fontDatas
[] = baseFont
.getFontData();
376 FontData data
= fontDatas
[0];
377 font
= new Font(Display
.getCurrent(), data
.getName(), data
.getHeight(), SWT
.BOLD
);
378 m_FontToBoldFontMap
.put(baseFont
, font
);
384 * Dispose all of the cached fonts
386 public static void disposeFonts() {
388 for (Iterator
<Font
> iter
= m_FontMap
.values().iterator(); iter
.hasNext();)
389 iter
.next().dispose();
392 for (Iterator
<Font
> iter
= m_FontToBoldFontMap
.values().iterator(); iter
.hasNext();)
393 iter
.next().dispose();
394 m_FontToBoldFontMap
.clear();
397 //////////////////////////////
399 //////////////////////////////
402 * Fix the layout of the specified CoolBar
403 * @param bar CoolBar The CoolBar that shgoud be fixed
405 public static void fixCoolBarSize(CoolBar bar
) {
406 CoolItem
[] items
= bar
.getItems();
407 // ensure that each item has control (at least empty one)
408 for (int i
= 0; i
< items
.length
; i
++) {
409 CoolItem item
= items
[i
];
410 if (item
.getControl() == null)
411 item
.setControl(new Canvas(bar
, SWT
.NONE
) {
413 public Point
computeSize(int wHint
, int hHint
, boolean changed
) {
414 return new Point(20, 20);
418 // compute size for each item
419 for (int i
= 0; i
< items
.length
; i
++) {
420 CoolItem item
= items
[i
];
421 Control control
= item
.getControl();
423 Point size
= control
.getSize();
424 item
.setSize(item
.computeSize(size
.x
, size
.y
));
428 //////////////////////////////
430 //////////////////////////////
433 * Maps IDs to cursors
435 private static HashMap
<Integer
, Cursor
> m_IdToCursorMap
= new HashMap
<Integer
, Cursor
>();
438 * Returns the system cursor matching the specific ID
439 * @param id int The ID value for the cursor
440 * @return Cursor The system cursor matching the specific ID
442 public static Cursor
getCursor(int id
) {
443 Integer key
= new Integer(id
);
444 Cursor cursor
= m_IdToCursorMap
.get(key
);
445 if (cursor
== null) {
446 cursor
= new Cursor(Display
.getDefault(), id
);
447 m_IdToCursorMap
.put(key
, cursor
);
453 * Dispose all of the cached cursors
455 public static void disposeCursors() {
456 for (Iterator
<Cursor
> iter
= m_IdToCursorMap
.values().iterator(); iter
.hasNext();)
457 iter
.next().dispose();
458 m_IdToCursorMap
.clear();