Source Code Cross Referenced for AWT.java in  » Testing » abbot-1.0.1 » abbot » util » 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 » Testing » abbot 1.0.1 » abbot.util 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        package abbot.util;
0002:
0003:        import java.applet.Applet;
0004:        import java.awt.*;
0005:        import java.awt.event.*;
0006:        import java.beans.PropertyChangeEvent;
0007:        import java.beans.PropertyChangeListener;
0008:        import java.lang.reflect.*;
0009:        import java.util.*;
0010:        import java.util.List;
0011:
0012:        import javax.swing.*;
0013:        import javax.swing.text.View;
0014:
0015:        import sun.awt.AppContext;
0016:        import abbot.Log;
0017:        import abbot.Platform;
0018:        import abbot.finder.*;
0019:        import abbot.finder.matchers.ClassMatcher;
0020:        import abbot.tester.*;
0021:        import abbot.tester.Robot;
0022:
0023:        /** Various AWT utilities to facilitate component-oriented operations. */
0024:
0025:        public class AWT {
0026:
0027:            public static int POPUP_TIMEOUT = 5000;
0028:
0029:            private static Hierarchy hierarchy = new AWTHierarchy();
0030:
0031:            static {
0032:                String to = System.getProperty("abbot.finder.popup_timeout");
0033:                if (to != null) {
0034:                    try {
0035:                        POPUP_TIMEOUT = Integer.parseInt(to);
0036:                    } catch (Exception e) {
0037:                    }
0038:                }
0039:            }
0040:
0041:            private static final Point RELATIVE_OFFSET = new Point(10, 10);
0042:
0043:            /** Set this client property on components which contain a heavyweight 
0044:             * component.  Use {@link Boolean#TRUE} as the value. 
0045:             */
0046:            public final static String CONTAINS_HEAVYWEIGHT_COMPONENT = "containsHeavyweightComponent";
0047:            /** Offset from the position of the currently active window to the 
0048:             * position of a new window.
0049:             */
0050:            public static final Point DEFAULT_CASCADE = new Point(15, 15);
0051:
0052:            /** Return whether the given {@link Point} is visible on any screen. */
0053:            public static boolean onScreen(Point p) {
0054:                GraphicsEnvironment env = GraphicsEnvironment
0055:                        .getLocalGraphicsEnvironment();
0056:                GraphicsDevice[] gs = env.getScreenDevices();
0057:                for (int i = 0; i < gs.length; i++) {
0058:                    GraphicsConfiguration[] gc = gs[i].getConfigurations();
0059:                    for (int j = 0; j < gc.length; j++) {
0060:                        Rectangle r = getVisibleBounds(gc[j]);
0061:                        if (r.contains(p))
0062:                            return true;
0063:                    }
0064:                }
0065:                return false;
0066:            }
0067:
0068:            /** Returns whether one of the upper corners of the given window is 
0069:             * accessible.
0070:             */
0071:            public static boolean onScreen(Window w) {
0072:                return onScreen(w.getLocation())
0073:                        || onScreen(new Point(w.getX() + w.getWidth() - 1, w
0074:                                .getY()));
0075:            }
0076:
0077:            /** Returns the GraphicsConfiguration which contains the given point,
0078:             * or null if none. 
0079:             */
0080:            public static GraphicsConfiguration getGraphicsConfiguration(Point p) {
0081:                GraphicsEnvironment env = GraphicsEnvironment
0082:                        .getLocalGraphicsEnvironment();
0083:                GraphicsDevice[] gs = env.getScreenDevices();
0084:                for (int i = 0; i < gs.length; i++) {
0085:                    GraphicsConfiguration[] gc = gs[i].getConfigurations();
0086:                    Rectangle bounds = getVisibleBounds(gc[i]);
0087:                    if (bounds.contains(p)) {
0088:                        return gc[i];
0089:                    }
0090:                }
0091:                return null;
0092:            }
0093:
0094:            /** Returns a Rectangle spanning all screens.  Note that not all pixels
0095:             * within the rectangle are necessarily on a display.<p>  
0096:             * Includes any toolbar/dashboard regions.
0097:             */
0098:            public static Rectangle getVirtualDisplayBounds(
0099:                    boolean includeInsets) {
0100:                Rectangle bounds = null;
0101:                GraphicsEnvironment env = GraphicsEnvironment
0102:                        .getLocalGraphicsEnvironment();
0103:                GraphicsDevice[] gs = env.getScreenDevices();
0104:                for (int i = 0; i < gs.length; i++) {
0105:                    GraphicsConfiguration[] gc = gs[i].getConfigurations();
0106:                    for (int j = 0; j < gc.length; j++) {
0107:                        Rectangle r = includeInsets ? gc[j].getBounds()
0108:                                : getVisibleBounds(gc[j]);
0109:                        if (bounds == null)
0110:                            bounds = r;
0111:                        else
0112:                            bounds = bounds.union(r);
0113:                    }
0114:                }
0115:                return bounds;
0116:            }
0117:
0118:            /** Return the visible bounds for the graphics configuration.  This will
0119:             * exclude any permanent menu bar or dashboard decorations.
0120:             */
0121:            public static Rectangle getVisibleBounds(GraphicsConfiguration gc) {
0122:                Insets insets = Toolkit.getDefaultToolkit().getScreenInsets(gc);
0123:                Rectangle r = gc.getBounds();
0124:                r.x += insets.left;
0125:                r.y += insets.top;
0126:                r.width -= insets.left + insets.right;
0127:                r.height -= insets.top + insets.bottom;
0128:                return r;
0129:            }
0130:
0131:            private static final int SCREEN_MARGIN = 10;
0132:
0133:            /** Ensure the given window is visible on screen. */
0134:            public static void ensureOnScreen(Window w) {
0135:                // One of the upper corners of the window needs to be on screen
0136:                if (!onScreen(w)) {
0137:                    Rectangle bounds = getVirtualDisplayBounds(false);
0138:                    int x = w.getX();
0139:                    int y = w.getY();
0140:                    if (w.getX() + w.getWidth() < bounds.x + SCREEN_MARGIN) {
0141:                        x = bounds.x + SCREEN_MARGIN - w.getWidth();
0142:                    }
0143:                    if (w.getX() > bounds.x + bounds.width + SCREEN_MARGIN) {
0144:                        x = bounds.x + bounds.width - SCREEN_MARGIN;
0145:                    }
0146:                    if (w.getY() < bounds.y + SCREEN_MARGIN) {
0147:                        y = bounds.y + SCREEN_MARGIN;
0148:                    }
0149:                    if (w.getY() > bounds.y + bounds.height + SCREEN_MARGIN) {
0150:                        y = bounds.y + bounds.height - SCREEN_MARGIN;
0151:                    }
0152:                    w.setLocation(x, y);
0153:                    if (!onScreen(w)) {
0154:                        // If still not on screen, just center it on the default screen
0155:                        centerOnScreen(w);
0156:                    }
0157:                }
0158:            }
0159:
0160:            /** Set the position of the window in a platform-specific manner.
0161:             * Uses Window.setLocationByPlatform if available, otherwise
0162:             * centers on screen. 
0163:             */
0164:            public static void setLocationByPlatform(Window w) {
0165:                try {
0166:                    Method m = Window.class.getDeclaredMethod(
0167:                            "setLocationByPlatform",
0168:                            new Class[] { boolean.class });
0169:                    m.invoke(w, new Object[] { Boolean.TRUE });
0170:                } catch (Exception e) {
0171:                    centerOnScreen(w);
0172:                }
0173:            }
0174:
0175:            /** Ensure the given component renders its initial HTML wrapped at the 
0176:             * given preferred width.
0177:             */
0178:            public static void setHTMLPreferredWidth(JComponent c, int width) {
0179:                // Something of a hack.  This property gets set prior to setting
0180:                // the component's initial size, so we tweak the view to have 
0181:                // a preferred x-axis span to what we want, restoring it after
0182:                // the initial size has been set.
0183:                c.addPropertyChangeListener("ancestor",
0184:                        new PropertyChangeListener() {
0185:                            final int PREF_WIDTH = 200;
0186:
0187:                            public void propertyChange(PropertyChangeEvent e) {
0188:                                JComponent c = (JComponent) e.getSource();
0189:                                c
0190:                                        .removePropertyChangeListener(
0191:                                                "ancestor", this );
0192:                                final View view = (View) c
0193:                                        .getClientProperty("html");
0194:                                if (view != null) {
0195:                                    final float prefx = view
0196:                                            .getPreferredSpan(View.X_AXIS);
0197:                                    final float prefy = view
0198:                                            .getPreferredSpan(View.Y_AXIS);
0199:                                    view.setSize(Math.min(PREF_WIDTH, prefx),
0200:                                            prefy);
0201:                                    SwingUtilities.invokeLater(new Runnable() {
0202:                                        public void run() {
0203:                                            view.setSize(prefx, prefy);
0204:                                        }
0205:                                    });
0206:                                }
0207:                            }
0208:                        });
0209:            }
0210:
0211:            /** Combine the two colors with equal weight. */
0212:            public static Color combine(Color c1, Color c2) {
0213:                return combine(c1, c2, 0.5f);
0214:            }
0215:
0216:            /** Combine the two colors, giving the requested weight to the first.
0217:             */
0218:            public static Color combine(Color c1, Color c2, float weight) {
0219:                float w1 = (float) Math.max(Math.min(weight, 1.0), 0);
0220:                float w2 = 1.0f - w1;
0221:                return new Color((int) (c1.getRed() * w1 + c2.getRed() * w2),
0222:                        (int) (c1.getGreen() * w1 + c2.getGreen() * w2),
0223:                        (int) (c1.getBlue() * w1 + c2.getBlue() * w2),
0224:                        (int) (c1.getAlpha() * w1 + c2.getAlpha() * w2));
0225:            }
0226:
0227:            /** Returns true if there is an active menu on the JFrame (if any)
0228:                containing the given component. */
0229:            public static boolean isMenuActive(Component c) {
0230:                Frame f = getFrame(c);
0231:                if (f instanceof  JFrame) {
0232:                    JFrame frame = (JFrame) f;
0233:                    JMenuBar mb = frame.getJMenuBar();
0234:                    if (mb != null) {
0235:                        for (int i = 0; i < mb.getMenuCount(); i++) {
0236:                            JMenu menu = mb.getMenu(i);
0237:                            if (menu == null)
0238:                                continue;
0239:                            if (menu.isSelected() || menu.isPopupMenuVisible())
0240:                                return true;
0241:                        }
0242:                    }
0243:                }
0244:
0245:                return false;
0246:            }
0247:
0248:            /**
0249:             * Display a frame relative to the given component.
0250:             */
0251:            public static void showFrameRelative(Frame frame,
0252:                    Component relativeTo) {
0253:                moveFrameRelativeTo(frame, relativeTo);
0254:                if (frame.getState() == Frame.ICONIFIED) {
0255:                    frame.setState(Frame.NORMAL);
0256:                }
0257:                frame.show();
0258:            }
0259:
0260:            /** Center the given {@link Window} on the default screen. */
0261:            public static void centerOnScreen(Window window) {
0262:                Point center = GraphicsEnvironment
0263:                        .getLocalGraphicsEnvironment().getCenterPoint();
0264:                Rectangle max = GraphicsEnvironment
0265:                        .getLocalGraphicsEnvironment().getMaximumWindowBounds();
0266:                int x = Math.max(center.x - Math.round(window.getWidth() / 2f),
0267:                        max.x);
0268:                int y = Math.max(
0269:                        center.y - Math.round(window.getHeight() / 2f), max.y);
0270:                window.setLocation(new Point(x, y));
0271:            }
0272:
0273:            /** Center on the specified frame. */
0274:            public static void centerOnFrame(Window window, Frame frame) {
0275:                int ww = window.getWidth();
0276:                int wh = window.getHeight();
0277:
0278:                int fw = frame.getWidth();
0279:                int fh = frame.getHeight();
0280:
0281:                int x = (int) Math.round((double) (fw - ww) / 2);
0282:                int y = (int) Math.round((double) (fh - wh) / 2);
0283:
0284:                Point location = frame.getLocationOnScreen();
0285:                location.translate(x, y);
0286:                window.setLocation(location);
0287:                ensureOnScreen(window);
0288:            }
0289:
0290:            public static void moveFrameRelativeTo(Frame frame,
0291:                    Component relativeTo) {
0292:                Point location = RELATIVE_OFFSET;
0293:                Window reference = null;
0294:                if (relativeTo != null) {
0295:                    reference = getWindow(relativeTo);
0296:                }
0297:                if (reference != null) {
0298:                    location = reference.getLocationOnScreen();
0299:                    location.translate(RELATIVE_OFFSET.x, RELATIVE_OFFSET.y);
0300:                }
0301:                frame.setLocation(location);
0302:                ensureOnScreen(frame);
0303:            }
0304:
0305:            /** Return whether the given component either has focus or is the ancestor
0306:             * of the focused component.
0307:             */
0308:            public static boolean containsFocus(Component c) {
0309:                KeyboardFocusManager mgr = KeyboardFocusManager
0310:                        .getCurrentKeyboardFocusManager();
0311:                Component owner = mgr.getFocusOwner();
0312:                return owner != null
0313:                        && SwingUtilities.isDescendingFrom(owner, c);
0314:            }
0315:
0316:            /** NOTE: on pointer-focused systems, the frontmost window is not 
0317:             * necessarily the one with focus.
0318:             */
0319:            public static Window getFocusedWindow() {
0320:                KeyboardFocusManager mgr = KeyboardFocusManager
0321:                        .getCurrentKeyboardFocusManager();
0322:                return mgr.getFocusedWindow();
0323:            }
0324:
0325:            /** NOTE: NOT necessarily the same thing as the focused window. */
0326:            public static Window getActiveWindow() {
0327:                KeyboardFocusManager mgr = KeyboardFocusManager
0328:                        .getCurrentKeyboardFocusManager();
0329:                return mgr.getActiveWindow();
0330:            }
0331:
0332:            private static boolean containsHeavyweightComponent(Component root) {
0333:                if (root instanceof  Container) {
0334:                    if (root instanceof  JComponent
0335:                            && Boolean.TRUE
0336:                                    .equals(((JComponent) root)
0337:                                            .getClientProperty(CONTAINS_HEAVYWEIGHT_COMPONENT))) {
0338:                        return true;
0339:                    }
0340:                    Container c = (Container) root;
0341:                    for (int i = 0; i < c.getComponentCount(); i++) {
0342:                        if (containsHeavyweightComponent(c.getComponents()[i])) {
0343:                            return true;
0344:                        }
0345:                    }
0346:                }
0347:                return false;
0348:            }
0349:
0350:            /** @return whether the hierarchy within which the given Component sits
0351:             * contains a heavyweight component. 
0352:             */
0353:            public static boolean hierarchyHasHeavyweightComponent(
0354:                    Component base) {
0355:                Window w = getWindow(base);
0356:                return containsHeavyweightComponent(w);
0357:            }
0358:
0359:            /** Return the {@link Frame} corresponding to the given object. */
0360:            public static Frame getFrame(Object o) {
0361:                Window w = getWindow(o);
0362:                while (!(w instanceof  Frame) && w != null) {
0363:                    w = (Window) w.getParent();
0364:                }
0365:                return w instanceof  Frame ? (Frame) w : JOptionPane
0366:                        .getRootFrame();
0367:            }
0368:
0369:            /** Return the window corresponding to the given object. */
0370:            public static Window getWindow(Object o) {
0371:                if (o instanceof  Component) {
0372:                    Component c = (Component) o;
0373:                    while (c instanceof  JMenuItem) {
0374:                        c = c.getParent();
0375:                    }
0376:                    if (c instanceof  JPopupMenu) {
0377:                        return getWindow(((JPopupMenu) c).getInvoker());
0378:                    }
0379:                    return c instanceof  Window ? (Window) c : SwingUtilities
0380:                            .getWindowAncestor(c);
0381:                }
0382:                return JOptionPane.getRootFrame();
0383:            }
0384:
0385:            /** Return a copy of the given color with a new alpha component. */
0386:            public static Color alpha(Color c, int alpha) {
0387:                return new Color(c.getRed(), c.getGreen(), c.getBlue(), alpha);
0388:            }
0389:
0390:            /** Find the first instance of the given class under the given component,
0391:             * or null if none found.
0392:             */
0393:            public static Component find(Component root, final Class type) {
0394:                return find(root, new ComponentPredicate() {
0395:                    public boolean evaluate(Component o) {
0396:                        return o != null && type.isAssignableFrom(o.getClass());
0397:                    }
0398:                });
0399:            }
0400:
0401:            /** Cascade the given window based on the currently active {@link Frame}. */
0402:            public static void cascade(Window w) {
0403:                cascade(w, DEFAULT_CASCADE.x, DEFAULT_CASCADE.y);
0404:            }
0405:
0406:            /** Cascade the given window based on the currently active {@link Frame}. */
0407:            public static void cascade(Window w, int xoff, int yoff) {
0408:                // Make sure we get a frame, not a dialog
0409:                Frame f = getFrame(getActiveWindow());
0410:                if (f != null && f.isShowing()) {
0411:                    w.setLocation(f.getX() + xoff, f.getY() + yoff);
0412:                    ensureOnScreen(w);
0413:                } else {
0414:                    centerOnScreen(w);
0415:                }
0416:            }
0417:
0418:            public static interface ComponentPredicate {
0419:                /** Return whether the given component is the desired one. */
0420:                boolean evaluate(Component c);
0421:            }
0422:
0423:            /** Find the first component matching the given predicate, 
0424:             * or null if none found.
0425:             */
0426:            public static Component find(Component root, ComponentPredicate test) {
0427:                if (test.evaluate(root))
0428:                    return root;
0429:                if (root instanceof  Container) {
0430:                    Component[] kids = ((Container) root).getComponents();
0431:                    for (int i = 0; i < kids.length; i++) {
0432:                        Component c = find(kids[i], test);
0433:                        if (c != null)
0434:                            return c;
0435:                    }
0436:                }
0437:                return null;
0438:            }
0439:
0440:            /** Find the first instance of {@link RootPaneContainer} in the given
0441:             * container.  Basically finds applets.
0442:             */
0443:            public static RootPaneContainer findRootPaneContainer(Container c) {
0444:                if (c instanceof  RootPaneContainer) {
0445:                    return (RootPaneContainer) c;
0446:                }
0447:                Component[] kids = c.getComponents();
0448:                for (int i = 0; i < kids.length; i++) {
0449:                    if (kids[i] instanceof  RootPaneContainer)
0450:                        return (RootPaneContainer) kids[i];
0451:                    if (kids[i] instanceof  Container) {
0452:                        RootPaneContainer rcp = findRootPaneContainer((Container) kids[i]);
0453:                        if (rcp != null)
0454:                            return rcp;
0455:                    }
0456:                }
0457:                return null;
0458:            }
0459:
0460:            private AWT() {
0461:            }
0462:
0463:            /** Return whether the given Component has only its default name set. */
0464:            public static boolean hasDefaultName(Component c) {
0465:                String name = getName(c);
0466:                if (name == null)
0467:                    return true;
0468:
0469:                if (c instanceof  JComponent) {
0470:                    return (c instanceof  JLayeredPane && "null.layeredPane"
0471:                            .equals(name))
0472:                            || (c instanceof  JPanel && ("null.glassPane"
0473:                                    .equals(name) || "null.contentPane"
0474:                                    .equals(name)));
0475:                }
0476:
0477:                return (c instanceof  Button && Regexp.stringMatch(
0478:                        "button[0-9]+", name))
0479:                        || (c instanceof  Canvas && Regexp.stringMatch(
0480:                                "canvas[0-9]+", name))
0481:                        || (c instanceof  Checkbox && Regexp.stringMatch(
0482:                                "checkbox[0-9]+", name))
0483:                        || (c instanceof  Choice && Regexp.stringMatch(
0484:                                "choice[0-9]+", name))
0485:                        || (c instanceof  Dialog && Regexp.stringMatch(
0486:                                "dialog[0-9]+", name))
0487:                        || (c instanceof  FileDialog && Regexp.stringMatch(
0488:                                "filedlg[0-9]+", name))
0489:                        || (c instanceof  Frame && Regexp.stringMatch(
0490:                                "frame[0-9]+", name))
0491:                        || (c instanceof  java.awt.List && Regexp.stringMatch(
0492:                                "list[0-9]+", name))
0493:                        || (c instanceof  Label && Regexp.stringMatch(
0494:                                "label[0-9]+", name))
0495:                        || (c instanceof  Panel && Regexp.stringMatch(
0496:                                "panel[0-9]+", name))
0497:                        || (c instanceof  Scrollbar && Regexp.stringMatch(
0498:                                "scrollbar[0-9]+", name))
0499:                        || (c instanceof  ScrollPane && Regexp.stringMatch(
0500:                                "scrollpane[0-9]+", name))
0501:                        || (c instanceof  TextArea && Regexp.stringMatch(
0502:                                "text[0-9]+", name))
0503:                        || (c instanceof  TextField && Regexp.stringMatch(
0504:                                "textfield[0-9]+", name))
0505:                        || (c instanceof  Window && Regexp.stringMatch(
0506:                                "win[0-9]+", name));
0507:            }
0508:
0509:            /** Ensure the given action happens on the event dispatch thread.  Any
0510:             * component modifications must be invoked this way.
0511:             */
0512:            public static void invokeAndWait(Runnable action) {
0513:                if (EventQueue.isDispatchThread()) {
0514:                    action.run();
0515:                } else {
0516:                    try {
0517:                        EventQueue.invokeAndWait(action);
0518:                    } catch (InterruptedException ie) {
0519:                        Log.warn(ie);
0520:                    } catch (java.lang.reflect.InvocationTargetException ite) {
0521:                        Log.warn(ite);
0522:                    }
0523:                }
0524:            }
0525:
0526:            /** Ensure the given action happens on the event dispatch thread.  Any
0527:             * component modifications must be invoked this way.  Note that this is
0528:             * <b>not</b> the same as EventQueue.invokeLater, since if the current
0529:             * thread is the dispatch thread, the action is invoked immediately.
0530:             */
0531:            public static void invokeAction(Runnable action) {
0532:                if (EventQueue.isDispatchThread()) {
0533:                    action.run();
0534:                } else {
0535:                    EventQueue.invokeLater(action);
0536:                }
0537:            }
0538:
0539:            /** Returns whether the menu component is on a MenuBar. */
0540:            public static boolean isOnMenuBar(MenuComponent mc) {
0541:                if (mc instanceof  MenuBar)
0542:                    return true;
0543:                return mc.getParent() instanceof  MenuComponent
0544:                        && isOnMenuBar((MenuComponent) mc.getParent());
0545:            }
0546:
0547:            /** Returns the invoker, if any, of the given AWT menu component.  Returns
0548:                null if the menu component is not attached to anything, or if it is
0549:                within a MenuBar hierarchy.
0550:             */
0551:            public static Component getInvoker(MenuComponent mc) {
0552:                if (isOnMenuBar(mc))
0553:                    return null;
0554:                MenuContainer parent = mc.getParent();
0555:                while (parent instanceof  MenuComponent) {
0556:                    parent = ((MenuComponent) parent).getParent();
0557:                }
0558:                return parent instanceof  Component ? (Component) parent : null;
0559:            }
0560:
0561:            /** Returns the invoker, if any, of the given component.  Returns null if
0562:             * the component is not on a popup of any sort.
0563:             */
0564:            public static Component getInvoker(Component comp) {
0565:                if (comp instanceof  JPopupMenu)
0566:                    return ((JPopupMenu) comp).getInvoker();
0567:                comp = comp.getParent();
0568:                return comp != null ? getInvoker(comp) : null;
0569:            }
0570:
0571:            /** Similar to SwingUtilities.getWindowAncestor(), but returns the
0572:             * component itself if it is a Window, or the invoker's window if on a
0573:             * popup.
0574:             */
0575:            public static Window getWindow(Component comp) {
0576:                if (comp == null)
0577:                    return null;
0578:                if (comp instanceof  Window)
0579:                    return (Window) comp;
0580:                if (comp instanceof  MenuElement) {
0581:                    Component invoker = getInvoker(comp);
0582:                    if (invoker != null)
0583:                        return getWindow(invoker);
0584:                }
0585:                return getWindow(hierarchy.getParent(comp));
0586:            }
0587:
0588:            /** Returns whether there is an AWT popup menu currently showing. */
0589:            public static boolean isAWTPopupMenuBlocking() {
0590:                // For now, just do a quick check to see if a PopupMenu is active on
0591:                // w32.  Extend it if we find other common situations that might block
0592:                // the EDT, but for now, keep it simple and restricted to what we've
0593:                // run into.
0594:                // NOTE: technically, the popup menu blocks the toolkit, not the EDT,
0595:                // but in practice it doesn't make much difference since the EDT 
0596:                // depends heavily on the toolkit.
0597:                return Bugs.showAWTPopupMenuBlocks() && isAWTTreeLockHeld();
0598:            }
0599:
0600:            /** Returns whether the AWT Tree Lock is currently held. */
0601:            private static boolean isAWTTreeLockHeld() {
0602:                return isAWTTreeLockHeld(Toolkit.getDefaultToolkit()
0603:                        .getSystemEventQueue());
0604:            }
0605:
0606:            /** Returns whether the AWT Tree Lock is currently held. */
0607:            public static boolean isAWTTreeLockHeld(EventQueue eq) {
0608:                Frame[] frames = Frame.getFrames();
0609:                if (frames.length == 0)
0610:                    return false;
0611:
0612:                // hack based on 1.4.2 java.awt.PopupMenu implementation,
0613:                // which blocks the event dispatch thread while the popup is visible,
0614:                // while holding the AWT tree lock
0615:
0616:                // Start another thread which attempts to get the tree lock
0617:                // If it can't get the tree lock, then there is a popup active in the
0618:                // current tree.
0619:                // Any component can provide the tree lock
0620:                ThreadStateChecker checker = new ThreadStateChecker(frames[0]
0621:                        .getTreeLock());
0622:                try {
0623:                    checker.start();
0624:                    // Wait a little bit for the checker to finish
0625:                    int delay = Properties.getProperty("abbot.treelock_wait",
0626:                            100, 0, 60000);
0627:                    if (checker.isAlive())
0628:                        checker.join(delay);
0629:                    return checker.isAlive();
0630:                } catch (InterruptedException e) {
0631:                    return false;
0632:                }
0633:            }
0634:
0635:            /** Ensure any extant AWT popup is dismissed.  This should only be called
0636:             * from off the EDT, since (at least on w32) the EDT is blocked while
0637:             * an AWT popup is showing.
0638:             */
0639:            // FIXME this sometimes causes the windows menu to display on w32
0640:            public static void dismissAWTPopup() {
0641:                // If we're on the EDT, we know a priori there is no AWT popup
0642:                if (SwingUtilities.isEventDispatchThread())
0643:                    return;
0644:                java.awt.Robot robot = Robot.getRobot();
0645:                if (robot != null) {
0646:                    Component c = getFocusOwner();
0647:                    if (c != null) {
0648:                        Window w = getWindow(c);
0649:                        if (w != null && w.isShowing()) {
0650:                            robot.keyPress(KeyEvent.VK_ESCAPE);
0651:                            robot.keyRelease(KeyEvent.VK_ESCAPE);
0652:                        }
0653:                    }
0654:                } else {
0655:                    Log
0656:                            .warn("The current system configuation can not automatically dismiss an AWT popup");
0657:                }
0658:            }
0659:
0660:            /** Returns whether the given MenuComponent is on a top-level AWT popup
0661:                (that is, <i>not</i> under a MenuBar. 
0662:             */
0663:            public static boolean isOnPopup(MenuComponent mc) {
0664:                MenuContainer parent = mc.getParent();
0665:                while (parent instanceof  MenuComponent) {
0666:                    if (parent instanceof  MenuBar)
0667:                        return false;
0668:                    parent = ((MenuComponent) parent).getParent();
0669:                }
0670:                return true;
0671:            }
0672:
0673:            /** Returns whether the given component is on a top-level popup.  A
0674:             * top-level popup is one generated by a popup trigger, which means popups
0675:             * generated from a JMenu are not included.
0676:             */
0677:            public static boolean isOnPopup(Component comp) {
0678:                boolean isWrapper = isTransientPopup(comp);
0679:                Component invoker = getInvoker(comp);
0680:                boolean isOnJMenu = invoker instanceof  JMenu
0681:                        && invoker.getParent() instanceof  JMenuBar;
0682:                return isWrapper || (invoker != null && !isOnJMenu);
0683:            }
0684:
0685:            /** Returns whether the given component is a heavyweight popup, that is, a
0686:                container for a JPopupMenu that is implemented with a heavyweight
0687:                component (usually a Window).
0688:             */
0689:            public static boolean isHeavyweightPopup(Component c) {
0690:                if (c instanceof  Window && !(c instanceof  Dialog)
0691:                        && !(c instanceof  Frame)) {
0692:                    String name = getName(c);
0693:                    String cname = c.getClass().getName();
0694:                    return ("###overrideRedirect###".equals(name)
0695:                            || "###focusableSwingPopup###".equals(name)
0696:                            // These classes are known to be heavyweight popups
0697:                            // javax.swing.DefaultPopupFactory$WindowPopup (1.3)
0698:                            || cname.indexOf("PopupFactory$WindowPopup") != -1
0699:                    // javax.swing.Popup.HeavyWeightWindow (1.4)
0700:                    || cname.indexOf("HeavyWeightWindow") != -1);
0701:                }
0702:                return false;
0703:            }
0704:
0705:            // Work around some components throwing exceptions if getName is 
0706:            // called prematurely
0707:            private static String getName(Component c) {
0708:                try {
0709:                    return c.getName();
0710:                } catch (Throwable e) {
0711:                    Log.warn(e);
0712:                    return null;
0713:                }
0714:            }
0715:
0716:            /** Returns whether the given component is a lightweight popup, that is, a
0717:                container for a JPopupMenu that is implemented with a lightweight
0718:                component (usually JPanel).
0719:             */
0720:            public static boolean isLightweightPopup(Component c) {
0721:                if (c instanceof  JPanel) {
0722:                    Window w = SwingUtilities.getWindowAncestor(c);
0723:                    if (w != null && isHeavyweightPopup(w))
0724:                        return false;
0725:                    JPanel panel = (JPanel) c;
0726:                    Container parent = panel.getParent();
0727:                    if (parent != null) {
0728:                        if (parent instanceof  JLayeredPane) {
0729:                            int layer = JLayeredPane.POPUP_LAYER.intValue();
0730:                            if (JLayeredPane.getLayer(panel) == layer)
0731:                                return true;
0732:                        }
0733:                    }
0734:                    return panel.getComponentCount() == 1
0735:                            && panel.getComponents()[0] instanceof  JPopupMenu;
0736:                }
0737:                return false;
0738:            }
0739:
0740:            /** Returns whether the given Component is the content pane for a
0741:                {@link RootPaneContainer}. 
0742:                @see javax.swing.RootPaneContainer#getContentPane
0743:             */
0744:            public static boolean isContentPane(Component c) {
0745:                if (c.getParent() instanceof  JLayeredPane) {
0746:                    JLayeredPane p = (JLayeredPane) c.getParent();
0747:                    if (p.getParent() instanceof  JRootPane) {
0748:                        return ((JRootPane) p.getParent()).getContentPane() == c;
0749:                    }
0750:                    int layer = JLayeredPane.FRAME_CONTENT_LAYER.intValue();
0751:                    return p.getLayer(c) == layer && !(c instanceof  JMenuBar);
0752:                }
0753:                return false;
0754:            }
0755:
0756:            /** Returns whether the given Component is the Glass Pane for a
0757:                {@link JRootPane}. 
0758:                @see javax.swing.JRootPane#getGlassPane
0759:             */
0760:            public static boolean isGlassPane(Component c) {
0761:                if (c.getParent() instanceof  JRootPane) {
0762:                    JRootPane p = (JRootPane) c.getParent();
0763:                    return p.getGlassPane() == c;
0764:                }
0765:                return false;
0766:            }
0767:
0768:            /** Return whether the given component is part of the transient wrapper
0769:             * around a popup.
0770:             */
0771:            public static boolean isTransientPopup(Component c) {
0772:                return isLightweightPopup(c) || isHeavyweightPopup(c);
0773:            }
0774:
0775:            private static boolean containsToolTip(Component c) {
0776:                if (c instanceof  JToolTip)
0777:                    return true;
0778:                if (c instanceof  Container) {
0779:                    Component[] kids = ((Container) c).getComponents();
0780:                    for (int i = 0; i < kids.length; i++) {
0781:                        if (containsToolTip(kids[i]))
0782:                            return true;
0783:                    }
0784:                }
0785:                return false;
0786:            }
0787:
0788:            /** Return whether the given component is part of the transient wrapper
0789:                around a tooltip.
0790:             */
0791:            public static boolean isToolTip(Component c) {
0792:                return isTransientPopup(c) && containsToolTip(c);
0793:            }
0794:
0795:            /** Return whether the given component is part of an internal frame's LAF
0796:                decoration.
0797:             */
0798:            public static boolean isInternalFrameDecoration(Component c) {
0799:                Component parent = c.getParent();
0800:                return (parent instanceof  JInternalFrame && !(c instanceof  JRootPane))
0801:                        || (parent != null
0802:                                && (parent.getParent() instanceof  JInternalFrame) && (!(parent instanceof  JRootPane)));
0803:            }
0804:
0805:            // Macintosh *used* to map button2 to the popup trigger (circa 1.3)
0806:            // Not clear when this changed
0807:            private static final boolean POPUP_ON_BUTTON2 = false;
0808:
0809:            /** Returns the InputEvent mask for the popup trigger button. */
0810:            public static int getPopupMask() {
0811:                return POPUP_ON_BUTTON2 ? InputEvent.BUTTON2_MASK
0812:                        : InputEvent.BUTTON3_MASK;
0813:            }
0814:
0815:            /** Returns the InputEvent mask for the tertiary button. */
0816:            public static int getTertiaryMask() {
0817:                return POPUP_ON_BUTTON2 ? InputEvent.BUTTON3_MASK
0818:                        : InputEvent.BUTTON2_MASK;
0819:            }
0820:
0821:            /** Returns whether the platform registers a popup on mouse press. */
0822:            public static boolean getPopupOnPress() {
0823:                // Only w32 is popup on release 
0824:                return !Platform.isWindows();
0825:            }
0826:
0827:            private static final PopupMenu[] NO_POPUPS = new PopupMenu[0];
0828:
0829:            /** Return all AWT popup menus associated with the given component. */
0830:            public static PopupMenu[] getPopupMenus(Component c) {
0831:                // Here's a nice little hack to get access to the popup list on the
0832:                // given invoker...
0833:                try {
0834:                    Field field = Component.class.getDeclaredField("popups");
0835:                    boolean accessible = field.isAccessible();
0836:                    field.setAccessible(true);
0837:                    Vector popups = (Vector) field.get(c);
0838:                    field.setAccessible(accessible);
0839:                    if (popups != null)
0840:                        return (PopupMenu[]) popups
0841:                                .toArray(new PopupMenu[popups.size()]);
0842:                    return NO_POPUPS;
0843:                } catch (NoSuchFieldException e) {
0844:                    // not gonna happen
0845:                    throw new Error(
0846:                            "No field named 'popups' in class Component");
0847:                } catch (IllegalAccessException e) {
0848:                    // neither should this
0849:                    throw new Error("Can't access popup for component " + c);
0850:                }
0851:            }
0852:
0853:            /** Returns all MenuItems matching the given label or path which are on
0854:                PopupMenus on the given Component. */
0855:            public static MenuItem[] findAWTPopupMenuItems(Component parent,
0856:                    String path) {
0857:                PopupMenu[] popups = getPopupMenus(parent);
0858:                ArrayList list = new ArrayList();
0859:                for (int i = 0; i < popups.length; i++) {
0860:                    list.addAll(findMenuItems(popups[i], path, true));
0861:                }
0862:                return (MenuItem[]) list.toArray(new MenuItem[list.size()]);
0863:            }
0864:
0865:            /** Returns all MenuItems matching the given label or path which are found
0866:                in the given Frame's MenuBar. */
0867:            public static MenuItem[] findAWTMenuItems(Frame frame, String path) {
0868:                MenuBar mb = frame.getMenuBar();
0869:                if (mb != null) {
0870:                    Collection items = findMenuItems(mb, path, true);
0871:                    return (MenuItem[]) items
0872:                            .toArray(new MenuItem[items.size()]);
0873:                }
0874:                return new MenuItem[0];
0875:            }
0876:
0877:            /** Returns a unique path to the given MenuItem. */
0878:            public static String getPath(MenuItem item) {
0879:                String path = getPath(item, false);
0880:                if (isOnPopup(item)
0881:                        && findAWTPopupMenuItems(getInvoker(item), path).length > 1) {
0882:                    path = getPath(item, true);
0883:                }
0884:                return path;
0885:            }
0886:
0887:            /** Returns a unique path to the given MenuItem.  If on a PopupMenu,
0888:                optionally include the PopupMenu name. */
0889:            private static String getPath(MenuItem item,
0890:                    boolean includePopupName) {
0891:                MenuContainer invoker = getInvoker(item);
0892:                MenuContainer top;
0893:                if (invoker == null) {
0894:                    // Find the top-most Menu above this MenuItem
0895:                    top = item.getParent();
0896:                    while (top instanceof  Menu
0897:                            && !(((Menu) top).getParent() instanceof  MenuBar)) {
0898:                        top = ((Menu) top).getParent();
0899:                    }
0900:                    if (top == null)
0901:                        throw new RuntimeException(
0902:                                "MenuItem is not attached to the hierarchy");
0903:                } else {
0904:                    // Find the containing PopupMenu
0905:                    top = item.getParent();
0906:                    while (top instanceof  Menu
0907:                            && !(((Menu) top).getParent() instanceof  Component)) {
0908:                        top = ((Menu) top).getParent();
0909:                    }
0910:                }
0911:
0912:                // Return a path to the item, starting at the first top level Menu 
0913:                String path = item.getLabel();
0914:                MenuItem mi = item;
0915:                while (mi.getParent() != top) {
0916:                    mi = (MenuItem) mi.getParent();
0917:                    path = mi.getLabel() + "|" + path;
0918:                }
0919:                if (top instanceof  PopupMenu) {
0920:                    if (includePopupName) {
0921:                        // If the popup has the default name, use its index
0922:                        // on the invoker instead.  
0923:                        String name = ((PopupMenu) top).getName();
0924:                        if (Regexp.stringMatch("popup[0-9]+", name)) {
0925:                            PopupMenu[] all = getPopupMenus((Component) invoker);
0926:                            for (int i = 0; i < all.length; i++) {
0927:                                if (all[i] == top) {
0928:                                    // Make it different from the default name
0929:                                    name = "popup#" + i;
0930:                                    break;
0931:                                }
0932:                            }
0933:                        }
0934:                        path = name + "|" + path;
0935:                    }
0936:                } else {
0937:                    path = ((Menu) top).getLabel() + "|" + path;
0938:                }
0939:                Log.debug("Path for " + item + " is " + path);
0940:                return path;
0941:            }
0942:
0943:            /** Returns all AWT menu items found with the given label; if matchPath is
0944:                set then the MenuItem path is examined as well as the label.
0945:             */
0946:            private static Collection findMenuItems(MenuContainer mc,
0947:                    String path, boolean matchPath) {
0948:                if (matchPath)
0949:                    Log.debug("Searching for '" + path + "' on '" + mc);
0950:                ArrayList list = new ArrayList();
0951:                if (mc instanceof  MenuBar) {
0952:                    for (int i = 0; i < ((MenuBar) mc).getMenuCount(); i++) {
0953:                        Menu menu = ((MenuBar) mc).getMenu(i);
0954:                        Log.debug("Scanning '" + menu + "'");
0955:                        list.addAll(findMenuItems(menu, path, matchPath));
0956:                    }
0957:                } else if (mc instanceof  Menu) {
0958:                    for (int i = 0; i < ((Menu) mc).getItemCount(); i++) {
0959:                        MenuItem mi = ((Menu) mc).getItem(i);
0960:                        if (mi instanceof  MenuContainer) {
0961:                            Log.debug("Scanning '" + mi + "'");
0962:                            list.addAll(findMenuItems((MenuContainer) mi, path,
0963:                                    matchPath));
0964:                        } else if (path.equals(mi.getLabel())) {
0965:                            Log.debug("Found '" + mi + "'");
0966:                            list.add(mi);
0967:                        } else if (matchPath) {
0968:                            if (ExtendedComparator.stringsMatch(path, getPath(
0969:                                    mi, false))
0970:                                    || ExtendedComparator.stringsMatch(path,
0971:                                            getPath(mi, true))) {
0972:                                Log.debug("Found (path) '" + mi + "'");
0973:                                list.add(mi);
0974:                            }
0975:                            // TODO: fuzzy matching on the unique id (i.e. drop off or
0976:                            // add the popup menu name.
0977:                        }
0978:                    }
0979:                }
0980:                return list;
0981:            }
0982:
0983:            /** Return the focus owner under the given Window. 
0984:                As of 1.4.x, components will report that they do not have focus
0985:                if asked from a different AppContext than their own.  Account
0986:                for that here.
0987:             */
0988:            public static Component getFocusOwner() {
0989:                try {
0990:                    Class cls = Class.forName("java.awt.KeyboardFocusManager");
0991:                    Field field = cls.getDeclaredField("focusOwner");
0992:                    boolean accessible = field.isAccessible();
0993:                    field.setAccessible(true);
0994:                    Component c = (Component) field.get(null);
0995:                    field.setAccessible(accessible);
0996:                    return c;
0997:                } catch (Exception e) {
0998:                    if (!(e instanceof  ClassNotFoundException))
0999:                        Log.log(e);
1000:                    // FIXME this lookup doesn't seem to work on 1.3!
1001:                    Iterator iter = new AWTHierarchy().getRoots().iterator();
1002:                    Component focus = null;
1003:                    while (iter.hasNext()) {
1004:                        Window w = (Window) iter.next();
1005:                        if (w.isShowing() && (focus = getFocusOwner(w)) != null)
1006:                            break;
1007:                    }
1008:                    return focus;
1009:                }
1010:            }
1011:
1012:            private static Component getFocusOwner(Window w) {
1013:                Component focus = w.getFocusOwner();
1014:                if (focus == null) {
1015:                    Window[] owned = w.getOwnedWindows();
1016:                    for (int i = 0; i < owned.length; i++) {
1017:                        if ((focus = owned[i].getFocusOwner()) != null)
1018:                            return focus;
1019:                    }
1020:                }
1021:                return focus;
1022:            }
1023:
1024:            /** For debugging purposes only. */
1025:            public static AppContext getAppContext(Component c) {
1026:                try {
1027:                    Field field = Component.class
1028:                            .getDeclaredField("appContext");
1029:                    boolean accessible = field.isAccessible();
1030:                    field.setAccessible(true);
1031:                    AppContext appContext = (AppContext) field.get(c);
1032:                    field.setAccessible(accessible);
1033:                    return appContext;
1034:                } catch (Exception e) {
1035:                    Log.warn(e);
1036:                    return null;
1037:                }
1038:            }
1039:
1040:            /** WARNING: This uses 1.3/1.4 implementation details. */
1041:            public static boolean eventTypeEnabled(Component c, int id) {
1042:                // certain AWT components should have events enabled, even if they
1043:                // claim not to.
1044:                // NOTE: Checkbox could be included here, obviating the need for
1045:                // CheckboxTester's AWT-mode function.
1046:                if (c instanceof  Choice)
1047:                    return true;
1048:                try {
1049:                    AWTEvent ev = new AWTEvent(c, id) {
1050:                    };
1051:                    Method m = Component.class.getDeclaredMethod(
1052:                            "eventEnabled", new Class[] { AWTEvent.class });
1053:                    m.setAccessible(true);
1054:                    Boolean b = (Boolean) m.invoke(c, new Object[] { ev });
1055:                    return b.booleanValue();
1056:                } catch (Exception e) {
1057:                    Log.warn(e);
1058:                    return true;
1059:                }
1060:            }
1061:
1062:            // Don't use the full classname, since anonymous inner classnames
1063:            // are dependent on order of appearance in the source
1064:            static final String ROOT_FRAME_CLASSNAME = SwingUtilities.class
1065:                    .getName()
1066:                    + "$";
1067:
1068:            /** Is the given component the default Swing hidden frame? */
1069:            public static boolean isSharedInvisibleFrame(Component c) {
1070:                // Must perform an additional check, since applets may
1071:                // have their own version in their AppContext
1072:                return c instanceof  Frame
1073:                        && (c == JOptionPane.getRootFrame() || c.getClass()
1074:                                .getName().startsWith(ROOT_FRAME_CLASSNAME));
1075:            }
1076:
1077:            public static boolean isAppletViewerFrame(Component c) {
1078:                return c.getClass().getName().equals("sun.applet.AppletViewer");
1079:            }
1080:
1081:            private static final Matcher POPUP_MATCHER = new ClassMatcher(
1082:                    JPopupMenu.class, true);
1083:
1084:            /** Returns the currently active popup menu, if any.  If no popup is
1085:                currently showing, returns null.
1086:             */
1087:            public static JPopupMenu getActivePopupMenu() {
1088:                try {
1089:                    return (JPopupMenu) BasicFinder.getDefault().find(
1090:                            POPUP_MATCHER);
1091:                } catch (ComponentSearchException e) {
1092:                    return null;
1093:                }
1094:            }
1095:
1096:            /** Find the currently active Swing popup menu, if any, waiting up to
1097:                POPUP_TIMEOUT ms.  Returns null if no popup found.
1098:             */
1099:            public static JPopupMenu findActivePopupMenu() {
1100:                JPopupMenu popup = getActivePopupMenu();
1101:                if (popup == null && !SwingUtilities.isEventDispatchThread()) {
1102:                    long now = System.currentTimeMillis();
1103:                    while ((popup = getActivePopupMenu()) == null) {
1104:                        if (System.currentTimeMillis() - now > POPUP_TIMEOUT) {
1105:                            break;
1106:                        }
1107:                        try {
1108:                            Thread.sleep(100);
1109:                        } catch (Exception e) {
1110:                        }
1111:                    }
1112:                }
1113:                return popup;
1114:            }
1115:
1116:            /** Safe version of {@link Component#getLocationOnScreen}, which 
1117:             * avoids lockup if an AWT popup menu is showing.  The AWT popup
1118:             * holds the AWT tree lock when showing, which lock is required by
1119:             * {@link Component#getLocationOnScreen}.
1120:             */
1121:            public static Point getLocationOnScreen(Component c) {
1122:                if (isAWTTreeLockHeld()) {
1123:                    if (!c.isShowing())
1124:                        throw new IllegalComponentStateException(
1125:                                "component must be showing on the screen to determine its location");
1126:                    Point loc = new Point(c.getLocation());
1127:                    if (!(c instanceof  Window)) {
1128:                        Container parent = c.getParent();
1129:                        if (parent == null)
1130:                            throw new IllegalComponentStateException(
1131:                                    "component must be showing on the screen to determine its location");
1132:                        Point ploc = getLocationOnScreen(parent);
1133:                        loc.translate(ploc.x, ploc.y);
1134:                    }
1135:                    return loc;
1136:                }
1137:                return new Point(c.getLocationOnScreen());
1138:            }
1139:
1140:            /** Return whether the given component is part of a transient dialog.
1141:             * This includes dialogs generated by JFileChooser, JOptionPane,
1142:             * JColorChooser, and ProgressMonitor.<p>
1143:             * Note that it is possible to use JOptionPane.createDialog to create a
1144:             * reusable dialog, so just because it's transient doesn't mean it will be
1145:             * disposed of when it is hidden.<p>
1146:             * Note that this won't detect transient Dialogs after their components
1147:             * have been reassigned to a new transient Dialog.
1148:             */
1149:            public static boolean isTransientDialog(Component c) {
1150:                if (c instanceof  Window) {
1151:                    if (c instanceof  JDialog) {
1152:                        Container contentPane = ((JDialog) c).getContentPane();
1153:                        Component[] kids = contentPane.getComponents();
1154:                        if (kids.length == 1) {
1155:                            return kids[0] instanceof  JOptionPane
1156:                                    || kids[0] instanceof  JFileChooser
1157:                                    || kids[0] instanceof  JColorChooser;
1158:                        }
1159:                    }
1160:                } else if (!(c instanceof  JOptionPane // also covers ProgressMonitor
1161:                        || c instanceof  JFileChooser || c instanceof  JColorChooser)) {
1162:                    Container parent = c.getParent();
1163:                    return parent != null && isTransientDialog(parent);
1164:                }
1165:                return false;
1166:            }
1167:
1168:            /** Returns the Applet descendent of the given Container, if any. */
1169:            public static Applet findAppletDescendent(Container c) {
1170:                try {
1171:                    return (Applet) BasicFinder.getDefault().find(c,
1172:                            new ClassMatcher(Applet.class));
1173:                } catch (ComponentSearchException e) {
1174:                    return null;
1175:                }
1176:            }
1177:
1178:            /** Return whether this is the tertiary button, considering primary to be
1179:             * button1 and secondary to be the popup trigger button.
1180:             */
1181:            public static boolean isTertiaryButton(int mods) {
1182:                return ((mods & AWTConstants.BUTTON_MASK) != InputEvent.BUTTON1_MASK)
1183:                        && ((mods & AWTConstants.POPUP_MASK) == 0);
1184:            }
1185:
1186:            /** Convert the string representation into the actual modifier mask. */
1187:            public static int getModifiers(String mods) {
1188:                int value = 0;
1189:                if (mods != null && !mods.equals("")) {
1190:                    StringTokenizer st = new StringTokenizer(mods, "| ");
1191:                    while (st.hasMoreTokens()) {
1192:                        String flag = st.nextToken();
1193:                        // Allow short-form modifiers
1194:                        if (!flag.endsWith("_MASK"))
1195:                            flag = flag + "_MASK";
1196:                        if (AWTConstants.POPUP_MODIFIER.equals(flag))
1197:                            value |= AWTConstants.POPUP_MASK;
1198:                        else if (AWTConstants.TERTIARY_MODIFIER.equals(flag))
1199:                            value |= AWTConstants.TERTIARY_MASK;
1200:                        else if (!flag.equals("0"))
1201:                            value |= Reflector.getFieldValue(InputEvent.class,
1202:                                    flag);
1203:                    }
1204:                }
1205:                return value;
1206:            }
1207:
1208:            private static String getModifiers(int flags, boolean isMouse) {
1209:                // Historical note: 
1210:                // On a mac, ALT+BUTTON1 means BUTTON2; META+BUTTON1 means BUTTON3
1211:                int macModifiers = InputEvent.CTRL_MASK | InputEvent.ALT_MASK
1212:                        | InputEvent.META_MASK;
1213:                boolean isMacButton = isMouse && Platform.isMacintosh()
1214:                        && (flags & macModifiers) != 0;
1215:                String mods = "";
1216:                String or = "";
1217:                if ((flags & InputEvent.ALT_GRAPH_MASK) != 0) {
1218:                    mods += or + "ALT_GRAPH_MASK";
1219:                    or = "|";
1220:                    flags &= ~InputEvent.ALT_GRAPH_MASK;
1221:                }
1222:                if ((flags & InputEvent.BUTTON1_MASK) != 0 && !isMacButton) {
1223:                    mods += or + "BUTTON1_MASK";
1224:                    or = "|";
1225:                    flags &= ~InputEvent.BUTTON1_MASK;
1226:                }
1227:                // Mask for ALT is the same as MB2
1228:                if ((flags & InputEvent.ALT_MASK) != 0 && !isMacButton
1229:                        && !isMouse) {
1230:                    mods += or + "ALT_MASK";
1231:                    or = "|";
1232:                    flags &= ~InputEvent.ALT_MASK;
1233:                }
1234:                // Mac uses ctrl modifier to get MB2
1235:                if ((flags & InputEvent.CTRL_MASK) != 0 && !isMacButton) {
1236:                    mods += or + "CTRL_MASK";
1237:                    or = "|";
1238:                    flags &= ~InputEvent.CTRL_MASK;
1239:                }
1240:                // Mask for META is the same as MB3
1241:                if ((flags & InputEvent.META_MASK) != 0 && !isMacButton
1242:                        && !isMouse) {
1243:                    mods += or + "META_MASK";
1244:                    or = "|";
1245:                    flags &= ~InputEvent.META_MASK;
1246:                }
1247:                if ((flags & AWTConstants.POPUP_MASK) != 0) {
1248:                    mods += or + "POPUP_MASK";
1249:                    or = "|";
1250:                    flags &= ~AWTConstants.POPUP_MASK;
1251:                }
1252:                if ((flags & AWTConstants.TERTIARY_MASK) != 0) {
1253:                    mods += or + "TERTIARY_MASK";
1254:                    or = "|";
1255:                    flags &= ~AWTConstants.TERTIARY_MASK;
1256:                }
1257:                if ((flags & InputEvent.SHIFT_MASK) != 0) {
1258:                    mods += or + "SHIFT_MASK";
1259:                    or = "|";
1260:                    flags &= ~InputEvent.SHIFT_MASK;
1261:                }
1262:                // Empty strings are confusing and invisible; make it explicit
1263:                if ("".equals(mods))
1264:                    mods = "0";
1265:                return mods;
1266:            }
1267:
1268:            public static String getKeyModifiers(int flags) {
1269:                return getModifiers(flags, false);
1270:            }
1271:
1272:            public static String getMouseModifiers(int flags) {
1273:                return getModifiers(flags, true);
1274:            }
1275:
1276:            /** Convert the integer modifier flags into a string representation. */
1277:            public static String getModifiers(InputEvent event) {
1278:                return getModifiers(event.getModifiers(),
1279:                        event instanceof  MouseEvent);
1280:            }
1281:
1282:            public static String getKeyCode(int keycode) {
1283:                return Reflector.getFieldName(KeyEvent.class, keycode, "VK_");
1284:            }
1285:
1286:            public static int getKeyCode(String code) {
1287:                return Reflector.getFieldValue(KeyEvent.class, code);
1288:            }
1289:
1290:            public static boolean isModifier(int keycode) {
1291:                switch (keycode) {
1292:                case KeyEvent.VK_META:
1293:                case KeyEvent.VK_ALT:
1294:                case KeyEvent.VK_ALT_GRAPH:
1295:                case KeyEvent.VK_CONTROL:
1296:                case KeyEvent.VK_SHIFT:
1297:                    return true;
1298:                default:
1299:                    return false;
1300:                }
1301:            }
1302:
1303:            public static int keyCodeToMask(int code) {
1304:                switch (code) {
1305:                case KeyEvent.VK_META:
1306:                    return InputEvent.META_MASK;
1307:                case KeyEvent.VK_ALT:
1308:                    return InputEvent.ALT_MASK;
1309:                case KeyEvent.VK_ALT_GRAPH:
1310:                    return InputEvent.ALT_GRAPH_MASK;
1311:                case KeyEvent.VK_CONTROL:
1312:                    return InputEvent.CTRL_MASK;
1313:                case KeyEvent.VK_SHIFT:
1314:                    return InputEvent.SHIFT_MASK;
1315:                default:
1316:                    throw new IllegalArgumentException(
1317:                            "Keycode is not a modifier: " + code);
1318:                }
1319:            }
1320:
1321:            /** Convert the given modifier event mask to the equivalent key code. */
1322:            public static int maskToKeyCode(int mask) {
1323:                switch (mask) {
1324:                case InputEvent.META_MASK:
1325:                    return KeyEvent.VK_META;
1326:                case InputEvent.ALT_MASK:
1327:                    return KeyEvent.VK_ALT;
1328:                case InputEvent.ALT_GRAPH_MASK:
1329:                    return KeyEvent.VK_ALT_GRAPH;
1330:                case InputEvent.CTRL_MASK:
1331:                    return KeyEvent.VK_CONTROL;
1332:                case InputEvent.SHIFT_MASK:
1333:                    return KeyEvent.VK_SHIFT;
1334:                default:
1335:                    throw new IllegalArgumentException("Unrecognized mask '"
1336:                            + mask + "'");
1337:                }
1338:            }
1339:
1340:            /** If a component does not have mouse events enabled, use the
1341:                first ancestor which does.
1342:             */
1343:            public static Component retargetMouseEvent(Component comp, int id,
1344:                    Point pt) {
1345:                Point where = pt;
1346:                while (!(comp instanceof  Window) && !eventTypeEnabled(comp, id)) {
1347:                    Log.debug("Retargeting event, " + Robot.toString(comp)
1348:                            + " not interested");
1349:                    where = SwingUtilities.convertPoint(comp, where.x, where.y,
1350:                            comp.getParent());
1351:                    comp = comp.getParent();
1352:                }
1353:                pt.setLocation(where);
1354:                return comp;
1355:            }
1356:
1357:            public static Insets getInsets(Container c) {
1358:                try {
1359:                    Insets insets = c.getInsets();
1360:                    if (insets != null)
1361:                        return insets;
1362:                } catch (NullPointerException e) {
1363:                    // FileDialog.getInsets() throws (1.4.2_07)
1364:                }
1365:                return new Insets(0, 0, 0, 0);
1366:            }
1367:
1368:            // Try to lock the AWT tree lock; returns immediately if it can
1369:            private static class ThreadStateChecker extends Thread {
1370:                public boolean started;
1371:                private Object lock;
1372:
1373:                public ThreadStateChecker(Object lock) {
1374:                    super ("thread state checker");
1375:                    setDaemon(true);
1376:                    this .lock = lock;
1377:                }
1378:
1379:                public synchronized void start() {
1380:                    super .start();
1381:                    try {
1382:                        wait(30000);
1383:                    } catch (InterruptedException e) {
1384:                    }
1385:                }
1386:
1387:                public void run() {
1388:                    synchronized (this ) {
1389:                        started = true;
1390:                        notifyAll();
1391:                    }
1392:                    synchronized (lock) {
1393:                        // dummy operation
1394:                        setName(super.getName());
1395:                    }
1396:                }
1397:            }
1398:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.