Source Code Cross Referenced for JideSwingUtilities.java in  » Swing-Library » jide-common » com » jidesoft » swing » 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 » Swing Library » jide common » com.jidesoft.swing 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * @(#)JideSwingUtilities.java
0003:         *
0004:         * Copyright 2002 JIDE Software. All rights reserved.
0005:         */
0006:        package com.jidesoft.swing;
0007:
0008:        import com.jidesoft.dialog.ButtonPanel;
0009:        import com.jidesoft.plaf.UIDefaultsLookup;
0010:        import com.jidesoft.plaf.WindowsDesktopProperty;
0011:        import com.jidesoft.plaf.basic.ThemePainter;
0012:        import com.jidesoft.utils.SecurityUtils;
0013:        import com.jidesoft.utils.SystemInfo;
0014:
0015:        import javax.swing.*;
0016:        import javax.swing.border.Border;
0017:        import javax.swing.event.ChangeEvent;
0018:        import javax.swing.event.ChangeListener;
0019:        import javax.swing.event.EventListenerList;
0020:        import javax.swing.plaf.FontUIResource;
0021:        import javax.swing.plaf.UIResource;
0022:        import javax.swing.table.DefaultTableModel;
0023:        import javax.swing.text.JTextComponent;
0024:        import javax.swing.text.View;
0025:        import java.awt.*;
0026:        import java.awt.event.*;
0027:        import java.awt.image.BufferedImage;
0028:        import java.beans.PropertyChangeEvent;
0029:        import java.beans.PropertyChangeListener;
0030:        import java.lang.reflect.Array;
0031:        import java.lang.reflect.InvocationTargetException;
0032:        import java.security.AccessControlException;
0033:        import java.util.*;
0034:
0035:        /**
0036:         * A utilities class for Swing.
0037:         */
0038:        public class JideSwingUtilities implements  SwingConstants {
0039:            /**
0040:             * Whether or not text is drawn anti-aliased.  This is only used if
0041:             * <code>AA_TEXT_DEFINED</code> is true.
0042:             */
0043:            private static final boolean AA_TEXT;
0044:
0045:            /**
0046:             * Whether or not the system property 'swing.aatext' is defined.
0047:             */
0048:            private static final boolean AA_TEXT_DEFINED;
0049:
0050:            /**
0051:             * Key used in client properties to indicate whether or not the component
0052:             * should use aa text.
0053:             */
0054:            public static final Object AA_TEXT_PROPERTY_KEY = new StringBuffer(
0055:                    "AATextPropertyKey");
0056:
0057:            static {
0058:                Object aa = SecurityUtils.getProperty("swing.aatext", "false");
0059:                AA_TEXT_DEFINED = (aa != null);
0060:                AA_TEXT = "true".equals(aa);
0061:            }
0062:
0063:            /**
0064:             * Create a Panel around a component so that
0065:             * component aligns to left.
0066:             *
0067:             * @param object
0068:             * @return a Panel
0069:             */
0070:            public static JPanel createLeftPanel(Component object) {
0071:                JPanel ret = new NullPanel(new BorderLayout());
0072:                ret.setOpaque(false);
0073:                ret.add(object, BorderLayout.BEFORE_LINE_BEGINS);
0074:                return ret;
0075:            }
0076:
0077:            /**
0078:             * Create a Panel around a component so that
0079:             * component aligns to right.
0080:             *
0081:             * @param object
0082:             * @return a Panel
0083:             */
0084:            public static JPanel createRightPanel(Component object) {
0085:                JPanel ret = new NullPanel(new BorderLayout());
0086:                ret.setOpaque(false);
0087:                ret.add(object, BorderLayout.AFTER_LINE_ENDS);
0088:                return ret;
0089:            }
0090:
0091:            /**
0092:             * Create a Panel around a component so that
0093:             * component aligns to top.
0094:             *
0095:             * @param object
0096:             * @return a Panel
0097:             */
0098:            public static JPanel createTopPanel(Component object) {
0099:                JPanel ret = new NullPanel(new BorderLayout());
0100:                ret.setOpaque(false);
0101:                ret.add(object, BorderLayout.BEFORE_FIRST_LINE);
0102:                return ret;
0103:            }
0104:
0105:            /**
0106:             * Create a Panel around a component so that
0107:             * component aligns to buttom.
0108:             *
0109:             * @param object
0110:             * @return a Panel
0111:             */
0112:            public static JPanel createBottomPanel(Component object) {
0113:                JPanel ret = new NullPanel(new BorderLayout());
0114:                ret.setOpaque(false);
0115:                ret.add(object, BorderLayout.AFTER_LAST_LINE);
0116:                return ret;
0117:            }
0118:
0119:            /**
0120:             * Create a Panel around a component so that
0121:             * component is right in the middle.
0122:             *
0123:             * @param object
0124:             * @return a Panel
0125:             */
0126:            public static JPanel createCenterPanel(Component object) {
0127:                JPanel ret = new NullPanel(new GridBagLayout());
0128:                ret.setOpaque(false);
0129:                ret.add(object, new GridBagConstraints());
0130:                return ret;
0131:            }
0132:
0133:            /**
0134:             * Center the component to it's parent window.
0135:             */
0136:            public static void centerWindow(Window childToCenter) {
0137:                childToCenter.setLocationRelativeTo(childToCenter.getParent());
0138:                //        Container parentWindow = childToCenter.getParent();
0139:                //
0140:                //        int width = (parentWindow.getWidth() - childToCenter.getWidth()) >> 1;
0141:                //        int height = (parentWindow.getHeight() - childToCenter.getHeight()) >> 1;
0142:                //
0143:                //        // according to javadoc of setLocation, it's relavent to parent window. but it's not the case.
0144:                //        Point location = parentWindow.getLocation();
0145:                //        width += location.x;
0146:                //        height += location.y;
0147:                //        childToCenter.setLocation(width, height);
0148:            }
0149:
0150:            /**
0151:             * Center the window to the whole screen.
0152:             */
0153:            public static void globalCenterWindow(Window childToCenter) {
0154:                childToCenter.setLocationRelativeTo(null);
0155:                //        Dimension screenDim = Toolkit.getDefaultToolkit().getScreenSize();
0156:                //
0157:                //        // Get the bounds of the splash window
0158:                //        Rectangle frameDim = childToCenter.getBounds();
0159:                //
0160:                //        // Compute the location of the window
0161:                //        childToCenter.setLocation((screenDim.width - frameDim.width) >> 1, (screenDim.height - frameDim.height) >> 1);
0162:            }
0163:
0164:            /**
0165:             * Paints an arrow shape.
0166:             *
0167:             * @param g
0168:             * @param color
0169:             * @param startX
0170:             * @param startY
0171:             * @param width
0172:             * @param orientation
0173:             */
0174:            public static void paintArrow(Graphics g, Color color, int startX,
0175:                    int startY, int width, int orientation) {
0176:                Color oldColor = g.getColor();
0177:                g.setColor(color);
0178:                width = width / 2 * 2 + 1; // make sure it's odd
0179:                if (orientation == HORIZONTAL) {
0180:                    for (int i = 0; i < (width + 1) / 2; i++) {
0181:                        g.drawLine(startX + i, startY + i, startX + width - i
0182:                                - 1, startY + i);
0183:                    }
0184:                } else {
0185:                    for (int i = 0; i < (width + 1) / 2; i++) {
0186:                        g.drawLine(startX + i, startY + i, startX + i, startY
0187:                                + width - i - 1);
0188:                    }
0189:                }
0190:                g.setColor(oldColor);
0191:            }
0192:
0193:            /**
0194:             * Paints a cross shape.
0195:             *
0196:             * @param g
0197:             * @param color
0198:             * @param centerX
0199:             * @param centerY
0200:             * @param size
0201:             * @param width
0202:             */
0203:            public static void paintCross(Graphics g, Color color, int centerX,
0204:                    int centerY, int size, int width) {
0205:                g.setColor(color);
0206:                size = size / 2; // make sure it's odd
0207:                for (int i = 0; i < width; i++) {
0208:                    g.drawLine(centerX - size, centerY - size, centerX + size,
0209:                            centerY + size);
0210:                    g.drawLine(centerX + size, centerY - size, centerX - size,
0211:                            centerY + size);
0212:                    centerX++;
0213:                }
0214:            }
0215:
0216:            /**
0217:             * Gets the top level Frame of the component.
0218:             *
0219:             * @param component
0220:             * @return the top level Frame. Null if we didn't find an ancestor which is instance of Frame.
0221:             */
0222:            public static Frame getFrame(Component component) {
0223:                if (component == null)
0224:                    return null;
0225:
0226:                if (component instanceof  Frame)
0227:                    return (Frame) component;
0228:
0229:                // Find framel
0230:                Container p = component.getParent();
0231:                while (p != null) {
0232:                    if (p instanceof  Frame) {
0233:                        return (Frame) p;
0234:                    }
0235:                    p = p.getParent();
0236:                }
0237:                return null;
0238:            }
0239:
0240:            /**
0241:             * Toggles between RTL and LTR.
0242:             *
0243:             * @param topContainer
0244:             */
0245:            public static void toggleRTLnLTR(Component topContainer) {
0246:                ComponentOrientation co = topContainer
0247:                        .getComponentOrientation();
0248:                if (co == ComponentOrientation.RIGHT_TO_LEFT)
0249:                    co = ComponentOrientation.LEFT_TO_RIGHT;
0250:                else
0251:                    co = ComponentOrientation.RIGHT_TO_LEFT;
0252:                topContainer.applyComponentOrientation(co);
0253:            }
0254:
0255:            /**
0256:             * @param view1
0257:             * @param view2
0258:             * @param orientation
0259:             * @deprecated there is a typo. Use {@link #synchronizeView(javax.swing.JViewport,javax.swing.JViewport,int)}.
0260:             */
0261:            public static void synchonizeView(final JViewport view1,
0262:                    final JViewport view2, final int orientation) {
0263:                synchronizeView(view1, view2, orientation);
0264:            }
0265:
0266:            /**
0267:             * Synchonizes the two viewports. The view position in one view changes, the other view's view position will change too.
0268:             * Generally speaking, if you want the two viewports to synchronize vertically, they should have the same height.
0269:             * If horizonally, the same width.
0270:             *
0271:             * @param view1       the first viewport
0272:             * @param view2       the second viewport
0273:             * @param orientation the orientation. It could be either SwingConstants.HORIZONTAL or SwingConstants.VERTICAL.
0274:             */
0275:            public static void synchronizeView(final JViewport view1,
0276:                    final JViewport view2, final int orientation) {
0277:                final ChangeListener c1 = new ChangeListener() {
0278:                    public void stateChanged(ChangeEvent e) {
0279:                        if (orientation == HORIZONTAL) {
0280:                            Point v1 = view1.getViewPosition();
0281:                            Point v2 = view2.getViewPosition();
0282:                            if (v1.x != v2.x) {
0283:                                view2.setViewPosition(new Point(v1.x, v2.y));
0284:                            }
0285:                        } else if (orientation == VERTICAL) {
0286:                            Point v1 = view1.getViewPosition();
0287:                            Point v2 = view2.getViewPosition();
0288:                            if (v1.y != v2.y) {
0289:                                view2.setViewPosition(new Point(v2.x, v1.y));
0290:                            }
0291:                        }
0292:                    }
0293:                };
0294:
0295:                final ChangeListener c2 = new ChangeListener() {
0296:                    public void stateChanged(ChangeEvent e) {
0297:                        if (orientation == HORIZONTAL) {
0298:                            Point v1 = view1.getViewPosition();
0299:                            Point v2 = view2.getViewPosition();
0300:                            if (v1.x != v2.x) {
0301:                                view1.setViewPosition(new Point(v2.x, v1.y));
0302:                            }
0303:                        } else if (orientation == VERTICAL) {
0304:                            Point v1 = view1.getViewPosition();
0305:                            Point v2 = view2.getViewPosition();
0306:                            if (v1.y != v2.y) {
0307:                                view1.setViewPosition(new Point(v1.x, v2.y));
0308:                            }
0309:                        }
0310:                    }
0311:                };
0312:
0313:                view1.addChangeListener(c1);
0314:                view2.addChangeListener(c2);
0315:            }
0316:
0317:            public static int getButtonState(AbstractButton b) {
0318:                ButtonModel model = b.getModel();
0319:                if (!model.isEnabled()) {
0320:                    if (model.isSelected()) {
0321:                        return ThemePainter.STATE_DISABLE_SELECTED;
0322:                    } else {
0323:                        return ThemePainter.STATE_DISABLE;
0324:                    }
0325:                } else if (b.hasFocus() && b.isFocusPainted()) {
0326:                    if (model.isSelected()) {
0327:                        return ThemePainter.STATE_PRESSED;
0328:                    } else {
0329:                        return ThemePainter.STATE_ROLLOVER;
0330:                    }
0331:                } else if (model.isPressed() && model.isArmed()) {
0332:                    if (model.isRollover()) {
0333:                        return ThemePainter.STATE_PRESSED;
0334:                    }
0335:                } else if (b.isRolloverEnabled() && model.isRollover()) {
0336:                    if (model.isSelected()) {
0337:                        return ThemePainter.STATE_PRESSED; // should be rollover selected
0338:                    } else {
0339:                        return ThemePainter.STATE_ROLLOVER;
0340:                    }
0341:                } else if (model.isSelected()) {
0342:                    return ThemePainter.STATE_SELECTED;
0343:                }
0344:                return ThemePainter.STATE_DEFAULT;
0345:            }
0346:
0347:            public static int[] getButtonState(JideSplitButton b) {
0348:                int[] states = new int[2];
0349:                SplitButtonModel model = (SplitButtonModel) b.getModel();
0350:                if (!model.isEnabled()) {
0351:                    if (model.isButtonSelected()) {
0352:                        states[0] = ThemePainter.STATE_DISABLE_SELECTED;
0353:                    } else {
0354:                        states[0] = ThemePainter.STATE_DISABLE;
0355:                    }
0356:                } else if (b.hasFocus() && b.isFocusPainted()) {
0357:                    if (model.isButtonSelected()) {
0358:                        states[0] = ThemePainter.STATE_SELECTED;
0359:                        states[1] = ThemePainter.STATE_INACTIVE_ROLLOVER;
0360:                    } else if (model.isSelected()) {
0361:                        states[0] = ThemePainter.STATE_INACTIVE_ROLLOVER;
0362:                        states[1] = ThemePainter.STATE_SELECTED;
0363:                    } else {
0364:                        states[0] = ThemePainter.STATE_ROLLOVER;
0365:                        states[1] = ThemePainter.STATE_INACTIVE_ROLLOVER;
0366:                    }
0367:                } else if (model.isPressed() && model.isArmed()) {
0368:                    if (model.isButtonRollover()) {
0369:                        states[0] = ThemePainter.STATE_PRESSED;
0370:                        states[1] = ThemePainter.STATE_INACTIVE_ROLLOVER;
0371:                    } else if (model.isRollover()) {
0372:                        states[0] = ThemePainter.STATE_INACTIVE_ROLLOVER;
0373:                        states[1] = ThemePainter.STATE_ROLLOVER;
0374:                    }
0375:                } else if (b.isRolloverEnabled() && model.isButtonRollover()) {
0376:                    if (model.isButtonSelected()) {
0377:                        states[0] = ThemePainter.STATE_PRESSED;
0378:                        states[1] = ThemePainter.STATE_INACTIVE_ROLLOVER;
0379:                    } else if (model.isSelected()) {
0380:                        states[0] = ThemePainter.STATE_ROLLOVER;
0381:                        states[1] = ThemePainter.STATE_PRESSED;
0382:                    } else {
0383:                        states[0] = ThemePainter.STATE_ROLLOVER;
0384:                        states[1] = ThemePainter.STATE_INACTIVE_ROLLOVER;
0385:                    }
0386:                } else if (b.isRolloverEnabled() && model.isRollover()) {
0387:                    if (model.isButtonSelected()) {
0388:                        states[0] = ThemePainter.STATE_PRESSED;
0389:                        states[1] = ThemePainter.STATE_ROLLOVER;
0390:                    } else if (model.isSelected()) {
0391:                        states[0] = ThemePainter.STATE_INACTIVE_ROLLOVER;
0392:                        states[1] = ThemePainter.STATE_PRESSED;
0393:                    } else {
0394:                        states[0] = ThemePainter.STATE_INACTIVE_ROLLOVER;
0395:                        states[1] = ThemePainter.STATE_ROLLOVER;
0396:                    }
0397:                } else if (model.isButtonSelected()) {
0398:                    states[0] = ThemePainter.STATE_SELECTED;
0399:                    states[1] = ThemePainter.STATE_INACTIVE_ROLLOVER;
0400:                } else if (model.isSelected()) {
0401:                    states[0] = ThemePainter.STATE_INACTIVE_ROLLOVER;
0402:                    states[1] = ThemePainter.STATE_SELECTED;
0403:                } else {
0404:                    states[0] = ThemePainter.STATE_DEFAULT;
0405:                    states[1] = ThemePainter.STATE_DEFAULT;
0406:                }
0407:                return states;
0408:            }
0409:
0410:            /**
0411:             * Checks if the two objects equal. If both are null, they are equal. If o1 and o2 both are Comparable, we will
0412:             * use compareTo method to see if it equals 0.
0413:             * At last, we will use <code>o1.equals(o2)</code> to compare.
0414:             * If none of the above conditions match, we return false.
0415:             *
0416:             * @param o1 the first object to compare
0417:             * @param o2 the second object to compare
0418:             * @return true if the two objects are equal. Otherwise false.
0419:             */
0420:            public static boolean equals(Object o1, Object o2) {
0421:                return equals(o1, o2, false);
0422:            }
0423:
0424:            /**
0425:             * Checks if the two objects equal. If both are null, they are equal. If o1 and o2 both are Comparable, we will
0426:             * use compareTo method to see if it equals 0. If considerArray is true and o1 and o2 are both array, we will compare each element in the array.
0427:             * At last, we will use <code>o1.equals(o2)</code> to compare.
0428:             * If none of the above conditions match, we return false.
0429:             *
0430:             * @param o1            the first object to compare
0431:             * @param o2            the second object to compare
0432:             * @param considerArray If true, and if o1 and o2 are both array, we will compare each element in the array instead of just compare the two array objects.
0433:             * @return true if the two objects are equal. Otherwise false.
0434:             */
0435:            public static boolean equals(Object o1, Object o2,
0436:                    boolean considerArray) {
0437:                if (o1 == null && o2 == null) {
0438:                    return true;
0439:                } else if (o1 != null && o2 == null) {
0440:                    return false;
0441:                } else if (o1 == null) {
0442:                    return false;
0443:                } else if (o1 instanceof  Comparable && o2 instanceof  Comparable
0444:                        && o1.getClass().isAssignableFrom(o2.getClass())) {
0445:                    return ((Comparable) o1).compareTo(o2) == 0;
0446:                } else if (o1 instanceof  Comparable && o2 instanceof  Comparable
0447:                        && o2.getClass().isAssignableFrom(o1.getClass())) {
0448:                    return ((Comparable) o2).compareTo(o1) == 0;
0449:                } else {
0450:                    if (considerArray && o1.getClass().isArray()
0451:                            && o2.getClass().isArray()) {
0452:                        int length1 = Array.getLength(o1);
0453:                        int length2 = Array.getLength(o2);
0454:                        if (length1 != length2) {
0455:                            return false;
0456:                        }
0457:                        for (int i = 0; i < length1; i++) {
0458:                            boolean equals = equals(Array.get(o1, i), Array
0459:                                    .get(o1, i));
0460:                            if (!equals) {
0461:                                return false;
0462:                            }
0463:                        }
0464:                        return true;
0465:                    } else {
0466:                        return o1.equals(o2);
0467:                    }
0468:                }
0469:            }
0470:
0471:            /**
0472:             * Convenience method that returns a scaled instance of the
0473:             * provided BufferedImage.
0474:             *
0475:             * @param img                 the original image to be scaled
0476:             * @param targetWidth         the desired width of the scaled instance,
0477:             *                            in pixels
0478:             * @param targetHeight        the desired height of the scaled instance,
0479:             *                            in pixels
0480:             * @param hint                one of the rendering hints that corresponds to
0481:             *                            RenderingHints.KEY_INTERPOLATION (e.g.
0482:             *                            RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR,
0483:             *                            RenderingHints.VALUE_INTERPOLATION_BILINEAR,
0484:             *                            RenderingHints.VALUE_INTERPOLATION_BICUBIC)
0485:             * @param progressiveBilinear if true, this method will use a multi-step
0486:             *                            scaling technique that provides higher quality than the usual
0487:             *                            one-step technique (only useful in down-scaling cases, where
0488:             *                            targetWidth or targetHeight is
0489:             *                            smaller than the original dimensions)
0490:             * @return a scaled version of the original BufferedImage
0491:             */
0492:            public static BufferedImage getFasterScaledInstance(
0493:                    BufferedImage img, int targetWidth, int targetHeight,
0494:                    Object hint, boolean progressiveBilinear) {
0495:                int type = (img.getTransparency() == Transparency.OPAQUE) ? BufferedImage.TYPE_INT_RGB
0496:                        : BufferedImage.TYPE_INT_ARGB;
0497:                BufferedImage ret = img;
0498:                BufferedImage scratchImage = null;
0499:                Graphics2D g2 = null;
0500:                int w, h;
0501:                int prevW = ret.getWidth();
0502:                int prevH = ret.getHeight();
0503:                boolean isTranslucent = img.getTransparency() != Transparency.OPAQUE;
0504:
0505:                if (progressiveBilinear) {
0506:                    // Use multi-step technique: start with original size, then
0507:                    // scale down in multiple passes with drawImage()
0508:                    // until the target size is reached
0509:                    w = img.getWidth();
0510:                    h = img.getHeight();
0511:                } else {
0512:                    // Use one-step technique: scale directly from original
0513:                    // size to target size with a single drawImage() call
0514:                    w = targetWidth;
0515:                    h = targetHeight;
0516:                }
0517:
0518:                do {
0519:                    if (progressiveBilinear && w > targetWidth) {
0520:                        w /= 2;
0521:                        if (w < targetWidth) {
0522:                            w = targetWidth;
0523:                        }
0524:                    }
0525:
0526:                    if (progressiveBilinear && h > targetHeight) {
0527:                        h /= 2;
0528:                        if (h < targetHeight) {
0529:                            h = targetHeight;
0530:                        }
0531:                    }
0532:
0533:                    if (scratchImage == null || isTranslucent) {
0534:                        // Use a single scratch buffer for all iterations
0535:                        // and then copy to the final, correctly-sized image
0536:                        // before returning
0537:                        scratchImage = new BufferedImage(w, h, type);
0538:                        g2 = scratchImage.createGraphics();
0539:                    }
0540:                    g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);
0541:                    g2.drawImage(ret, 0, 0, w, h, 0, 0, prevW, prevH, null);
0542:                    prevW = w;
0543:                    prevH = h;
0544:
0545:                    ret = scratchImage;
0546:                } while (w != targetWidth || h != targetHeight);
0547:
0548:                if (g2 != null) {
0549:                    g2.dispose();
0550:                }
0551:
0552:                // If we used a scratch buffer that is larger than our target size,
0553:                // create an image of the right size and copy the results into it
0554:                if (targetWidth != ret.getWidth()
0555:                        || targetHeight != ret.getHeight()) {
0556:                    scratchImage = new BufferedImage(targetWidth, targetHeight,
0557:                            type);
0558:                    g2 = scratchImage.createGraphics();
0559:                    g2.drawImage(ret, 0, 0, null);
0560:                    g2.dispose();
0561:                    ret = scratchImage;
0562:                }
0563:
0564:                return ret;
0565:            }
0566:
0567:            private static class GetPropertyAction implements 
0568:                    java.security.PrivilegedAction {
0569:                private String theProp;
0570:                private String defaultVal;
0571:
0572:                /**
0573:                 * Constructor that takes the name of the system property whose
0574:                 * string value needs to be determined.
0575:                 *
0576:                 * @param theProp the name of the system property.
0577:                 */
0578:                public GetPropertyAction(String theProp) {
0579:                    this .theProp = theProp;
0580:                }
0581:
0582:                /**
0583:                 * Constructor that takes the name of the system property and the default
0584:                 * value of that property.
0585:                 *
0586:                 * @param theProp    the name of the system property.
0587:                 * @param defaultVal the default value.
0588:                 */
0589:                public GetPropertyAction(String theProp, String defaultVal) {
0590:                    this .theProp = theProp;
0591:                    this .defaultVal = defaultVal;
0592:                }
0593:
0594:                /**
0595:                 * Determines the string value of the system property whose
0596:                 * name was specified in the constructor.
0597:                 *
0598:                 * @return the string value of the system property,
0599:                 *         or the default value if there is no property with that key.
0600:                 */
0601:                public Object run() {
0602:                    String value = System.getProperty(theProp);
0603:                    return (value == null) ? defaultVal : value;
0604:                }
0605:            }
0606:
0607:            /**
0608:             * In JDK1.4, it uses a wrong font for Swing component in Windows L&F which
0609:             * is actually one big reason for people to think Swing application ugly.
0610:             * To address this issue, we changed the code to force to use Tahoma font
0611:             * for all the fonts in L&F instead of using the system font.
0612:             * <p/>
0613:             * However this is a downside to this. Tahoma cannot display unicode characters
0614:             * such as Chinese, Japanese and Korean. So if the locale is CJK ({@link SystemInfo#isCJKLocale()},
0615:             * we shouldn't use Tahoma. If you are on JDK 1.5 and above, you shouldn't force to use Tahoma either
0616:             * because JDK fixed it in 1.5 and above.
0617:             * <p/>
0618:             * There are also a few system properties you can set to control
0619:             * if system font should be used. "swing.useSystemFontSettings"
0620:             * is the one for all Swing applications. "Application.useSystemFontSettings" is the
0621:             * one for a particular Swing application.
0622:             * <p/>
0623:             * This method considers all the cases above. If JDK is 1.5 and above, this method will return true.
0624:             * If you are on Chinese, Japanese or Korean locale, it will return true. If "swing.useSystemFontSettings" property us true,
0625:             * it will return true. If "Application.useSystemFontSettings" property is true, it will return true. Otherwise,
0626:             * it will return false. All JIDE L&F considered the returned value and decide if Tahoma font should be used or not.
0627:             *
0628:             * @return true if the L&F should use system font.
0629:             */
0630:            public static boolean shouldUseSystemFont() {
0631:                if (SystemInfo.isJdk15Above() || SystemInfo.isCJKLocale()) {
0632:                    return true;
0633:                }
0634:
0635:                String systemFonts = null;
0636:                try {
0637:                    systemFonts = (String) java.security.AccessController
0638:                            .doPrivileged(new GetPropertyAction(
0639:                                    "swing.useSystemFontSettings"));
0640:                } catch (AccessControlException e) {
0641:                    // ignore
0642:                }
0643:
0644:                boolean useSystemFontSettings = (systemFonts != null && Boolean
0645:                        .valueOf(systemFonts));
0646:
0647:                if (useSystemFontSettings) {
0648:                    Object value = UIDefaultsLookup
0649:                            .get("Application.useSystemFontSettings");
0650:
0651:                    useSystemFontSettings = (value != null || Boolean.TRUE
0652:                            .equals(value));
0653:                }
0654:
0655:                return "true".equals(SecurityUtils.getProperty("defaultFont",
0656:                        "false"))
0657:                        || useSystemFontSettings;
0658:            }
0659:
0660:            public static void printUIDefaults() {
0661:                Enumeration e = UIManager.getDefaults().keys();
0662:                java.util.List list = new ArrayList();
0663:
0664:                System.out.println("Non-string keys ---");
0665:                while (e.hasMoreElements()) {
0666:                    Object key = e.nextElement();
0667:                    if (key instanceof  String) {
0668:                        list.add(key);
0669:                    } else {
0670:                        System.out.println(key + " => "
0671:                                + UIDefaultsLookup.get(key));
0672:                    }
0673:                }
0674:
0675:                System.out.println();
0676:
0677:                Object[] array = list.toArray(new Object[list.size()]);
0678:                Arrays.sort(array);
0679:                System.out.println("String keys ---");
0680:                for (int i = 0; i < array.length; i++) {
0681:                    Object key = array[i];
0682:                    System.out
0683:                            .println(key + " => " + UIDefaultsLookup.get(key));
0684:                }
0685:            }
0686:
0687:            /**
0688:             * A simple handler used by setRecursively.
0689:             * <pre>
0690:             *  if ( condition() ) {
0691:             *      action();
0692:             *  }
0693:             *  postAction();
0694:             * </pre>.
0695:             */
0696:            public interface Handler {
0697:                /**
0698:                 * If true, it will call {@link #action(java.awt.Component)} on this component.
0699:                 *
0700:                 * @param c the component
0701:                 * @return true or false.
0702:                 */
0703:                boolean condition(Component c);
0704:
0705:                /**
0706:                 * The action you want to perform on this component. This method will only be called
0707:                 * if {@link #condition(java.awt.Component)} returns true.
0708:                 *
0709:                 * @param c the component
0710:                 */
0711:                void action(Component c);
0712:
0713:                /**
0714:                 * The actino you want to perform to any components. If action(c) is called, this action is after it.
0715:                 *
0716:                 * @param c the component.
0717:                 */
0718:                void postAction(Component c);
0719:
0720:            }
0721:
0722:            /**
0723:             * A simple handler used by setRecursively.
0724:             * <pre>
0725:             *  if ( condition() ) {
0726:             *      action();
0727:             *  }
0728:             *  postAction();
0729:             * </pre>.
0730:             */
0731:            public interface ConditionHandler extends Handler {
0732:                /**
0733:                 * If this method returns true, the recursive call will stop at the component and will not call to its children.
0734:                 *
0735:                 * @param c the component
0736:                 * @return true or false.
0737:                 */
0738:                boolean stopCondition(Component c);
0739:            }
0740:
0741:            /**
0742:             * A simple handler used by getRecursively.
0743:             * <code><pre>
0744:             *  if ( condition() ) {
0745:             *      return action();
0746:             *  }
0747:             * </pre></code>.
0748:             * Here is an example to get the first child of the specified type.
0749:             * <code><pre>
0750:             * public static Component getFirstChildOf(final Class clazz, Component c) {
0751:             *     return getRecursively(c, new GetHandler() {
0752:             *         public boolean condition(Component c) {
0753:             *             return clazz.isAssignableFrom(c.getClass());
0754:             *         }
0755:             *         public Component action(Component c) {
0756:             *             return c;
0757:             *         }
0758:             *     });
0759:             * }
0760:             * </pre></code>
0761:             */
0762:            public interface GetHandler {
0763:                /**
0764:                 * If true, it will call {@link #action(java.awt.Component)} on this component.
0765:                 *
0766:                 * @param c the component
0767:                 * @return true or false.
0768:                 */
0769:                boolean condition(Component c);
0770:
0771:                /**
0772:                 * The action you want to perform on this component. This method will only be called
0773:                 * if {@link #condition(java.awt.Component)} returns true.
0774:                 *
0775:                 * @param c the component
0776:                 * @return the component that will be returned from {@link com.jidesoft.swing.JideSwingUtilities#getRecursively(java.awt.Component,com.jidesoft.swing.JideSwingUtilities.GetHandler)}.
0777:                 */
0778:                Component action(Component c);
0779:            }
0780:
0781:            /**
0782:             * Calls the handler recursively on a component.
0783:             *
0784:             * @param c       component
0785:             * @param handler handler to be called
0786:             */
0787:            public static void setRecursively(final Component c,
0788:                    final Handler handler) {
0789:                setRecursively0(c, handler);
0790:                handler.postAction(c);
0791:            }
0792:
0793:            private static void setRecursively0(final Component c,
0794:                    final Handler handler) {
0795:                if (handler.condition(c)) {
0796:                    handler.action(c);
0797:                }
0798:
0799:                if (handler instanceof  ConditionHandler
0800:                        && ((ConditionHandler) handler).stopCondition(c)) {
0801:                    return;
0802:                }
0803:
0804:                Component[] children = null;
0805:
0806:                if (c instanceof  JMenu) {
0807:                    children = ((JMenu) c).getMenuComponents();
0808:                } else if (c instanceof  JTabbedPane) {
0809:                    JTabbedPane tabbedPane = (JTabbedPane) c;
0810:                    children = new Component[tabbedPane.getTabCount()];
0811:                    for (int i = 0; i < children.length; i++) {
0812:                        children[i] = tabbedPane.getComponentAt(i);
0813:                    }
0814:                } else if (c instanceof  Container) {
0815:                    children = ((Container) c).getComponents();
0816:                }
0817:                if (children != null) {
0818:                    for (Component child : children) {
0819:                        setRecursively0(child, handler);
0820:                    }
0821:                }
0822:            }
0823:
0824:            /**
0825:             * Gets to a child of a component recursively based on certain condition.
0826:             *
0827:             * @param c       component
0828:             * @param handler handler to be called
0829:             */
0830:            public static Component getRecursively(final Component c,
0831:                    final GetHandler handler) {
0832:                return getRecursively0(c, handler);
0833:            }
0834:
0835:            private static Component getRecursively0(final Component c,
0836:                    final GetHandler handler) {
0837:                if (handler.condition(c)) {
0838:                    return handler.action(c);
0839:                }
0840:
0841:                Component[] children = null;
0842:
0843:                if (c instanceof  JMenu) {
0844:                    children = ((JMenu) c).getMenuComponents();
0845:                } else if (c instanceof  Container) {
0846:                    children = ((Container) c).getComponents();
0847:                }
0848:
0849:                if (children != null) {
0850:                    for (int i = 0; i < children.length; i++) {
0851:                        Component result = getRecursively0(children[i], handler);
0852:                        if (result != null) {
0853:                            return result;
0854:                        }
0855:                    }
0856:                }
0857:                return null;
0858:            }
0859:
0860:            /**
0861:             * Calls setEnabled method recursively on component. <code>Component</code> c is usually a <code>Container</code>
0862:             *
0863:             * @param c       component
0864:             * @param enabled true if enable; false otherwise
0865:             */
0866:            public static void setEnabledRecursively(final Component c,
0867:                    final boolean enabled) {
0868:                setRecursively(c, new Handler() {
0869:                    public boolean condition(Component c) {
0870:                        return true;
0871:                    }
0872:
0873:                    public void action(Component c) {
0874:                        c.setEnabled(enabled);
0875:                    }
0876:
0877:                    public void postAction(Component c) {
0878:                    }
0879:                });
0880:            }
0881:
0882:            /**
0883:             * Calls setRequestFocusEnabled method recursively on component. <code>Component</code> c is usually a <code>Container</code>
0884:             *
0885:             * @param c       component
0886:             * @param enabled true if setRequestFocusEnabled to true; false otherwise
0887:             */
0888:            public static void setRequestFocusEnabledRecursively(
0889:                    final Component c, final boolean enabled) {
0890:                setRecursively(c, new Handler() {
0891:                    public boolean condition(Component c) {
0892:                        return true;
0893:                    }
0894:
0895:                    public void action(Component c) {
0896:                        if (c instanceof  JComponent)
0897:                            ((JComponent) c).setRequestFocusEnabled(enabled);
0898:                    }
0899:
0900:                    public void postAction(Component c) {
0901:                    }
0902:                });
0903:            }
0904:
0905:            private static PropertyChangeListener _setOpaqueTrueListener = new PropertyChangeListener() {
0906:                public void propertyChange(PropertyChangeEvent evt) {
0907:                    if (evt.getSource() instanceof  JComponent) {
0908:                        ((JComponent) evt.getSource()).setOpaque(true);
0909:                    }
0910:                }
0911:            };
0912:
0913:            private static PropertyChangeListener _setOpaqueFalseListener;
0914:            private static final String OPAQUE_LISTENER = "setOpaqueRecursively.opaqueListener";
0915:
0916:            /**
0917:             * setOpaqueRecursively method will make all child components opaque true or false. But if you call
0918:             * jcomponent.putClientProperty(SET_OPAQUE_RECURSIVELY_EXCLUDED, Boolean.TRUE), we will not touch
0919:             * this particular component when setOpaqueRecursively.
0920:             */
0921:            public static final String SET_OPAQUE_RECURSIVELY_EXCLUDED = "setOpaqueRecursively.excluded";
0922:
0923:            /**
0924:             * Calls setOpaque method recursively on each component except
0925:             * for JButton, JComboBox and JTextComponent.
0926:             * <code>Component</code> c is usually a <code>Container</code>.
0927:             * If you would like certain child component not affected by this call, you can
0928:             * call jcomponent.putClientProperty(SET_OPAQUE_RECURSIVELY_EXCLUDED, Boolean.TRUE) before calling this method.
0929:             *
0930:             * @param c      component
0931:             * @param opaque true if setOpaque to true; false otherwise
0932:             */
0933:            public static void setOpaqueRecursively(final Component c,
0934:                    final boolean opaque) {
0935:                setRecursively(c, new Handler() {
0936:                    public boolean condition(Component c) {
0937:                        return !(c instanceof  JComboBox || c instanceof  JButton || c instanceof  JTextComponent);
0938:                    }
0939:
0940:                    public void action(Component c) {
0941:                        if (c instanceof  JComponent) {
0942:                            JComponent jc = (JComponent) c;
0943:                            if (Boolean.TRUE
0944:                                    .equals(jc
0945:                                            .getClientProperty(SET_OPAQUE_RECURSIVELY_EXCLUDED))) {
0946:                                return;
0947:                            }
0948:
0949:                            jc.setOpaque(opaque);
0950:                            if (jc.getClientProperty(OPAQUE_LISTENER) == null) {
0951:                                if (opaque) {
0952:                                    if (_setOpaqueTrueListener == null) {
0953:                                        _setOpaqueTrueListener = new PropertyChangeListener() {
0954:                                            public void propertyChange(
0955:                                                    PropertyChangeEvent evt) {
0956:                                                if (evt.getSource() instanceof  JComponent) {
0957:                                                    ((JComponent) evt
0958:                                                            .getSource())
0959:                                                            .setOpaque(true);
0960:                                                }
0961:                                            }
0962:                                        };
0963:                                    }
0964:                                    jc.addPropertyChangeListener("opaque",
0965:                                            _setOpaqueTrueListener);
0966:                                    jc.putClientProperty("opaqueListener",
0967:                                            _setOpaqueTrueListener);
0968:                                } else {
0969:                                    if (_setOpaqueFalseListener == null) {
0970:                                        _setOpaqueFalseListener = new PropertyChangeListener() {
0971:                                            public void propertyChange(
0972:                                                    PropertyChangeEvent evt) {
0973:                                                if (evt.getSource() instanceof  JComponent) {
0974:                                                    ((JComponent) evt
0975:                                                            .getSource())
0976:                                                            .setOpaque(false);
0977:                                                }
0978:                                            }
0979:                                        };
0980:                                    }
0981:                                    jc.addPropertyChangeListener("opaque",
0982:                                            _setOpaqueFalseListener);
0983:                                    jc.putClientProperty(OPAQUE_LISTENER,
0984:                                            _setOpaqueFalseListener);
0985:                                }
0986:                            }
0987:                        }
0988:                    }
0989:
0990:                    public void postAction(Component c) {
0991:                    }
0992:                });
0993:            }
0994:
0995:            public static Dimension getPreferredButtonSize(AbstractButton b,
0996:                    int textIconGap, boolean isHorizontal) {
0997:                if (b.getComponentCount() > 0) {
0998:                    return null;
0999:                }
1000:
1001:                Icon icon = (Icon) b.getIcon();
1002:                String text = b.getText();
1003:
1004:                Font font = b.getFont();
1005:                FontMetrics fm = b.getFontMetrics(font);
1006:
1007:                Rectangle iconR = new Rectangle();
1008:                Rectangle textR = new Rectangle();
1009:                Rectangle viewR = new Rectangle(Short.MAX_VALUE,
1010:                        Short.MAX_VALUE);
1011:
1012:                layoutCompoundLabel((JComponent) b, fm, text, icon,
1013:                        isHorizontal, b.getVerticalAlignment(), b
1014:                                .getHorizontalAlignment(), b
1015:                                .getVerticalTextPosition(), b
1016:                                .getHorizontalTextPosition(), viewR, iconR,
1017:                        textR, (text == null ? 0 : textIconGap));
1018:
1019:                /* The preferred size of the button is the size of
1020:                 * the text and icon rectangles plus the buttons insets.
1021:                 */
1022:
1023:                Rectangle r = iconR.union(textR);
1024:
1025:                Insets insets = b.getInsets();
1026:                r.width += insets.left + insets.right;
1027:                r.height += insets.top + insets.bottom;
1028:
1029:                return r.getSize();
1030:            }
1031:
1032:            /**
1033:             * Compute and return the location of the icons origin, the
1034:             * location of origin of the text baseline, and a possibly clipped
1035:             * version of the compound labels string.  Locations are computed
1036:             * relative to the viewR rectangle.
1037:             * The JComponents orientation (LEADING/TRAILING) will also be taken
1038:             * into account and translated into LEFT/RIGHT values accordingly.
1039:             */
1040:            public static String layoutCompoundLabel(JComponent c,
1041:                    FontMetrics fm, String text, Icon icon,
1042:                    boolean isHorizontal, int verticalAlignment,
1043:                    int horizontalAlignment, int verticalTextPosition,
1044:                    int horizontalTextPosition, Rectangle viewR,
1045:                    Rectangle iconR, Rectangle textR, int textIconGap) {
1046:                boolean orientationIsLeftToRight = true;
1047:                int hAlign = horizontalAlignment;
1048:                int hTextPos = horizontalTextPosition;
1049:
1050:                if (c != null) {
1051:                    if (!(c.getComponentOrientation().isLeftToRight())) {
1052:                        orientationIsLeftToRight = false;
1053:                    }
1054:                }
1055:
1056:                // Translate LEADING/TRAILING values in horizontalAlignment
1057:                // to LEFT/RIGHT values depending on the components orientation
1058:                switch (horizontalAlignment) {
1059:                case LEADING:
1060:                    hAlign = (orientationIsLeftToRight) ? LEFT : RIGHT;
1061:                    break;
1062:                case TRAILING:
1063:                    hAlign = (orientationIsLeftToRight) ? RIGHT : LEFT;
1064:                    break;
1065:                }
1066:
1067:                // Translate LEADING/TRAILING values in horizontalTextPosition
1068:                // to LEFT/RIGHT values depending on the components orientation
1069:                switch (horizontalTextPosition) {
1070:                case LEADING:
1071:                    hTextPos = (orientationIsLeftToRight) ? LEFT : RIGHT;
1072:                    break;
1073:                case TRAILING:
1074:                    hTextPos = (orientationIsLeftToRight) ? RIGHT : LEFT;
1075:                    break;
1076:                }
1077:
1078:                return layoutCompoundLabelImpl(c, fm, text, icon, isHorizontal,
1079:                        verticalAlignment, hAlign, verticalTextPosition,
1080:                        hTextPos, viewR, iconR, textR, textIconGap);
1081:            }
1082:
1083:            /**
1084:             * Compute and return the location of the icons origin, the
1085:             * location of origin of the text baseline, and a possibly clipped
1086:             * version of the compound labels string.  Locations are computed
1087:             * relative to the viewR rectangle.
1088:             * This layoutCompoundLabel() does not know how to handle LEADING/TRAILING
1089:             * values in horizontalTextPosition (they will default to RIGHT) and in
1090:             * horizontalAlignment (they will default to CENTER).
1091:             * Use the other version of layoutCompoundLabel() instead.
1092:             */
1093:            public static String layoutCompoundLabel(FontMetrics fm,
1094:                    String text, Icon icon, boolean isHorizontal,
1095:                    int verticalAlignment, int horizontalAlignment,
1096:                    int verticalTextPosition, int horizontalTextPosition,
1097:                    Rectangle viewR, Rectangle iconR, Rectangle textR,
1098:                    int textIconGap) {
1099:                return layoutCompoundLabelImpl(null, fm, text, icon,
1100:                        isHorizontal, verticalAlignment, horizontalAlignment,
1101:                        verticalTextPosition, horizontalTextPosition, viewR,
1102:                        iconR, textR, textIconGap);
1103:            }
1104:
1105:            /**
1106:             * Compute and return the location of the icons origin, the
1107:             * location of origin of the text baseline, and a possibly clipped
1108:             * version of the compound labels string.  Locations are computed
1109:             * relative to the viewR rectangle.
1110:             * This layoutCompoundLabel() does not know how to handle LEADING/TRAILING
1111:             * values in horizontalTextPosition (they will default to RIGHT) and in
1112:             * horizontalAlignment (they will default to CENTER).
1113:             * Use the other version of layoutCompoundLabel() instead.
1114:             */
1115:            private static String layoutCompoundLabelImpl(JComponent c,
1116:                    FontMetrics fm, String text, Icon icon,
1117:                    boolean isHorizontal, int verticalAlignment,
1118:                    int horizontalAlignment, int verticalTextPosition,
1119:                    int horizontalTextPosition, Rectangle viewR,
1120:                    Rectangle iconR, Rectangle textR, int textIconGap) {
1121:                /* Initialize the icon bounds rectangle iconR.
1122:                 */
1123:                if (isHorizontal)
1124:                    return layoutCompoundLabelImplHorizontal(c, fm, text, icon,
1125:                            verticalAlignment, horizontalAlignment,
1126:                            verticalTextPosition, horizontalTextPosition,
1127:                            viewR, iconR, textR, textIconGap);
1128:                else
1129:                    return layoutCompoundLabelImplVertical(c, fm, text, icon,
1130:                            verticalAlignment, horizontalAlignment,
1131:                            verticalTextPosition, horizontalTextPosition,
1132:                            viewR, iconR, textR, textIconGap);
1133:
1134:            }
1135:
1136:            private static String getMaxLengthWord(String text) {
1137:                if (text.indexOf(' ') == -1) {
1138:                    return text;
1139:                } else {
1140:                    int minDiff = text.length();
1141:                    int minPos = -1;
1142:                    int mid = text.length() / 2;
1143:
1144:                    int pos = -1;
1145:                    while (true) {
1146:                        pos = text.indexOf(' ', pos + 1);
1147:                        if (pos == -1) {
1148:                            break;
1149:                        }
1150:                        int diff = Math.abs(pos - mid);
1151:                        if (diff < minDiff) {
1152:                            minDiff = diff;
1153:                            minPos = pos;
1154:                        }
1155:                    }
1156:                    return minPos >= mid ? text.substring(0, minPos) : text
1157:                            .substring(minPos + 1);
1158:                }
1159:            }
1160:
1161:            private static String layoutCompoundLabelImplHorizontal(
1162:                    JComponent c, FontMetrics fm, String text, Icon icon,
1163:                    int verticalAlignment, int horizontalAlignment,
1164:                    int verticalTextPosition, int horizontalTextPosition,
1165:                    Rectangle viewR, Rectangle iconR, Rectangle textR,
1166:                    int textIconGap) {
1167:                /* Initialize the icon bounds rectangle iconR.
1168:                 */
1169:
1170:                if (icon != null) {
1171:                    iconR.width = icon.getIconWidth();
1172:                    iconR.height = icon.getIconHeight();
1173:                } else {
1174:                    iconR.width = iconR.height = 0;
1175:                }
1176:
1177:                /* Initialize the text bounds rectangle textR.  If a null
1178:                 * or and empty String was specified we substitute "" here
1179:                 * and use 0,0,0,0 for textR.
1180:                 */
1181:
1182:                boolean textIsEmpty = (text == null) || text.equals("");
1183:
1184:                View v = null;
1185:                if (textIsEmpty) {
1186:                    textR.width = textR.height = 0;
1187:                    text = "";
1188:                } else {
1189:                    v = (c != null) ? (View) c.getClientProperty("html") : null;
1190:                    if (v != null) {
1191:                        textR.width = (int) v.getPreferredSpan(View.X_AXIS);
1192:                        textR.height = (int) v.getPreferredSpan(View.Y_AXIS);
1193:                    } else {
1194:                        if (false) { // TODO: debug switch
1195:                            boolean wrapText = false;
1196:                            if (verticalTextPosition == BOTTOM
1197:                                    && horizontalTextPosition == CENTER) { // in this case, we will wrap the text into two lines
1198:                                wrapText = true;
1199:                            }
1200:
1201:                            if (wrapText) {
1202:                                textR.width = SwingUtilities
1203:                                        .computeStringWidth(fm,
1204:                                                getMaxLengthWord(text));
1205:                                textR.height = fm.getHeight() + fm.getAscent()
1206:                                        + 2; // gap between the two lines is 2.
1207:                            } else {
1208:                                textR.width = SwingUtilities
1209:                                        .computeStringWidth(fm, text) + 1; // add an extra pixel at the end of the text
1210:                                textR.height = fm.getHeight();
1211:                            }
1212:                        } else {
1213:                            textR.width = SwingUtilities.computeStringWidth(fm,
1214:                                    text); // add an extra pixel at the end of the text
1215:                            textR.height = fm.getHeight();
1216:                        }
1217:                    }
1218:                }
1219:
1220:                /* Unless both text and icon are non-null, we effectively ignore
1221:                 * the value of textIconGap.  The code that follows uses the
1222:                 * value of gap instead of textIconGap.
1223:                 */
1224:
1225:                int gap = (textIsEmpty || (icon == null)) ? 0 : textIconGap;
1226:
1227:                if (!textIsEmpty) {
1228:
1229:                    /* If the label text string is too wide to fit within the available
1230:                     * space "..." and as many characters as will fit will be
1231:                     * displayed instead.
1232:                     */
1233:
1234:                    int availTextWidth;
1235:
1236:                    if (horizontalTextPosition == CENTER) {
1237:                        availTextWidth = viewR.width;
1238:                    } else {
1239:                        availTextWidth = viewR.width - (iconR.width + gap);
1240:                    }
1241:
1242:                    if (textR.width > availTextWidth) {
1243:                        if (v != null) {
1244:                            textR.width = availTextWidth;
1245:                        } else {
1246:                            String clipString = "...";
1247:                            int totalWidth = SwingUtilities.computeStringWidth(
1248:                                    fm, clipString);
1249:                            int nChars;
1250:                            for (nChars = 0; nChars < text.length(); nChars++) {
1251:                                totalWidth += fm.charWidth(text.charAt(nChars));
1252:                                if (totalWidth > availTextWidth) {
1253:                                    break;
1254:                                }
1255:                            }
1256:                            text = text.substring(0, nChars) + clipString;
1257:                            textR.width = SwingUtilities.computeStringWidth(fm,
1258:                                    text);
1259:                        }
1260:                    }
1261:                }
1262:
1263:                /* Compute textR.x,y given the verticalTextPosition and
1264:                 * horizontalTextPosition properties
1265:                 */
1266:
1267:                if (verticalTextPosition == TOP) {
1268:                    if (horizontalTextPosition != CENTER) {
1269:                        textR.y = 0;
1270:                    } else {
1271:                        textR.y = -(textR.height + gap);
1272:                    }
1273:                } else if (verticalTextPosition == CENTER) {
1274:                    textR.y = (iconR.height >> 1) - (textR.height >> 1);
1275:                } else { // (verticalTextPosition == BOTTOM)
1276:                    if (horizontalTextPosition != CENTER) {
1277:                        textR.y = iconR.height - textR.height;
1278:                    } else {
1279:                        textR.y = (iconR.height + gap);
1280:                    }
1281:                }
1282:
1283:                if (horizontalTextPosition == LEFT) {
1284:                    textR.x = -(textR.width + gap);
1285:                } else if (horizontalTextPosition == CENTER) {
1286:                    textR.x = (iconR.width >> 1) - (textR.width >> 1);
1287:                } else { // (horizontalTextPosition == RIGHT)
1288:                    textR.x = (iconR.width + gap);
1289:                }
1290:
1291:                /* labelR is the rectangle that contains iconR and textR.
1292:                 * Move it to its proper position given the labelAlignment
1293:                 * properties.
1294:                 *
1295:                 * To avoid actually allocating a Rectangle, Rectangle.union
1296:                 * has been inlined below.
1297:                 */
1298:                int labelR_x = Math.min(iconR.x, textR.x);
1299:                int labelR_width = Math.max(iconR.x + iconR.width, textR.x
1300:                        + textR.width)
1301:                        - labelR_x;
1302:                int labelR_y = Math.min(iconR.y, textR.y);
1303:                int labelR_height = Math.max(iconR.y + iconR.height, textR.y
1304:                        + textR.height)
1305:                        - labelR_y;
1306:
1307:                int dx, dy;
1308:
1309:                if (verticalAlignment == TOP) {
1310:                    dy = viewR.y - labelR_y;
1311:                } else if (verticalAlignment == CENTER) {
1312:                    dy = (viewR.y + (viewR.height >> 1))
1313:                            - (labelR_y + (labelR_height >> 1));
1314:                } else { // (verticalAlignment == BOTTOM)
1315:                    dy = (viewR.y + viewR.height) - (labelR_y + labelR_height);
1316:                }
1317:
1318:                if (horizontalAlignment == LEFT) {
1319:                    dx = viewR.x - labelR_x;
1320:                } else if (horizontalAlignment == RIGHT) {
1321:                    dx = (viewR.x + viewR.width) - (labelR_x + labelR_width);
1322:                } else { // (horizontalAlignment == CENTER)
1323:                    dx = (viewR.x + (viewR.width >> 1))
1324:                            - (labelR_x + (labelR_width >> 1));
1325:                }
1326:
1327:                /* Translate textR and glypyR by dx,dy.
1328:                 */
1329:
1330:                textR.x += dx;
1331:                textR.y += dy;
1332:
1333:                iconR.x += dx;
1334:                iconR.y += dy;
1335:
1336:                return text;
1337:            }
1338:
1339:            private static String layoutCompoundLabelImplVertical(JComponent c,
1340:                    FontMetrics fm, String text, Icon icon,
1341:                    int verticalAlignment, int horizontalAlignment,
1342:                    int verticalTextPosition, int horizontalTextPosition,
1343:                    Rectangle viewR, Rectangle iconR, Rectangle textR,
1344:                    int textIconGap) {
1345:                /* Initialize the icon bounds rectangle iconR.
1346:                 */
1347:
1348:                if (icon != null) {
1349:                    iconR.width = icon.getIconWidth();
1350:                    iconR.height = icon.getIconHeight();
1351:                } else {
1352:                    iconR.width = iconR.height = 0;
1353:                }
1354:
1355:                /* Initialize the text bounds rectangle textR.  If a null
1356:                 * or and empty String was specified we substitute "" here
1357:                 * and use 0,0,0,0 for textR.
1358:                 */
1359:
1360:                boolean textIsEmpty = (text == null) || text.equals("");
1361:
1362:                View v = null;
1363:                if (textIsEmpty) {
1364:                    textR.width = textR.height = 0;
1365:                    text = "";
1366:                } else {
1367:                    v = (c != null) ? (View) c.getClientProperty("html") : null;
1368:                    if (v != null) {
1369:                        textR.height = (int) v.getPreferredSpan(View.X_AXIS);
1370:                        textR.width = (int) v.getPreferredSpan(View.Y_AXIS);
1371:                    } else {
1372:                        textR.height = SwingUtilities.computeStringWidth(fm,
1373:                                text);
1374:                        textR.width = fm.getHeight();
1375:                    }
1376:                }
1377:
1378:                /* Unless both text and icon are non-null, we effectively ignore
1379:                 * the value of textIconGap.  The code that follows uses the
1380:                 * value of gap instead of textIconGap.
1381:                 */
1382:
1383:                int gap = (textIsEmpty || (icon == null)) ? 0 : textIconGap;
1384:
1385:                if (!textIsEmpty) {
1386:
1387:                    /* If the label text string is too wide to fit within the available
1388:                     * space "..." and as many characters as will fit will be
1389:                     * displayed instead.
1390:                     */
1391:
1392:                    int availTextHeight;
1393:
1394:                    if (horizontalTextPosition == CENTER) {
1395:                        availTextHeight = viewR.height;
1396:                    } else {
1397:                        availTextHeight = viewR.height - (iconR.height + gap);
1398:                    }
1399:
1400:                    if (textR.height > availTextHeight) {
1401:                        if (v != null) {
1402:                            textR.height = availTextHeight;
1403:                        } else {
1404:                            String clipString = "...";
1405:                            int totalHeight = SwingUtilities
1406:                                    .computeStringWidth(fm, clipString);
1407:                            int nChars;
1408:                            for (nChars = 0; nChars < text.length(); nChars++) {
1409:                                totalHeight += fm
1410:                                        .charWidth(text.charAt(nChars));
1411:                                if (totalHeight > availTextHeight) {
1412:                                    break;
1413:                                }
1414:                            }
1415:                            text = text.substring(0, nChars) + clipString;
1416:                            textR.height = SwingUtilities.computeStringWidth(
1417:                                    fm, text);
1418:                        }
1419:                    }
1420:                }
1421:
1422:                /* Compute textR.x,y given the verticalTextPosition and
1423:                 * horizontalTextPosition properties
1424:                 */
1425:
1426:                if (verticalTextPosition == TOP) {
1427:                    if (horizontalTextPosition != CENTER) {
1428:                        textR.x = 0;
1429:                    } else {
1430:                        textR.x = -(textR.width + gap);
1431:                    }
1432:                } else if (verticalTextPosition == CENTER) {
1433:                    textR.y = (iconR.width >> 1) - (textR.width >> 1);
1434:                } else { // (verticalTextPosition == BOTTOM)
1435:                    if (horizontalTextPosition != CENTER) {
1436:                        textR.x = iconR.width - textR.width;
1437:                    } else {
1438:                        textR.x = (iconR.width + gap);
1439:                    }
1440:                }
1441:
1442:                if (horizontalTextPosition == LEFT) {
1443:                    textR.y = -(textR.height + gap);
1444:                } else if (horizontalTextPosition == CENTER) {
1445:                    textR.y = (iconR.height >> 1) - (textR.height >> 1);
1446:                } else { // (horizontalTextPosition == RIGHT)
1447:                    textR.y = (iconR.height + gap);
1448:                }
1449:
1450:                /* labelR is the rectangle that contains iconR and textR.
1451:                 * Move it to its proper position given the labelAlignment
1452:                 * properties.
1453:                 *
1454:                 * To avoid actually allocating a Rectangle, Rectangle.union
1455:                 * has been inlined below.
1456:                 */
1457:                int labelR_x = Math.min(iconR.y, textR.y);
1458:                int labelR_width = Math.max(iconR.y + iconR.height, textR.y
1459:                        + textR.height)
1460:                        - labelR_x;
1461:                int labelR_y = Math.min(iconR.x, textR.x);
1462:                int labelR_height = Math.max(iconR.x + iconR.width, textR.x
1463:                        + textR.width)
1464:                        - labelR_y;
1465:
1466:                int dx, dy;
1467:                int dIcony; // because we will retate icon, so the position will
1468:                // be different from text. However after transform, they will be same
1469:
1470:                if (verticalAlignment == TOP) {
1471:                    dy = viewR.x - labelR_y;
1472:                    dIcony = (viewR.x + viewR.width)
1473:                            - (labelR_y + labelR_height);
1474:                } else if (verticalAlignment == CENTER) {
1475:                    dy = (viewR.x + (viewR.width >> 1))
1476:                            - (labelR_y + (labelR_height >> 1));
1477:                    dIcony = dy;
1478:                } else { // (verticalAlignment == BOTTOM)
1479:                    dy = (viewR.x + viewR.width) - (labelR_y + labelR_height);
1480:                    dIcony = viewR.x - labelR_y;
1481:                }
1482:
1483:                if (horizontalAlignment == LEFT) {
1484:                    dx = viewR.y - labelR_x;
1485:                } else if (horizontalAlignment == RIGHT) {
1486:                    dx = (viewR.y + viewR.height) - (labelR_x + labelR_width);
1487:                } else { // (horizontalAlignment == CENTER)
1488:                    dx = (viewR.y + (viewR.height >> 1))
1489:                            - (labelR_x + (labelR_width >> 1));
1490:                }
1491:
1492:                /* Translate textR and iconR by dx,dy.
1493:                 */
1494:
1495:                textR.y += dx;
1496:                textR.x += dy;
1497:
1498:                iconR.y += dx;
1499:                iconR.x += dIcony;
1500:
1501:                return text;
1502:            }
1503:
1504:            public static int getOrientationOf(Component component) {
1505:                if (component instanceof  Alignable) {
1506:                    return ((Alignable) component).getOrientation();
1507:                } else if (component instanceof  JComponent) {
1508:                    Integer value = (Integer) ((JComponent) component)
1509:                            .getClientProperty(Alignable.PROPERTY_ORIENTATION);
1510:                    if (value != null)
1511:                        return value;
1512:                }
1513:                return HORIZONTAL;
1514:            }
1515:
1516:            public static void setOrientationOf(Component component,
1517:                    int orientation) {
1518:                int old = getOrientationOf(component);
1519:                if (orientation != old) {
1520:                    if (component instanceof  Alignable) {
1521:                        ((Alignable) component).setOrientation(orientation);
1522:                    } else if (component instanceof  JComponent) {
1523:                        ((JComponent) component).putClientProperty(
1524:                                Alignable.PROPERTY_ORIENTATION, orientation);
1525:                    }
1526:                }
1527:            }
1528:
1529:            public static void setChildrenOrientationOf(Container c,
1530:                    int orientation) {
1531:                Component[] components = c.getComponents();
1532:                for (int i = 0; i < components.length; ++i) {
1533:                    Component component = components[i];
1534:                    setOrientationOf(component, orientation);
1535:                }
1536:            }
1537:
1538:            /**
1539:             * Disables the double buffered flag of the component and its children. The return map contains
1540:             * the components that were double buffered. After this call, you can then restore the double buffered flag
1541:             * using {@link #restoreDoubleBuffered(java.awt.Component,java.util.Map)} using the map that is returned from
1542:             * this method.
1543:             *
1544:             * @param c the parent container.
1545:             * @return the map that contains all components that were double buffered.
1546:             */
1547:            public static Map<Component, Boolean> disableDoubleBuffered(
1548:                    final Component c) {
1549:                final Map<Component, Boolean> map = new HashMap();
1550:                if (c instanceof  JComponent) {
1551:                    JideSwingUtilities.setRecursively(c,
1552:                            new JideSwingUtilities.Handler() {
1553:                                public boolean condition(Component c) {
1554:                                    return c instanceof  JComponent
1555:                                            && ((JComponent) c)
1556:                                                    .isDoubleBuffered();
1557:                                }
1558:
1559:                                public void action(Component c) {
1560:                                    map.put(c, Boolean.TRUE);
1561:                                    ((JComponent) c).setDoubleBuffered(false);
1562:                                }
1563:
1564:                                public void postAction(Component c) {
1565:
1566:                                }
1567:                            });
1568:                }
1569:                return map;
1570:            }
1571:
1572:            /**
1573:             * Enables the double buffered flag of the component and its children. The return map contains
1574:             * the components that weren't double buffered. After this call, you can then restore the double buffered flag
1575:             * using {@link #restoreDoubleBuffered(java.awt.Component,java.util.Map)} using the map that is returned from
1576:             * this method.
1577:             *
1578:             * @param c the parent container.
1579:             * @return the map that contains all components that weren't double buffered.
1580:             */
1581:            public static Map<Component, Boolean> enableDoubleBuffered(
1582:                    final Component c) {
1583:                final Map<Component, Boolean> map = new HashMap();
1584:                if (c instanceof  JComponent) {
1585:                    JideSwingUtilities.setRecursively(c,
1586:                            new JideSwingUtilities.Handler() {
1587:                                public boolean condition(Component c) {
1588:                                    return c instanceof  JComponent
1589:                                            && !c.isDoubleBuffered();
1590:                                }
1591:
1592:                                public void action(Component c) {
1593:                                    map.put(c, Boolean.FALSE);
1594:                                    ((JComponent) c).setDoubleBuffered(true);
1595:                                }
1596:
1597:                                public void postAction(Component c) {
1598:
1599:                                }
1600:                            });
1601:                }
1602:                return map;
1603:            }
1604:
1605:            /**
1606:             * Restores the double buffered flag of the component and its children. Only components that are in the map will be changed.
1607:             *
1608:             * @param c   the parent container.
1609:             * @param map a map maps from component to a boolean. If the boolean is true, it means the component was double buffered bore.
1610:             *            Otherwise, not double buffered.
1611:             */
1612:            public static void restoreDoubleBuffered(final Component c,
1613:                    final Map<Component, Boolean> map) {
1614:                JideSwingUtilities.setRecursively(c,
1615:                        new JideSwingUtilities.Handler() {
1616:                            public boolean condition(Component c) {
1617:                                return c instanceof  JComponent;
1618:                            }
1619:
1620:                            public void action(Component c) {
1621:                                Boolean value = map.get(c);
1622:                                if (value != null) {
1623:                                    ((JComponent) c)
1624:                                            .setDoubleBuffered(Boolean.TRUE
1625:                                                    .equals(value));
1626:                                }
1627:                            }
1628:
1629:                            public void postAction(Component c) {
1630:                            }
1631:                        });
1632:            }
1633:
1634:            public static void paintBackground(Graphics g, Rectangle rect,
1635:                    Color border, Color bk) {
1636:                Color old = g.getColor();
1637:                g.setColor(bk);
1638:                g.fillRect(rect.x + 1, rect.y + 1, rect.width - 2,
1639:                        rect.height - 2);
1640:                g.setColor(border);
1641:                g.drawRect(rect.x, rect.y, rect.width - 1, rect.height - 1);
1642:                g.setColor(old);
1643:            }
1644:
1645:            public static void paintBackground(Graphics2D g2d, Rectangle rect,
1646:                    Color border, Paint paint) {
1647:                Color old = g2d.getColor();
1648:                g2d.setPaint(paint);
1649:                g2d.fillRect(rect.x + 1, rect.y + 1, rect.width - 2,
1650:                        rect.height - 2);
1651:                g2d.setColor(border);
1652:                g2d.drawRect(rect.x, rect.y, rect.width - 1, rect.height - 1);
1653:                g2d.setColor(old);
1654:            }
1655:
1656:            /**
1657:             * Returns whether or not text should be drawn antialiased.
1658:             *
1659:             * @param c JComponent to test.
1660:             * @return Whether or not text should be drawn antialiased for the
1661:             *         specified component.
1662:             */
1663:            private static boolean drawTextAntialiased(Component c) {
1664:                if (!AA_TEXT_DEFINED) {
1665:                    if (c != null) {
1666:                        // Check if the component wants aa text
1667:                        if (c instanceof  JComponent) {
1668:                            Boolean aaProperty = (Boolean) ((JComponent) c)
1669:                                    .getClientProperty(AA_TEXT_PROPERTY_KEY);
1670:                            return aaProperty != null ? aaProperty : false;
1671:                        } else {
1672:                            return false;
1673:                        }
1674:                    }
1675:                    // No component, assume aa is off
1676:                    return false;
1677:                }
1678:                // 'swing.aatext' was defined, use its value.
1679:                return AA_TEXT;
1680:            }
1681:
1682:            /**
1683:             * Returns whether or not text should be drawn antialiased.
1684:             *
1685:             * @param aaText Whether or not aa text has been turned on for the
1686:             *               component.
1687:             * @return Whether or not text should be drawn antialiased.
1688:             */
1689:            public static boolean drawTextAntialiased(boolean aaText) {
1690:                if (!AA_TEXT_DEFINED) {
1691:                    // 'swing.aatext' wasn't defined, use the components aa text value.
1692:                    return aaText;
1693:                }
1694:                // 'swing.aatext' was defined, use its value.
1695:                return AA_TEXT;
1696:            }
1697:
1698:            public static void drawStringUnderlineCharAt(JComponent c,
1699:                    Graphics g, String text, int underlinedIndex, int x, int y) {
1700:                drawString(c, g, text, x, y);
1701:
1702:                if (underlinedIndex >= 0 && underlinedIndex < text.length()) {
1703:                    FontMetrics fm = g.getFontMetrics();
1704:                    int underlineRectX = x
1705:                            + fm
1706:                                    .stringWidth(text.substring(0,
1707:                                            underlinedIndex));
1708:                    int underlineRectY = y;
1709:                    int underlineRectWidth = fm.charWidth(text
1710:                            .charAt(underlinedIndex));
1711:                    int underlineRectHeight = 1;
1712:                    g.fillRect(underlineRectX, underlineRectY + fm.getDescent()
1713:                            - 1, underlineRectWidth, underlineRectHeight);
1714:                }
1715:            }
1716:
1717:            static RenderingHints renderingHints = null;
1718:
1719:            static {
1720:                if (SystemInfo.isJdk6Above()) {
1721:                    Toolkit tk = Toolkit.getDefaultToolkit();
1722:                    renderingHints = (RenderingHints) (tk
1723:                            .getDesktopProperty("awt.font.desktophints"));
1724:                    tk.addPropertyChangeListener("awt.font.desktophints",
1725:                            new PropertyChangeListener() {
1726:                                public void propertyChange(
1727:                                        PropertyChangeEvent evt) {
1728:                                    if (evt.getNewValue() instanceof  RenderingHints) {
1729:                                        renderingHints = (RenderingHints) evt
1730:                                                .getNewValue();
1731:                                    }
1732:                                }
1733:                            });
1734:                }
1735:            }
1736:
1737:            /**
1738:             * Get rendering hints from a Graphics instance.
1739:             * "hintsToSave" is a Map of RenderingHint key-values.
1740:             * For each hint key present in that map, the value of that
1741:             * hint is obtained from the Graphics and stored as the value
1742:             * for the key in savedHints.
1743:             */
1744:            private static RenderingHints getRenderingHints(Graphics2D g2d,
1745:                    RenderingHints hintsToSave, RenderingHints savedHints) {
1746:                if (savedHints == null) {
1747:                    savedHints = new RenderingHints(null);
1748:                } else {
1749:                    savedHints.clear();
1750:                }
1751:                if (hintsToSave == null || hintsToSave.size() == 0) {
1752:                    return savedHints;
1753:                }
1754:                /* RenderingHints.keySet() returns Set*/
1755:                Set objects = hintsToSave.keySet();
1756:                for (Iterator iterator = objects.iterator(); iterator.hasNext();) {
1757:                    Object o = iterator.next();
1758:                    RenderingHints.Key key = (RenderingHints.Key) o;
1759:                    Object value = g2d.getRenderingHint(key);
1760:                    savedHints.put(key, value);
1761:                }
1762:
1763:                return savedHints;
1764:            }
1765:
1766:            public static void drawString(JComponent c, Graphics g,
1767:                    String text, int x, int y) {
1768:                if (SystemInfo.isJdk6Above()) {
1769:                    Graphics2D g2d = (Graphics2D) g;
1770:                    RenderingHints oldHints = null;
1771:                    if (renderingHints != null) {
1772:                        oldHints = getRenderingHints(g2d, renderingHints, null);
1773:                        g2d.addRenderingHints(renderingHints);
1774:                    }
1775:                    g2d.drawString(text, x, y);
1776:                    if (oldHints != null) {
1777:                        g2d.addRenderingHints(oldHints);
1778:                    }
1779:                } else {
1780:                    // If we get here we're not printing
1781:                    if (drawTextAntialiased(c) && (g instanceof  Graphics2D)) {
1782:                        Graphics2D g2 = (Graphics2D) g;
1783:                        Object oldAAValue = g2
1784:                                .getRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING);
1785:                        g2.setRenderingHint(
1786:                                RenderingHints.KEY_TEXT_ANTIALIASING,
1787:                                RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
1788:                        g2.drawString(text, x, y);
1789:                        g2.setRenderingHint(
1790:                                RenderingHints.KEY_TEXT_ANTIALIASING,
1791:                                oldAAValue);
1792:                    } else {
1793:                        g.drawString(text, x, y);
1794:                    }
1795:                }
1796:            }
1797:
1798:            /**
1799:             * Setups the graphics to draw text using anti-alias.
1800:             * <p/>
1801:             * Under JDK1.4 and JDK5, this method will use a system property "swing.aatext" to determine if anti-alias is used.
1802:             * Under JDK6, we will read the system setting. For example, on Windows XP, there is a check box to turn on clear type anti-alias.
1803:             * We will use the same settings.
1804:             *
1805:             * @param c
1806:             * @param g
1807:             * @return the old hints. You will need this value as the third parameter in {@link #restoreAntialiasing(java.awt.Component,java.awt.Graphics,Object)}.
1808:             */
1809:            public static Object setupAntialiasing(Component c, Graphics g) {
1810:                Graphics2D g2d = (Graphics2D) g;
1811:                Object oldHints = null;
1812:                if (SystemInfo.isJdk6Above()) {
1813:                    oldHints = getRenderingHints(g2d, renderingHints, null);
1814:                    if (renderingHints != null) {
1815:                        g2d.addRenderingHints(renderingHints);
1816:                    }
1817:                } else {
1818:                    oldHints = g2d
1819:                            .getRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING);
1820:                    if (drawTextAntialiased(c)) {
1821:                        g2d.setRenderingHint(
1822:                                RenderingHints.KEY_TEXT_ANTIALIASING,
1823:                                RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
1824:                    }
1825:                }
1826:                return oldHints;
1827:            }
1828:
1829:            /**
1830:             * Restores the old setting for text anti-alias.
1831:             *
1832:             * @param c
1833:             * @param g
1834:             * @param oldHints the value returned from {@link #setupAntialiasing(java.awt.Component,java.awt.Graphics)}.
1835:             */
1836:            public static void restoreAntialiasing(Component c, Graphics g,
1837:                    Object oldHints) {
1838:                Graphics2D g2d = (Graphics2D) g;
1839:                if (SystemInfo.isJdk6Above()) {
1840:                    if (oldHints != null) {
1841:                        g2d.addRenderingHints((RenderingHints) oldHints);
1842:                    }
1843:                } else {
1844:                    g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
1845:                            oldHints);
1846:                }
1847:            }
1848:
1849:            /**
1850:             * Setups the graphics to draw shape using anti-alias.
1851:             *
1852:             * @param g
1853:             * @return the old hints. You will need this value as the third parameter in {@link #restoreShapeAntialiasing(java.awt.Graphics,Object)}.
1854:             */
1855:            public static Object setupShapeAntialiasing(Graphics g) {
1856:                Graphics2D g2d = (Graphics2D) g;
1857:                Object oldHints = g2d
1858:                        .getRenderingHint(RenderingHints.KEY_ANTIALIASING);
1859:                g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
1860:                        RenderingHints.VALUE_ANTIALIAS_ON);
1861:                return oldHints;
1862:            }
1863:
1864:            /**
1865:             * Restores the old setting for shape anti-alias.
1866:             *
1867:             * @param g
1868:             * @param oldHints the value returned from {@link #setupShapeAntialiasing(java.awt.Graphics)}.
1869:             */
1870:            public static void restoreShapeAntialiasing(Graphics g,
1871:                    Object oldHints) {
1872:                Graphics2D g2d = (Graphics2D) g;
1873:                g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, oldHints);
1874:            }
1875:
1876:            public static void drawGrip(Graphics g, Rectangle rectangle,
1877:                    int maxLength, int maxThickness) {
1878:                drawGrip(g, rectangle, maxLength, maxThickness, true);
1879:            }
1880:
1881:            public static void drawGrip(Graphics g, Rectangle rectangle,
1882:                    int maxLength, int maxThickness, boolean isSelected) {
1883:                if (rectangle.width > rectangle.height) {
1884:                    int count = maxLength;
1885:                    if (maxLength * 3 > rectangle.width) {
1886:                        count = rectangle.width / 3;
1887:                    }
1888:                    int startX = rectangle.x
1889:                            + ((rectangle.width - (count * 3)) >> 1);
1890:                    int startY = rectangle.y
1891:                            + ((rectangle.height - (maxThickness * 3)) >> 1);
1892:                    for (int i = 0; i < maxThickness; i++) {
1893:                        for (int j = 0; j < count; j++) {
1894:                            if (isSelected) {
1895:                                g.setColor(UIDefaultsLookup
1896:                                        .getColor("controlLtHighlight"));
1897:                                g.drawLine(startX + j * 3, startY + i * 3,
1898:                                        startX + j * 3, startY + i * 3);
1899:                            }
1900:                            g.setColor(UIDefaultsLookup
1901:                                    .getColor("controlShadow"));
1902:                            g.drawLine(startX + j * 3 + 1, startY + i * 3 + 1,
1903:                                    startX + j * 3 + 1, startY + i * 3 + 1);
1904:                        }
1905:                    }
1906:                } else {
1907:                    int count = maxLength;
1908:                    if (maxLength * 3 > rectangle.height) {
1909:                        count = rectangle.height / 3;
1910:                    }
1911:                    int startX = rectangle.x
1912:                            + ((rectangle.width - (maxThickness * 3)) >> 1);
1913:                    int startY = rectangle.y
1914:                            + ((rectangle.height - (count * 3)) >> 1);
1915:                    for (int i = 0; i < maxThickness; i++) {
1916:                        for (int j = 0; j < count; j++) {
1917:                            if (isSelected) {
1918:                                g.setColor(UIDefaultsLookup
1919:                                        .getColor("controlLtHighlight"));
1920:                                g.drawLine(startX + i * 3, startY + j * 3,
1921:                                        startX + i * 3, startY + j * 3);
1922:                            }
1923:                            g.setColor(UIDefaultsLookup
1924:                                    .getColor("controlShadow"));
1925:                            g.drawLine(startX + i * 3 + 1, startY + j * 3 + 1,
1926:                                    startX + i * 3 + 1, startY + j * 3 + 1);
1927:                        }
1928:                    }
1929:                }
1930:            }
1931:
1932:            /**
1933:             * Register the tab key with the container.
1934:             *
1935:             * @param container
1936:             */
1937:            public static void registerTabKey(Container container) {
1938:                if (container instanceof  JComponent) {
1939:                    ((JComponent) container).registerKeyboardAction(
1940:                            new AbstractAction() {
1941:                                public void actionPerformed(ActionEvent e) {
1942:                                    // JDK 1.3 Porting Hint
1943:                                    // comment out for now
1944:                                    DefaultKeyboardFocusManager
1945:                                            .getCurrentKeyboardFocusManager()
1946:                                            .focusNextComponent();
1947:                                }
1948:                            }, KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0),
1949:                            JComponent.WHEN_FOCUSED);
1950:                } else {
1951:                    for (int i = 0; i < container.getComponentCount(); i++) {
1952:                        Component c = container.getComponent(i);
1953:                        // JDK 1.3 Porting Hint
1954:                        // change to isFocusTraversable()
1955:                        if (c instanceof  JComponent && c.isFocusable()) {
1956:                            ((JComponent) container).registerKeyboardAction(
1957:                                    new AbstractAction() {
1958:                                        public void actionPerformed(
1959:                                                ActionEvent e) {
1960:                                            // JDK 1.3 Porting Hint
1961:                                            // comment out for now
1962:                                            DefaultKeyboardFocusManager
1963:                                                    .getCurrentKeyboardFocusManager()
1964:                                                    .focusNextComponent();
1965:                                        }
1966:                                    }, KeyStroke.getKeyStroke(KeyEvent.VK_TAB,
1967:                                            0), JComponent.WHEN_FOCUSED);
1968:                        }
1969:                    }
1970:                }
1971:            }
1972:
1973:            public static void fillGradient(Graphics g, Rectangle rect,
1974:                    int orientation) {
1975:                Graphics2D g2d = (Graphics2D) g;
1976:                // paint upper gradient
1977:                Color col1 = new Color(255, 255, 255, 0);
1978:                Color col2 = new Color(255, 255, 255, 48);
1979:                Color col3 = new Color(0, 0, 0, 0);
1980:                Color col4 = new Color(0, 0, 0, 32);
1981:
1982:                if (orientation == SwingConstants.HORIZONTAL) {
1983:                    // paint upper gradient
1984:                    fillGradient(g2d, new Rectangle(rect.x, rect.y, rect.width,
1985:                            rect.height >> 1), col2, col1, true);
1986:
1987:                    // paint lower gradient
1988:                    fillGradient(g2d,
1989:                            new Rectangle(rect.x, rect.y + (rect.height >> 1),
1990:                                    rect.width, rect.height >> 1), col3, col4,
1991:                            true);
1992:                } else {
1993:                    // paint left gradient
1994:                    fillGradient(g2d, new Rectangle(rect.x, rect.y,
1995:                            rect.width >> 1, rect.height), col2, col1, false);
1996:
1997:                    // paint right gradient
1998:                    fillGradient(g2d, new Rectangle(rect.x + (rect.width >> 1),
1999:                            rect.y, rect.width >> 1, rect.height), col3, col4,
2000:                            false);
2001:                }
2002:            }
2003:
2004:            public static void fillSingleGradient(Graphics g, Rectangle rect,
2005:                    int orientation) {
2006:                fillSingleGradient(g, rect, orientation, 127);
2007:            }
2008:
2009:            public static void fillSingleGradient(Graphics g, Rectangle rect,
2010:                    int orientation, int level) {
2011:                Graphics2D g2d = (Graphics2D) g;
2012:                Color col1 = new Color(255, 255, 255, 0);
2013:                Color col2 = new Color(255, 255, 255, level);
2014:
2015:                if (orientation == SwingConstants.SOUTH) {
2016:                    fillGradient(g2d, new Rectangle(rect.x, rect.y, rect.width,
2017:                            rect.height), col2, col1, true);
2018:                } else if (orientation == SwingConstants.NORTH) {
2019:                    fillGradient(g2d, new Rectangle(rect.x, rect.y, rect.width,
2020:                            rect.height), col1, col2, true);
2021:                } else if (orientation == SwingConstants.EAST) {
2022:                    fillGradient(g2d, new Rectangle(rect.x, rect.y, rect.width,
2023:                            rect.height), col2, col1, false);
2024:                } else if (orientation == SwingConstants.WEST) {
2025:                    fillGradient(g2d, new Rectangle(rect.x, rect.y, rect.width,
2026:                            rect.height), col1, col2, false);
2027:                }
2028:            }
2029:
2030:            /**
2031:             * containerContainsFocus, does the specified container contain the current
2032:             * focusOwner?
2033:             *
2034:             * @param cont the specified container
2035:             * @return Is the current focusOwner a descendent of the specified
2036:             *         container, or the container itself?
2037:             */
2038:            public static boolean containerContainsFocus(Container cont) {
2039:                Component focusOwner = KeyboardFocusManager
2040:                        .getCurrentKeyboardFocusManager().getFocusOwner();
2041:                Component permFocusOwner = KeyboardFocusManager
2042:                        .getCurrentKeyboardFocusManager()
2043:                        .getPermanentFocusOwner();
2044:                boolean focusOwned = false;
2045:                focusOwned = ((focusOwner != null) && SwingUtilities
2046:                        .isDescendingFrom(focusOwner, cont));
2047:                if (!focusOwned) {
2048:                    focusOwned = ((permFocusOwner != null) && SwingUtilities
2049:                            .isDescendingFrom(permFocusOwner, cont));
2050:                }
2051:                return focusOwned;
2052:            }
2053:
2054:            //<syd_0002>
2055:
2056:            public static boolean componentIsPermanentFocusOwner(Component comp) {
2057:                return ((comp != null) && (KeyboardFocusManager
2058:                        .getCurrentKeyboardFocusManager()
2059:                        .getPermanentFocusOwner() == comp));
2060:            }
2061:
2062:            //</syd_0002>
2063:
2064:            public static void installColorsAndFont(Component c,
2065:                    Color background, Color foreground, Font font) {
2066:                installFont(c, font);
2067:                installColors(c, background, foreground);
2068:            }
2069:
2070:            public static void installFont(Component c, Font font) {
2071:                Font f = c.getFont();
2072:                if (f == null || f instanceof  UIResource) {
2073:                    c.setFont(font);
2074:                }
2075:            }
2076:
2077:            public static void installColors(Component c, Color background,
2078:                    Color foreground) {
2079:                Color bg = c.getBackground();
2080:                if (background != null
2081:                        && (bg == null || bg instanceof  UIResource)) {
2082:                    c.setBackground(background);
2083:                }
2084:
2085:                Color fg = c.getForeground();
2086:                if (foreground != null
2087:                        && (fg == null || fg instanceof  UIResource)) {
2088:                    c.setForeground(foreground);
2089:                }
2090:            }
2091:
2092:            public static void installBorder(JComponent c, Border defaultBorder) {
2093:                Border border = c.getBorder();
2094:                if (border == null || border instanceof  UIResource) {
2095:                    c.setBorder(defaultBorder);
2096:                }
2097:            }
2098:
2099:            public static void fillNormalGradient(Graphics2D g2d, Shape s,
2100:                    Color startColor, Color endColor, boolean isVertical) {
2101:                Rectangle rect = s.getBounds();
2102:                GradientPaint paint = null;
2103:                if (isVertical) {
2104:                    paint = new GradientPaint(rect.x, rect.y, startColor,
2105:                            rect.x, rect.height + rect.y, endColor, true); // turn cyclic to true will be faster
2106:                } else {
2107:                    paint = new GradientPaint(rect.x, rect.y, startColor,
2108:                            rect.width + rect.x, rect.y, endColor, true); // turn cyclic to true will be faster
2109:                }
2110:                Paint old = g2d.getPaint();
2111:                g2d.setPaint(paint);
2112:                g2d.fill(s);
2113:                g2d.setPaint(old);
2114:            }
2115:
2116:            /**
2117:             * Fills a gradient using the startColor and endColor specified. This is a fast version of fill gradient
2118:             * which will not only leverage hardware acceleration, but also cache GradientPaint and reuse it.
2119:             * <p/>
2120:             * We also leave an option to use the normal GradientPaint to paint the gradient. To do so, just set a system property
2121:             * "normalGradientPaint" to "false".
2122:             *
2123:             * @param g2d
2124:             * @param s
2125:             * @param startColor
2126:             * @param endColor
2127:             * @param isVertical
2128:             */
2129:            public static void fillGradient(Graphics2D g2d, Shape s,
2130:                    Color startColor, Color endColor, boolean isVertical) {
2131:                if ("true".equals(SecurityUtils.getProperty(
2132:                        "normalGradientPaint", "false"))) {
2133:                    fillNormalGradient(g2d, s, startColor, endColor, isVertical);
2134:                } else {
2135:                    FastGradientPainter.drawGradient(g2d, s, startColor,
2136:                            endColor, isVertical);
2137:                }
2138:            }
2139:
2140:            /**
2141:             * Gets the top modal dialog of current window.
2142:             *
2143:             * @param w
2144:             * @return the top modal dialog of current window.
2145:             */
2146:            public static Window getTopModalDialog(Window w) {
2147:                Window[] ws = w.getOwnedWindows();
2148:                for (int i = 0; i < ws.length; i++) {
2149:                    if (ws[i].isVisible() && ws[i] instanceof  Dialog
2150:                            && ((Dialog) ws[i]).isModal()) {
2151:                        return (getTopModalDialog(ws[i]));
2152:                    }
2153:                }
2154:                return w;
2155:            }
2156:
2157:            /**
2158:             * For internal usage only.
2159:             */
2160:            public static void traceFocus() {
2161:                PropertyChangeListener listener = new PropertyChangeListener() {
2162:                    public void propertyChange(PropertyChangeEvent evt) {
2163:                        String oldName = evt.getOldValue() == null ? "null"
2164:                                : evt.getOldValue().getClass().getName();
2165:                        System.out.println(evt.getPropertyName()
2166:                                + ": "
2167:                                + oldName
2168:                                + " ==> "
2169:                                + (evt.getNewValue() == null ? "null" : evt
2170:                                        .getNewValue().getClass().getName()));
2171:                    }
2172:                };
2173:                DefaultKeyboardFocusManager.getCurrentKeyboardFocusManager()
2174:                        .addPropertyChangeListener("focusOwner", listener);
2175:                DefaultKeyboardFocusManager.getCurrentKeyboardFocusManager()
2176:                        .addPropertyChangeListener("permanentFocusOwner",
2177:                                listener);
2178:                DefaultKeyboardFocusManager.getCurrentKeyboardFocusManager()
2179:                        .addPropertyChangeListener("activeWindow", listener);
2180:            }
2181:
2182:            /**
2183:             * For internal usage only.
2184:             */
2185:            public static JPanel createTableModelModifier(
2186:                    final DefaultTableModel tableModel) {
2187:                JPanel tableModelPanel = new JPanel(new BorderLayout(6, 6));
2188:                final JTable table = new JTable(tableModel);
2189:                tableModelPanel.add(new JScrollPane(table));
2190:                ButtonPanel buttonPanel = new ButtonPanel();
2191:
2192:                JButton insert = new JButton("Insert");
2193:                insert.addActionListener(new AbstractAction() {
2194:                    public void actionPerformed(ActionEvent e) {
2195:                        Vector rowData = tableModel.getDataVector();
2196:                        int index = table.getSelectedRow();
2197:                        if (index != -1) {
2198:                            Vector v = (Vector) rowData.get(index);
2199:                            Vector clone = new Vector();
2200:                            for (int i = 0; i < v.size(); i++) {
2201:                                if (i == 0) {
2202:                                    clone.add((int) (Math.random() * 10));
2203:                                } else {
2204:                                    clone.add("" + v.get(i));
2205:                                }
2206:                            }
2207:                            tableModel.insertRow(index, clone);
2208:                        }
2209:                    }
2210:                });
2211:
2212:                JButton delete = new JButton("Delete");
2213:                delete.addActionListener(new AbstractAction() {
2214:                    public void actionPerformed(ActionEvent e) {
2215:                        int[] rows = table.getSelectedRows();
2216:                        for (int i = rows.length - 1; i >= 0; i--) {
2217:                            int row = rows[i];
2218:                            tableModel.removeRow(row);
2219:                        }
2220:                    }
2221:                });
2222:
2223:                JButton clear = new JButton("Clear");
2224:                clear.addActionListener(new AbstractAction() {
2225:                    public void actionPerformed(ActionEvent e) {
2226:                        for (int i = 0; i < tableModel.getRowCount(); i++) {
2227:                            tableModel.removeRow(0);
2228:                        }
2229:                    }
2230:                });
2231:
2232:                buttonPanel.add(insert);
2233:                buttonPanel.add(delete);
2234:                buttonPanel.add(clear);
2235:                tableModelPanel.add(buttonPanel, BorderLayout.AFTER_LAST_LINE);
2236:                return tableModelPanel;
2237:            }
2238:
2239:            /**
2240:             * Find some subcomponent of the specified container that will accept focus.
2241:             * <p/>
2242:             * Note that this doesn't do something smart like trying to walk the
2243:             * hierarchy horizontally at each level so that the focused subcomponent is
2244:             * as high as possible. Rather, it drills vertically. It's just a safety
2245:             * valve so that focus can be requested somewhere rather than being lost.
2246:             *
2247:             * @param container
2248:             * @return a focusable subcomponent
2249:             */
2250:            public static Component findSomethingFocusable(Container container) {
2251:                if (passesFocusabilityTest(container)) {
2252:                    container.requestFocusInWindow();
2253:                    return container;
2254:                }
2255:                Component[] comps;
2256:                Component comp;
2257:                comps = container.getComponents();
2258:                for (int i = 0; i < comps.length; i++) {
2259:                    if (passesFocusabilityTest(comps[i])) {
2260:                        container.requestFocusInWindow();
2261:                        return container;
2262:                    } else if (comps[i] instanceof  Container) {
2263:                        comp = findSomethingFocusable((Container) (comps[i]));
2264:                        if (comp != null) {
2265:                            return comp;
2266:                        }
2267:                    }
2268:                }
2269:                return null;
2270:            }
2271:
2272:            /**
2273:             * There are four standard tests which determine if Swing will be able to
2274:             * request focus for a component. Test them.
2275:             *
2276:             * @param comp
2277:             * @return does the specified component pass the four focusability tests
2278:             */
2279:            public static boolean passesFocusabilityTest(Component comp) {
2280:                return ((comp != null) && comp.isEnabled()
2281:                        && comp.isDisplayable() && comp.isVisible() && comp
2282:                        .isFocusable());
2283:            }
2284:
2285:            /**
2286:             * Ignore the exception. This method does nothing. However it's a
2287:             * good practice to use this method so that we can easily find
2288:             * out the place that ignoring exception. In development phase,
2289:             * we can log a message in this method so that we can verify if it
2290:             * makes sense to ignore.
2291:             *
2292:             * @param e
2293:             */
2294:            public static void ignoreException(Exception e) {
2295:            }
2296:
2297:            /**
2298:             * Prints out the message of the exception.
2299:             *
2300:             * @param e
2301:             */
2302:            public static void printException(Exception e) {
2303:                System.err.println(e.getLocalizedMessage());
2304:            }
2305:
2306:            /**
2307:             * Throws the exception. If the exception is RuntimeException, just throw it. Otherwise,
2308:             * wrap it in RuntimeException and throw it.
2309:             *
2310:             * @param e
2311:             */
2312:            public static void throwException(Exception e) {
2313:                if (e instanceof  RuntimeException) {
2314:                    throw (RuntimeException) e;
2315:                } else {
2316:                    throw new RuntimeException(e);
2317:                }
2318:            }
2319:
2320:            /**
2321:             * Throws the InvocationTargetException. Usually InvocationTargetException
2322:             * has a nested exception as target exception. If the target exception is a RuntimeException
2323:             * or Error, we will throw it. Otherwise, we will wrap it inside RuntimeException and throw it.
2324:             *
2325:             * @param e
2326:             */
2327:            public static void throwInvocationTargetException(
2328:                    InvocationTargetException e) {
2329:                // in most cases, target exception will be RuntimeException
2330:                // but to be on saferside(it may be Error) we explicitly check it
2331:                if (e.getTargetException() instanceof  RuntimeException) {
2332:                    throw (RuntimeException) e.getTargetException();
2333:                } else if (e.getTargetException() instanceof  Error) {
2334:                    throw (Error) e.getTargetException();
2335:                } else {
2336:                    throw new RuntimeException(e.getTargetException());
2337:                }
2338:            }
2339:
2340:            public static int findDisplayedMnemonicIndex(String text,
2341:                    int mnemonic) {
2342:                if (text == null || mnemonic == '\0') {
2343:                    return -1;
2344:                }
2345:
2346:                char uc = Character.toUpperCase((char) mnemonic);
2347:                char lc = Character.toLowerCase((char) mnemonic);
2348:
2349:                int uci = text.indexOf(uc);
2350:                int lci = text.indexOf(lc);
2351:
2352:                if (uci == -1) {
2353:                    return lci;
2354:                } else if (lci == -1) {
2355:                    return uci;
2356:                } else {
2357:                    return (lci < uci) ? lci : uci;
2358:                }
2359:            }
2360:
2361:            /**
2362:             * Gets the first occurence of the component with specified type in the container. It used deep-first searching
2363:             * to find it.
2364:             *
2365:             * @param c
2366:             * @param container
2367:             * @return the first occurence of the component with specified type in the container. Null if nothing is found.
2368:             */
2369:            public static Component getDescendantOfClass(Class c,
2370:                    Container container) {
2371:                if (container == null || c == null)
2372:                    return null;
2373:
2374:                Component[] components = container.getComponents();
2375:
2376:                for (int i = 0; i < components.length; i++) {
2377:                    Component component = components[i];
2378:                    if (c.isInstance(component)) {
2379:                        return component;
2380:                    }
2381:                    if (component instanceof  Container) {
2382:                        Component found = getDescendantOfClass(c,
2383:                                (Container) component);
2384:                        if (found != null) {
2385:                            return found;
2386:                        }
2387:                    }
2388:                }
2389:                return null;
2390:            }
2391:
2392:            public static float getDefaultFontSize() {
2393:                // read the font size from system property.
2394:                String fontSize = SecurityUtils.getProperty("jide.fontSize",
2395:                        null);
2396:                float defaultFontSize = -1f;
2397:                try {
2398:                    if (fontSize != null) {
2399:                        defaultFontSize = Float.parseFloat(fontSize);
2400:                    }
2401:                } catch (NumberFormatException e) {
2402:                }
2403:
2404:                return defaultFontSize;
2405:            }
2406:
2407:            public static Object getMenuFont(Toolkit toolkit, UIDefaults table) {
2408:                Object menuFont = null;
2409:                // read the font size from system property.
2410:                float defaultFontSize = getDefaultFontSize();
2411:
2412:                if (JideSwingUtilities.shouldUseSystemFont()) {
2413:                    if (defaultFontSize == -1/* || SystemInfo.isCJKLocale()*/) {
2414:                        menuFont = table.getFont("ToolBar.font");
2415:                    } else {
2416:                        menuFont = new WindowsDesktopProperty("win.menu.font",
2417:                                table.getFont("ToolBar.font"), toolkit,
2418:                                defaultFontSize);
2419:                    }
2420:                } else {
2421:                    menuFont = SecurityUtils
2422:                            .createFontUIResource(
2423:                                    "Tahoma",
2424:                                    Font.PLAIN,
2425:                                    defaultFontSize != -1f ? (int) defaultFontSize
2426:                                            : 11);
2427:                }
2428:
2429:                if (menuFont == null) {
2430:                    return getControlFont(toolkit, table);
2431:                } else {
2432:                    return menuFont;
2433:                }
2434:            }
2435:
2436:            public static Object getControlFont(Toolkit toolkit,
2437:                    UIDefaults table) {
2438:                Object controlFont = null;
2439:                // read the font size from system property.
2440:                float defaultFontSize = getDefaultFontSize();
2441:
2442:                if (JideSwingUtilities.shouldUseSystemFont()) {
2443:                    Font font = table.getFont("Label.font");
2444:                    if (font == null) {
2445:                        font = new Font("Tahoma", Font.PLAIN, 12); // use default font
2446:                    }
2447:                    if (defaultFontSize == -1/* || SystemInfo.isCJKLocale()*/) {
2448:                        controlFont = font;
2449:                    } else {
2450:                        controlFont = new WindowsDesktopProperty(
2451:                                "win.defaultGUI.font", font, toolkit,
2452:                                defaultFontSize);
2453:                    }
2454:                } else {
2455:                    controlFont = SecurityUtils
2456:                            .createFontUIResource(
2457:                                    "Tahoma",
2458:                                    Font.PLAIN,
2459:                                    defaultFontSize != -1f ? (int) defaultFontSize
2460:                                            : 11);
2461:                }
2462:
2463:                return controlFont;
2464:            }
2465:
2466:            public static Object getBoldFont(Toolkit toolkit, UIDefaults table) {
2467:                if (SystemInfo.isCJKLocale()) {
2468:                    return getControlFont(toolkit, table);
2469:                } else {
2470:                    Object boldFont = null;
2471:                    // read the font size from system property.
2472:                    float defaultFontSize = getDefaultFontSize();
2473:
2474:                    if (JideSwingUtilities.shouldUseSystemFont()) {
2475:                        Font font = table.getFont("Label.font");
2476:                        if (font == null) {
2477:                            font = new Font("Tahoma", Font.PLAIN, 12); // use default font
2478:                        }
2479:                        if (defaultFontSize == -1) {
2480:                            boldFont = new FontUIResource(font
2481:                                    .deriveFont(Font.BOLD));
2482:                        } else {
2483:                            boldFont = new WindowsDesktopProperty(
2484:                                    "win.defaultGUI.font", font, toolkit,
2485:                                    defaultFontSize, Font.BOLD);
2486:                        }
2487:                    } else {
2488:                        boldFont = SecurityUtils.createFontUIResource("Tahoma",
2489:                                Font.BOLD,
2490:                                defaultFontSize != -1f ? (int) defaultFontSize
2491:                                        : 11);
2492:                    }
2493:                    return boldFont;
2494:                }
2495:            }
2496:
2497:            public static void drawShadow(Graphics g, Component c, int x,
2498:                    int y, int w, int h) {
2499:                ShadowFactory factory = new ShadowFactory(6, 0.7f, Color.GRAY);
2500:                BufferedImage temp = new BufferedImage(w, h,
2501:                        BufferedImage.TYPE_INT_ARGB);
2502:                Graphics2D g2 = temp.createGraphics();
2503:                g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
2504:                        RenderingHints.VALUE_INTERPOLATION_BILINEAR);
2505:                g2.setColor(Color.BLACK);
2506:                g2.fillRect(0, 0, temp.getWidth(), temp.getHeight());
2507:                g2.dispose();
2508:                BufferedImage shadow = factory.createShadow(temp);
2509:                g.drawImage(shadow, x, y, c);
2510:            }
2511:
2512:            static {
2513:                Font.getFont("defaultFont");
2514:                Font.getFont("emphasizedFont");
2515:            }
2516:
2517:            /**
2518:             * Draws a border based on an image. The image can be divided into nine different areas. Each area size is determined
2519:             * by the insets.
2520:             */
2521:            public static void drawImageBorder(Graphics g, ImageIcon img,
2522:                    Rectangle rect, Insets ins, boolean drawCenter) {
2523:                int left = ins.left;
2524:                int right = ins.right;
2525:                int top = ins.top;
2526:                int bottom = ins.bottom;
2527:                int x = rect.x;
2528:                int y = rect.y;
2529:                int w = rect.width;
2530:                int h = rect.height;
2531:
2532:                // top
2533:                g.drawImage(img.getImage(), x, y, x + left, y + top, 0, 0,
2534:                        left, top, null);
2535:                g
2536:                        .drawImage(img.getImage(), x + left, y, x + w - right,
2537:                                y + top, left, 0, img.getIconWidth() - right,
2538:                                top, null);
2539:                g.drawImage(img.getImage(), x + w - right, y, x + w, y + top,
2540:                        img.getIconWidth() - right, 0, img.getIconWidth(), top,
2541:                        null);
2542:
2543:                // middle
2544:                g.drawImage(img.getImage(), x, y + top, x + left, y + h
2545:                        - bottom, 0, top, left, img.getIconHeight() - bottom,
2546:                        null);
2547:                g.drawImage(img.getImage(), x + left, y + top, x + w - right, y
2548:                        + h - bottom, left, top, img.getIconWidth() - right,
2549:                        img.getIconHeight() - bottom, null);
2550:                g.drawImage(img.getImage(), x + w - right, y + top, x + w, y
2551:                        + h - bottom, img.getIconWidth() - right, top, img
2552:                        .getIconWidth(), img.getIconHeight() - bottom, null);
2553:
2554:                // bottom
2555:                g.drawImage(img.getImage(), x, y + h - bottom, x + left, y + h,
2556:                        0, img.getIconHeight() - bottom, left, img
2557:                                .getIconHeight(), null);
2558:                g.drawImage(img.getImage(), x + left, y + h - bottom, x + w
2559:                        - right, y + h, left, img.getIconHeight() - bottom, img
2560:                        .getIconWidth()
2561:                        - right, img.getIconHeight(), null);
2562:                g
2563:                        .drawImage(img.getImage(), x + w - right, y + h
2564:                                - bottom, x + w, y + h, img.getIconWidth()
2565:                                - right, img.getIconHeight() - bottom, img
2566:                                .getIconWidth(), img.getIconHeight(), null);
2567:
2568:                if (drawCenter) {
2569:                    g.drawImage(img.getImage(), x + left, y + top, x + w
2570:                            - right, y + h - bottom, left, top, img
2571:                            .getIconWidth()
2572:                            - right, img.getIconHeight() - bottom, null);
2573:                }
2574:            }
2575:
2576:            /**
2577:             * Copied from BasicLookAndFeel as the method is package local.
2578:             *
2579:             * @param component
2580:             * @return if request focus is success or not.
2581:             */
2582:            public static boolean compositeRequestFocus(Component component) {
2583:                if (component instanceof  Container) {
2584:                    Container container = (Container) component;
2585:                    if (container.isFocusCycleRoot()) {
2586:                        FocusTraversalPolicy policy = container
2587:                                .getFocusTraversalPolicy();
2588:                        Component comp = policy.getDefaultComponent(container);
2589:                        if (comp != null) {
2590:                            comp.requestFocus();
2591:                            return true;
2592:                        }
2593:                    }
2594:                    Container rootAncestor = container
2595:                            .getFocusCycleRootAncestor();
2596:                    if (rootAncestor != null) {
2597:                        FocusTraversalPolicy policy = rootAncestor
2598:                                .getFocusTraversalPolicy();
2599:                        Component comp = policy.getComponentAfter(rootAncestor,
2600:                                container);
2601:
2602:                        if (comp != null
2603:                                && SwingUtilities.isDescendingFrom(comp,
2604:                                        container)) {
2605:                            comp.requestFocus();
2606:                            return true;
2607:                        }
2608:                    }
2609:                }
2610:                if (component.isFocusable()) {
2611:                    component.requestFocus();
2612:                    return true;
2613:                }
2614:                return false;
2615:            }
2616:
2617:            public static boolean isAncestorOfFocusOwner(Component component) {
2618:                boolean hasFocus = false;
2619:                Component focusOwner = KeyboardFocusManager
2620:                        .getCurrentKeyboardFocusManager().getFocusOwner();
2621:                if (component == focusOwner
2622:                        || (component instanceof  Container && ((Container) component)
2623:                                .isAncestorOf(focusOwner))) {
2624:                    hasFocus = true;
2625:                }
2626:                return hasFocus;
2627:            }
2628:
2629:            /**
2630:             * Gets the top level Window of the component.
2631:             *
2632:             * @param component
2633:             * @return the top level Frame. Null if we didn't find an ancestor which is instance of Frame.
2634:             * @deprecated Please use {@link #getWindowForComponent(java.awt.Component)} instead. getWindowForComponent
2635:             *             method is the same as the same name method in JOptionPane. We have to copy it here because it's not public.
2636:             *             getWindowForComponent is better than this method is because it will give you a shared root frame even when parentComponent is null.
2637:             *             You can refer to {@link javax.swing.JOptionPane#getRootFrame()} for more information.
2638:             */
2639:            public static Window getWindow(Component component) {
2640:                if (component == null)
2641:                    return null;
2642:
2643:                if (component instanceof  Window)
2644:                    return (Window) component;
2645:
2646:                // Find framel
2647:                Container p = component.getParent();
2648:                while (p != null) {
2649:                    if (p instanceof  Window) {
2650:                        return (Window) p;
2651:                    }
2652:                    p = p.getParent();
2653:                }
2654:                return null;
2655:            }
2656:
2657:            public static Window getWindowForComponent(Component parentComponent)
2658:                    throws HeadlessException {
2659:                if (parentComponent == null)
2660:                    return JOptionPane.getRootFrame();
2661:                if (parentComponent instanceof  Frame
2662:                        || parentComponent instanceof  Dialog)
2663:                    return (Window) parentComponent;
2664:                return getWindowForComponent(parentComponent.getParent());
2665:            }
2666:
2667:            /**
2668:             * Checks if the key listener is already registerd on the component.
2669:             *
2670:             * @param component the component
2671:             * @param l         the listener
2672:             * @return true if already registered. Otherwise false.
2673:             */
2674:            public static boolean isKeyListenerRegistered(Component component,
2675:                    KeyListener l) {
2676:                KeyListener[] listeners = component.getKeyListeners();
2677:                for (KeyListener listener : listeners) {
2678:                    if (listener == l) {
2679:                        return true;
2680:                    }
2681:                }
2682:                return false;
2683:            }
2684:
2685:            /**
2686:             * Inserts the key listener at the particular index in the listeners' chain.
2687:             *
2688:             * @param component
2689:             * @param l
2690:             * @param index
2691:             */
2692:            public static void insertKeyListener(Component component,
2693:                    KeyListener l, int index) {
2694:                KeyListener[] listeners = component.getKeyListeners();
2695:                for (KeyListener listener : listeners) {
2696:                    component.removeKeyListener(listener);
2697:                }
2698:                for (int i = 0; i < listeners.length; i++) {
2699:                    KeyListener listener = listeners[i];
2700:                    if (index == i) {
2701:                        component.addKeyListener(l);
2702:                    }
2703:                    component.addKeyListener(listener);
2704:                }
2705:                // inex is too large, add to the end.
2706:                if (index > listeners.length - 1) {
2707:                    component.addKeyListener(l);
2708:                }
2709:            }
2710:
2711:            /**
2712:             * Checks if the mouse listener is already registerd on the component.
2713:             *
2714:             * @param component the component
2715:             * @param l         the listener
2716:             * @return true if already registered. Otherwise false.
2717:             */
2718:            public static boolean isMouseListenerRegistered(
2719:                    Component component, MouseListener l) {
2720:                MouseListener[] listeners = component.getMouseListeners();
2721:                for (MouseListener listener : listeners) {
2722:                    if (listener == l) {
2723:                        return true;
2724:                    }
2725:                }
2726:                return false;
2727:            }
2728:
2729:            /**
2730:             * Inserts the mouse listener at the particular index in the listeners' chain.
2731:             *
2732:             * @param component
2733:             * @param l
2734:             * @param index
2735:             */
2736:            public static void insertMouseListener(Component component,
2737:                    MouseListener l, int index) {
2738:                MouseListener[] listeners = component.getMouseListeners();
2739:                for (MouseListener listener : listeners) {
2740:                    component.removeMouseListener(listener);
2741:                }
2742:                for (int i = 0; i < listeners.length; i++) {
2743:                    MouseListener listener = listeners[i];
2744:                    if (index == i) {
2745:                        component.addMouseListener(l);
2746:                    }
2747:                    component.addMouseListener(listener);
2748:                }
2749:                // inex is too large, add to the end.
2750:                if (index > listeners.length - 1) {
2751:                    component.addMouseListener(l);
2752:                }
2753:            }
2754:
2755:            /**
2756:             * Checks if the mouse motion listener is already registerd on the component.
2757:             *
2758:             * @param component the component
2759:             * @param l         the listener
2760:             * @return true if already registered. Otherwise false.
2761:             */
2762:            public static boolean isMouseMotionListenerRegistered(
2763:                    Component component, MouseMotionListener l) {
2764:                MouseMotionListener[] listeners = component
2765:                        .getMouseMotionListeners();
2766:                for (MouseMotionListener listener : listeners) {
2767:                    if (listener == l) {
2768:                        return true;
2769:                    }
2770:                }
2771:                return false;
2772:            }
2773:
2774:            /**
2775:             * Inserts the mouse motion listener at the particular index in the listeners' chain.
2776:             *
2777:             * @param component
2778:             * @param l
2779:             * @param index
2780:             */
2781:            public static void insertMouseMotionListener(Component component,
2782:                    MouseMotionListener l, int index) {
2783:                MouseMotionListener[] listeners = component
2784:                        .getMouseMotionListeners();
2785:                for (MouseMotionListener listener : listeners) {
2786:                    component.removeMouseMotionListener(listener);
2787:                }
2788:                for (int i = 0; i < listeners.length; i++) {
2789:                    MouseMotionListener listener = listeners[i];
2790:                    if (index == i) {
2791:                        component.addMouseMotionListener(l);
2792:                    }
2793:                    component.addMouseMotionListener(listener);
2794:                }
2795:                // inex is too large, add to the end.
2796:                if (index > listeners.length - 1) {
2797:                    component.addMouseMotionListener(l);
2798:                }
2799:            }
2800:
2801:            /**
2802:             * Gets the scroll pane around the component.
2803:             *
2804:             * @param innerComponent
2805:             * @return the scroll pane. Null if the component is not in any JScrollPane.
2806:             */
2807:            public static Component getScrollPane(Component innerComponent) {
2808:                Component component = innerComponent;
2809:                if (component.getParent() != null
2810:                        && component.getParent().getParent() != null
2811:                        && component.getParent().getParent() instanceof  JScrollPane) {
2812:                    component = (JComponent) component.getParent().getParent();
2813:                    return component;
2814:                } else {
2815:                    return null;
2816:                }
2817:            }
2818:
2819:            /**
2820:             * Checks if the listener is always registered to the EventListenerList to avoid duplicated registration of the same listener
2821:             *
2822:             * @param list the EventListenerList to register the listener.
2823:             * @param t    the type of the EventListener.
2824:             * @param l    the listener.
2825:             * @return true if already registered. Otherwise false.
2826:             */
2827:            public static boolean isListenerRegistered(EventListenerList list,
2828:                    Class t, EventListener l) {
2829:                Object[] objects = list.getListenerList();
2830:                return isListenerRegistered(objects, t, l);
2831:            }
2832:
2833:            /**
2834:             * Checks if the listener is always registered to the Component to avoid duplicated registration of the same listener
2835:             *
2836:             * @param component the component that you want to register the listener.
2837:             * @param t         the type of the EventListener.
2838:             * @param l         the listener.
2839:             * @return true if already registered. Otherwise false.
2840:             */
2841:            public static boolean isListenerRegistered(Component component,
2842:                    Class t, EventListener l) {
2843:                Object[] objects = component.getListeners(t);
2844:                return isListenerRegistered(objects, t, l);
2845:            }
2846:
2847:            private static boolean isListenerRegistered(Object[] objects,
2848:                    Class t, EventListener l) {
2849:                for (int i = 0; i < objects.length; i++) {
2850:                    Object listener = objects[i];
2851:                    if (t.isAssignableFrom(listener.getClass())
2852:                            && listener == l) {
2853:                        return true;
2854:                    }
2855:                }
2856:                return false;
2857:            }
2858:
2859:            /**
2860:             * Gets the first child of the component that is the specified type.
2861:             *
2862:             * @param clazz
2863:             * @param c
2864:             * @return the first child of the component that is the specified type.
2865:             */
2866:            public static Component getFirstChildOf(final Class clazz,
2867:                    Component c) {
2868:                return getRecursively(c, new GetHandler() {
2869:                    public boolean condition(Component c) {
2870:                        return clazz.isAssignableFrom(c.getClass());
2871:                    }
2872:
2873:                    public Component action(Component c) {
2874:                        return c;
2875:                    }
2876:                });
2877:            }
2878:
2879:            public static Vector convertDefaultComboBoxModelToVector(
2880:                    DefaultComboBoxModel model) {
2881:                Vector v = new Vector();
2882:                for (int i = 0; i < model.getSize(); i++) {
2883:                    v.add(model.getElementAt(i));
2884:                }
2885:                return v;
2886:
2887:            }
2888:
2889:            /**
2890:             * To make sure the row is visible. If the table's horizontal scroll bar is visible, the method will
2891:             * not change the horizontal scroll bar's position.
2892:             *
2893:             * @param table
2894:             * @param row
2895:             */
2896:            public static void ensureRowVisible(JTable table, int row) {
2897:                Rectangle r = table.getVisibleRect();
2898:                // Hack! make above and below visible if necessary
2899:                // TODO: how to center it or make it the first?
2900:                Rectangle rMid = table.getCellRect(row, 0, true);
2901:                Rectangle rBefore = null, rAfter = null;
2902:                if (row < table.getModel().getRowCount() - 1)
2903:                    rAfter = table.getCellRect(row + 1, 0, true);
2904:                if (row > 0)
2905:                    rBefore = table.getCellRect(row - 1, 0, true);
2906:
2907:                int yLow = (int) rMid.getMinY();
2908:                int yHi = (int) rMid.getMaxY();
2909:                int xLow = r.x;
2910:                int xHi = r.x + r.width;
2911:
2912:                if (rBefore != null)
2913:                    yLow = (int) rBefore.getMinY();
2914:
2915:                if (rAfter != null) {
2916:                    yHi = (int) rAfter.getMaxY();
2917:                }
2918:
2919:                Rectangle rScrollTo = new Rectangle(xLow, yLow, xHi - xLow, yHi
2920:                        - yLow);
2921:                if (!r.contains(rScrollTo) && rScrollTo.height != 0) {
2922:                    table.scrollRectToVisible(rScrollTo);
2923:                }
2924:            }
2925:
2926:            public static void retargetMouseEvent(int id, MouseEvent e,
2927:                    Component target) {
2928:                if (target == null || target == e.getSource()) {
2929:                    return;
2930:                }
2931:                if (e.isConsumed()) {
2932:                    return;
2933:                }
2934:
2935:                // fix for bug #4202966 -- hania
2936:                // When retargetting a mouse event, we need to translate
2937:                // the event's coordinates relative to the target.
2938:
2939:                Point p = SwingUtilities.convertPoint(
2940:                        (Component) e.getSource(), e.getX(), e.getY(), target);
2941:                MouseEvent retargeted = new MouseEvent(target, id, e.getWhen(),
2942:                        e.getModifiersEx() | e.getModifiers(), p.x, p.y, e
2943:                                .getClickCount(), e.isPopupTrigger());
2944:                target.dispatchEvent(retargeted);
2945:            }
2946:
2947:            /**
2948:             * If c is a JRootPane descendant return its outermost JRootPane ancestor.
2949:             * If c is a RootPaneContainer then return its JRootPane.
2950:             *
2951:             * @return the outermost JRootPane for Component c or {@code null}.
2952:             */
2953:            public static JRootPane getOutermostRootPane(Component c) {
2954:                if (c instanceof  RootPaneContainer && c.getParent() == null) {
2955:                    return ((RootPaneContainer) c).getRootPane();
2956:                }
2957:                JRootPane lastRootPane = null;
2958:                for (; c != null; c = SwingUtilities.getRootPane(c)) {
2959:                    if (c instanceof  JRootPane) {
2960:                        lastRootPane = (JRootPane) c;
2961:                        if (c.getParent().getParent() == null) {
2962:                            return lastRootPane;
2963:                        }
2964:                        c = c.getParent();
2965:                    }
2966:                }
2967:                return null;
2968:            }
2969:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.