Skip to content

Package: SWTResourceManager

SWTResourceManager

nameinstructionbranchcomplexitylinemethod
SWTResourceManager()
M: 3 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
decorateImage(Image, Image)
M: 5 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
decorateImage(Image, Image, int)
M: 132 C: 0
0%
M: 18 C: 0
0%
M: 10 C: 0
0%
M: 28 C: 0
0%
M: 1 C: 0
0%
dispose()
M: 5 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 5 C: 0
0%
M: 1 C: 0
0%
disposeColors()
M: 17 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 4 C: 0
0%
M: 1 C: 0
0%
disposeCursors()
M: 17 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 4 C: 0
0%
M: 1 C: 0
0%
disposeFonts()
M: 33 C: 0
0%
M: 4 C: 0
0%
M: 3 C: 0
0%
M: 7 C: 0
0%
M: 1 C: 0
0%
disposeImages()
M: 61 C: 0
0%
M: 10 C: 0
0%
M: 6 C: 0
0%
M: 12 C: 0
0%
M: 1 C: 0
0%
getBoldFont(Font)
M: 31 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 7 C: 0
0%
M: 1 C: 0
0%
getColor(RGB)
M: 22 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 6 C: 0
0%
M: 1 C: 0
0%
getColor(int)
M: 6 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 2 C: 0
0%
M: 1 C: 0
0%
getColor(int, int, int)
M: 8 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
getCursor(int)
M: 23 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 6 C: 0
0%
M: 1 C: 0
0%
getFont(String, int, int)
M: 7 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
getFont(String, int, int, boolean, boolean)
M: 96 C: 0
0%
M: 14 C: 0
0%
M: 8 C: 0
0%
M: 19 C: 0
0%
M: 1 C: 0
0%
getImage(Class, String)
M: 40 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 9 C: 0
0%
M: 1 C: 0
0%
getImage(InputStream)
M: 30 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 6 C: 0
0%
M: 1 C: 0
0%
getImage(String)
M: 29 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 8 C: 0
0%
M: 1 C: 0
0%
getMissingImage()
M: 26 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 6 C: 0
0%
M: 1 C: 0
0%
static {...}
M: 24 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 6 C: 0
0%
M: 1 C: 0
0%

Coverage

