~ubuntu-branches/debian/stretch/insubstantial/stretch

« back to all changes in this revision

Viewing changes to laf-widget/src/main/java/org/pushingpixels/lafwidget/LafWidgetUtilities.java

  • Committer: Package Import Robot
  • Author(s): Felix Natter
  • Date: 2016-01-18 20:58:45 UTC
  • Revision ID: package-import@ubuntu.com-20160118205845-crbmrkda61qsi5qa
Tags: upstream-7.3+dfsg2
ImportĀ upstreamĀ versionĀ 7.3+dfsg2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 2005-2010 Laf-Widget Kirill Grouchnikov. All Rights Reserved.
 
3
 *
 
4
 * Redistribution and use in source and binary forms, with or without
 
5
 * modification, are permitted provided that the following conditions are met:
 
6
 *
 
7
 *  o Redistributions of source code must retain the above copyright notice,
 
8
 *    this list of conditions and the following disclaimer.
 
9
 *
 
10
 *  o Redistributions in binary form must reproduce the above copyright notice,
 
11
 *    this list of conditions and the following disclaimer in the documentation
 
12
 *    and/or other materials provided with the distribution.
 
13
 *
 
14
 *  o Neither the name of Laf-Widget Kirill Grouchnikov nor the names of
 
15
 *    its contributors may be used to endorse or promote products derived
 
16
 *    from this software without specific prior written permission.
 
17
 *
 
18
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 
19
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 
20
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 
21
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 
22
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 
23
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 
24
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 
25
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 
26
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 
27
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 
28
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
29
 */
 
30
package org.pushingpixels.lafwidget;
 
31
 
 
32
import java.awt.*;
 
33
import java.awt.geom.GeneralPath;
 
34
import java.awt.image.BufferedImage;
 
35
import java.beans.PropertyChangeEvent;
 
36
import java.beans.PropertyChangeListener;
 
37
import java.util.*;
 
38
 
 
39
import javax.swing.*;
 
40
import javax.swing.text.JTextComponent;
 
41
 
 
42
import org.pushingpixels.lafwidget.animation.AnimationConfigurationManager;
 
43
import org.pushingpixels.lafwidget.animation.AnimationFacet;
 
44
 
 
45
/**
 
46
 * Various utility functions.
 
47
 * 
 
48
 * @author Kirill Grouchnikov
 
49
 * @author Romain Guy
 
50
 */
 
