Source Code Cross Referenced for SwingUtilities.java in  » 6.0-JDK-Core » swing » javax » swing » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Home
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
26.ERP CRM Financial
27.ESB
28.Forum
29.Game
30.GIS
31.Graphic 3D
32.Graphic Library
33.Groupware
34.HTML Parser
35.IDE
36.IDE Eclipse
37.IDE Netbeans
38.Installer
39.Internationalization Localization
40.Inversion of Control
41.Issue Tracking
42.J2EE
43.J2ME
44.JBoss
45.JMS
46.JMX
47.Library
48.Mail Clients
49.Music
50.Net
51.Parser
52.PDF
53.Portal
54.Profiler
55.Project Management
56.Report
57.RSS RDF
58.Rule Engine
59.Science
60.Scripting
61.Search Engine
62.Security
63.Sevlet Container
64.Source Control
65.Swing Library
66.Template Engine
67.Test Coverage
68.Testing
69.UML
70.Web Crawler
71.Web Framework
72.Web Mail
73.Web Server
74.Web Services
75.Web Services apache cxf 2.2.6
76.Web Services AXIS2
77.Wiki Engine
78.Workflow Engines
79.XML
80.XML UI
Java Source Code / Java Documentation » 6.0 JDK Core » swing » javax.swing 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001        /*
0002         * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
0003         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004         *
0005         * This code is free software; you can redistribute it and/or modify it
0006         * under the terms of the GNU General Public License version 2 only, as
0007         * published by the Free Software Foundation.  Sun designates this
0008         * particular file as subject to the "Classpath" exception as provided
0009         * by Sun in the LICENSE file that accompanied this code.
0010         *
0011         * This code is distributed in the hope that it will be useful, but WITHOUT
0012         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
0014         * version 2 for more details (a copy is included in the LICENSE file that
0015         * accompanied this code).
0016         *
0017         * You should have received a copy of the GNU General Public License version
0018         * 2 along with this work; if not, write to the Free Software Foundation,
0019         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020         *
0021         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022         * CA 95054 USA or visit www.sun.com if you need additional information or
0023         * have any questions.
0024         */
0025        package javax.swing;
0026
0027        import sun.swing.SwingUtilities2;
0028        import sun.swing.UIAction;
0029
0030        import java.applet.*;
0031
0032        import java.awt.*;
0033        import java.awt.event.*;
0034        import java.awt.dnd.DropTarget;
0035
0036        import java.util.Vector;
0037        import java.util.Hashtable;
0038
0039        import java.lang.reflect.*;
0040
0041        import javax.accessibility.*;
0042        import javax.swing.event.MenuDragMouseEvent;
0043        import javax.swing.plaf.UIResource;
0044        import javax.swing.text.View;
0045        import java.security.AccessController;
0046        import sun.security.action.GetPropertyAction;
0047
0048        import sun.awt.AppContext;
0049
0050        /**
0051         * A collection of utility methods for Swing.
0052         *
0053         * @version 1.154 05/05/07
0054         * @author unknown
0055         */
0056        public class SwingUtilities implements  SwingConstants {
0057            // These states are system-wide, rather than AppContext wide.
0058            private static boolean canAccessEventQueue = false;
0059            private static boolean eventQueueTested = false;
0060
0061            /**
0062             * Indicates if we should change the drop target when a
0063             * {@code TransferHandler} is set.
0064             */
0065            private static boolean suppressDropSupport;
0066
0067            /**
0068             * Indiciates if we've checked the system property for suppressing
0069             * drop support.
0070             */
0071            private static boolean checkedSuppressDropSupport;
0072
0073            /**
0074             * Returns true if <code>setTransferHandler</code> should change the
0075             * <code>DropTarget</code>.
0076             */
0077            private static boolean getSuppressDropTarget() {
0078                if (!checkedSuppressDropSupport) {
0079                    suppressDropSupport = Boolean.valueOf(AccessController
0080                            .doPrivileged(new GetPropertyAction(
0081                                    "suppressSwingDropSupport")));
0082                    checkedSuppressDropSupport = true;
0083                }
0084                return suppressDropSupport;
0085            }
0086
0087            /**
0088             * Installs a {@code DropTarget} on the component as necessary for a
0089             * {@code TransferHandler} change.
0090             */
0091            static void installSwingDropTargetAsNecessary(Component c,
0092                    TransferHandler t) {
0093
0094                if (!getSuppressDropTarget()) {
0095                    DropTarget dropHandler = c.getDropTarget();
0096                    if ((dropHandler == null)
0097                            || (dropHandler instanceof  UIResource)) {
0098                        if (t == null) {
0099                            c.setDropTarget(null);
0100                        } else if (!GraphicsEnvironment.isHeadless()) {
0101                            c
0102                                    .setDropTarget(new TransferHandler.SwingDropTarget(
0103                                            c));
0104                        }
0105                    }
0106                }
0107            }
0108
0109            /** 
0110             * Return true if <code>a</code> contains <code>b</code>
0111             */
0112            public static final boolean isRectangleContainingRectangle(
0113                    Rectangle a, Rectangle b) {
0114                if (b.x >= a.x && (b.x + b.width) <= (a.x + a.width)
0115                        && b.y >= a.y && (b.y + b.height) <= (a.y + a.height)) {
0116                    return true;
0117                }
0118                return false;
0119            }
0120
0121            /**
0122             * Return the rectangle (0,0,bounds.width,bounds.height) for the component <code>aComponent</code>
0123             */
0124            public static Rectangle getLocalBounds(Component aComponent) {
0125                Rectangle b = new Rectangle(aComponent.getBounds());
0126                b.x = b.y = 0;
0127                return b;
0128            }
0129
0130            /**
0131             * Returns the first <code>Window </code> ancestor of <code>c</code>, or
0132             * {@code null} if <code>c</code> is not contained inside a <code>Window</code>.
0133             *
0134             * @param c <code>Component</code> to get <code>Window</code> ancestor
0135             *        of.
0136             * @return the first <code>Window </code> ancestor of <code>c</code>, or
0137             *         {@code null} if <code>c</code> is not contained inside a
0138             *         <code>Window</code>.
0139             * @since 1.3
0140             */
0141            public static Window getWindowAncestor(Component c) {
0142                for (Container p = c.getParent(); p != null; p = p.getParent()) {
0143                    if (p instanceof  Window) {
0144                        return (Window) p;
0145                    }
0146                }
0147                return null;
0148            }
0149
0150            /**
0151             * Converts the location <code>x</code> <code>y</code> to the
0152             * parents coordinate system, returning the location.
0153             */
0154            static Point convertScreenLocationToParent(Container parent, int x,
0155                    int y) {
0156                for (Container p = parent; p != null; p = p.getParent()) {
0157                    if (p instanceof  Window) {
0158                        Point point = new Point(x, y);
0159
0160                        SwingUtilities.convertPointFromScreen(point, parent);
0161                        return point;
0162                    }
0163                }
0164                throw new Error(
0165                        "convertScreenLocationToParent: no window ancestor");
0166            }
0167
0168            /**
0169             * Convert a <code>aPoint</code> in <code>source</code> coordinate system to
0170             * <code>destination</code> coordinate system.
0171             * If <code>source</code> is {@code null}, <code>aPoint</code> is assumed to be in <code>destination</code>'s
0172             * root component coordinate system.
0173             * If <code>destination</code> is {@code null}, <code>aPoint</code> will be converted to <code>source</code>'s
0174             * root component coordinate system.
0175             * If both <code>source</code> and <code>destination</code> are {@code null}, return <code>aPoint</code>
0176             * without any conversion.
0177             */
0178            public static Point convertPoint(Component source, Point aPoint,
0179                    Component destination) {
0180                Point p;
0181
0182                if (source == null && destination == null)
0183                    return aPoint;
0184                if (source == null) {
0185                    source = getWindowAncestor(destination);
0186                    if (source == null)
0187                        throw new Error(
0188                                "Source component not connected to component tree hierarchy");
0189                }
0190                p = new Point(aPoint);
0191                convertPointToScreen(p, source);
0192                if (destination == null) {
0193                    destination = getWindowAncestor(source);
0194                    if (destination == null)
0195                        throw new Error(
0196                                "Destination component not connected to component tree hierarchy");
0197                }
0198                convertPointFromScreen(p, destination);
0199                return p;
0200            }
0201
0202            /**
0203             * Convert the point <code>(x,y)</code> in <code>source</code> coordinate system to
0204             * <code>destination</code> coordinate system.
0205             * If <code>source</code> is {@code null}, <code>(x,y)</code> is assumed to be in <code>destination</code>'s
0206             * root component coordinate system.
0207             * If <code>destination</code> is {@code null}, <code>(x,y)</code> will be converted to <code>source</code>'s
0208             * root component coordinate system.
0209             * If both <code>source</code> and <code>destination</code> are {@code null}, return <code>(x,y)</code>
0210             * without any conversion.
0211             */
0212            public static Point convertPoint(Component source, int x, int y,
0213                    Component destination) {
0214                Point point = new Point(x, y);
0215                return convertPoint(source, point, destination);
0216            }
0217
0218            /** 
0219             * Convert the rectangle <code>aRectangle</code> in <code>source</code> coordinate system to
0220             * <code>destination</code> coordinate system.
0221             * If <code>source</code> is {@code null}, <code>aRectangle</code> is assumed to be in <code>destination</code>'s
0222             * root component coordinate system.
0223             * If <code>destination</code> is {@code null}, <code>aRectangle</code> will be converted to <code>source</code>'s
0224             * root component coordinate system.
0225             * If both <code>source</code> and <code>destination</code> are {@code null}, return <code>aRectangle</code>
0226             * without any conversion.
0227             */
0228            public static Rectangle convertRectangle(Component source,
0229                    Rectangle aRectangle, Component destination) {
0230                Point point = new Point(aRectangle.x, aRectangle.y);
0231                point = convertPoint(source, point, destination);
0232                return new Rectangle(point.x, point.y, aRectangle.width,
0233                        aRectangle.height);
0234            }
0235
0236            /**
0237             * Convenience method for searching above <code>comp</code> in the
0238             * component hierarchy and returns the first object of class <code>c</code> it
0239             * finds. Can return {@code null}, if a class <code>c</code> cannot be found.
0240             */
0241            public static Container getAncestorOfClass(Class<?> c,
0242                    Component comp) {
0243                if (comp == null || c == null)
0244                    return null;
0245
0246                Container parent = comp.getParent();
0247                while (parent != null && !(c.isInstance(parent)))
0248                    parent = parent.getParent();
0249                return parent;
0250            }
0251
0252            /**
0253             * Convenience method for searching above <code>comp</code> in the
0254             * component hierarchy and returns the first object of <code>name</code> it
0255             * finds. Can return {@code null}, if <code>name</code> cannot be found.
0256             */
0257            public static Container getAncestorNamed(String name, Component comp) {
0258                if (comp == null || name == null)
0259                    return null;
0260
0261                Container parent = comp.getParent();
0262                while (parent != null && !(name.equals(parent.getName())))
0263                    parent = parent.getParent();
0264                return parent;
0265            }
0266
0267            /**
0268             * Returns the deepest visible descendent Component of <code>parent</code> 
0269             * that contains the location <code>x</code>, <code>y</code>. 
0270             * If <code>parent</code> does not contain the specified location,
0271             * then <code>null</code> is returned.  If <code>parent</code> is not a 
0272             * container, or none of <code>parent</code>'s visible descendents 
0273             * contain the specified location, <code>parent</code> is returned.
0274             *
0275             * @param parent the root component to begin the search
0276             * @param x the x target location 
0277             * @param y the y target location  
0278             */
0279            public static Component getDeepestComponentAt(Component parent,
0280                    int x, int y) {
0281                if (!parent.contains(x, y)) {
0282                    return null;
0283                }
0284                if (parent instanceof  Container) {
0285                    Component components[] = ((Container) parent)
0286                            .getComponents();
0287                    for (int i = 0; i < components.length; i++) {
0288                        Component comp = components[i];
0289                        if (comp != null && comp.isVisible()) {
0290                            Point loc = comp.getLocation();
0291                            if (comp instanceof  Container) {
0292                                comp = getDeepestComponentAt(comp, x - loc.x, y
0293                                        - loc.y);
0294                            } else {
0295                                comp = comp
0296                                        .getComponentAt(x - loc.x, y - loc.y);
0297                            }
0298                            if (comp != null && comp.isVisible()) {
0299                                return comp;
0300                            }
0301                        }
0302                    }
0303                }
0304                return parent;
0305            }
0306
0307            /** 
0308             * Returns a MouseEvent similar to <code>sourceEvent</code> except that its x
0309             * and y members have been converted to <code>destination</code>'s coordinate
0310             * system.  If <code>source</code> is {@code null}, <code>sourceEvent</code> x and y members
0311             * are assumed to be into <code>destination</code>'s root component coordinate system.
0312             * If <code>destination</code> is <code>null</code>, the
0313             * returned MouseEvent will be in <code>source</code>'s coordinate system.
0314             * <code>sourceEvent</code> will not be changed. A new event is returned.
0315             * the <code>source</code> field of the returned event will be set
0316             * to <code>destination</code> if destination is non-{@code null}
0317             * use the translateMouseEvent() method to translate a mouse event from
0318             * one component to another without changing the source.
0319             */
0320            public static MouseEvent convertMouseEvent(Component source,
0321                    MouseEvent sourceEvent, Component destination) {
0322                Point p = convertPoint(source, new Point(sourceEvent.getX(),
0323                        sourceEvent.getY()), destination);
0324                Component newSource;
0325
0326                if (destination != null)
0327                    newSource = destination;
0328                else
0329                    newSource = source;
0330
0331                MouseEvent newEvent;
0332                if (sourceEvent instanceof  MouseWheelEvent) {
0333                    MouseWheelEvent sourceWheelEvent = (MouseWheelEvent) sourceEvent;
0334                    newEvent = new MouseWheelEvent(newSource, sourceWheelEvent
0335                            .getID(), sourceWheelEvent.getWhen(),
0336                            sourceWheelEvent.getModifiers(), p.x, p.y,
0337                            sourceWheelEvent.getXOnScreen(), sourceWheelEvent
0338                                    .getYOnScreen(), sourceWheelEvent
0339                                    .getClickCount(), sourceWheelEvent
0340                                    .isPopupTrigger(), sourceWheelEvent
0341                                    .getScrollType(), sourceWheelEvent
0342                                    .getScrollAmount(), sourceWheelEvent
0343                                    .getWheelRotation());
0344                } else if (sourceEvent instanceof  MenuDragMouseEvent) {
0345                    MenuDragMouseEvent sourceMenuDragEvent = (MenuDragMouseEvent) sourceEvent;
0346                    newEvent = new MenuDragMouseEvent(newSource,
0347                            sourceMenuDragEvent.getID(), sourceMenuDragEvent
0348                                    .getWhen(), sourceMenuDragEvent
0349                                    .getModifiers(), p.x, p.y,
0350                            sourceMenuDragEvent.getXOnScreen(),
0351                            sourceMenuDragEvent.getYOnScreen(),
0352                            sourceMenuDragEvent.getClickCount(),
0353                            sourceMenuDragEvent.isPopupTrigger(),
0354                            sourceMenuDragEvent.getPath(), sourceMenuDragEvent
0355                                    .getMenuSelectionManager());
0356                } else {
0357                    newEvent = new MouseEvent(newSource, sourceEvent.getID(),
0358                            sourceEvent.getWhen(), sourceEvent.getModifiers(),
0359                            p.x, p.y, sourceEvent.getXOnScreen(), sourceEvent
0360                                    .getYOnScreen(), sourceEvent
0361                                    .getClickCount(), sourceEvent
0362                                    .isPopupTrigger(), MouseEvent.NOBUTTON);
0363                }
0364                return newEvent;
0365            }
0366
0367            /**
0368             * Convert a point from a component's coordinate system to
0369             * screen coordinates.
0370             *
0371             * @param p  a Point object (converted to the new coordinate system)
0372             * @param c  a Component object
0373             */
0374            public static void convertPointToScreen(Point p, Component c) {
0375                Rectangle b;
0376                int x, y;
0377
0378                do {
0379                    if (c instanceof  JComponent) {
0380                        x = ((JComponent) c).getX();
0381                        y = ((JComponent) c).getY();
0382                    } else if (c instanceof  java.applet.Applet
0383                            || c instanceof  java.awt.Window) {
0384                        try {
0385                            Point pp = c.getLocationOnScreen();
0386                            x = pp.x;
0387                            y = pp.y;
0388                        } catch (IllegalComponentStateException icse) {
0389                            x = c.getX();
0390                            y = c.getY();
0391                        }
0392                    } else {
0393                        x = c.getX();
0394                        y = c.getY();
0395                    }
0396
0397                    p.x += x;
0398                    p.y += y;
0399
0400                    if (c instanceof  java.awt.Window
0401                            || c instanceof  java.applet.Applet)
0402                        break;
0403                    c = c.getParent();
0404                } while (c != null);
0405            }
0406
0407            /**
0408             * Convert a point from a screen coordinates to a component's 
0409             * coordinate system
0410             *
0411             * @param p  a Point object (converted to the new coordinate system)
0412             * @param c  a Component object
0413             */
0414            public static void convertPointFromScreen(Point p, Component c) {
0415                Rectangle b;
0416                int x, y;
0417
0418                do {
0419                    if (c instanceof  JComponent) {
0420                        x = ((JComponent) c).getX();
0421                        y = ((JComponent) c).getY();
0422                    } else if (c instanceof  java.applet.Applet
0423                            || c instanceof  java.awt.Window) {
0424                        try {
0425                            Point pp = c.getLocationOnScreen();
0426                            x = pp.x;
0427                            y = pp.y;
0428                        } catch (IllegalComponentStateException icse) {
0429                            x = c.getX();
0430                            y = c.getY();
0431                        }
0432                    } else {
0433                        x = c.getX();
0434                        y = c.getY();
0435                    }
0436
0437                    p.x -= x;
0438                    p.y -= y;
0439
0440                    if (c instanceof  java.awt.Window
0441                            || c instanceof  java.applet.Applet)
0442                        break;
0443                    c = c.getParent();
0444                } while (c != null);
0445            }
0446
0447            /**
0448             * Returns the first <code>Window </code> ancestor of <code>c</code>, or
0449             * {@code null} if <code>c</code> is not contained inside a <code>Window</code>.
0450             * <p>
0451             * Note: This method provides the same functionality as
0452             * <code>getWindowAncestor</code>.
0453             *
0454             * @param c <code>Component</code> to get <code>Window</code> ancestor
0455             *        of.
0456             * @return the first <code>Window </code> ancestor of <code>c</code>, or
0457             *         {@code null} if <code>c</code> is not contained inside a
0458             *         <code>Window</code>.
0459             */
0460            public static Window windowForComponent(Component c) {
0461                return getWindowAncestor(c);
0462            }
0463
0464            /**
0465             * Return <code>true</code> if a component <code>a</code> descends from a component <code>b</code>
0466             */
0467            public static boolean isDescendingFrom(Component a, Component b) {
0468                if (a == b)
0469                    return true;
0470                for (Container p = a.getParent(); p != null; p = p.getParent())
0471                    if (p == b)
0472                        return true;
0473                return false;
0474            }
0475
0476            /**
0477             * Convenience to calculate the intersection of two rectangles
0478             * without allocating a new rectangle.
0479             * If the two rectangles don't intersect, 
0480             * then the returned rectangle begins at (0,0)
0481             * and has zero width and height.
0482             *
0483             * @param x       the X coordinate of the first rectangle's top-left point
0484             * @param y       the Y coordinate of the first rectangle's top-left point
0485             * @param width   the width of the first rectangle
0486             * @param height  the height of the first rectangle
0487             * @param dest    the second rectangle
0488             *
0489             * @return <code>dest</code>, modified to specify the intersection
0490             */
0491            public static Rectangle computeIntersection(int x, int y,
0492                    int width, int height, Rectangle dest) {
0493                int x1 = (x > dest.x) ? x : dest.x;
0494                int x2 = ((x + width) < (dest.x + dest.width)) ? (x + width)
0495                        : (dest.x + dest.width);
0496                int y1 = (y > dest.y) ? y : dest.y;
0497                int y2 = ((y + height) < (dest.y + dest.height) ? (y + height)
0498                        : (dest.y + dest.height));
0499
0500                dest.x = x1;
0501                dest.y = y1;
0502                dest.width = x2 - x1;
0503                dest.height = y2 - y1;
0504
0505                // If rectangles don't intersect, return zero'd intersection.
0506                if (dest.width < 0 || dest.height < 0) {
0507                    dest.x = dest.y = dest.width = dest.height = 0;
0508                }
0509
0510                return dest;
0511            }
0512
0513            /**
0514             * Convenience method that calculates the union of two rectangles
0515             * without allocating a new rectangle.
0516             *
0517             * @param x the x-coordinate of the first rectangle
0518             * @param y the y-coordinate of the first rectangle
0519             * @param width the width of the first rectangle
0520             * @param height the height of the first rectangle
0521             * @param dest  the coordinates of the second rectangle; the union
0522             *    of the two rectangles is returned in this rectangle
0523             * @return the <code>dest</code> <code>Rectangle</code>
0524             */
0525            public static Rectangle computeUnion(int x, int y, int width,
0526                    int height, Rectangle dest) {
0527                int x1 = (x < dest.x) ? x : dest.x;
0528                int x2 = ((x + width) > (dest.x + dest.width)) ? (x + width)
0529                        : (dest.x + dest.width);
0530                int y1 = (y < dest.y) ? y : dest.y;
0531                int y2 = ((y + height) > (dest.y + dest.height)) ? (y + height)
0532                        : (dest.y + dest.height);
0533
0534                dest.x = x1;
0535                dest.y = y1;
0536                dest.width = (x2 - x1);
0537                dest.height = (y2 - y1);
0538                return dest;
0539            }
0540
0541            /**
0542             * Convenience returning an array of rect representing the regions within
0543             * <code>rectA</code> that do not overlap with <code>rectB</code>. If the
0544             * two Rects do not overlap, returns an empty array
0545             */
0546            public static Rectangle[] computeDifference(Rectangle rectA,
0547                    Rectangle rectB) {
0548                if (rectB == null || !rectA.intersects(rectB)
0549                        || isRectangleContainingRectangle(rectB, rectA)) {
0550                    return new Rectangle[0];
0551                }
0552
0553                Rectangle t = new Rectangle();
0554                Rectangle a = null, b = null, c = null, d = null;
0555                Rectangle result[];
0556                int rectCount = 0;
0557
0558                /* rectA contains rectB */
0559                if (isRectangleContainingRectangle(rectA, rectB)) {
0560                    t.x = rectA.x;
0561                    t.y = rectA.y;
0562                    t.width = rectB.x - rectA.x;
0563                    t.height = rectA.height;
0564                    if (t.width > 0 && t.height > 0) {
0565                        a = new Rectangle(t);
0566                        rectCount++;
0567                    }
0568
0569                    t.x = rectB.x;
0570                    t.y = rectA.y;
0571                    t.width = rectB.width;
0572                    t.height = rectB.y - rectA.y;
0573                    if (t.width > 0 && t.height > 0) {
0574                        b = new Rectangle(t);
0575                        rectCount++;
0576                    }
0577
0578                    t.x = rectB.x;
0579                    t.y = rectB.y + rectB.height;
0580                    t.width = rectB.width;
0581                    t.height = rectA.y + rectA.height
0582                            - (rectB.y + rectB.height);
0583                    if (t.width > 0 && t.height > 0) {
0584                        c = new Rectangle(t);
0585                        rectCount++;
0586                    }
0587
0588                    t.x = rectB.x + rectB.width;
0589                    t.y = rectA.y;
0590                    t.width = rectA.x + rectA.width - (rectB.x + rectB.width);
0591                    t.height = rectA.height;
0592                    if (t.width > 0 && t.height > 0) {
0593                        d = new Rectangle(t);
0594                        rectCount++;
0595                    }
0596                } else {
0597                    /* 1 */
0598                    if (rectB.x <= rectA.x && rectB.y <= rectA.y) {
0599                        if ((rectB.x + rectB.width) > (rectA.x + rectA.width)) {
0600
0601                            t.x = rectA.x;
0602                            t.y = rectB.y + rectB.height;
0603                            t.width = rectA.width;
0604                            t.height = rectA.y + rectA.height
0605                                    - (rectB.y + rectB.height);
0606                            if (t.width > 0 && t.height > 0) {
0607                                a = t;
0608                                rectCount++;
0609                            }
0610                        } else if ((rectB.y + rectB.height) > (rectA.y + rectA.height)) {
0611                            t.setBounds((rectB.x + rectB.width), rectA.y,
0612                                    (rectA.x + rectA.width)
0613                                            - (rectB.x + rectB.width),
0614                                    rectA.height);
0615                            if (t.width > 0 && t.height > 0) {
0616                                a = t;
0617                                rectCount++;
0618                            }
0619                        } else {
0620                            t.setBounds((rectB.x + rectB.width), rectA.y,
0621                                    (rectA.x + rectA.width)
0622                                            - (rectB.x + rectB.width),
0623                                    (rectB.y + rectB.height) - rectA.y);
0624                            if (t.width > 0 && t.height > 0) {
0625                                a = new Rectangle(t);
0626                                rectCount++;
0627                            }
0628
0629                            t.setBounds(rectA.x, (rectB.y + rectB.height),
0630                                    rectA.width, (rectA.y + rectA.height)
0631                                            - (rectB.y + rectB.height));
0632                            if (t.width > 0 && t.height > 0) {
0633                                b = new Rectangle(t);
0634                                rectCount++;
0635                            }
0636                        }
0637                    } else if (rectB.x <= rectA.x
0638                            && (rectB.y + rectB.height) >= (rectA.y + rectA.height)) {
0639                        if ((rectB.x + rectB.width) > (rectA.x + rectA.width)) {
0640                            t.setBounds(rectA.x, rectA.y, rectA.width, rectB.y
0641                                    - rectA.y);
0642                            if (t.width > 0 && t.height > 0) {
0643                                a = t;
0644                                rectCount++;
0645                            }
0646                        } else {
0647                            t.setBounds(rectA.x, rectA.y, rectA.width, rectB.y
0648                                    - rectA.y);
0649                            if (t.width > 0 && t.height > 0) {
0650                                a = new Rectangle(t);
0651                                rectCount++;
0652                            }
0653                            t.setBounds((rectB.x + rectB.width), rectB.y,
0654                                    (rectA.x + rectA.width)
0655                                            - (rectB.x + rectB.width),
0656                                    (rectA.y + rectA.height) - rectB.y);
0657                            if (t.width > 0 && t.height > 0) {
0658                                b = new Rectangle(t);
0659                                rectCount++;
0660                            }
0661                        }
0662                    } else if (rectB.x <= rectA.x) {
0663                        if ((rectB.x + rectB.width) >= (rectA.x + rectA.width)) {
0664                            t.setBounds(rectA.x, rectA.y, rectA.width, rectB.y
0665                                    - rectA.y);
0666                            if (t.width > 0 && t.height > 0) {
0667                                a = new Rectangle(t);
0668                                rectCount++;
0669                            }
0670
0671                            t.setBounds(rectA.x, (rectB.y + rectB.height),
0672                                    rectA.width, (rectA.y + rectA.height)
0673                                            - (rectB.y + rectB.height));
0674                            if (t.width > 0 && t.height > 0) {
0675                                b = new Rectangle(t);
0676                                rectCount++;
0677                            }
0678                        } else {
0679                            t.setBounds(rectA.x, rectA.y, rectA.width, rectB.y
0680                                    - rectA.y);
0681                            if (t.width > 0 && t.height > 0) {
0682                                a = new Rectangle(t);
0683                                rectCount++;
0684                            }
0685
0686                            t.setBounds((rectB.x + rectB.width), rectB.y,
0687                                    (rectA.x + rectA.width)
0688                                            - (rectB.x + rectB.width),
0689                                    rectB.height);
0690                            if (t.width > 0 && t.height > 0) {
0691                                b = new Rectangle(t);
0692                                rectCount++;
0693                            }
0694
0695                            t.setBounds(rectA.x, (rectB.y + rectB.height),
0696                                    rectA.width, (rectA.y + rectA.height)
0697                                            - (rectB.y + rectB.height));
0698                            if (t.width > 0 && t.height > 0) {
0699                                c = new Rectangle(t);
0700                                rectCount++;
0701                            }
0702                        }
0703                    } else if (rectB.x <= (rectA.x + rectA.width)
0704                            && (rectB.x + rectB.width) > (rectA.x + rectA.width)) {
0705                        if (rectB.y <= rectA.y
0706                                && (rectB.y + rectB.height) > (rectA.y + rectA.height)) {
0707                            t.setBounds(rectA.x, rectA.y, rectB.x - rectA.x,
0708                                    rectA.height);
0709                            if (t.width > 0 && t.height > 0) {
0710                                a = t;
0711                                rectCount++;
0712                            }
0713                        } else if (rectB.y <= rectA.y) {
0714                            t.setBounds(rectA.x, rectA.y, rectB.x - rectA.x,
0715                                    (rectB.y + rectB.height) - rectA.y);
0716                            if (t.width > 0 && t.height > 0) {
0717                                a = new Rectangle(t);
0718                                rectCount++;
0719                            }
0720
0721                            t.setBounds(rectA.x, (rectB.y + rectB.height),
0722                                    rectA.width, (rectA.y + rectA.height)
0723                                            - (rectB.y + rectB.height));
0724                            if (t.width > 0 && t.height > 0) {
0725                                b = new Rectangle(t);
0726                                rectCount++;
0727                            }
0728                        } else if ((rectB.y + rectB.height) > (rectA.y + rectA.height)) {
0729                            t.setBounds(rectA.x, rectA.y, rectA.width, rectB.y
0730                                    - rectA.y);
0731                            if (t.width > 0 && t.height > 0) {
0732                                a = new Rectangle(t);
0733                                rectCount++;
0734                            }
0735
0736                            t.setBounds(rectA.x, rectB.y, rectB.x - rectA.x,
0737                                    (rectA.y + rectA.height) - rectB.y);
0738                            if (t.width > 0 && t.height > 0) {
0739                                b = new Rectangle(t);
0740                                rectCount++;
0741                            }
0742                        } else {
0743                            t.setBounds(rectA.x, rectA.y, rectA.width, rectB.y
0744                                    - rectA.y);
0745                            if (t.width > 0 && t.height > 0) {
0746                                a = new Rectangle(t);
0747                                rectCount++;
0748                            }
0749
0750                            t.setBounds(rectA.x, rectB.y, rectB.x - rectA.x,
0751                                    rectB.height);
0752                            if (t.width > 0 && t.height > 0) {
0753                                b = new Rectangle(t);
0754                                rectCount++;
0755                            }
0756
0757                            t.setBounds(rectA.x, (rectB.y + rectB.height),
0758                                    rectA.width, (rectA.y + rectA.height)
0759                                            - (rectB.y + rectB.height));
0760                            if (t.width > 0 && t.height > 0) {
0761                                c = new Rectangle(t);
0762                                rectCount++;
0763                            }
0764                        }
0765                    } else if (rectB.x >= rectA.x
0766                            && (rectB.x + rectB.width) <= (rectA.x + rectA.width)) {
0767                        if (rectB.y <= rectA.y
0768                                && (rectB.y + rectB.height) > (rectA.y + rectA.height)) {
0769                            t.setBounds(rectA.x, rectA.y, rectB.x - rectA.x,
0770                                    rectA.height);
0771                            if (t.width > 0 && t.height > 0) {
0772                                a = new Rectangle(t);
0773                                rectCount++;
0774                            }
0775                            t.setBounds((rectB.x + rectB.width), rectA.y,
0776                                    (rectA.x + rectA.width)
0777                                            - (rectB.x + rectB.width),
0778                                    rectA.height);
0779                            if (t.width > 0 && t.height > 0) {
0780                                b = new Rectangle(t);
0781                                rectCount++;
0782                            }
0783                        } else if (rectB.y <= rectA.y) {
0784                            t.setBounds(rectA.x, rectA.y, rectB.x - rectA.x,
0785                                    rectA.height);
0786                            if (t.width > 0 && t.height > 0) {
0787                                a = new Rectangle(t);
0788                                rectCount++;
0789                            }
0790
0791                            t.setBounds(rectB.x, (rectB.y + rectB.height),
0792                                    rectB.width, (rectA.y + rectA.height)
0793                                            - (rectB.y + rectB.height));
0794                            if (t.width > 0 && t.height > 0) {
0795                                b = new Rectangle(t);
0796                                rectCount++;
0797                            }
0798
0799                            t.setBounds((rectB.x + rectB.width), rectA.y,
0800                                    (rectA.x + rectA.width)
0801                                            - (rectB.x + rectB.width),
0802                                    rectA.height);
0803                            if (t.width > 0 && t.height > 0) {
0804                                c = new Rectangle(t);
0805                                rectCount++;
0806                            }
0807                        } else {
0808                            t.setBounds(rectA.x, rectA.y, rectB.x - rectA.x,
0809                                    rectA.height);
0810                            if (t.width > 0 && t.height > 0) {
0811                                a = new Rectangle(t);
0812                                rectCount++;
0813                            }
0814
0815                            t.setBounds(rectB.x, rectA.y, rectB.width, rectB.y
0816                                    - rectA.y);
0817                            if (t.width > 0 && t.height > 0) {
0818                                b = new Rectangle(t);
0819                                rectCount++;
0820                            }
0821
0822                            t.setBounds((rectB.x + rectB.width), rectA.y,
0823                                    (rectA.x + rectA.width)
0824                                            - (rectB.x + rectB.width),
0825                                    rectA.height);
0826                            if (t.width > 0 && t.height > 0) {
0827                                c = new Rectangle(t);
0828                                rectCount++;
0829                            }
0830                        }
0831                    }
0832                }
0833
0834                result = new Rectangle[rectCount];
0835                rectCount = 0;
0836                if (a != null)
0837                    result[rectCount++] = a;
0838                if (b != null)
0839                    result[rectCount++] = b;
0840                if (c != null)
0841                    result[rectCount++] = c;
0842                if (d != null)
0843                    result[rectCount++] = d;
0844                return result;
0845            }
0846
0847            /**
0848             * Returns true if the mouse event specifies the left mouse button.
0849             *
0850             * @param anEvent  a MouseEvent object
0851             * @return true if the left mouse button was active
0852             */
0853            public static boolean isLeftMouseButton(MouseEvent anEvent) {
0854                return ((anEvent.getModifiers() & InputEvent.BUTTON1_MASK) != 0);
0855            }
0856
0857            /**
0858             * Returns true if the mouse event specifies the middle mouse button.
0859             *
0860             * @param anEvent  a MouseEvent object
0861             * @return true if the middle mouse button was active
0862             */
0863            public static boolean isMiddleMouseButton(MouseEvent anEvent) {
0864                return ((anEvent.getModifiers() & InputEvent.BUTTON2_MASK) == InputEvent.BUTTON2_MASK);
0865            }
0866
0867            /**
0868             * Returns true if the mouse event specifies the right mouse button.
0869             *
0870             * @param anEvent  a MouseEvent object
0871             * @return true if the right mouse button was active
0872             */
0873            public static boolean isRightMouseButton(MouseEvent anEvent) {
0874                return ((anEvent.getModifiers() & InputEvent.BUTTON3_MASK) == InputEvent.BUTTON3_MASK);
0875            }
0876
0877            /**
0878             * Compute the width of the string using a font with the specified
0879             * "metrics" (sizes).
0880             *
0881             * @param fm   a FontMetrics object to compute with
0882             * @param str  the String to compute
0883             * @return an int containing the string width
0884             */
0885            public static int computeStringWidth(FontMetrics fm, String str) {
0886                // You can't assume that a string's width is the sum of its
0887                // characters' widths in Java2D -- it may be smaller due to
0888                // kerning, etc.
0889                return SwingUtilities2.stringWidth(null, fm, str);
0890            }
0891
0892            /**
0893             * Compute and return the location of the icons origin, the
0894             * location of origin of the text baseline, and a possibly clipped
0895             * version of the compound labels string.  Locations are computed
0896             * relative to the viewR rectangle.
0897             * The JComponents orientation (LEADING/TRAILING) will also be taken
0898             * into account and translated into LEFT/RIGHT values accordingly.
0899             */
0900            public static String layoutCompoundLabel(JComponent c,
0901                    FontMetrics fm, String text, Icon icon,
0902                    int verticalAlignment, int horizontalAlignment,
0903                    int verticalTextPosition, int horizontalTextPosition,
0904                    Rectangle viewR, Rectangle iconR, Rectangle textR,
0905                    int textIconGap) {
0906                boolean orientationIsLeftToRight = true;
0907                int hAlign = horizontalAlignment;
0908                int hTextPos = horizontalTextPosition;
0909
0910                if (c != null) {
0911                    if (!(c.getComponentOrientation().isLeftToRight())) {
0912                        orientationIsLeftToRight = false;
0913                    }
0914                }
0915
0916                // Translate LEADING/TRAILING values in horizontalAlignment
0917                // to LEFT/RIGHT values depending on the components orientation
0918                switch (horizontalAlignment) {
0919                case LEADING:
0920                    hAlign = (orientationIsLeftToRight) ? LEFT : RIGHT;
0921                    break;
0922                case TRAILING:
0923                    hAlign = (orientationIsLeftToRight) ? RIGHT : LEFT;
0924                    break;
0925                }
0926
0927                // Translate LEADING/TRAILING values in horizontalTextPosition
0928                // to LEFT/RIGHT values depending on the components orientation
0929                switch (horizontalTextPosition) {
0930                case LEADING:
0931                    hTextPos = (orientationIsLeftToRight) ? LEFT : RIGHT;
0932                    break;
0933                case TRAILING:
0934                    hTextPos = (orientationIsLeftToRight) ? RIGHT : LEFT;
0935                    break;
0936                }
0937
0938                return layoutCompoundLabelImpl(c, fm, text, icon,
0939                        verticalAlignment, hAlign, verticalTextPosition,
0940                        hTextPos, viewR, iconR, textR, textIconGap);
0941            }
0942
0943            /**
0944             * Compute and return the location of the icons origin, the
0945             * location of origin of the text baseline, and a possibly clipped
0946             * version of the compound labels string.  Locations are computed
0947             * relative to the viewR rectangle.
0948             * This layoutCompoundLabel() does not know how to handle LEADING/TRAILING
0949             * values in horizontalTextPosition (they will default to RIGHT) and in
0950             * horizontalAlignment (they will default to CENTER).
0951             * Use the other version of layoutCompoundLabel() instead.
0952             */
0953            public static String layoutCompoundLabel(FontMetrics fm,
0954                    String text, Icon icon, int verticalAlignment,
0955                    int horizontalAlignment, int verticalTextPosition,
0956                    int horizontalTextPosition, Rectangle viewR,
0957                    Rectangle iconR, Rectangle textR, int textIconGap) {
0958                return layoutCompoundLabelImpl(null, fm, text, icon,
0959                        verticalAlignment, horizontalAlignment,
0960                        verticalTextPosition, horizontalTextPosition, viewR,
0961                        iconR, textR, textIconGap);
0962            }
0963
0964            /**
0965             * Compute and return the location of the icons origin, the
0966             * location of origin of the text baseline, and a possibly clipped
0967             * version of the compound labels string.  Locations are computed
0968             * relative to the viewR rectangle.
0969             * This layoutCompoundLabel() does not know how to handle LEADING/TRAILING
0970             * values in horizontalTextPosition (they will default to RIGHT) and in
0971             * horizontalAlignment (they will default to CENTER).
0972             * Use the other version of layoutCompoundLabel() instead.
0973             */
0974            private static String layoutCompoundLabelImpl(JComponent c,
0975                    FontMetrics fm, String text, Icon icon,
0976                    int verticalAlignment, int horizontalAlignment,
0977                    int verticalTextPosition, int horizontalTextPosition,
0978                    Rectangle viewR, Rectangle iconR, Rectangle textR,
0979                    int textIconGap) {
0980                /* Initialize the icon bounds rectangle iconR.
0981                 */
0982
0983                if (icon != null) {
0984                    iconR.width = icon.getIconWidth();
0985                    iconR.height = icon.getIconHeight();
0986                } else {
0987                    iconR.width = iconR.height = 0;
0988                }
0989
0990                /* Initialize the text bounds rectangle textR.  If a null
0991                 * or and empty String was specified we substitute "" here
0992                 * and use 0,0,0,0 for textR.
0993                 */
0994
0995                boolean textIsEmpty = (text == null) || text.equals("");
0996                int lsb = 0;
0997                /* Unless both text and icon are non-null, we effectively ignore
0998                 * the value of textIconGap.
0999                 */
1000                int gap;
1001
1002                View v = null;
1003                if (textIsEmpty) {
1004                    textR.width = textR.height = 0;
1005                    text = "";
1006                    gap = 0;
1007                } else {
1008                    int availTextWidth;
1009                    gap = (icon == null) ? 0 : textIconGap;
1010
1011                    if (horizontalTextPosition == CENTER) {
1012                        availTextWidth = viewR.width;
1013                    } else {
1014                        availTextWidth = viewR.width - (iconR.width + gap);
1015                    }
1016                    v = (c != null) ? (View) c.getClientProperty("html") : null;
1017                    if (v != null) {
1018                        textR.width = Math.min(availTextWidth, (int) v
1019                                .getPreferredSpan(View.X_AXIS));
1020                        textR.height = (int) v.getPreferredSpan(View.Y_AXIS);
1021                    } else {
1022                        textR.width = SwingUtilities2.stringWidth(c, fm, text);
1023
1024                        // Take into account the left and right side bearings. 
1025                        // This gives more space than it is actually needed,
1026                        // but there are two reasons:
1027                        // 1. If we set the width to the actual bounds, 
1028                        //    all callers would have to account for the bearings
1029                        //    themselves. NOTE: all pref size calculations don't do it. 
1030                        // 2. You can do a drawString at the returned location
1031                        //    and the text won't be clipped.
1032                        lsb = SwingUtilities2.getLeftSideBearing(c, fm, text);
1033                        if (lsb < 0) {
1034                            textR.width -= lsb;
1035                        }
1036                        int rsb = SwingUtilities2.getRightSideBearing(c, fm,
1037                                text);
1038                        if (rsb > 0) {
1039                            textR.width += rsb;
1040                        }
1041
1042                        if (textR.width > availTextWidth) {
1043                            text = SwingUtilities2.clipString(c, fm, text,
1044                                    availTextWidth);
1045                            textR.width = SwingUtilities2.stringWidth(c, fm,
1046                                    text);
1047                        }
1048                        textR.height = fm.getHeight();
1049                    }
1050                }
1051
1052                /* Compute textR.x,y given the verticalTextPosition and
1053                 * horizontalTextPosition properties
1054                 */
1055
1056                if (verticalTextPosition == TOP) {
1057                    if (horizontalTextPosition != CENTER) {
1058                        textR.y = 0;
1059                    } else {
1060                        textR.y = -(textR.height + gap);
1061                    }
1062                } else if (verticalTextPosition == CENTER) {
1063                    textR.y = (iconR.height / 2) - (textR.height / 2);
1064                } else { // (verticalTextPosition == BOTTOM)
1065                    if (horizontalTextPosition != CENTER) {
1066                        textR.y = iconR.height - textR.height;
1067                    } else {
1068                        textR.y = (iconR.height + gap);
1069                    }
1070                }
1071
1072                if (horizontalTextPosition == LEFT) {
1073                    textR.x = -(textR.width + gap);
1074                } else if (horizontalTextPosition == CENTER) {
1075                    textR.x = (iconR.width / 2) - (textR.width / 2);
1076                } else { // (horizontalTextPosition == RIGHT)
1077                    textR.x = (iconR.width + gap);
1078                }
1079
1080                // WARNING: DefaultTreeCellEditor uses a shortened version of
1081                // this algorithm to position it's Icon. If you change how this
1082                // is calculated, be sure and update DefaultTreeCellEditor too.
1083
1084                /* labelR is the rectangle that contains iconR and textR.
1085                 * Move it to its proper position given the labelAlignment
1086                 * properties.
1087                 *
1088                 * To avoid actually allocating a Rectangle, Rectangle.union
1089                 * has been inlined below.
1090                 */
1091                int labelR_x = Math.min(iconR.x, textR.x);
1092                int labelR_width = Math.max(iconR.x + iconR.width, textR.x
1093                        + textR.width)
1094                        - labelR_x;
1095                int labelR_y = Math.min(iconR.y, textR.y);
1096                int labelR_height = Math.max(iconR.y + iconR.height, textR.y
1097                        + textR.height)
1098                        - labelR_y;
1099
1100                int dx, dy;
1101
1102                if (verticalAlignment == TOP) {
1103                    dy = viewR.y - labelR_y;
1104                } else if (verticalAlignment == CENTER) {
1105                    dy = (viewR.y + (viewR.height / 2))
1106                            - (labelR_y + (labelR_height / 2));
1107                } else { // (verticalAlignment == BOTTOM)
1108                    dy = (viewR.y + viewR.height) - (labelR_y + labelR_height);
1109                }
1110
1111                if (horizontalAlignment == LEFT) {
1112                    dx = viewR.x - labelR_x;
1113                } else if (horizontalAlignment == RIGHT) {
1114                    dx = (viewR.x + viewR.width) - (labelR_x + labelR_width);
1115                } else { // (horizontalAlignment == CENTER)
1116                    dx = (viewR.x + (viewR.width / 2))
1117                            - (labelR_x + (labelR_width / 2));
1118                }
1119
1120                /* Translate textR and glypyR by dx,dy.
1121                 */
1122
1123                textR.x += dx;
1124                textR.y += dy;
1125
1126                iconR.x += dx;
1127                iconR.y += dy;
1128
1129                if (lsb < 0) {
1130                    // lsb is negative. Shift the x location so that the text is
1131                    // visually drawn at the right location.
1132                    textR.x -= lsb;
1133                }
1134
1135                return text;
1136            }
1137
1138            /**
1139             * Paints a component to the specified <code>Graphics</code>.
1140             * This method is primarily useful to render
1141             * <code>Component</code>s that don't exist as part of the visible
1142             * containment hierarchy, but are used for rendering.  For
1143             * example, if you are doing your own rendering and want to render
1144             * some text (or even HTML), you could make use of
1145             * <code>JLabel</code>'s text rendering support and have it paint
1146             * directly by way of this method, without adding the label to the
1147             * visible containment hierarchy.
1148             * <p>
1149             * This method makes use of <code>CellRendererPane</code> to handle
1150             * the actual painting, and is only recommended if you use one
1151             * component for rendering.  If you make use of multiple components
1152             * to handle the rendering, as <code>JTable</code> does, use
1153             * <code>CellRendererPane</code> directly.  Otherwise, as described
1154             * below, you could end up with a <code>CellRendererPane</code>
1155             * per <code>Component</code>.
1156             * <p>
1157             * If <code>c</code>'s parent is not a <code>CellRendererPane</code>, 
1158             * a new <code>CellRendererPane</code> is created, <code>c</code> is
1159             * added to it, and the <code>CellRendererPane</code> is added to
1160             * <code>p</code>.  If <code>c</code>'s parent is a
1161             * <code>CellRendererPane</code> and the <code>CellRendererPane</code>s
1162             * parent is not <code>p</code>, it is added to <code>p</code>.
1163             * <p>
1164             * The component should either descend from <code>JComponent</code>
1165             * or be another kind of lightweight component.
1166             * A lightweight component is one whose "lightweight" property
1167             * (returned by the <code>Component</code>
1168             * <code>isLightweight</code> method)
1169             * is true. If the Component is not lightweight, bad things map happen:
1170             * crashes, exceptions, painting problems...
1171             *
1172             * @param g  the <code>Graphics</code> object to draw on
1173             * @param c  the <code>Component</code> to draw
1174             * @param p  the intermediate <code>Container</code>
1175             * @param x  an int specifying the left side of the area draw in, in pixels,
1176             *           measured from the left edge of the graphics context
1177             * @param y  an int specifying the top of the area to draw in, in pixels
1178             *           measured down from the top edge of the graphics context
1179             * @param w  an int specifying the width of the area draw in, in pixels
1180             * @param h  an int specifying the height of the area draw in, in pixels
1181             * 
1182             * @see CellRendererPane
1183             * @see java.awt.Component#isLightweight
1184             */
1185            public static void paintComponent(Graphics g, Component c,
1186                    Container p, int x, int y, int w, int h) {
1187                getCellRendererPane(c, p).paintComponent(g, c, p, x, y, w, h,
1188                        false);
1189            }
1190
1191            /**
1192             * Paints a component to the specified <code>Graphics</code>.  This
1193             * is a cover method for
1194             * {@link #paintComponent(Graphics,Component,Container,int,int,int,int)}.
1195             * Refer to it for more information.
1196             *
1197             * @param g  the <code>Graphics</code> object to draw on
1198             * @param c  the <code>Component</code> to draw
1199             * @param p  the intermediate <code>Container</code>
1200             * @param r  the <code>Rectangle</code> to draw in
1201             * 
1202             * @see #paintComponent(Graphics,Component,Container,int,int,int,int)
1203             * @see CellRendererPane
1204             */
1205            public static void paintComponent(Graphics g, Component c,
1206                    Container p, Rectangle r) {
1207                paintComponent(g, c, p, r.x, r.y, r.width, r.height);
1208            }
1209
1210            /*
1211             * Ensures that cell renderer <code>c</code> has a 
1212             * <code>ComponentShell</code> parent and that
1213             * the shell's parent is p.
1214             */
1215            private static CellRendererPane getCellRendererPane(Component c,
1216                    Container p) {
1217                Container shell = c.getParent();
1218                if (shell instanceof  CellRendererPane) {
1219                    if (shell.getParent() != p) {
1220                        p.add(shell);
1221                    }
1222                } else {
1223                    shell = new CellRendererPane();
1224                    shell.add(c);
1225                    p.add(shell);
1226                }
1227                return (CellRendererPane) shell;
1228            }
1229
1230            /**
1231             * A simple minded look and feel change: ask each node in the tree
1232             * to <code>updateUI()</code> -- that is, to initialize its UI property
1233             * with the current look and feel.
1234             */
1235            public static void updateComponentTreeUI(Component c) {
1236                updateComponentTreeUI0(c);
1237                c.invalidate();
1238                c.validate();
1239                c.repaint();
1240            }
1241
1242            private static void updateComponentTreeUI0(Component c) {
1243                if (c instanceof  JComponent) {
1244                    JComponent jc = (JComponent) c;
1245                    jc.updateUI();
1246                    JPopupMenu jpm = jc.getComponentPopupMenu();
1247                    if (jpm != null) {
1248                        updateComponentTreeUI(jpm);
1249                    }
1250                }
1251                Component[] children = null;
1252                if (c instanceof  JMenu) {
1253                    children = ((JMenu) c).getMenuComponents();
1254                } else if (c instanceof  Container) {
1255                    children = ((Container) c).getComponents();
1256                }
1257                if (children != null) {
1258                    for (int i = 0; i < children.length; i++) {
1259                        updateComponentTreeUI0(children[i]);
1260                    }
1261                }
1262            }
1263
1264            /**
1265             * Causes <i>doRun.run()</i> to be executed asynchronously on the
1266             * AWT event dispatching thread.  This will happen after all
1267             * pending AWT events have been processed.  This method should
1268             * be used when an application thread needs to update the GUI.
1269             * In the following example the <code>invokeLater</code> call queues
1270             * the <code>Runnable</code> object <code>doHelloWorld</code>
1271             * on the event dispatching thread and
1272             * then prints a message.
1273             * <pre>
1274             * Runnable doHelloWorld = new Runnable() {
1275             *     public void run() {
1276             *         System.out.println("Hello World on " + Thread.currentThread());
1277             *     }
1278             * };
1279             *
1280             * SwingUtilities.invokeLater(doHelloWorld);
1281             * System.out.println("This might well be displayed before the other message.");
1282             * </pre>
1283             * If invokeLater is called from the event dispatching thread --
1284             * for example, from a JButton's ActionListener -- the <i>doRun.run()</i> will
1285             * still be deferred until all pending events have been processed.
1286             * Note that if the <i>doRun.run()</i> throws an uncaught exception
1287             * the event dispatching thread will unwind (not the current thread).
1288             * <p>
1289             * Additional documentation and examples for this method can be
1290             * found in
1291             * <A HREF="http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html">How to Use Threads</a>,
1292             * in <em>The Java Tutorial</em>.
1293             * <p>
1294             * As of 1.3 this method is just a cover for <code>java.awt.EventQueue.invokeLater()</code>.
1295             * <p>
1296             * Unlike the rest of Swing, this method can be invoked from any thread.
1297             * 
1298             * @see #invokeAndWait
1299             */
1300            public static void invokeLater(Runnable doRun) {
1301                EventQueue.invokeLater(doRun);
1302            }
1303
1304            /**
1305             * Causes <code>doRun.run()</code> to be executed synchronously on the
1306             * AWT event dispatching thread.  This call blocks until
1307             * all pending AWT events have been processed and (then)
1308             * <code>doRun.run()</code> returns. This method should
1309             * be used when an application thread needs to update the GUI.
1310             * It shouldn't be called from the event dispatching thread.
1311             * Here's an example that creates a new application thread
1312             * that uses <code>invokeAndWait</code> to print a string from the event
1313             * dispatching thread and then, when that's finished, print
1314             * a string from the application thread.
1315             * <pre>
1316             * final Runnable doHelloWorld = new Runnable() {
1317             *     public void run() {
1318             *         System.out.println("Hello World on " + Thread.currentThread());
1319             *     }
1320             * };
1321             *
1322             * Thread appThread = new Thread() {
1323             *     public void run() {
1324             *         try {
1325             *             SwingUtilities.invokeAndWait(doHelloWorld);
1326             *         }
1327             *         catch (Exception e) {
1328             *             e.printStackTrace();
1329             *         }
1330             *         System.out.println("Finished on " + Thread.currentThread());
1331             *     }
1332             * };
1333             * appThread.start();
1334             * </pre>
1335             * Note that if the <code>Runnable.run</code> method throws an
1336             * uncaught exception
1337             * (on the event dispatching thread) it's caught and rethrown, as
1338             * an <code>InvocationTargetException</code>, on the caller's thread.
1339             * <p>
1340             * Additional documentation and examples for this method can be
1341             * found in
1342             * <A HREF="http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html">How to Use Threads</a>,
1343             * in <em>The Java Tutorial</em>.
1344             * <p>
1345             * As of 1.3 this method is just a cover for
1346             * <code>java.awt.EventQueue.invokeAndWait()</code>.
1347             *
1348             * @exception  InterruptedException if we're interrupted while waiting for
1349             *             the event dispatching thread to finish excecuting
1350             *             <code>doRun.run()</code>
1351             * @exception  InvocationTargetException  if an exception is thrown
1352             *             while running <code>doRun</code>
1353             *
1354             * @see #invokeLater
1355             */
1356            public static void invokeAndWait(final Runnable doRun)
1357                    throws InterruptedException, InvocationTargetException {
1358                EventQueue.invokeAndWait(doRun);
1359            }
1360
1361            /**
1362             * Returns true if the current thread is an AWT event dispatching thread.
1363             * <p>
1364             * As of 1.3 this method is just a cover for 
1365             * <code>java.awt.EventQueue.isDispatchThread()</code>.
1366             * 
1367             * @return true if the current thread is an AWT event dispatching thread
1368             */
1369            public static boolean isEventDispatchThread() {
1370                return EventQueue.isDispatchThread();
1371            }
1372
1373            /*
1374             * --- Accessibility Support ---
1375             *
1376             */
1377
1378            /**
1379             * Get the index of this object in its accessible parent.<p>
1380             *
1381             * Note: as of the Java 2 platform v1.3, it is recommended that developers call
1382             * Component.AccessibleAWTComponent.getAccessibleIndexInParent() instead
1383             * of using this method.
1384             *
1385             * @return -1 of this object does not have an accessible parent.
1386             * Otherwise, the index of the child in its accessible parent.
1387             */
1388            public static int getAccessibleIndexInParent(Component c) {
1389                return c.getAccessibleContext().getAccessibleIndexInParent();
1390            }
1391
1392            /**
1393             * Returns the <code>Accessible</code> child contained at the
1394             * local coordinate <code>Point</code>, if one exists.
1395             * Otherwise returns <code>null</code>.
1396             *
1397             * @return the <code>Accessible</code> at the specified location,
1398             *    if it exists; otherwise <code>null</code>
1399             */
1400            public static Accessible getAccessibleAt(Component c, Point p) {
1401                if (c instanceof  Container) {
1402                    return c.getAccessibleContext().getAccessibleComponent()
1403                            .getAccessibleAt(p);
1404                } else if (c instanceof  Accessible) {
1405                    Accessible a = (Accessible) c;
1406                    if (a != null) {
1407                        AccessibleContext ac = a.getAccessibleContext();
1408                        if (ac != null) {
1409                            AccessibleComponent acmp;
1410                            Point location;
1411                            int nchildren = ac.getAccessibleChildrenCount();
1412                            for (int i = 0; i < nchildren; i++) {
1413                                a = ac.getAccessibleChild(i);
1414                                if ((a != null)) {
1415                                    ac = a.getAccessibleContext();
1416                                    if (ac != null) {
1417                                        acmp = ac.getAccessibleComponent();
1418                                        if ((acmp != null)
1419                                                && (acmp.isShowing())) {
1420                                            location = acmp.getLocation();
1421                                            Point np = new Point(p.x
1422                                                    - location.x, p.y
1423                                                    - location.y);
1424                                            if (acmp.contains(np)) {
1425                                                return a;
1426                                            }
1427                                        }
1428                                    }
1429                                }
1430                            }
1431                        }
1432                    }
1433                    return (Accessible) c;
1434                }
1435                return null;
1436            }
1437
1438            /**
1439             * Get the state of this object. <p>
1440             *
1441             * Note: as of the Java 2 platform v1.3, it is recommended that developers call
1442             * Component.AccessibleAWTComponent.getAccessibleIndexInParent() instead
1443             * of using this method.
1444             *
1445             * @return an instance of AccessibleStateSet containing the current state
1446             * set of the object
1447             * @see AccessibleState
1448             */
1449            public static AccessibleStateSet getAccessibleStateSet(Component c) {
1450                return c.getAccessibleContext().getAccessibleStateSet();
1451            }
1452
1453            /**
1454             * Returns the number of accessible children in the object.  If all
1455             * of the children of this object implement Accessible, than this
1456             * method should return the number of children of this object. <p>
1457             *
1458             * Note: as of the Java 2 platform v1.3, it is recommended that developers call
1459             * Component.AccessibleAWTComponent.getAccessibleIndexInParent() instead
1460             * of using this method.
1461             *
1462             * @return the number of accessible children in the object.
1463             */
1464            public static int getAccessibleChildrenCount(Component c) {
1465                return c.getAccessibleContext().getAccessibleChildrenCount();
1466            }
1467
1468            /**
1469             * Return the nth Accessible child of the object. <p>
1470             *
1471             * Note: as of the Java 2 platform v1.3, it is recommended that developers call
1472             * Component.AccessibleAWTComponent.getAccessibleIndexInParent() instead
1473             * of using this method.
1474             *
1475             * @param i zero-based index of child
1476             * @return the nth Accessible child of the object
1477             */
1478            public static Accessible getAccessibleChild(Component c, int i) {
1479                return c.getAccessibleContext().getAccessibleChild(i);
1480            }
1481
1482            /**
1483             * Return the child <code>Component</code> of the specified
1484             * <code>Component</code> that is the focus owner, if any.
1485             *
1486             * @param c the root of the <code>Component</code> hierarchy to
1487             *        search for the focus owner
1488             * @return the focus owner, or <code>null</code> if there is no focus
1489             *         owner, or if the focus owner is not <code>comp</code>, or a
1490             *         descendant of <code>comp</code>
1491             *
1492             * @see java.awt.KeyboardFocusManager#getFocusOwner
1493             * @deprecated As of 1.4, replaced by
1494             *   <code>KeyboardFocusManager.getFocusOwner()</code>.
1495             */
1496            @Deprecated
1497            public static Component findFocusOwner(Component c) {
1498                Component focusOwner = KeyboardFocusManager
1499                        .getCurrentKeyboardFocusManager().getFocusOwner();
1500
1501                // verify focusOwner is a descendant of c
1502                for (Component temp = focusOwner; temp != null; temp = (temp instanceof  Window) ? null
1503                        : temp.getParent()) {
1504                    if (temp == c) {
1505                        return focusOwner;
1506                    }
1507                }
1508
1509                return null;
1510            }
1511
1512            /**
1513             * If c is a JRootPane descendant return its JRootPane ancestor.
1514             * If c is a RootPaneContainer then return its JRootPane.
1515             * @return the JRootPane for Component c or {@code null}.
1516             */
1517            public static JRootPane getRootPane(Component c) {
1518                if (c instanceof  RootPaneContainer) {
1519                    return ((RootPaneContainer) c).getRootPane();
1520                }
1521                for (; c != null; c = c.getParent()) {
1522                    if (c instanceof  JRootPane) {
1523                        return (JRootPane) c;
1524                    }
1525                }
1526                return null;
1527            }
1528
1529            /**
1530             * Returns the root component for the current component tree.
1531             * @return the first ancestor of c that's a Window or the last Applet ancestor
1532             */
1533            public static Component getRoot(Component c) {
1534                Component applet = null;
1535                for (Component p = c; p != null; p = p.getParent()) {
1536                    if (p instanceof  Window) {
1537                        return p;
1538                    }
1539                    if (p instanceof  Applet) {
1540                        applet = p;
1541                    }
1542                }
1543                return applet;
1544            }
1545
1546            /**
1547             * Process the key bindings for the <code>Component</code> associated with
1548             * <code>event</code>. This method is only useful if
1549             * <code>event.getComponent()</code> does not descend from
1550             * <code>JComponent</code>, or your are not invoking
1551             * <code>super.processKeyEvent</code> from within your
1552             * <code>JComponent</code> subclass. <code>JComponent</code>
1553             * automatically processes bindings from within its
1554             * <code>processKeyEvent</code> method, hence you rarely need
1555             * to directly invoke this method.
1556             *
1557             * @param event KeyEvent used to identify which bindings to process, as
1558             *              well as which Component has focus.
1559             * @return true if a binding has found and processed
1560             * @since 1.4
1561             */
1562            public static boolean processKeyBindings(KeyEvent event) {
1563                if (event != null) {
1564                    if (event.isConsumed()) {
1565                        return false;
1566                    }
1567
1568                    Component component = event.getComponent();
1569                    boolean pressed = (event.getID() == KeyEvent.KEY_PRESSED);
1570
1571                    if (!isValidKeyEventForKeyBindings(event)) {
1572                        return false;
1573                    }
1574                    // Find the first JComponent in the ancestor hierarchy, and
1575                    // invoke processKeyBindings on it
1576                    while (component != null) {
1577                        if (component instanceof  JComponent) {
1578                            return ((JComponent) component).processKeyBindings(
1579                                    event, pressed);
1580                        }
1581                        if ((component instanceof  Applet)
1582                                || (component instanceof  Window)) {
1583                            // No JComponents, if Window or Applet parent, process
1584                            // WHEN_IN_FOCUSED_WINDOW bindings.
1585                            return JComponent
1586                                    .processKeyBindingsForAllComponents(event,
1587                                            (Container) component, pressed);
1588                        }
1589                        component = component.getParent();
1590                    }
1591                }
1592                return false;
1593            }
1594
1595            /**
1596             * Returns true if the <code>e</code> is a valid KeyEvent to use in
1597             * processing the key bindings associated with JComponents.
1598             */
1599            static boolean isValidKeyEventForKeyBindings(KeyEvent e) {
1600                if (e.getID() == KeyEvent.KEY_TYPED) {
1601                    int mod = e.getModifiers();
1602                    if (((mod & ActionEvent.ALT_MASK) != 0)
1603                            && ((mod & ActionEvent.CTRL_MASK) == 0)) {
1604                        // filter out typed "alt-?" keys, but not those created
1605                        // with AltGr, and not control characters
1606                        return false;
1607                    }
1608                }
1609                return true;
1610            }
1611
1612            /**
1613             * Invokes <code>actionPerformed</code> on <code>action</code> if
1614             * <code>action</code> is enabled (and non-{@code null}). The command for the
1615             * ActionEvent is determined by:
1616             * <ol>
1617             *   <li>If the action was registered via
1618             *       <code>registerKeyboardAction</code>, then the command string
1619             *       passed in ({@code null} will be used if {@code null} was passed in).
1620             *   <li>Action value with name Action.ACTION_COMMAND_KEY, unless {@code null}.
1621             *   <li>String value of the KeyEvent, unless <code>getKeyChar</code>
1622             *       returns KeyEvent.CHAR_UNDEFINED..
1623             * </ol>
1624             * This will return true if <code>action</code> is non-{@code null} and
1625             * actionPerformed is invoked on it.
1626             *
1627             * @since 1.3
1628             */
1629            public static boolean notifyAction(Action action, KeyStroke ks,
1630                    KeyEvent event, Object sender, int modifiers) {
1631                if (action == null) {
1632                    return false;
1633                }
1634                if (action instanceof  UIAction) {
1635                    if (!((UIAction) action).isEnabled(sender)) {
1636                        return false;
1637                    }
1638                } else if (!action.isEnabled()) {
1639                    return false;
1640                }
1641                Object commandO;
1642                boolean stayNull;
1643
1644                // Get the command object.
1645                commandO = action.getValue(Action.ACTION_COMMAND_KEY);
1646                if (commandO == null
1647                        && (action instanceof  JComponent.ActionStandin)) {
1648                    // ActionStandin is used for historical reasons to support
1649                    // registerKeyboardAction with a null value.
1650                    stayNull = true;
1651                } else {
1652                    stayNull = false;
1653                }
1654
1655                // Convert it to a string.
1656                String command;
1657
1658                if (commandO != null) {
1659                    command = commandO.toString();
1660                } else if (!stayNull
1661                        && event.getKeyChar() != KeyEvent.CHAR_UNDEFINED) {
1662                    command = String.valueOf(event.getKeyChar());
1663                } else {
1664                    // Do null for undefined chars, or if registerKeyboardAction
1665                    // was called with a null.
1666                    command = null;
1667                }
1668                action.actionPerformed(new ActionEvent(sender,
1669                        ActionEvent.ACTION_PERFORMED, command, event.getWhen(),
1670                        modifiers));
1671                return true;
1672            }
1673
1674            /**
1675             * Convenience method to change the UI InputMap for <code>component</code>
1676             * to <code>uiInputMap</code>. If <code>uiInputMap</code> is {@code null},
1677             * this removes any previously installed UI InputMap.
1678             *
1679             * @since 1.3
1680             */
1681            public static void replaceUIInputMap(JComponent component,
1682                    int type, InputMap uiInputMap) {
1683                InputMap map = component
1684                        .getInputMap(type, (uiInputMap != null));
1685
1686                while (map != null) {
1687                    InputMap parent = map.getParent();
1688                    if (parent == null || (parent instanceof  UIResource)) {
1689                        map.setParent(uiInputMap);
1690                        return;
1691                    }
1692                    map = parent;
1693                }
1694            }
1695
1696            /**
1697             * Convenience method to change the UI ActionMap for <code>component</code>
1698             * to <code>uiActionMap</code>. If <code>uiActionMap</code> is {@code null},
1699             * this removes any previously installed UI ActionMap.
1700             *
1701             * @since 1.3
1702             */
1703            public static void replaceUIActionMap(JComponent component,
1704                    ActionMap uiActionMap) {
1705                ActionMap map = component.getActionMap((uiActionMap != null));
1706                ;
1707
1708                while (map != null) {
1709                    ActionMap parent = map.getParent();
1710                    if (parent == null || (parent instanceof  UIResource)) {
1711                        map.setParent(uiActionMap);
1712                        return;
1713                    }
1714                    map = parent;
1715                }
1716            }
1717
1718            /**
1719             * Returns the InputMap provided by the UI for condition
1720             * <code>condition</code> in component <code>component</code>.
1721             * <p>This will return {@code null} if the UI has not installed a InputMap
1722             * of the specified type.
1723             *
1724             * @since 1.3
1725             */
1726            public static InputMap getUIInputMap(JComponent component,
1727                    int condition) {
1728                InputMap map = component.getInputMap(condition, false);
1729                while (map != null) {
1730                    InputMap parent = map.getParent();
1731                    if (parent instanceof  UIResource) {
1732                        return parent;
1733                    }
1734                    map = parent;
1735                }
1736                return null;
1737            }
1738
1739            /**
1740             * Returns the ActionMap provided by the UI 
1741             * in component <code>component</code>.
1742             * <p>This will return {@code null} if the UI has not installed an ActionMap.
1743             *
1744             * @since 1.3
1745             */
1746            public static ActionMap getUIActionMap(JComponent component) {
1747                ActionMap map = component.getActionMap(false);
1748                while (map != null) {
1749                    ActionMap parent = map.getParent();
1750                    if (parent instanceof  UIResource) {
1751                        return parent;
1752                    }
1753                    map = parent;
1754                }
1755                return null;
1756            }
1757
1758            // Don't use String, as it's not guaranteed to be unique in a Hashtable.
1759            private static final Object sharedOwnerFrameKey = new StringBuffer(
1760                    "SwingUtilities.sharedOwnerFrame");
1761
1762            static class SharedOwnerFrame extends Frame implements 
1763                    WindowListener {
1764                public void addNotify() {
1765                    super .addNotify();
1766                    installListeners();
1767                }
1768
1769                /**
1770                 * Install window listeners on owned windows to watch for displayability changes
1771                 */
1772                void installListeners() {
1773                    Window[] windows = getOwnedWindows();
1774                    for (int ind = 0; ind < windows.length; ind++) {
1775                        Window window = windows[ind];
1776                        if (window != null) {
1777                            window.removeWindowListener(this );
1778                            window.addWindowListener(this );
1779                        }
1780                    }
1781                }
1782
1783                /**
1784                 * Watches for displayability changes and disposes shared instance if there are no
1785                 * displayable children left.
1786                 */
1787                public void windowClosed(WindowEvent e) {
1788                    synchronized (getTreeLock()) {
1789                        Window[] windows = getOwnedWindows();
1790                        for (int ind = 0; ind < windows.length; ind++) {
1791                            Window window = windows[ind];
1792                            if (window != null) {
1793                                if (window.isDisplayable()) {
1794                                    return;
1795                                }
1796                                window.removeWindowListener(this );
1797                            }
1798                        }
1799                        dispose();
1800                    }
1801                }
1802
1803                public void windowOpened(WindowEvent e) {
1804                }
1805
1806                public void windowClosing(WindowEvent e) {
1807                }
1808
1809                public void windowIconified(WindowEvent e) {
1810                }
1811
1812                public void windowDeiconified(WindowEvent e) {
1813                }
1814
1815                public void windowActivated(WindowEvent e) {
1816                }
1817
1818                public void windowDeactivated(WindowEvent e) {
1819                }
1820
1821                public void show() {
1822                    // This frame can never be shown
1823                }
1824
1825                public void dispose() {
1826                    try {
1827                        getToolkit().getSystemEventQueue();
1828                        super .dispose();
1829                    } catch (Exception e) {
1830                        // untrusted code not allowed to dispose
1831                    }
1832                }
1833            }
1834
1835            /**
1836             * Returns a toolkit-private, shared, invisible Frame
1837             * to be the owner for JDialogs and JWindows created with
1838             * {@code null} owners.
1839             * @exception HeadlessException if GraphicsEnvironment.isHeadless()
1840             * returns true.
1841             * @see java.awt.GraphicsEnvironment#isHeadless
1842             */
1843            static Frame getSharedOwnerFrame() throws HeadlessException {
1844                Frame sharedOwnerFrame = (Frame) SwingUtilities
1845                        .appContextGet(sharedOwnerFrameKey);
1846                if (sharedOwnerFrame == null) {
1847                    sharedOwnerFrame = new SharedOwnerFrame();
1848                    SwingUtilities.appContextPut(sharedOwnerFrameKey,
1849                            sharedOwnerFrame);
1850                }
1851                return sharedOwnerFrame;
1852            }
1853
1854            /**
1855             * Returns a SharedOwnerFrame's shutdown listener to dispose the SharedOwnerFrame
1856             * if it has no more displayable children.
1857             * @exception HeadlessException if GraphicsEnvironment.isHeadless()
1858             * returns true.
1859             * @see java.awt.GraphicsEnvironment#isHeadless
1860             */
1861            static WindowListener getSharedOwnerFrameShutdownListener()
1862                    throws HeadlessException {
1863                Frame sharedOwnerFrame = getSharedOwnerFrame();
1864                return (WindowListener) sharedOwnerFrame;
1865            }
1866
1867            /* Don't make these AppContext accessors public or protected --
1868             * since AppContext is in sun.awt in 1.2, we shouldn't expose it
1869             * even indirectly with a public API.
1870             */
1871            // REMIND(aim): phase out use of 4 methods below since they
1872            // are just private covers for AWT methods (?)
1873            static Object appContextGet(Object key) {
1874                return AppContext.getAppContext().get(key);
1875            }
1876
1877            static void appContextPut(Object key, Object value) {
1878                AppContext.getAppContext().put(key, value);
1879            }
1880
1881            static void appContextRemove(Object key) {
1882                AppContext.getAppContext().remove(key);
1883            }
1884
1885            static Class loadSystemClass(String className)
1886                    throws ClassNotFoundException {
1887                return Class.forName(className, true, Thread.currentThread()
1888                        .getContextClassLoader());
1889            }
1890
1891            /*
1892             * Convenience function for determining ComponentOrientation.  Helps us
1893             * avoid having Munge directives throughout the code.
1894             */
1895            static boolean isLeftToRight(Component c) {
1896                return c.getComponentOrientation().isLeftToRight();
1897            }
1898
1899            private SwingUtilities() {
1900                throw new Error(
1901                        "SwingUtilities is just a container for static methods");
1902            }
1903
1904            /**
1905             * Returns true if the Icon <code>icon</code> is an instance of
1906             * ImageIcon, and the image it contains is the same as <code>image</code>.
1907             */
1908            static boolean doesIconReferenceImage(Icon icon, Image image) {
1909                Image iconImage = (icon != null && (icon instanceof  ImageIcon)) ? ((ImageIcon) icon)
1910                        .getImage()
1911                        : null;
1912                return (iconImage == image);
1913            }
1914
1915            /**
1916             * Returns index of the first occurrence of <code>mnemonic</code>
1917             * within string <code>text</code>. Matching algorithm is not
1918             * case-sensitive.
1919             *
1920             * @param text The text to search through, may be {@code null}
1921             * @param mnemonic The mnemonic to find the character for.
1922             * @return index into the string if exists, otherwise -1
1923             */
1924            static int findDisplayedMnemonicIndex(String text, int mnemonic) {
1925                if (text == null || mnemonic == '\0') {
1926                    return -1;
1927                }
1928
1929                char uc = Character.toUpperCase((char) mnemonic);
1930                char lc = Character.toLowerCase((char) mnemonic);
1931
1932                int uci = text.indexOf(uc);
1933                int lci = text.indexOf(lc);
1934
1935                if (uci == -1) {
1936                    return lci;
1937                } else if (lci == -1) {
1938                    return uci;
1939                } else {
1940                    return (lci < uci) ? lci : uci;
1941                }
1942            }
1943
1944            /**
1945             * Stores the position and size of
1946             * the inner painting area of the specified component
1947             * in <code>r</code> and returns <code>r</code>.
1948             * The position and size specify the bounds of the component,
1949             * adjusted so as not to include the border area (the insets).
1950             * This method is useful for classes 
1951             * that implement painting code.
1952             *
1953             * @param c  the JComponent in question; if {@code null}, this method returns {@code null}
1954             * @param r  the Rectangle instance to be modified;
1955             *           may be {@code null}
1956             * @return {@code null} if the Component is {@code null};
1957             *         otherwise, returns the passed-in rectangle (if non-{@code null})
1958             *         or a new rectangle specifying position and size information
1959             *
1960             * @since 1.4
1961             */
1962            public static Rectangle calculateInnerArea(JComponent c, Rectangle r) {
1963                if (c == null) {
1964                    return null;
1965                }
1966                Rectangle rect = r;
1967                Insets insets = c.getInsets();
1968
1969                if (rect == null) {
1970                    rect = new Rectangle();
1971                }
1972
1973                rect.x = insets.left;
1974                rect.y = insets.top;
1975                rect.width = c.getWidth() - insets.left - insets.right;
1976                rect.height = c.getHeight() - insets.top - insets.bottom;
1977
1978                return rect;
1979            }
1980
1981            static void updateRendererOrEditorUI(Object rendererOrEditor) {
1982                if (rendererOrEditor == null) {
1983                    return;
1984                }
1985
1986                Component component = null;
1987
1988                if (rendererOrEditor instanceof  Component) {
1989                    component = (Component) rendererOrEditor;
1990                }
1991                if (rendererOrEditor instanceof  DefaultCellEditor) {
1992                    component = ((DefaultCellEditor) rendererOrEditor)
1993                            .getComponent();
1994                }
1995
1996                if (component != null) {
1997                    SwingUtilities.updateComponentTreeUI(component);
1998                }
1999            }
2000        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.