1: /**
2: * Copyright (c) 2011 Google, Inc.
3: *
4: * All rights reserved. This program and the accompanying materials
5: * are made available under the terms of the Eclipse Public License 2.0
6: * which accompanies this distribution, and is available at
7: * https://www.eclipse.org/legal/epl-2.0/
8: *
9: * SPDX-License-Identifier: EPL-2.0
10: *
11: * Contributors:
12: * Google, Inc. - initial API and implementation
13: * *****************************************************************************
14: */
15: package org.eclipse.emf.ecp.cdo.internal.ui;
16:
17: import java.io.FileInputStream;
18: import java.io.IOException;
19: import java.io.InputStream;
20: import java.util.HashMap;
21: import java.util.Map;
22:
23: import org.eclipse.swt.SWT;
24: import org.eclipse.swt.graphics.Color;
25: import org.eclipse.swt.graphics.Cursor;
26: import org.eclipse.swt.graphics.Font;
27: import org.eclipse.swt.graphics.FontData;
28: import org.eclipse.swt.graphics.GC;
29: import org.eclipse.swt.graphics.Image;
30: import org.eclipse.swt.graphics.ImageData;
31: import org.eclipse.swt.graphics.RGB;
32: import org.eclipse.swt.graphics.Rectangle;
33: import org.eclipse.swt.widgets.Display;
34:
35: /**
36: * Utility class for managing OS resources associated with SWT controls such as colors, fonts, images, etc.
37: * <p>
38: * !!! IMPORTANT !!! Application code must explicitly invoke the <code>dispose()</code> method to release the operating
39: * system resources managed by cached objects when those objects and OS resources are no longer needed (e.g. on
40: * application shutdown)
41: * <p>
42: * This class may be freely distributed as part of any application or plugin.
43: * <p>
44: *
45: * @author scheglov_ke
46: * @author Dan Rubel
47: * @generated
48: */
49: public class SWTResourceManager {
50:
51:         // //////////////////////////////////////////////////////////////////////////
52:         //
53:         // Color
54:         //
55:         // //////////////////////////////////////////////////////////////////////////
56:         private static Map<RGB, Color> m_colorMap = new HashMap<RGB, Color>();
57:
58:         /**
59:          * Returns the system {@link Color} matching the specific ID.
60:          *
61:          * @param systemColorID
62:          * the ID value for the color
63:          * @return the system {@link Color} matching the specific ID
64:          */
65:         public static Color getColor(int systemColorID) {
66:                 final Display display = Display.getCurrent();
67:                 return display.getSystemColor(systemColorID);
68:         }
69:
70:         /**
71:          * Returns a {@link Color} given its red, green and blue component values.
72:          *
73:          * @param r
74:          * the red component of the color
75:          * @param g
76:          * the green component of the color
77:          * @param b
78:          * the blue component of the color
79:          * @return the {@link Color} matching the given red, green and blue component values
80:          */
81:         public static Color getColor(int r, int g, int b) {
82:                 return getColor(new RGB(r, g, b));
83:         }
84:
85:         /**
86:          * Returns a {@link Color} given its RGB value.
87:          *
88:          * @param rgb
89:          * the {@link RGB} value of the color
90:          * @return the {@link Color} matching the RGB value
91:          */
92:         public static Color getColor(RGB rgb) {
93:                 Color color = m_colorMap.get(rgb);
94:•                if (color == null) {
95:                         final Display display = Display.getCurrent();
96:                         color = new Color(display, rgb);
97:                         m_colorMap.put(rgb, color);
98:                 }
99:                 return color;
100:         }
101:
102:         /**
103:          * Dispose of all the cached {@link Color}'s.
104:          */
105:         public static void disposeColors() {
106:•                for (final Color color : m_colorMap.values()) {
107:                         color.dispose();
108:                 }
109:                 m_colorMap.clear();
110:         }
111:
112:         // //////////////////////////////////////////////////////////////////////////
113:         //
114:         // Image
115:         //
116:         // //////////////////////////////////////////////////////////////////////////
117:         /**
118:          * Maps image paths to images.
119:          */
120:         private static Map<String, Image> m_imageMap = new HashMap<String, Image>();
121:
122:         /**
123:          * Returns an {@link Image} encoded by the specified {@link InputStream}.
124:          *
125:          * @param stream
126:          * the {@link InputStream} encoding the image data
127:          * @return the {@link Image} encoded by the specified input stream
128:          */
129:         protected static Image getImage(InputStream stream) throws IOException {
130:                 try {
131:                         final Display display = Display.getCurrent();
132:                         final ImageData data = new ImageData(stream);
133:•                        if (data.transparentPixel > 0) {
134:                                 return new Image(display, data, data.getTransparencyMask());
135:                         }
136:                         return new Image(display, data);
137:                 } finally {
138:                         stream.close();
139:                 }
140:         }
141:
142:         /**
143:          * Returns an {@link Image} stored in the file at the specified path.
144:          *
145:          * @param path
146:          * the path to the image file
147:          * @return the {@link Image} stored in the file at the specified path
148:          */
149:         public static Image getImage(String path) {
150:                 Image image = m_imageMap.get(path);
151:•                if (image == null) {
152:                         try {
153:                                 image = getImage(new FileInputStream(path));
154:                                 m_imageMap.put(path, image);
155:                         } catch (final Exception e) {
156:                                 image = getMissingImage();
157:                                 m_imageMap.put(path, image);
158:                         }
159:                 }
160:                 return image;
161:         }
162:
163:         /**
164:          * Returns an {@link Image} stored in the file at the specified path relative to the specified class.
165:          *
166:          * @param clazz
167:          * the {@link Class} relative to which to find the image
168:          * @param path
169:          * the path to the image file, if starts with <code>'/'</code>
170:          * @return the {@link Image} stored in the file at the specified path
171:          */
172:         public static Image getImage(Class<?> clazz, String path) {
173:                 final String key = clazz.getName() + '|' + path;
174:                 Image image = m_imageMap.get(key);
175:•                if (image == null) {
176:                         try {
177:                                 image = getImage(clazz.getResourceAsStream(path));
178:                                 m_imageMap.put(key, image);
179:                         } catch (final Exception e) {
180:                                 image = getMissingImage();
181:                                 m_imageMap.put(key, image);
182:                         }
183:                 }
184:                 return image;
185:         }
186:
187:         private static final int MISSING_IMAGE_SIZE = 10;
188:
189:         /**
190:          * @return the small {@link Image} that can be used as placeholder for missing image.
191:          */
192:         private static Image getMissingImage() {
193:                 final Image image = new Image(Display.getCurrent(), MISSING_IMAGE_SIZE, MISSING_IMAGE_SIZE);
194:                 //
195:                 final GC gc = new GC(image);
196:                 gc.setBackground(getColor(SWT.COLOR_RED));
197:                 gc.fillRectangle(0, 0, MISSING_IMAGE_SIZE, MISSING_IMAGE_SIZE);
198:                 gc.dispose();
199:                 //
200:                 return image;
201:         }
202:
203:         /**
204:          * Style constant for placing decorator image in top left corner of base image.
205:          */
206:         public static final int TOP_LEFT = 1;
207:
208:         /**
209:          * Style constant for placing decorator image in top right corner of base image.
210:          */
211:         public static final int TOP_RIGHT = 2;
212:
213:         /**
214:          * Style constant for placing decorator image in bottom left corner of base image.
215:          */
216:         public static final int BOTTOM_LEFT = 3;
217:
218:         /**
219:          * Style constant for placing decorator image in bottom right corner of base image.
220:          */
221:         public static final int BOTTOM_RIGHT = 4;
222:
223:         /**
224:          * Internal value.
225:          */
226:         protected static final int LAST_CORNER_KEY = 5;
227:
228:         /**
229:          * Maps images to decorated images.
230:          */
231:         @SuppressWarnings("unchecked")
232:         private static Map<Image, Map<Image, Image>>[] m_decoratedImageMap = new Map[LAST_CORNER_KEY];
233:
234:         /**
235:          * Returns an {@link Image} composed of a base image decorated by another image.
236:          *
237:          * @param baseImage
238:          * the base {@link Image} that should be decorated
239:          * @param decorator
240:          * the {@link Image} to decorate the base image
241:          * @return {@link Image} The resulting decorated image
242:          */
243:         public static Image decorateImage(Image baseImage, Image decorator) {
244:                 return decorateImage(baseImage, decorator, BOTTOM_RIGHT);
245:         }
246:
247:         /**
248:          * Returns an {@link Image} composed of a base image decorated by another image.
249:          *
250:          * @param baseImage
251:          * the base {@link Image} that should be decorated
252:          * @param decorator
253:          * the {@link Image} to decorate the base image
254:          * @param corner
255:          * the corner to place decorator image
256:          * @return the resulting decorated {@link Image}
257:          */
258:         public static Image decorateImage(final Image baseImage, final Image decorator, final int corner) {
259:•                if (corner <= 0 || corner >= LAST_CORNER_KEY) {
260:                         throw new IllegalArgumentException("Wrong decorate corner"); //$NON-NLS-1$
261:                 }
262:                 Map<Image, Map<Image, Image>> cornerDecoratedImageMap = m_decoratedImageMap[corner];
263:•                if (cornerDecoratedImageMap == null) {
264:                         cornerDecoratedImageMap = new HashMap<Image, Map<Image, Image>>();
265:                         m_decoratedImageMap[corner] = cornerDecoratedImageMap;
266:                 }
267:                 Map<Image, Image> decoratedMap = cornerDecoratedImageMap.get(baseImage);
268:•                if (decoratedMap == null) {
269:                         decoratedMap = new HashMap<Image, Image>();
270:                         cornerDecoratedImageMap.put(baseImage, decoratedMap);
271:                 }
272:                 //
273:                 Image result = decoratedMap.get(decorator);
274:•                if (result == null) {
275:                         final Rectangle bib = baseImage.getBounds();
276:                         final Rectangle dib = decorator.getBounds();
277:                         //
278:                         result = new Image(Display.getCurrent(), bib.width, bib.height);
279:                         //
280:                         final GC gc = new GC(result);
281:                         gc.drawImage(baseImage, 0, 0);
282:•                        if (corner == TOP_LEFT) {
283:                                 gc.drawImage(decorator, 0, 0);
284:•                        } else if (corner == TOP_RIGHT) {
285:                                 gc.drawImage(decorator, bib.width - dib.width, 0);
286:•                        } else if (corner == BOTTOM_LEFT) {
287:                                 gc.drawImage(decorator, 0, bib.height - dib.height);
288:•                        } else if (corner == BOTTOM_RIGHT) {
289:                                 gc.drawImage(decorator, bib.width - dib.width, bib.height - dib.height);
290:                         }
291:                         gc.dispose();
292:                         //
293:                         decoratedMap.put(decorator, result);
294:                 }
295:                 return result;
296:         }
297:
298:         /**
299:          * Dispose all of the cached {@link Image}'s.
300:          */
301:         public static void disposeImages() {
302:                 // dispose loaded images
303:                 {
304:•                        for (final Image image : m_imageMap.values()) {
305:                                 image.dispose();
306:                         }
307:                         m_imageMap.clear();
308:                 }
309:                 // dispose decorated images
310:•                for (int i = 0; i < m_decoratedImageMap.length; i++) {
311:                         final Map<Image, Map<Image, Image>> cornerDecoratedImageMap = m_decoratedImageMap[i];
312:•                        if (cornerDecoratedImageMap != null) {
313:•                                for (final Map<Image, Image> decoratedMap : cornerDecoratedImageMap.values()) {
314:•                                        for (final Image image : decoratedMap.values()) {
315:                                                 image.dispose();
316:                                         }
317:                                         decoratedMap.clear();
318:                                 }
319:                                 cornerDecoratedImageMap.clear();
320:                         }
321:                 }
322:         }
323:
324:         // //////////////////////////////////////////////////////////////////////////
325:         //
326:         // Font
327:         //
328:         // //////////////////////////////////////////////////////////////////////////
329:         /**
330:          * Maps font names to fonts.
331:          */
332:         private static Map<String, Font> m_fontMap = new HashMap<String, Font>();
333:
334:         /**
335:          * Maps fonts to their bold versions.
336:          */
337:         private static Map<Font, Font> m_fontToBoldFontMap = new HashMap<Font, Font>();
338:
339:         /**
340:          * Returns a {@link Font} based on its name, height and style.
341:          *
342:          * @param name
343:          * the name of the font
344:          * @param height
345:          * the height of the font
346:          * @param style
347:          * the style of the font
348:          * @return {@link Font} The font matching the name, height and style
349:          */
350:         public static Font getFont(String name, int height, int style) {
351:                 return getFont(name, height, style, false, false);
352:         }
353:
354:         /**
355:          * Returns a {@link Font} based on its name, height and style. Windows-specific strikeout and underline flags are
356:          * also
357:          * supported.
358:          *
359:          * @param name
360:          * the name of the font
361:          * @param size
362:          * the size of the font
363:          * @param style
364:          * the style of the font
365:          * @param strikeout
366:          * the strikeout flag (warning: Windows only)
367:          * @param underline
368:          * the underline flag (warning: Windows only)
369:          * @return {@link Font} The font matching the name, height, style, strikeout and underline
370:          */
371:         public static Font getFont(String name, int size, int style, boolean strikeout, boolean underline) {
372:                 final String fontName = name + '|' + size + '|' + style + '|' + strikeout + '|' + underline;
373:                 Font font = m_fontMap.get(fontName);
374:•                if (font == null) {
375:                         final FontData fontData = new FontData(name, size, style);
376:•                        if (strikeout || underline) {
377:                                 try {
378:                                         final Class<?> logFontClass = Class.forName("org.eclipse.swt.internal.win32.LOGFONT"); //$NON-NLS-1$
379:                                         final Object logFont = FontData.class.getField("data").get(fontData); //$NON-NLS-1$
380:•                                        if (logFont != null && logFontClass != null) {
381:•                                                if (strikeout) {
382:                                                         logFontClass.getField("lfStrikeOut").set(logFont, Byte.valueOf((byte) 1)); //$NON-NLS-1$
383:                                                 }
384:•                                                if (underline) {
385:                                                         logFontClass.getField("lfUnderline").set(logFont, Byte.valueOf((byte) 1)); //$NON-NLS-1$
386:                                                 }
387:                                         }
388:                                 } catch (final Throwable e) {
389:                                         System.err
390:                                                 .println(
391:                                                         "Unable to set underline or strikeout" + " (probably on a non-Windows platform). " + e); //$NON-NLS-1$ //$NON-NLS-2$
392:                                 }
393:                         }
394:                         font = new Font(Display.getCurrent(), fontData);
395:                         m_fontMap.put(fontName, font);
396:                 }
397:                 return font;
398:         }
399:
400:         /**
401:          * Returns a bold version of the given {@link Font}.
402:          *
403:          * @param baseFont
404:          * the {@link Font} for which a bold version is desired
405:          * @return the bold version of the given {@link Font}
406:          */
407:         public static Font getBoldFont(Font baseFont) {
408:                 Font font = m_fontToBoldFontMap.get(baseFont);
409:•                if (font == null) {
410:                         final FontData[] fontDatas = baseFont.getFontData();
411:                         final FontData data = fontDatas[0];
412:                         font = new Font(Display.getCurrent(), data.getName(), data.getHeight(), SWT.BOLD);
413:                         m_fontToBoldFontMap.put(baseFont, font);
414:                 }
415:                 return font;
416:         }
417:
418:         /**
419:          * Dispose all of the cached {@link Font}'s.
420:          */
421:         public static void disposeFonts() {
422:                 // clear fonts
423:•                for (final Font font : m_fontMap.values()) {
424:                         font.dispose();
425:                 }
426:                 m_fontMap.clear();
427:                 // clear bold fonts
428:•                for (final Font font : m_fontToBoldFontMap.values()) {
429:                         font.dispose();
430:                 }
431:                 m_fontToBoldFontMap.clear();
432:         }
433:
434:         // //////////////////////////////////////////////////////////////////////////
435:         //
436:         // Cursor
437:         //
438:         // //////////////////////////////////////////////////////////////////////////
439:         /**
440:          * Maps IDs to cursors.
441:          */
442:         private static Map<Integer, Cursor> m_idToCursorMap = new HashMap<Integer, Cursor>();
443:
444:         /**
445:          * Returns the system cursor matching the specific ID.
446:          *
447:          * @param id
448:          * int The ID value for the cursor
449:          * @return Cursor The system cursor matching the specific ID
450:          */
451:         public static Cursor getCursor(int id) {
452:                 final Integer key = Integer.valueOf(id);
453:                 Cursor cursor = m_idToCursorMap.get(key);
454:•                if (cursor == null) {
455:                         cursor = new Cursor(Display.getDefault(), id);
456:                         m_idToCursorMap.put(key, cursor);
457:                 }
458:                 return cursor;
459:         }
460:
461:         /**
462:          * Dispose all of the cached cursors.
463:          */
464:         public static void disposeCursors() {
465:•                for (final Cursor cursor : m_idToCursorMap.values()) {
466:                         cursor.dispose();
467:                 }
468:                 m_idToCursorMap.clear();
469:         }
470:
471:         // //////////////////////////////////////////////////////////////////////////
472:         //
473:         // General
474:         //
475:         // //////////////////////////////////////////////////////////////////////////
476:         /**
477:          * Dispose of cached objects and their underlying OS resources. This should only be called when the cached objects
478:          * are
479:          * no longer needed (e.g. on application shutdown).
480:          */
481:         public static void dispose() {
482:                 disposeColors();
483:                 disposeImages();
484:                 disposeFonts();
485:                 disposeCursors();
486:         }
487: }