51
public class LafWidgetUtilities {
 
52
        /**
 
53
         * Name for the internal client property that marks a component as
 
54
         * previewable.
 
55
         */
 
56
        public static final String PREVIEW_MODE = "lafwidgets.internal.previewMode";
 
57
 
 
58
        /**
 
59
         * Private constructor. Is here to enforce using static methods only.
 
60
         */
 
61
        private LafWidgetUtilities() {
 
62
        }
 
63
 
 
64
        /**
 
65
         * Retrieves transparent image of specified dimension.
 
66
         * 
 
67
         * @param width
 
68
         *            Image width.
 
69
         * @param height
 
70
         *            Image height.
 
71
         * @return Transparent image of specified dimension.
 
72
         */
 
73
        public static BufferedImage getBlankImage(int width, int height) {
 
74
                BufferedImage image = new BufferedImage(width, height,
 
75
                                BufferedImage.TYPE_INT_ARGB);
 
76
 
 
77
                // get graphics and set hints
 
78
                Graphics2D graphics = (Graphics2D) image.getGraphics().create();
 
79
                graphics.setColor(new Color(0, 0, 0, 0));
 
80
                graphics.setComposite(AlphaComposite.Src);
 
81
                graphics.fillRect(0, 0, width, height);
 
82
                graphics.dispose();
 
83
 
 
84
                return image;
 
85
        }
 
86
 
 
87
        /**
 
88
         * Creates a compatible image (for efficient processing and drawing).
 
89
         * 
 
90
         * @param image
 
91
         *            The original image.
 
92
         * @return Compatible version of the original image.
 
93
         * @author Romain Guy
 
94
         */
 
95
        public static BufferedImage createCompatibleImage(BufferedImage image) {
 
96
                GraphicsEnvironment e = GraphicsEnvironment
 
97
                                .getLocalGraphicsEnvironment();
 
98
                GraphicsDevice d = e.getDefaultScreenDevice();
 
99
                GraphicsConfiguration c = d.getDefaultConfiguration();
 
100
                BufferedImage compatibleImage = c.createCompatibleImage(image
 
101
                                .getWidth(), image.getHeight());
 
102
                Graphics g = compatibleImage.getGraphics();
 
103
                g.drawImage(image, 0, 0, null);
 
104
                g.dispose();
 
105
                return compatibleImage;
 
106
        }
 
107
 
 
108
        /**
 
109
         * Creates a thumbnail of the specified width.
 
110
         * 
 
111
         * @param image
 
112
         *            The original image.
 
113
         * @param requestedThumbWidth
 
114
         *            The width of the resulting thumbnail.
 
115
         * @return Thumbnail of the specified width.
 
116
         * @author Romain Guy
 
117
         */
 
118
        public static BufferedImage createThumbnail(BufferedImage image,
 
119
                        int requestedThumbWidth) {
 
120
                float ratio = (float) image.getWidth() / (float) image.getHeight();
 
121
                int width = image.getWidth();
 
122
                BufferedImage thumb = image;
 
123
 
 
124
                do {
 
125
                        width /= 2;
 
126
                        if (width < requestedThumbWidth) {
 
127
                                width = requestedThumbWidth;
 
128
                        }
 
129
 
 
130
                        BufferedImage temp = new BufferedImage(width,
 
131
                                        (int) (width / ratio), BufferedImage.TYPE_INT_ARGB);
 
132
                        Graphics2D g2 = temp.createGraphics();
 
133
                        g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
 
134
                                        RenderingHints.VALUE_INTERPOLATION_BILINEAR);
 
135
                        g2.drawImage(thumb, 0, 0, temp.getWidth(), temp.getHeight(), null);
 
136
                        g2.dispose();
 
137
 
 
138
                        thumb = temp;
 
139
                } while (width != requestedThumbWidth);
 
140
 
 
141
                return thumb;
 
142
        }
 
143
 
 
144
        /**
 
145
         * Returns search icon.
 
146
         * 
 
147
         * @param dimension
 
148
         *            Icon dimension.
 
149
         * @param leftToRight
 
150
         *            Indicates the orientation of the resulting icon.
 
151
         * @return Search icon.
 
152
         */
 
153
        public static Icon getSearchIcon(int dimension, boolean leftToRight) {
 
154
                BufferedImage result = LafWidgetUtilities.getBlankImage(dimension,
 
155
                                dimension);
 
156
 
 
157
                Graphics2D graphics = (Graphics2D) result.getGraphics().create();
 
158
                graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
 
159
                                RenderingHints.VALUE_ANTIALIAS_ON);
 
160
 
 
161
                graphics.setColor(Color.black);
 
162
 
 
163
                graphics.setStroke(new BasicStroke(1.5f));
 
164
                if (leftToRight) {
 
165
                        int xc = (int) (0.6 * dimension);
 
166
                        int yc = (int) (0.45 * dimension);
 
167
                        int r = (int) (0.3 * dimension);
 
168
 
 
169
                        graphics.drawOval(xc - r, yc - r, 2 * r, 2 * r);
 
170
 
 
171
                        graphics.setStroke(new BasicStroke(3.0f));
 
172
                        GeneralPath handle = new GeneralPath();
 
173
                        handle.moveTo((float) (xc - r / Math.sqrt(2.0)), (float) (yc + r
 
174
                                        / Math.sqrt(2.0)));
 
175
                        handle.lineTo(1.8f, dimension - 2.2f);
 
176
                        graphics.draw(handle);
 
177
                } else {
 
178
                        int xc = (int) (0.4 * dimension);
 
179
                        int yc = (int) (0.45 * dimension);
 
180
                        int r = (int) (0.3 * dimension);
 
181
 
 
182
                        graphics.drawOval(xc - r, yc - r, 2 * r, 2 * r);
 
183
 
 
184
                        graphics.setStroke(new BasicStroke(3.0f));
 
185
                        GeneralPath handle = new GeneralPath();
 
186
                        handle.moveTo((float) (xc + r / Math.sqrt(2.0)), (float) (yc + r
 
187
                                        / Math.sqrt(2.0)));
 
188
                        handle.lineTo(dimension - 2.5f, dimension - 2.2f);
 
189
                        graphics.draw(handle);
 
190
                }
 
