Source Code Cross Referenced for XPStyle.java in  » 6.0-JDK-Modules-com.sun.java » swing » com » sun » java » swing » plaf » windows » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » 6.0 JDK Modules com.sun.java » swing » com.sun.java.swing.plaf.windows 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright 2002-2007 Sun Microsystems, Inc.  All Rights Reserved.
003:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004:         *
005:         * This code is free software; you can redistribute it and/or modify it
006:         * under the terms of the GNU General Public License version 2 only, as
007:         * published by the Free Software Foundation.  Sun designates this
008:         * particular file as subject to the "Classpath" exception as provided
009:         * by Sun in the LICENSE file that accompanied this code.
010:         *
011:         * This code is distributed in the hope that it will be useful, but WITHOUT
012:         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013:         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
014:         * version 2 for more details (a copy is included in the LICENSE file that
015:         * accompanied this code).
016:         *
017:         * You should have received a copy of the GNU General Public License version
018:         * 2 along with this work; if not, write to the Free Software Foundation,
019:         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020:         *
021:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022:         * CA 95054 USA or visit www.sun.com if you need additional information or
023:         * have any questions.
024:         */
025:
026:        /*
027:         * <p>These classes are designed to be used while the
028:         * corresponding <code>LookAndFeel</code> class has been installed
029:         * (<code>UIManager.setLookAndFeel(new <i>XXX</i>LookAndFeel())</code>).
030:         * Using them while a different <code>LookAndFeel</code> is installed
031:         * may produce unexpected results, including exceptions.
032:         * Additionally, changing the <code>LookAndFeel</code>
033:         * maintained by the <code>UIManager</code> without updating the
034:         * corresponding <code>ComponentUI</code> of any
035:         * <code>JComponent</code>s may also produce unexpected results,
036:         * such as the wrong colors showing up, and is generally not
037:         * encouraged.
038:         * 
039:         */
040:
041:        package com.sun.java.swing.plaf.windows;
042:
043:        import java.awt.*;
044:        import java.awt.image.*;
045:        import java.security.AccessController;
046:        import java.util.*;
047:
048:        import javax.swing.*;
049:        import javax.swing.border.*;
050:        import javax.swing.plaf.*;
051:        import javax.swing.text.JTextComponent;
052:
053:        import sun.awt.image.SunWritableRaster;
054:        import sun.awt.windows.ThemeReader;
055:        import sun.security.action.GetPropertyAction;
056:        import sun.swing.CachedPainter;
057:
058:        import static com.sun.java.swing.plaf.windows.TMSchema.*;
059:
060:        /**
061:         * Implements Windows XP Styles for the Windows Look and Feel.
062:         *
063:         * @version 1.34 07/13/06
064:         * @author Leif Samuelsson
065:         */
066:        class XPStyle {
067:            // Singleton instance of this class
068:            private static XPStyle xp;
069:
070:            // Singleton instance of SkinPainter
071:            private static SkinPainter skinPainter = new SkinPainter();
072:
073:            private static Boolean themeActive = null;
074:
075:            private HashMap<String, Border> borderMap;
076:            private HashMap<String, Color> colorMap;
077:
078:            private boolean flatMenus;
079:
080:            static {
081:                invalidateStyle();
082:            }
083:
084:            /** Static method for clearing the hashmap and loading the
085:             * current XP style and theme
086:             */
087:            static synchronized void invalidateStyle() {
088:                xp = null;
089:                themeActive = null;
090:                skinPainter.flush();
091:            }
092:
093:            /** Get the singleton instance of this class
094:             *
095:             * @return the singleton instance of this class or null if XP styles
096:             * are not active or if this is not Windows XP
097:             */
098:            static synchronized XPStyle getXP() {
099:                if (themeActive == null) {
100:                    Toolkit toolkit = Toolkit.getDefaultToolkit();
101:                    themeActive = (Boolean) toolkit
102:                            .getDesktopProperty("win.xpstyle.themeActive");
103:                    if (themeActive == null) {
104:                        themeActive = Boolean.FALSE;
105:                    }
106:                    if (themeActive.booleanValue()) {
107:                        GetPropertyAction propertyAction = new GetPropertyAction(
108:                                "swing.noxp");
109:                        if (AccessController.doPrivileged(propertyAction) == null
110:                                && ThemeReader.isThemed()
111:                                && !(UIManager.getLookAndFeel() instanceof  WindowsClassicLookAndFeel)) {
112:
113:                            xp = new XPStyle();
114:                        }
115:                    }
116:                }
117:                return xp;
118:            }
119:
120:            static boolean isVista() {
121:                XPStyle xp = XPStyle.getXP();
122:                return (xp != null && xp.isSkinDefined(null,
123:                        Part.CP_DROPDOWNBUTTONRIGHT));
124:            }
125:
126:            /** Get a named <code>String</code> value from the current style
127:             *
128:             * @param part a <code>Part</code>
129:             * @param state a <code>String</code>
130:             * @param attributeKey a <code>String</code>
131:             * @return a <code>String</code> or null if key is not found
132:             *    in the current style
133:             *
134:             * This is currently only used by WindowsInternalFrameTitlePane for painting
135:             * title foregound and can be removed when no longer needed
136:             */
137:            String getString(Component c, Part part, State state, Prop prop) {
138:                return getTypeEnumName(c, part, state, prop);
139:            }
140:
141:            TypeEnum getTypeEnum(Component c, Part part, State state, Prop prop) {
142:                int enumValue = ThemeReader.getEnum(part.getControlName(c),
143:                        part.getValue(), State.getValue(part, state), prop
144:                                .getValue());
145:                return TypeEnum.getTypeEnum(prop, enumValue);
146:            }
147:
148:            private static String getTypeEnumName(Component c, Part part,
149:                    State state, Prop prop) {
150:                int enumValue = ThemeReader.getEnum(part.getControlName(c),
151:                        part.getValue(), State.getValue(part, state), prop
152:                                .getValue());
153:                if (enumValue == -1) {
154:                    return null;
155:                }
156:                return TypeEnum.getTypeEnum(prop, enumValue).getName();
157:            }
158:
159:            /** Get a named <code>int</code> value from the current style
160:             *
161:             * @param part a <code>Part</code>
162:             * @return an <code>int</code> or null if key is not found
163:             *    in the current style
164:             */
165:            int getInt(Component c, Part part, State state, Prop prop,
166:                    int fallback) {
167:                return ThemeReader.getInt(part.getControlName(c), part
168:                        .getValue(), State.getValue(part, state), prop
169:                        .getValue());
170:            }
171:
172:            /** Get a named <code>Dimension</code> value from the current style
173:             *
174:             * @param key a <code>String</code>
175:             * @return a <code>Dimension</code> or null if key is not found
176:             *    in the current style
177:             *
178:             * This is currently only used by WindowsProgressBarUI and the value
179:             * should probably be cached there instead of here.
180:             */
181:            Dimension getDimension(Component c, Part part, State state,
182:                    Prop prop) {
183:                return ThemeReader.getPosition(part.getControlName(c), part
184:                        .getValue(), State.getValue(part, state), prop
185:                        .getValue());
186:            }
187:
188:            /** Get a named <code>Point</code> (e.g. a location or an offset) value
189:             *  from the current style
190:             *
191:             * @param key a <code>String</code>
192:             * @return a <code>Point</code> or null if key is not found
193:             *    in the current style
194:             *
195:             * This is currently only used by WindowsInternalFrameTitlePane for painting
196:             * title foregound and can be removed when no longer needed
197:             */
198:            Point getPoint(Component c, Part part, State state, Prop prop) {
199:                Dimension d = ThemeReader.getPosition(part.getControlName(c),
200:                        part.getValue(), State.getValue(part, state), prop
201:                                .getValue());
202:                if (d != null) {
203:                    return new Point(d.width, d.height);
204:                } else {
205:                    return null;
206:                }
207:            }
208:
209:            /** Get a named <code>Insets</code> value from the current style
210:             *
211:             * @param key a <code>String</code>
212:             * @return an <code>Insets</code> object or null if key is not found
213:             *    in the current style
214:             *
215:             * This is currently only used to create borders and by
216:             * WindowsInternalFrameTitlePane for painting title foregound.
217:             * The return value is already cached in those places.
218:             */
219:            Insets getMargin(Component c, Part part, State state, Prop prop) {
220:                return ThemeReader.getThemeMargins(part.getControlName(c), part
221:                        .getValue(), State.getValue(part, state), prop
222:                        .getValue());
223:            }
224:
225:            /** Get a named <code>Color</code> value from the current style
226:             *
227:             * @param part a <code>Part</code>
228:             * @return a <code>Color</code> or null if key is not found
229:             *    in the current style
230:             */
231:            synchronized Color getColor(Skin skin, Prop prop, Color fallback) {
232:                String key = skin.toString() + "." + prop.name();
233:                Part part = skin.part;
234:                Color color = colorMap.get(key);
235:                if (color == null) {
236:                    color = ThemeReader.getColor(part.getControlName(null),
237:                            part.getValue(), State.getValue(part, skin.state),
238:                            prop.getValue());
239:                    if (color != null) {
240:                        color = new ColorUIResource(color);
241:                        colorMap.put(key, color);
242:                    }
243:                }
244:                return (color != null) ? color : fallback;
245:            }
246:
247:            Color getColor(Component c, Part part, State state, Prop prop,
248:                    Color fallback) {
249:                return getColor(new Skin(c, part, state), prop, fallback);
250:            }
251:
252:            /** Get a named <code>Border</code> value from the current style
253:             *
254:             * @param part a <code>Part</code>
255:             * @return a <code>Border</code> or null if key is not found
256:             *    in the current style or if the style for the particular
257:             *    part is not defined as "borderfill".
258:             */
259:            synchronized Border getBorder(Component c, Part part) {
260:                if (part == Part.MENU) {
261:                    // Special case because XP has no skin for menus
262:                    if (flatMenus) {
263:                        // TODO: The classic border uses this color, but we should
264:                        // create a new UI property called "PopupMenu.borderColor"
265:                        // instead.
266:                        return new XPFillBorder(UIManager
267:                                .getColor("InternalFrame.borderShadow"), 1);
268:                    } else {
269:                        return null; // Will cause L&F to use classic border
270:                    }
271:                }
272:                Skin skin = new Skin(c, part, null);
273:                Border border = borderMap.get(skin.string);
274:                if (border == null) {
275:                    String bgType = getTypeEnumName(c, part, null, Prop.BGTYPE);
276:                    if ("borderfill".equalsIgnoreCase(bgType)) {
277:                        int thickness = getInt(c, part, null, Prop.BORDERSIZE,
278:                                1);
279:                        Color color = getColor(skin, Prop.BORDERCOLOR,
280:                                Color.black);
281:                        border = new XPFillBorder(color, thickness);
282:                        if (part == Part.CP_COMBOBOX) {
283:                            border = new XPStatefulFillBorder(color, thickness,
284:                                    part, Prop.BORDERCOLOR);
285:                        }
286:                    } else if ("imagefile".equalsIgnoreCase(bgType)) {
287:                        Insets m = getMargin(c, part, null, Prop.SIZINGMARGINS);
288:                        if (m != null) {
289:                            if (getBoolean(c, part, null, Prop.BORDERONLY)) {
290:                                border = new XPImageBorder(c, part);
291:                            } else if (part == Part.CP_COMBOBOX) {
292:                                border = new EmptyBorder(1, 1, 1, 1);
293:                            } else {
294:                                if (part == Part.TP_BUTTON) {
295:                                    border = new XPEmptyBorder(new Insets(3, 3,
296:                                            3, 3));
297:                                } else {
298:                                    border = new XPEmptyBorder(m);
299:                                }
300:                            }
301:                        }
302:                    }
303:                    if (border != null) {
304:                        borderMap.put(skin.string, border);
305:                    }
306:                }
307:                return border;
308:            }
309:
310:            private class XPFillBorder extends LineBorder implements  UIResource {
311:                XPFillBorder(Color color, int thickness) {
312:                    super (color, thickness);
313:                }
314:
315:                public Insets getBorderInsets(Component c) {
316:                    return getBorderInsets(c, new Insets(0, 0, 0, 0));
317:                }
318:
319:                public Insets getBorderInsets(Component c, Insets insets) {
320:                    Insets margin = null;
321:                    //
322:                    // Ideally we'd have an interface defined for classes which
323:                    // support margins (to avoid this hackery), but we've
324:                    // decided against it for simplicity
325:                    //
326:                    if (c instanceof  AbstractButton) {
327:                        margin = ((AbstractButton) c).getMargin();
328:                    } else if (c instanceof  JToolBar) {
329:                        margin = ((JToolBar) c).getMargin();
330:                    } else if (c instanceof  JTextComponent) {
331:                        margin = ((JTextComponent) c).getMargin();
332:                    }
333:                    insets.top = (margin != null ? margin.top : 0) + thickness;
334:                    insets.left = (margin != null ? margin.left : 0)
335:                            + thickness;
336:                    insets.bottom = (margin != null ? margin.bottom : 0)
337:                            + thickness;
338:                    insets.right = (margin != null ? margin.right : 0)
339:                            + thickness;
340:
341:                    return insets;
342:                }
343:            }
344:
345:            private class XPStatefulFillBorder extends XPFillBorder {
346:                private final Part part;
347:                private final Prop prop;
348:
349:                XPStatefulFillBorder(Color color, int thickness, Part part,
350:                        Prop prop) {
351:                    super (color, thickness);
352:                    this .part = part;
353:                    this .prop = prop;
354:                }
355:
356:                public void paintBorder(Component c, Graphics g, int x, int y,
357:                        int width, int height) {
358:                    State state = State.NORMAL;
359:                    // special casing for comboboxes.
360:                    // there may be more special cases in the future
361:                    if (c instanceof  JComboBox) {
362:                        JComboBox cb = (JComboBox) c;
363:                        // note. in the future this should be replaced with a call
364:                        // to BasicLookAndFeel.getUIOfType()
365:                        if (cb.getUI() instanceof  WindowsComboBoxUI) {
366:                            WindowsComboBoxUI wcb = (WindowsComboBoxUI) cb
367:                                    .getUI();
368:                            state = wcb.getXPComboBoxState(cb);
369:                        }
370:                    }
371:                    lineColor = getColor(c, part, state, prop, Color.black);
372:                    super .paintBorder(c, g, x, y, width, height);
373:                }
374:            }
375:
376:            private class XPImageBorder extends AbstractBorder implements 
377:                    UIResource {
378:                Skin skin;
379:
380:                XPImageBorder(Component c, Part part) {
381:                    this .skin = getSkin(c, part);
382:                }
383:
384:                public void paintBorder(Component c, Graphics g, int x, int y,
385:                        int width, int height) {
386:                    skin.paintSkin(g, x, y, width, height, null);
387:                }
388:
389:                public Insets getBorderInsets(Component c) {
390:                    return getBorderInsets(c, new Insets(0, 0, 0, 0));
391:                }
392:
393:                public Insets getBorderInsets(Component c, Insets insets) {
394:                    Insets margin = null;
395:                    Insets borderInsets = skin.getContentMargin();
396:                    if (borderInsets == null) {
397:                        borderInsets = new Insets(0, 0, 0, 0);
398:                    }
399:                    //
400:                    // Ideally we'd have an interface defined for classes which
401:                    // support margins (to avoid this hackery), but we've
402:                    // decided against it for simplicity
403:                    //
404:                    if (c instanceof  AbstractButton) {
405:                        margin = ((AbstractButton) c).getMargin();
406:                    } else if (c instanceof  JToolBar) {
407:                        margin = ((JToolBar) c).getMargin();
408:                    } else if (c instanceof  JTextComponent) {
409:                        margin = ((JTextComponent) c).getMargin();
410:                    }
411:                    insets.top = (margin != null ? margin.top : 0)
412:                            + borderInsets.top;
413:                    insets.left = (margin != null ? margin.left : 0)
414:                            + borderInsets.left;
415:                    insets.bottom = (margin != null ? margin.bottom : 0)
416:                            + borderInsets.bottom;
417:                    insets.right = (margin != null ? margin.right : 0)
418:                            + borderInsets.right;
419:
420:                    return insets;
421:                }
422:            }
423:
424:            private class XPEmptyBorder extends EmptyBorder implements 
425:                    UIResource {
426:                XPEmptyBorder(Insets m) {
427:                    super (m.top + 2, m.left + 2, m.bottom + 2, m.right + 2);
428:                }
429:
430:                public Insets getBorderInsets(Component c) {
431:                    return getBorderInsets(c, getBorderInsets());
432:                }
433:
434:                public Insets getBorderInsets(Component c, Insets insets) {
435:                    insets = super .getBorderInsets(c, insets);
436:
437:                    Insets margin = null;
438:                    if (c instanceof  AbstractButton) {
439:                        Insets m = ((AbstractButton) c).getMargin();
440:                        // if this is a toolbar button then ignore getMargin()
441:                        // and subtract the padding added by the constructor
442:                        if (c.getParent() instanceof  JToolBar
443:                                && !(c instanceof  JRadioButton)
444:                                && !(c instanceof  JCheckBox)
445:                                && m instanceof  InsetsUIResource) {
446:                            insets.top -= 2;
447:                            insets.left -= 2;
448:                            insets.bottom -= 2;
449:                            insets.right -= 2;
450:                        } else {
451:                            margin = m;
452:                        }
453:                    } else if (c instanceof  JToolBar) {
454:                        margin = ((JToolBar) c).getMargin();
455:                    } else if (c instanceof  JTextComponent) {
456:                        margin = ((JTextComponent) c).getMargin();
457:                    }
458:                    if (margin != null) {
459:                        insets.top = margin.top + 2;
460:                        insets.left = margin.left + 2;
461:                        insets.bottom = margin.bottom + 2;
462:                        insets.right = margin.right + 2;
463:                    }
464:                    return insets;
465:                }
466:            }
467:
468:            boolean isSkinDefined(Component c, Part part) {
469:                return (part.getValue() == 0)
470:                        || ThemeReader.isThemePartDefined(part
471:                                .getControlName(c), part.getValue(), 0);
472:            }
473:
474:            /** Get a <code>Skin</code> object from the current style
475:             * for a named part (component type)
476:             *
477:             * @param part a <code>Part</code>
478:             * @return a <code>Skin</code> object 
479:             */
480:            synchronized Skin getSkin(Component c, Part part) {
481:                assert isSkinDefined(c, part) : "part " + part
482:                        + " is not defined";
483:                return new Skin(c, part, null);
484:            }
485:
486:            long getThemeTransitionDuration(Component c, Part part,
487:                    State stateFrom, State stateTo, Prop prop) {
488:                return ThemeReader.getThemeTransitionDuration(part
489:                        .getControlName(c), part.getValue(), State.getValue(
490:                        part, stateFrom), State.getValue(part, stateTo),
491:                        (prop != null) ? prop.getValue() : 0);
492:            }
493:
494:            /** A class which encapsulates attributes for a given part
495:             * (component type) and which provides methods for painting backgrounds
496:             * and glyphs
497:             */
498:            static class Skin {
499:                final Component component;
500:                final Part part;
501:                final State state;
502:
503:                private final String string;
504:                private Dimension size = null;
505:
506:                Skin(Component component, Part part) {
507:                    this (component, part, null);
508:                }
509:
510:                Skin(Part part, State state) {
511:                    this (null, part, state);
512:                }
513:
514:                Skin(Component component, Part part, State state) {
515:                    this .component = component;
516:                    this .part = part;
517:                    this .state = state;
518:
519:                    String str = part.getControlName(component) + "."
520:                            + part.name();
521:                    if (state != null) {
522:                        str += "(" + state.name() + ")";
523:                    }
524:                    string = str;
525:                }
526:
527:                Insets getContentMargin() {
528:                    // This is only called by WindowsTableHeaderUI so far.
529:                    return ThemeReader.getThemeMargins(part
530:                            .getControlName(null), part.getValue(), 0,
531:                            Prop.SIZINGMARGINS.getValue());
532:                }
533:
534:                private int getWidth(State state) {
535:                    if (size == null) {
536:                        size = getPartSize(part, state);
537:                    }
538:                    return size.width;
539:                }
540:
541:                int getWidth() {
542:                    return getWidth((state != null) ? state : State.NORMAL);
543:                }
544:
545:                private int getHeight(State state) {
546:                    if (size == null) {
547:                        size = getPartSize(part, state);
548:                    }
549:                    return size.height;
550:                }
551:
552:                int getHeight() {
553:                    return getHeight((state != null) ? state : State.NORMAL);
554:                }
555:
556:                public String toString() {
557:                    return string;
558:                }
559:
560:                public boolean equals(Object obj) {
561:                    return (obj instanceof  Skin && ((Skin) obj).string
562:                            .equals(string));
563:                }
564:
565:                public int hashCode() {
566:                    return string.hashCode();
567:                }
568:
569:                /** Paint a skin at x, y.
570:                 *
571:                 * @param g   the graphics context to use for painting
572:                 * @param dx  the destination <i>x</i> coordinate
573:                 * @param dy  the destination <i>y</i> coordinate
574:                 * @param state which state to paint
575:                 */
576:                void paintSkin(Graphics g, int dx, int dy, State state) {
577:                    if (state == null) {
578:                        state = this .state;
579:                    }
580:                    paintSkin(g, dx, dy, getWidth(state), getHeight(state),
581:                            state);
582:                }
583:
584:                /** Paint a skin in an area defined by a rectangle.
585:                 *
586:                 * @param g the graphics context to use for painting
587:                 * @param r     a <code>Rectangle</code> defining the area to fill,
588:                 *                     may cause the image to be stretched or tiled
589:                 * @param state which state to paint
590:                 */
591:                void paintSkin(Graphics g, Rectangle r, State state) {
592:                    paintSkin(g, r.x, r.y, r.width, r.height, state);
593:                }
594:
595:                /** Paint a skin at a defined position and size
596:                 *  This method supports animation.
597:                 *
598:                 * @param g   the graphics context to use for painting
599:                 * @param dx  the destination <i>x</i> coordinate
600:                 * @param dy  the destination <i>y</i> coordinate
601:                 * @param dw  the width of the area to fill, may cause
602:                 *                  the image to be stretched or tiled
603:                 * @param dh  the height of the area to fill, may cause
604:                 *                  the image to be stretched or tiled
605:                 * @param state which state to paint
606:                 */
607:                void paintSkin(Graphics g, int dx, int dy, int dw, int dh,
608:                        State state) {
609:                    if (ThemeReader.isGetThemeTransitionDurationDefined()
610:                            && component instanceof  JComponent
611:                            && SwingUtilities.getAncestorOfClass(
612:                                    CellRendererPane.class, component) == null) {
613:                        AnimationController.paintSkin((JComponent) component,
614:                                this , g, dx, dy, dw, dh, state);
615:                    } else {
616:                        paintSkinRaw(g, dx, dy, dw, dh, state);
617:                    }
618:                }
619:
620:                /** Paint a skin at a defined position and size. This method
621:                 *  does not trigger animation. It is needed for the animation
622:                 *  support.
623:                 *
624:                 * @param g   the graphics context to use for painting
625:                 * @param dx  the destination <i>x</i> coordinate.
626:                 * @param dy  the destination <i>y</i> coordinate.
627:                 * @param dw  the width of the area to fill, may cause
628:                 *                  the image to be stretched or tiled
629:                 * @param dh  the height of the area to fill, may cause
630:                 *                  the image to be stretched or tiled
631:                 * @param state which state to paint
632:                 */
633:                void paintSkinRaw(Graphics g, int dx, int dy, int dw, int dh,
634:                        State state) {
635:                    skinPainter.paint(null, g, dx, dy, dw, dh, this , state);
636:                }
637:
638:                /** Paint a skin at a defined position and size
639:                 *
640:                 * @param g   the graphics context to use for painting
641:                 * @param dx  the destination <i>x</i> coordinate
642:                 * @param dy  the destination <i>y</i> coordinate
643:                 * @param dw  the width of the area to fill, may cause
644:                 *                  the image to be stretched or tiled
645:                 * @param dh  the height of the area to fill, may cause
646:                 *                  the image to be stretched or tiled
647:                 * @param state which state to paint
648:                 * @param borderFill should test if the component uses a border fill
649:                                    and skip painting if it is
650:                 */
651:                void paintSkin(Graphics g, int dx, int dy, int dw, int dh,
652:                        State state, boolean borderFill) {
653:                    if (borderFill
654:                            && "borderfill".equals(getTypeEnumName(component,
655:                                    part, state, Prop.BGTYPE))) {
656:                        return;
657:                    }
658:                    skinPainter.paint(null, g, dx, dy, dw, dh, this , state);
659:                }
660:            }
661:
662:            private static class SkinPainter extends CachedPainter {
663:                SkinPainter() {
664:                    super (30);
665:                    flush();
666:                }
667:
668:                public void flush() {
669:                    super .flush();
670:                }
671:
672:                protected void paintToImage(Component c, Image image,
673:                        Graphics g, int w, int h, Object[] args) {
674:                    boolean accEnabled = false;
675:                    Skin skin = (Skin) args[0];
676:                    Part part = skin.part;
677:                    State state = (State) args[1];
678:                    if (state == null) {
679:                        state = skin.state;
680:                    }
681:                    if (c == null) {
682:                        c = skin.component;
683:                    }
684:                    BufferedImage bi = (BufferedImage) image;
685:
686:                    WritableRaster raster = bi.getRaster();
687:                    DataBufferInt dbi = (DataBufferInt) raster.getDataBuffer();
688:                    // Note that stealData() requires a markDirty() afterwards
689:                    // since we modify the data in it.
690:                    ThemeReader.paintBackground(SunWritableRaster.stealData(
691:                            dbi, 0), part.getControlName(c), part.getValue(),
692:                            State.getValue(part, state), 0, 0, w, h, w);
693:                    SunWritableRaster.markDirty(dbi);
694:                }
695:
696:                protected Image createImage(Component c, int w, int h,
697:                        GraphicsConfiguration config, Object[] args) {
698:                    return new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
699:                }
700:            }
701:
702:            static class GlyphButton extends JButton {
703:                private Skin skin;
704:
705:                public GlyphButton(Component parent, Part part) {
706:                    XPStyle xp = getXP();
707:                    skin = xp.getSkin(parent, part);
708:                    setBorder(null);
709:                    setContentAreaFilled(false);
710:                    setMinimumSize(new Dimension(5, 5));
711:                    setPreferredSize(new Dimension(16, 16));
712:                    setMaximumSize(new Dimension(Integer.MAX_VALUE,
713:                            Integer.MAX_VALUE));
714:                }
715:
716:                public boolean isFocusTraversable() {
717:                    return false;
718:                }
719:
720:                protected State getState() {
721:                    State state = State.NORMAL;
722:                    if (!isEnabled()) {
723:                        state = State.DISABLED;
724:                    } else if (getModel().isPressed()) {
725:                        state = State.PRESSED;
726:                    } else if (getModel().isRollover()) {
727:                        state = State.HOT;
728:                    }
729:                    return state;
730:                }
731:
732:                public void paintComponent(Graphics g) {
733:                    Dimension d = getSize();
734:                    skin.paintSkin(g, 0, 0, d.width, d.height, getState());
735:                }
736:
737:                public void setPart(Component parent, Part part) {
738:                    XPStyle xp = getXP();
739:                    skin = xp.getSkin(parent, part);
740:                    revalidate();
741:                    repaint();
742:                }
743:
744:                protected void paintBorder(Graphics g) {
745:                }
746:
747:            }
748:
749:            // Private constructor
750:            private XPStyle() {
751:                flatMenus = getSysBoolean(Prop.FLATMENUS);
752:
753:                colorMap = new HashMap<String, Color>();
754:                borderMap = new HashMap<String, Border>();
755:                // Note: All further access to the maps must be synchronized
756:            }
757:
758:            private boolean getBoolean(Component c, Part part, State state,
759:                    Prop prop) {
760:                return ThemeReader.getBoolean(part.getControlName(c), part
761:                        .getValue(), State.getValue(part, state), prop
762:                        .getValue());
763:            }
764:
765:            static Dimension getPartSize(Part part, State state) {
766:                return ThemeReader.getPartSize(part.getControlName(null), part
767:                        .getValue(), State.getValue(part, state));
768:            }
769:
770:            private static boolean getSysBoolean(Prop prop) {
771:                // We can use any widget name here, I guess.
772:                return ThemeReader.getSysBoolean("window", prop.getValue());
773:            }
774:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.