191
 
 
192
                graphics.dispose();
 
193
                return new ImageIcon(result);
 
194
        }
 
195
 
 
196
        /**
 
197
         * Returns small icon representation of the specified integer value. The
 
198
         * remainder of dividing the integer by 16 is translated to four circles
 
199
         * arranged in 2*2 grid.
 
200
         * 
 
201
         * @param value
 
202
         *            Integer value to represent.
 
203
         * @return Icon representation of the specified integer value.
 
204
         */
 
205
        public static Icon getHexaMarker(int value) {
 
206
                BufferedImage result = LafWidgetUtilities.getBlankImage(9, 9);
 
207
 
 
208
                value %= 16;
 
209
                Color offColor = Color.gray;
 
210
                Color onColor = Color.black;
 
211
 
 
212
                boolean bit1 = ((value & 0x1) != 0);
 
213
                boolean bit2 = ((value & 0x2) != 0);
 
214
                boolean bit3 = ((value & 0x4) != 0);
 
215
                boolean bit4 = ((value & 0x8) != 0);
 
216
 
 
217
                Graphics2D graphics = (Graphics2D) result.getGraphics().create();
 
218
                graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
 
219
                                RenderingHints.VALUE_ANTIALIAS_ON);
 
220
 
 
221
                graphics.setColor(bit1 ? onColor : offColor);
 
222
                graphics.fillOval(5, 5, 4, 4);
 
223
                graphics.setColor(bit2 ? onColor : offColor);
 
224
                graphics.fillOval(5, 0, 4, 4);
 
225
                graphics.setColor(bit3 ? onColor : offColor);
 
226
                graphics.fillOval(0, 5, 4, 4);
 
227
                graphics.setColor(bit4 ? onColor : offColor);
 
228
                graphics.fillOval(0, 0, 4, 4);
 
229
 
 
230
                graphics.dispose();
 
231
                return new ImageIcon(result);
 
232
        }
 
233
 
 
234
        /**
 
235
         * Makes the specified component and all its descendants previewable.
 
236
         * 
 
237
         * @param comp
 
238
         *            Component.
 
239
         * @param dbSnapshot
 
240
         *            The "snapshot" map that will contain the original
 
241
         *            double-buffer status of the specified component and all its
 
242
         *            descendants. Key is {@link JComponent}, value is
 
243
         *            {@link Boolean}.
 
244
         */
 
245
        public static void makePreviewable(Component comp,
 
246
                        Map<Component, Boolean> dbSnapshot) {
 
247
                if (comp instanceof JComponent) {
 
248
                        JComponent jcomp = (JComponent) comp;
 
249
                        // if (jcomp.getParent() instanceof CellRendererPane) {
 
250
                        // System.out.println(jcomp.getClass().getSimpleName() + ":"
 
251
                        // + jcomp.hashCode());
 
252
                        // }
 
253
                        dbSnapshot.put(jcomp, jcomp.isDoubleBuffered());
 
254
                        jcomp.setDoubleBuffered(false);
 
255
                        jcomp.putClientProperty(LafWidgetUtilities.PREVIEW_MODE,
 
256
                                        Boolean.TRUE);
 
257
                }
 
258
                if (comp instanceof Container) {
 
259
                        Container cont = (Container) comp;
 
260
                        for (int i = 0; i < cont.getComponentCount(); i++)
 
261
                                LafWidgetUtilities.makePreviewable(cont.getComponent(i),
 
262
                                                dbSnapshot);
 
263
                }
 
264
        }
 
265
 
 
266
        /**
 
267
         * Restores the regular (non-previewable) status of the specified component
 
268
         * and all its descendants.
 
269
         * 
 
270
         * @param comp
 
271
         *            Component.
 
272
         * @param dbSnapshot
 
273
         *            The "snapshot" map that contains the original double-buffer
 
274
         *            status of the specified component and all its descendants. Key
 
275
         *            is {@link JComponent}, value is {@link Boolean}.
 
276
         */
 
277
        public static void restorePreviewable(Component comp,
 
278
                        Map<Component, Boolean> dbSnapshot) {
 
279
                if (comp instanceof JComponent) {
 
280
                        JComponent jcomp = (JComponent) comp;
 
281
                        if (dbSnapshot.containsKey(comp)) {
 
282
                // the key may exist, but may be set to null (lovely boxing quirk)
 
283
                // treat null as false, since that is the default
 
284
                Boolean buffered = dbSnapshot.get(comp);
 
285
                                jcomp.setDoubleBuffered(buffered == null ? false : buffered);
 
286
                                jcomp.putClientProperty(LafWidgetUtilities.PREVIEW_MODE, null);
 
287
                        } else {
 
288
                                // this can happen in case the application has
 
289
                                // renderers (combos, ...). Take the property from the parent
 
290
                                Component parent = comp.getParent();
 
291
                                if (parent instanceof JComponent && dbSnapshot.containsKey(parent)) {
 
292
                    // the key may exist, but may be set to null (lovely boxing quirk)
 
293
                    // treat null as false, since that is the default
 
294
                    Boolean buffered = dbSnapshot.get(parent);
 
295
                    jcomp.setDoubleBuffered(buffered == null ? false : buffered);
 
296
                                        jcomp.putClientProperty(LafWidgetUtilities.PREVIEW_MODE,
 
297
                                                        null);
 
298
                                }
 
299
                                // System.out.println("Not found");
 
300
                                // Component c = jcomp;
 
301
                                // while (c != null) {
 
302
                                // System.out.println("\t" + c.getClass().getSimpleName()
 
303
                                // + ":" + c.hashCode());
 
304
                                // c = c.getParent();
 
305
                                // }
 
306
                        }
 
307
                }
 
308
                if (comp instanceof Container) {
 
309
                        Container cont = (Container) comp;
 
310
                        for (int i = 0; i < cont.getComponentCount(); i++)
 
311
                                LafWidgetUtilities.restorePreviewable(cont.getComponent(i),
 
312
                                                dbSnapshot);
 
313
                }
 
314
        }
 
315
 
 
316
        /**
 
317
         * Returns a lock icon.
 
318
         * 
 
319
         * @return Lock icon.
 
320
         */
 
321
        public static Icon getSmallLockIcon() {
 
322
                BufferedImage result = LafWidgetUtilities.getBlankImage(6, 8);
 
323
 
 
324
                Color fore = Color.black;
 
325
                Color fill = new Color(208, 208, 48);
 
326
 
 
327
                Graphics2D graphics = (Graphics2D) result.getGraphics().create();
 
328
                graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
 
329
                                RenderingHints.VALUE_ANTIALIAS_OFF);
 
330
 
 
331
                graphics.setColor(fill);
 
332
                graphics.fillRect(1, 3, 4, 4);
 
333
                graphics.setColor(fore);
 
334
                graphics.drawLine(0, 3, 0, 7);
 
335
                graphics.drawLine(5, 3, 5, 7);
 
336
                graphics.drawLine(0, 7, 5, 7);
 
337
                graphics.drawLine(1, 2, 4, 2);
 
338
                graphics.drawLine(1, 1, 1, 2);
 
339
                graphics.drawLine(4, 1, 4, 2);
 
340
                graphics.drawLine(2, 0, 3, 0);
 
341
                graphics.drawLine(2, 4, 3, 4);
 
342
                graphics.drawLine(2, 5, 3, 5);
 
343
 
 
344
                graphics.dispose();
 
345
                return new ImageIcon(result);
 
346
        }
 
347
 
 
348
        /**
 
349
         * Checks whether the specified text component has
 
350
         * "select all on focus gain" property.
 
351
         * 
 
352
         * @param textComp
 
353
         *            Text component.
 
354
         * @return <code>true</code> if the specified text component has "select all
 
355
         *         on focus gain" property, <code>false</code> otherwise.
 
356
         */
 
357
        public static boolean hasTextFocusSelectAllProperty(JTextComponent textComp) {
 
358
                Component comp = textComp;
 
359
                while (comp != null) {
 
360
                        if (comp instanceof JComponent) {
 
361
                                Object textFocusSelectAllProperty = ((JComponent) comp)
 
362
                                                .getClientProperty(LafWidget.TEXT_SELECT_ON_FOCUS);
 
363
                                if (Boolean.TRUE.equals(textFocusSelectAllProperty))
 
364
                                        return true;
 
365
                                if (Boolean.FALSE.equals(textFocusSelectAllProperty))
 
366
                                        return false;
 
367
                        }
 
368
                        comp = comp.getParent();
 
369
                }
 
370
                return (Boolean.TRUE.equals(UIManager
 
371
                                .get(LafWidget.TEXT_SELECT_ON_FOCUS)));
 
372
        }
 
373
 
 
374
        /**
 
375
         * Checks whether the specified text component has "flip select on escape"
 
376
         * property.
 
377
         * 
 
378
         * @param textComp
 
379
         *            Text component.
 
380
         * @return <code>true</code> if the specified text component has "flip
 
381
         *         select on escape" property, <code>false</code> otherwise.
 
382
         */
 
383
        public static boolean hasTextFlipSelectOnEscapeProperty(
 
384
                        JTextComponent textComp) {
 
385
                Object textFocusSelectAllProperty = textComp
 
386
                                .getClientProperty(LafWidget.TEXT_FLIP_SELECT_ON_ESCAPE);
 
387
                return (Boolean.TRUE.equals(textFocusSelectAllProperty));
 
388
        }
 
389
 
 
390
        /**
 
391
         * Checks whether the specified text component has edit context menu
 
392
         * property.
 
393
         * 
 
394
         * @param textComp
 
395
         *            Text component.
 
396
         * @return <code>true</code> if the specified text component has edit
 
397
         *         context menu property, <code>false</code> otherwise.
 
398
         */
 
399
        public static boolean hasTextEditContextMenu(JTextComponent textComp) {
 
400
                Object textEditContextMenuProperty = textComp
 
401
                                .getClientProperty(LafWidget.TEXT_EDIT_CONTEXT_MENU);
 
402
                if (Boolean.TRUE.equals(textEditContextMenuProperty))
 
403
                        return true;
 
404
                if (Boolean.FALSE.equals(textEditContextMenuProperty))
 
405
                        return false;
 
406
                return (Boolean.TRUE.equals(UIManager
 
407
                                .get(LafWidget.TEXT_EDIT_CONTEXT_MENU)));
 
408
        }
 
409
 
 
410
        /**
 
411
         * Checks whether the specified scroll pane supports auto scroll.
 
412
         * 
 
413
         * @param scrollPane
 
414
         *            Scroll pane component.
 
415
         * @return <code>true</code> if the specified scroll pane supports auto
 
416
         *         scroll, <code>false</code> otherwise.
 
417
         */
 
418
        public static boolean hasAutoScroll(JScrollPane scrollPane) {
 
419
                Object compProperty = scrollPane
 
420
                                .getClientProperty(LafWidget.AUTO_SCROLL);
 
421
                if (Boolean.TRUE.equals(compProperty))
 
422
                        return true;
 
423
                if (Boolean.FALSE.equals(compProperty))
 
424
                        return false;
 
425
                return (Boolean.TRUE.equals(UIManager.get(LafWidget.AUTO_SCROLL)));
 
426
        }
 
427
 
 
428
        /**
 
429
         * Checks whether the specified tree component has automatic drag and drop
 
430
         * support.
 
431
         * 
 
432
         * @param tree
 
433
         *            Tree component.
 
434
         * @return <code>true</code> if the specified text component has automatic
 
435
         *         drag and drop support, <code>false</code> otherwise.
 
436
         */
 
437
        public static boolean hasAutomaticDnDSupport(JTree tree) {
 
438
                Object dndProperty = tree
 
439
                                .getClientProperty(LafWidget.TREE_AUTO_DND_SUPPORT);
 
440
                if (Boolean.TRUE.equals(dndProperty))
 
441
                        return true;
 
442
                if (Boolean.FALSE.equals(dndProperty))
 
443
                        return false;
 
444
                return (Boolean.TRUE.equals(UIManager
 
445
                                .get(LafWidget.TREE_AUTO_DND_SUPPORT)));
 
446
        }
 
447
 
 
448
        /**
 
449
         * Checks whether the label lookup should use component-specific locale on
 
450
         * the specified component.
 
451
         * 
 
452
         * @param jcomp
 
453
         *            Component.
 
454
         * @return <code>true</code> if the custom labels should be looked up based
 
455
         *         on the component locale as returned by
 
456
         *         {@link JComponent#getLocale()}, <code>false</code> if the custom
 
457
         *         labels should be looked up based on the global locale as returned
 
458
         *         by {@link Locale#getDefault()}.
 
459
         */
 
460
        public static boolean toIgnoreGlobalLocale(JComponent jcomp) {
 
461
                if (jcomp == null)
 
462
                        return false;
 
463
                return Boolean.TRUE.equals(jcomp
 
464
                                .getClientProperty(LafWidget.IGNORE_GLOBAL_LOCALE));
 
465
        }
 
466
 
 
467
        /**
 
468
         * Returns the resource bundle for the specified component.
 
469
         * 
 
470
         * @param jcomp
 
471
         *            Component.
 
472
         * @return Resource bundle for the specified component.
 
473
         */
 
474
        public static ResourceBundle getResourceBundle(JComponent jcomp) {
 
475
                if (toIgnoreGlobalLocale(jcomp)) {
 
476
                        return LafWidgetRepository.getLabelBundle(jcomp.getLocale());
 
477
                } else {
 
478
                        return LafWidgetRepository.getLabelBundle();
 
479
                }
 
480
        }
 
481
 
 
482
        /**
 
483
         * Checks whether the specified component has been configured (specifically
 
484
         * or globally) to have no animations of the specific facet. Can be used to
 
485
         * cull unnecessary code in animation listeners on large tables and lists.
 
486
         * 
 
487
         * @param comp
 
488
         *            Component.
 
489
         * @param animationFacet
 
490
         *            Animation facet.
 
491
         * @return <code>true</code> if the specified component has been configured
 
492
         *         (specifically or globally) to have no animations of the specific
 
493
         *         facet, <code>false</code> otherwise.
 
494
         */
 
495
        public static boolean hasNoAnimations(Component comp,
 
496
                        AnimationFacet animationFacet) {
 
497
                return !AnimationConfigurationManager.getInstance().isAnimationAllowed(
 
498
                                animationFacet, comp);
 
499
        }
 
500
 
 
501
        /**
 
502
         * Returns the current icon for the specified button. This method is <b>for
 
503
         * internal use only</b>.
 
504
         * 
 
505
         * @param b
 
506
         *            Button.
 
507
         * @return Icon for the specified button.
 
508
         */
 
509
        public static Icon getIcon(AbstractButton b) {
 
510
                Icon icon = b.getIcon();
 
511
                if (icon == null)
 
512
                        return null;
 
513
                ButtonModel model = b.getModel();
 
514
                Icon tmpIcon = null;
 
515
 
 
516
                if (icon != null) {
 
517
                        if (!model.isEnabled()) {
 
518
                                if (model.isSelected()) {
 
519
                                        tmpIcon = b.getDisabledSelectedIcon();
 
520
                                } else {
 
521
                                        tmpIcon = b.getDisabledIcon();
 
522
                                }
 
523
                        } else if (model.isPressed() && model.isArmed()) {
 
524
                                tmpIcon = b.getPressedIcon();
 
525
                        } else if (b.isRolloverEnabled() && model.isRollover()) {
 
526
                                if (model.isSelected()) {
 
527
                                        tmpIcon = b.getRolloverSelectedIcon();
 
528
                                } else {
 
529
                                        tmpIcon = b.getRolloverIcon();
 
530
                                }
 
531
                        } else if (model.isSelected()) {
 
532
                                tmpIcon = b.getSelectedIcon();
 
533
                        }
 
534
 
 
535
                        if (tmpIcon != null) {
 
536
                                icon = tmpIcon;
 
537
                        }
 
538
                }
 
539
                return icon;
 
540
        }
 
541
 
 
542
        public static boolean toIgnoreAnimations(Component comp) {
 
543
                if (comp instanceof JMenuItem)
 
544
                        return false;
 
545
                return (SwingUtilities.getAncestorOfClass(CellRendererPane.class, comp) != null);
 
546
        }
 
547
 
 
548
        /**
 
549
         * Tests UI threading violations on changing the state the specified
 
550
         * component.
 
551
         * 
 
552
         * @param comp
 
553
         *            Component.
 
554
         * @throws UiThreadingViolationException
 
555
         *             If the component is changing state off Event Dispatch Thread.
 
556
         */
 
557
        public static void testComponentStateChangeThreadingViolation(Component comp) {
 
558
                if (!SwingUtilities.isEventDispatchThread()) {
 
559
                        UiThreadingViolationException uiThreadingViolationError = new UiThreadingViolationException(
 
560
                                        "Component state change must be done on Event Dispatch Thread");
 
561
                        uiThreadingViolationError.printStackTrace(System.err);
 
562
                        throw uiThreadingViolationError;
 
563
                }
 
564
        }
 
565
 
 
566
        /**
 
567
         * Fires the matching property change event on the specific component.
 
568
         * 
 
569
         * @param component
 
570
         *            Component.
 
571
         * @param propertyName
 
572
         *            Property name.
 
573
         * @param oldValue
 
574
         *            Old property value.
 
575
         * @param newValue
 
576
         *            New property value.
 
577
         */
 
578
        public static void firePropertyChangeEvent(JComponent component,
 
579
                        String propertyName, Object oldValue, Object newValue) {
 
580
                PropertyChangeEvent pce = new PropertyChangeEvent(component,
 
581
                                propertyName, oldValue, newValue);
 
582
                for (PropertyChangeListener general : component
 
583
                                .getPropertyChangeListeners()) {
 
584
                        general.propertyChange(pce);
 
585
                }
 
586
                for (PropertyChangeListener specific : component
 
587
                                .getPropertyChangeListeners(propertyName)) {
 
588
                        specific.propertyChange(pce);
 
589
                }
 
590
        }
 
591
 
 
592
        /**
 
593
         * Returns the composite to use for painting the specified component. The
 
594
         * result should be set on the {@link Graphics2D} before any custom
 
595
         * rendering is done. This method can be used by application painting code
 
596
         * and by look-and-feel delegates.
 
597
         * 
 
598
         * @param c
 
599
         *            Component.
 
600
         * @param translucency
 
601
         *            The translucency of the original painting.
 
602
         * @param g
 
603
         *            The original graphics context.
 
604
         * @return The composite to use for painting the specified component.
 
605
         */
 
606
        public static Composite getAlphaComposite(Component c, float translucency,
 
607
                        Graphics g) {
 
608
                float xFactor = 1.0f;
 
609
                if (g instanceof Graphics2D) {
 
610
                        Graphics2D g2d = (Graphics2D) g;
 
611
                        Composite existingComposite = g2d.getComposite();
 
612
                        if (existingComposite instanceof AlphaComposite) {
 
613
                                AlphaComposite ac = (AlphaComposite) existingComposite;
 
614
                                if (ac.getRule() == AlphaComposite.SRC_OVER)
 
615
                                        xFactor = ac.getAlpha();
 
616
                        }
 
617
                }
 
618
                float finalAlpha = translucency * xFactor;
 
619
                if (finalAlpha < 0.0f) {
 
620
                        finalAlpha = 0.0f;
 
621
                }
 
622
                if (finalAlpha > 1.0f) {
 
623
                        finalAlpha = 1.0f;
 
624
                }
 
625
                if (finalAlpha == 1.0f) {
 
626
                        return AlphaComposite.SrcOver;
 
627
                }
 
628
                return AlphaComposite.SrcOver.derive(finalAlpha);
 
629
        }
 
630
 
 
631
        public static Composite getAlphaComposite(Component c, float translucency) {
 
632
                return getAlphaComposite(c, translucency, null);
 
633
        }
 
634
 
 
635
        /**
 
636
         * Returns the composite to use for painting the specified component. The
 
637
         * result should be set on the {@link Graphics2D} before any custom
 
638
         * rendering is done. This method can be used by application painting code
 
639
         * and by look-and-feel delegates.
 
640
         * 
 
641
         * @param c
 
642
         *            Component.
 
643
         * @return The composite to use for painting the specified component.
 
644
         */
 
645
        public static Composite getAlphaComposite(Component c, Graphics g) {
 
646
                return getAlphaComposite(c, 1.0f, g);
 
647
        }
 
648
 
 
649
        /**
 
650
         * Returns the composite to use for painting the specified component. The
 
651
         * result should be set on the {@link Graphics2D} before any custom
 
652
         * rendering is done. This method can be used by application painting code
 
653
         * and by look-and-feel delegates.
 
654
         * 
 
655
         * @param c
 
656
         *            Component.
 
657
         * @return The composite to use for painting the specified component.
 
658
         */
 
659
        public static Composite getAlphaComposite(Component c) {
 
660
                return getAlphaComposite(c, 1.0f, null);
 
661
        }
 
662
}