< prev index next >

src/java.desktop/share/classes/javax/swing/SwingUtilities.java

Print this page




  54 public class SwingUtilities implements SwingConstants
  55 {
  56     // These states are system-wide, rather than AppContext wide.
  57     private static boolean canAccessEventQueue = false;
  58     private static boolean eventQueueTested = false;
  59 
  60     /**
  61      * Indicates if we should change the drop target when a
  62      * {@code TransferHandler} is set.
  63      */
  64     private static boolean suppressDropSupport;
  65 
  66     /**
  67      * Indiciates if we've checked the system property for suppressing
  68      * drop support.
  69      */
  70     private static boolean checkedSuppressDropSupport;
  71 
  72 
  73     /**
  74      * Returns true if <code>setTransferHandler</code> should change the
  75      * <code>DropTarget</code>.
  76      */
  77     private static boolean getSuppressDropTarget() {
  78         if (!checkedSuppressDropSupport) {
  79             suppressDropSupport = Boolean.valueOf(
  80                 AccessController.doPrivileged(
  81                     new GetPropertyAction("suppressSwingDropSupport")));
  82             checkedSuppressDropSupport = true;
  83         }
  84         return suppressDropSupport;
  85     }
  86 
  87     /**
  88      * Installs a {@code DropTarget} on the component as necessary for a
  89      * {@code TransferHandler} change.
  90      */
  91     static void installSwingDropTargetAsNecessary(Component c,
  92                                                          TransferHandler t) {
  93 
  94         if (!getSuppressDropTarget()) {
  95             DropTarget dropHandler = c.getDropTarget();


 113      */
 114     public static final boolean isRectangleContainingRectangle(Rectangle a,Rectangle b) {
 115         return b.x >= a.x && (b.x + b.width) <= (a.x + a.width) &&
 116                 b.y >= a.y && (b.y + b.height) <= (a.y + a.height);
 117     }
 118 
 119     /**
 120      * Return the rectangle (0,0,bounds.width,bounds.height) for the component {@code aComponent}
 121      *
 122      * @param aComponent a component
 123      * @return the local bounds for the component {@code aComponent}
 124      */
 125     public static Rectangle getLocalBounds(Component aComponent) {
 126         Rectangle b = new Rectangle(aComponent.getBounds());
 127         b.x = b.y = 0;
 128         return b;
 129     }
 130 
 131 
 132     /**
 133      * Returns the first <code>Window </code> ancestor of <code>c</code>, or
 134      * {@code null} if <code>c</code> is not contained inside a <code>Window</code>.
 135      *
 136      * @param c <code>Component</code> to get <code>Window</code> ancestor
 137      *        of.
 138      * @return the first <code>Window </code> ancestor of <code>c</code>, or
 139      *         {@code null} if <code>c</code> is not contained inside a
 140      *         <code>Window</code>.
 141      * @since 1.3
 142      */
 143     public static Window getWindowAncestor(Component c) {
 144         for(Container p = c.getParent(); p != null; p = p.getParent()) {
 145             if (p instanceof Window) {
 146                 return (Window)p;
 147             }
 148         }
 149         return null;
 150     }
 151 
 152     /**
 153      * Converts the location <code>x</code> <code>y</code> to the
 154      * parents coordinate system, returning the location.
 155      */
 156     static Point convertScreenLocationToParent(Container parent,int x, int y) {
 157         for (Container p = parent; p != null; p = p.getParent()) {
 158             if (p instanceof Window) {
 159                 Point point = new Point(x, y);
 160 
 161                 SwingUtilities.convertPointFromScreen(point, parent);
 162                 return point;
 163             }
 164         }
 165         throw new Error("convertScreenLocationToParent: no window ancestor");
 166     }
 167 
 168     /**
 169      * Convert a <code>aPoint</code> in <code>source</code> coordinate system to
 170      * <code>destination</code> coordinate system.
 171      * If <code>source</code> is {@code null}, <code>aPoint</code> is assumed to be in <code>destination</code>'s
 172      * root component coordinate system.
 173      * If <code>destination</code> is {@code null}, <code>aPoint</code> will be converted to <code>source</code>'s
 174      * root component coordinate system.
 175      * If both <code>source</code> and <code>destination</code> are {@code null}, return <code>aPoint</code>
 176      * without any conversion.
 177      *
 178      * @param source the source component
 179      * @param aPoint the point
 180      * @param destination the destination component
 181      *
 182      * @return the converted coordinate
 183      */
 184     public static Point convertPoint(Component source,Point aPoint,Component destination) {
 185         Point p;
 186 
 187         if(source == null && destination == null)
 188             return aPoint;
 189         if(source == null) {
 190             source = getWindowAncestor(destination);
 191             if(source == null)
 192                 throw new Error("Source component not connected to component tree hierarchy");
 193         }
 194         p = new Point(aPoint);
 195         convertPointToScreen(p,source);
 196         if(destination == null) {
 197             destination = getWindowAncestor(source);
 198             if(destination == null)
 199                 throw new Error("Destination component not connected to component tree hierarchy");
 200         }
 201         convertPointFromScreen(p,destination);
 202         return p;
 203     }
 204 
 205     /**
 206      * Convert the point <code>(x,y)</code> in <code>source</code> coordinate system to
 207      * <code>destination</code> coordinate system.
 208      * If <code>source</code> is {@code null}, <code>(x,y)</code> is assumed to be in <code>destination</code>'s
 209      * root component coordinate system.
 210      * If <code>destination</code> is {@code null}, <code>(x,y)</code> will be converted to <code>source</code>'s
 211      * root component coordinate system.
 212      * If both <code>source</code> and <code>destination</code> are {@code null}, return <code>(x,y)</code>
 213      * without any conversion.
 214      *
 215      * @param source the source component
 216      * @param x the x-coordinate of the point
 217      * @param y the y-coordinate of the point
 218      * @param destination the destination component
 219      *
 220      * @return the converted coordinate
 221      */
 222     public static Point convertPoint(Component source,int x, int y,Component destination) {
 223         Point point = new Point(x,y);
 224         return convertPoint(source,point,destination);
 225     }
 226 
 227     /**
 228      * Convert the rectangle <code>aRectangle</code> in <code>source</code> coordinate system to
 229      * <code>destination</code> coordinate system.
 230      * If <code>source</code> is {@code null}, <code>aRectangle</code> is assumed to be in <code>destination</code>'s
 231      * root component coordinate system.
 232      * If <code>destination</code> is {@code null}, <code>aRectangle</code> will be converted to <code>source</code>'s
 233      * root component coordinate system.
 234      * If both <code>source</code> and <code>destination</code> are {@code null}, return <code>aRectangle</code>
 235      * without any conversion.
 236      *
 237      * @param source the source component
 238      * @param aRectangle a rectangle
 239      * @param destination the destination component
 240      *
 241      * @return the converted rectangle
 242      */
 243     public static Rectangle convertRectangle(Component source,Rectangle aRectangle,Component destination) {
 244         Point point = new Point(aRectangle.x,aRectangle.y);
 245         point =  convertPoint(source,point,destination);
 246         return new Rectangle(point.x,point.y,aRectangle.width,aRectangle.height);
 247     }
 248 
 249     /**
 250      * Convenience method for searching above <code>comp</code> in the
 251      * component hierarchy and returns the first object of class <code>c</code> it
 252      * finds. Can return {@code null}, if a class <code>c</code> cannot be found.
 253      *
 254      * @param c the class of a component
 255      * @param comp the component
 256      *
 257      * @return the ancestor of the {@code comp},
 258      *         or {@code null} if {@code c} cannot be found.
 259      */
 260     public static Container getAncestorOfClass(Class<?> c, Component comp)
 261     {
 262         if(comp == null || c == null)
 263             return null;
 264 
 265         Container parent = comp.getParent();
 266         while(parent != null && !(c.isInstance(parent)))
 267             parent = parent.getParent();
 268         return parent;
 269     }
 270 
 271     /**
 272      * Convenience method for searching above <code>comp</code> in the
 273      * component hierarchy and returns the first object of <code>name</code> it
 274      * finds. Can return {@code null}, if <code>name</code> cannot be found.
 275      *
 276      * @param name the name of a component
 277      * @param comp the component
 278      *
 279      * @return the ancestor of the {@code comp},
 280      *         or {@code null} if {@code name} cannot be found.
 281      */
 282     public static Container getAncestorNamed(String name, Component comp) {
 283         if(comp == null || name == null)
 284             return null;
 285 
 286         Container parent = comp.getParent();
 287         while(parent != null && !(name.equals(parent.getName())))
 288             parent = parent.getParent();
 289         return parent;
 290     }
 291 
 292     /**
 293      * Returns the deepest visible descendent Component of <code>parent</code>
 294      * that contains the location <code>x</code>, <code>y</code>.
 295      * If <code>parent</code> does not contain the specified location,
 296      * then <code>null</code> is returned.  If <code>parent</code> is not a
 297      * container, or none of <code>parent</code>'s visible descendents
 298      * contain the specified location, <code>parent</code> is returned.
 299      *
 300      * @param parent the root component to begin the search
 301      * @param x the x target location
 302      * @param y the y target location
 303      *
 304      * @return the deepest component
 305      */
 306     public static Component getDeepestComponentAt(Component parent, int x, int y) {
 307         if (!parent.contains(x, y)) {
 308             return null;
 309         }
 310         if (parent instanceof Container) {
 311             Component components[] = ((Container)parent).getComponents();
 312             for (Component comp : components) {
 313                 if (comp != null && comp.isVisible()) {
 314                     Point loc = comp.getLocation();
 315                     if (comp instanceof Container) {
 316                         comp = getDeepestComponentAt(comp, x - loc.x, y - loc.y);
 317                     } else {
 318                         comp = comp.getComponentAt(x - loc.x, y - loc.y);
 319                     }
 320                     if (comp != null && comp.isVisible()) {
 321                         return comp;
 322                     }
 323                 }
 324             }
 325         }
 326         return parent;
 327     }
 328 
 329 
 330     /**
 331      * Returns a MouseEvent similar to <code>sourceEvent</code> except that its x
 332      * and y members have been converted to <code>destination</code>'s coordinate
 333      * system.  If <code>source</code> is {@code null}, <code>sourceEvent</code> x and y members
 334      * are assumed to be into <code>destination</code>'s root component coordinate system.
 335      * If <code>destination</code> is <code>null</code>, the
 336      * returned MouseEvent will be in <code>source</code>'s coordinate system.
 337      * <code>sourceEvent</code> will not be changed. A new event is returned.
 338      * the <code>source</code> field of the returned event will be set
 339      * to <code>destination</code> if destination is non-{@code null}
 340      * use the translateMouseEvent() method to translate a mouse event from
 341      * one component to another without changing the source.
 342      *
 343      * @param source the source component
 344      * @param sourceEvent the source mouse event
 345      * @param destination the destination component
 346      *
 347      * @return the new mouse event
 348      */
 349     public static MouseEvent convertMouseEvent(Component source,
 350                                                MouseEvent sourceEvent,
 351                                                Component destination) {
 352         Point p = convertPoint(source,new Point(sourceEvent.getX(),
 353                                                 sourceEvent.getY()),
 354                                destination);
 355         Component newSource;
 356 
 357         if(destination != null)
 358             newSource = destination;
 359         else


 471                     y = pp.y;
 472                 } catch (IllegalComponentStateException icse) {
 473                     x = c.getX();
 474                     y = c.getY();
 475                 }
 476             } else {
 477                 x = c.getX();
 478                 y = c.getY();
 479             }
 480 
 481             p.x -= x;
 482             p.y -= y;
 483 
 484             if(c instanceof java.awt.Window || c instanceof java.applet.Applet)
 485                 break;
 486             c = c.getParent();
 487         } while(c != null);
 488     }
 489 
 490     /**
 491      * Returns the first <code>Window </code> ancestor of <code>c</code>, or
 492      * {@code null} if <code>c</code> is not contained inside a <code>Window</code>.
 493      * <p>
 494      * Note: This method provides the same functionality as
 495      * <code>getWindowAncestor</code>.
 496      *
 497      * @param c <code>Component</code> to get <code>Window</code> ancestor
 498      *        of.
 499      * @return the first <code>Window </code> ancestor of <code>c</code>, or
 500      *         {@code null} if <code>c</code> is not contained inside a
 501      *         <code>Window</code>.
 502      */
 503     public static Window windowForComponent(Component c) {
 504         return getWindowAncestor(c);
 505     }
 506 
 507     /**
 508      * Return {@code true} if a component {@code a} descends from a component {@code b}
 509      *
 510      * @param a the first component
 511      * @param b the second component
 512      * @return {@code true} if a component {@code a} descends from a component {@code b}
 513      */
 514     public static boolean isDescendingFrom(Component a,Component b) {
 515         if(a == b)
 516             return true;
 517         for(Container p = a.getParent();p!=null;p=p.getParent())
 518             if(p == b)
 519                 return true;
 520         return false;
 521     }
 522 
 523 
 524     /**
 525      * Convenience to calculate the intersection of two rectangles
 526      * without allocating a new rectangle.
 527      * If the two rectangles don't intersect,
 528      * then the returned rectangle begins at (0,0)
 529      * and has zero width and height.
 530      *
 531      * @param x       the X coordinate of the first rectangle's top-left point
 532      * @param y       the Y coordinate of the first rectangle's top-left point
 533      * @param width   the width of the first rectangle
 534      * @param height  the height of the first rectangle
 535      * @param dest    the second rectangle
 536      *
 537      * @return <code>dest</code>, modified to specify the intersection
 538      */
 539     public static Rectangle computeIntersection(int x,int y,int width,int height,Rectangle dest) {
 540         int x1 = (x > dest.x) ? x : dest.x;
 541         int x2 = ((x+width) < (dest.x + dest.width)) ? (x+width) : (dest.x + dest.width);
 542         int y1 = (y > dest.y) ? y : dest.y;
 543         int y2 = ((y + height) < (dest.y + dest.height) ? (y+height) : (dest.y + dest.height));
 544 
 545         dest.x = x1;
 546         dest.y = y1;
 547         dest.width = x2 - x1;
 548         dest.height = y2 - y1;
 549 
 550         // If rectangles don't intersect, return zero'd intersection.
 551         if (dest.width < 0 || dest.height < 0) {
 552             dest.x = dest.y = dest.width = dest.height = 0;
 553         }
 554 
 555         return dest;
 556     }
 557 
 558     /**
 559      * Convenience method that calculates the union of two rectangles
 560      * without allocating a new rectangle.
 561      *
 562      * @param x the x-coordinate of the first rectangle
 563      * @param y the y-coordinate of the first rectangle
 564      * @param width the width of the first rectangle
 565      * @param height the height of the first rectangle
 566      * @param dest  the coordinates of the second rectangle; the union
 567      *    of the two rectangles is returned in this rectangle
 568      * @return the <code>dest</code> <code>Rectangle</code>
 569      */
 570     public static Rectangle computeUnion(int x,int y,int width,int height,Rectangle dest) {
 571         int x1 = (x < dest.x) ? x : dest.x;
 572         int x2 = ((x+width) > (dest.x + dest.width)) ? (x+width) : (dest.x + dest.width);
 573         int y1 = (y < dest.y) ? y : dest.y;
 574         int y2 = ((y+height) > (dest.y + dest.height)) ? (y+height) : (dest.y + dest.height);
 575 
 576         dest.x = x1;
 577         dest.y = y1;
 578         dest.width = (x2 - x1);
 579         dest.height= (y2 - y1);
 580         return dest;
 581     }
 582 
 583     /**
 584      * Convenience returning an array of rect representing the regions within
 585      * <code>rectA</code> that do not overlap with <code>rectB</code>. If the
 586      * two Rects do not overlap, returns an empty array
 587      *
 588      * @param rectA the first rectangle
 589      * @param rectB the second rectangle
 590      *
 591      * @return an array of rectangles representing the regions within {@code rectA}
 592      *         that do not overlap with {@code rectB}.
 593      */
 594     public static Rectangle[] computeDifference(Rectangle rectA,Rectangle rectB) {
 595         if (rectB == null || !rectA.intersects(rectB) || isRectangleContainingRectangle(rectB,rectA)) {
 596             return new Rectangle[0];
 597         }
 598 
 599         Rectangle t = new Rectangle();
 600         Rectangle a=null,b=null,c=null,d=null;
 601         Rectangle result[];
 602         int rectCount = 0;
 603 
 604         /* rectA contains rectB */
 605         if (isRectangleContainingRectangle(rectA,rectB)) {


1198 
1199         iconR.x += dx;
1200         iconR.y += dy;
1201 
1202         if (lsb < 0) {
1203             // lsb is negative. Shift the x location so that the text is
1204             // visually drawn at the right location.
1205             textR.x -= lsb;
1206 
1207             textR.width += lsb;
1208         }
1209         if (rsb > 0) {
1210             textR.width -= rsb;
1211         }
1212 
1213         return text;
1214     }
1215 
1216 
1217     /**
1218      * Paints a component to the specified <code>Graphics</code>.
1219      * This method is primarily useful to render
1220      * <code>Component</code>s that don't exist as part of the visible
1221      * containment hierarchy, but are used for rendering.  For
1222      * example, if you are doing your own rendering and want to render
1223      * some text (or even HTML), you could make use of
1224      * <code>JLabel</code>'s text rendering support and have it paint
1225      * directly by way of this method, without adding the label to the
1226      * visible containment hierarchy.
1227      * <p>
1228      * This method makes use of <code>CellRendererPane</code> to handle
1229      * the actual painting, and is only recommended if you use one
1230      * component for rendering.  If you make use of multiple components
1231      * to handle the rendering, as <code>JTable</code> does, use
1232      * <code>CellRendererPane</code> directly.  Otherwise, as described
1233      * below, you could end up with a <code>CellRendererPane</code>
1234      * per <code>Component</code>.
1235      * <p>
1236      * If <code>c</code>'s parent is not a <code>CellRendererPane</code>,
1237      * a new <code>CellRendererPane</code> is created, <code>c</code> is
1238      * added to it, and the <code>CellRendererPane</code> is added to
1239      * <code>p</code>.  If <code>c</code>'s parent is a
1240      * <code>CellRendererPane</code> and the <code>CellRendererPane</code>s
1241      * parent is not <code>p</code>, it is added to <code>p</code>.
1242      * <p>
1243      * The component should either descend from <code>JComponent</code>
1244      * or be another kind of lightweight component.
1245      * A lightweight component is one whose "lightweight" property
1246      * (returned by the <code>Component</code>
1247      * <code>isLightweight</code> method)
1248      * is true. If the Component is not lightweight, bad things map happen:
1249      * crashes, exceptions, painting problems...
1250      *
1251      * @param g  the <code>Graphics</code> object to draw on
1252      * @param c  the <code>Component</code> to draw
1253      * @param p  the intermediate <code>Container</code>
1254      * @param x  an int specifying the left side of the area draw in, in pixels,
1255      *           measured from the left edge of the graphics context
1256      * @param y  an int specifying the top of the area to draw in, in pixels
1257      *           measured down from the top edge of the graphics context
1258      * @param w  an int specifying the width of the area draw in, in pixels
1259      * @param h  an int specifying the height of the area draw in, in pixels
1260      *
1261      * @see CellRendererPane
1262      * @see java.awt.Component#isLightweight
1263      */
1264     public static void paintComponent(Graphics g, Component c, Container p, int x, int y, int w, int h) {
1265         getCellRendererPane(c, p).paintComponent(g, c, p, x, y, w, h,false);
1266     }
1267 
1268     /**
1269      * Paints a component to the specified <code>Graphics</code>.  This
1270      * is a cover method for
1271      * {@link #paintComponent(Graphics,Component,Container,int,int,int,int)}.
1272      * Refer to it for more information.
1273      *
1274      * @param g  the <code>Graphics</code> object to draw on
1275      * @param c  the <code>Component</code> to draw
1276      * @param p  the intermediate <code>Container</code>
1277      * @param r  the <code>Rectangle</code> to draw in
1278      *
1279      * @see #paintComponent(Graphics,Component,Container,int,int,int,int)
1280      * @see CellRendererPane
1281      */
1282     public static void paintComponent(Graphics g, Component c, Container p, Rectangle r) {
1283         paintComponent(g, c, p, r.x, r.y, r.width, r.height);
1284     }
1285 
1286 
1287     /*
1288      * Ensures that cell renderer <code>c</code> has a
1289      * <code>ComponentShell</code> parent and that
1290      * the shell's parent is p.
1291      */
1292     private static CellRendererPane getCellRendererPane(Component c, Container p) {
1293         Container shell = c.getParent();
1294         if (shell instanceof CellRendererPane) {
1295             if (shell.getParent() != p) {
1296                 p.add(shell);
1297             }
1298         } else {
1299             shell = new CellRendererPane();
1300             shell.add(c);
1301             p.add(shell);
1302         }
1303         return (CellRendererPane)shell;
1304     }
1305 
1306     /**
1307      * A simple minded look and feel change: ask each node in the tree
1308      * to <code>updateUI()</code> -- that is, to initialize its UI property
1309      * with the current look and feel.
1310      *
1311      * @param c the component
1312      */
1313     public static void updateComponentTreeUI(Component c) {
1314         updateComponentTreeUI0(c);
1315         c.invalidate();
1316         c.validate();
1317         c.repaint();
1318     }
1319 
1320     private static void updateComponentTreeUI0(Component c) {
1321         if (c instanceof JComponent) {
1322             JComponent jc = (JComponent) c;
1323             jc.updateUI();
1324             JPopupMenu jpm =jc.getComponentPopupMenu();
1325             if(jpm != null) {
1326                 updateComponentTreeUI(jpm);
1327             }
1328         }
1329         Component[] children = null;
1330         if (c instanceof JMenu) {
1331             children = ((JMenu)c).getMenuComponents();
1332         }
1333         else if (c instanceof Container) {
1334             children = ((Container)c).getComponents();
1335         }
1336         if (children != null) {
1337             for (Component child : children) {
1338                 updateComponentTreeUI0(child);
1339             }
1340         }
1341     }
1342 
1343 
1344     /**
1345      * Causes <i>doRun.run()</i> to be executed asynchronously on the
1346      * AWT event dispatching thread.  This will happen after all
1347      * pending AWT events have been processed.  This method should
1348      * be used when an application thread needs to update the GUI.
1349      * In the following example the <code>invokeLater</code> call queues
1350      * the <code>Runnable</code> object <code>doHelloWorld</code>
1351      * on the event dispatching thread and
1352      * then prints a message.
1353      * <pre>
1354      * Runnable doHelloWorld = new Runnable() {
1355      *     public void run() {
1356      *         System.out.println("Hello World on " + Thread.currentThread());
1357      *     }
1358      * };
1359      *
1360      * SwingUtilities.invokeLater(doHelloWorld);
1361      * System.out.println("This might well be displayed before the other message.");
1362      * </pre>
1363      * If invokeLater is called from the event dispatching thread --
1364      * for example, from a JButton's ActionListener -- the <i>doRun.run()</i> will
1365      * still be deferred until all pending events have been processed.
1366      * Note that if the <i>doRun.run()</i> throws an uncaught exception
1367      * the event dispatching thread will unwind (not the current thread).
1368      * <p>
1369      * Additional documentation and examples for this method can be
1370      * found in
1371      * <A HREF="http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency in Swing</a>.
1372      * <p>
1373      * As of 1.3 this method is just a cover for <code>java.awt.EventQueue.invokeLater()</code>.
1374      * <p>
1375      * Unlike the rest of Swing, this method can be invoked from any thread.
1376      *
1377      * @param doRun the instance of {@code Runnable}
1378      * @see #invokeAndWait
1379      */
1380     public static void invokeLater(Runnable doRun) {
1381         EventQueue.invokeLater(doRun);
1382     }
1383 
1384 
1385     /**
1386      * Causes <code>doRun.run()</code> to be executed synchronously on the
1387      * AWT event dispatching thread.  This call blocks until
1388      * all pending AWT events have been processed and (then)
1389      * <code>doRun.run()</code> returns. This method should
1390      * be used when an application thread needs to update the GUI.
1391      * It shouldn't be called from the event dispatching thread.
1392      * Here's an example that creates a new application thread
1393      * that uses <code>invokeAndWait</code> to print a string from the event
1394      * dispatching thread and then, when that's finished, print
1395      * a string from the application thread.
1396      * <pre>
1397      * final Runnable doHelloWorld = new Runnable() {
1398      *     public void run() {
1399      *         System.out.println("Hello World on " + Thread.currentThread());
1400      *     }
1401      * };
1402      *
1403      * Thread appThread = new Thread() {
1404      *     public void run() {
1405      *         try {
1406      *             SwingUtilities.invokeAndWait(doHelloWorld);
1407      *         }
1408      *         catch (Exception e) {
1409      *             e.printStackTrace();
1410      *         }
1411      *         System.out.println("Finished on " + Thread.currentThread());
1412      *     }
1413      * };
1414      * appThread.start();
1415      * </pre>
1416      * Note that if the <code>Runnable.run</code> method throws an
1417      * uncaught exception
1418      * (on the event dispatching thread) it's caught and rethrown, as
1419      * an <code>InvocationTargetException</code>, on the caller's thread.
1420      * <p>
1421      * Additional documentation and examples for this method can be
1422      * found in
1423      * <A HREF="http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency in Swing</a>.
1424      * <p>
1425      * As of 1.3 this method is just a cover for
1426      * <code>java.awt.EventQueue.invokeAndWait()</code>.
1427      *
1428      * @param doRun the instance of {@code Runnable}
1429      * @exception  InterruptedException if we're interrupted while waiting for
1430      *             the event dispatching thread to finish executing
1431      *             <code>doRun.run()</code>
1432      * @exception  InvocationTargetException  if an exception is thrown
1433      *             while running <code>doRun</code>
1434      *
1435      * @see #invokeLater
1436      */
1437     public static void invokeAndWait(final Runnable doRun)
1438         throws InterruptedException, InvocationTargetException
1439     {
1440         EventQueue.invokeAndWait(doRun);
1441     }
1442 
1443     /**
1444      * Returns true if the current thread is an AWT event dispatching thread.
1445      * <p>
1446      * As of 1.3 this method is just a cover for
1447      * <code>java.awt.EventQueue.isDispatchThread()</code>.
1448      *
1449      * @return true if the current thread is an AWT event dispatching thread
1450      */
1451     public static boolean isEventDispatchThread()
1452     {
1453         return EventQueue.isDispatchThread();
1454     }
1455 
1456 
1457     /*
1458      * --- Accessibility Support ---
1459      *
1460      */
1461 
1462     /**
1463      * Get the index of this object in its accessible parent.<p>
1464      *
1465      * Note: as of the Java 2 platform v1.3, it is recommended that developers call
1466      * Component.AccessibleAWTComponent.getAccessibleIndexInParent() instead
1467      * of using this method.
1468      *
1469      * @param c the component
1470      * @return -1 of this object does not have an accessible parent.
1471      * Otherwise, the index of the child in its accessible parent.
1472      */
1473     public static int getAccessibleIndexInParent(Component c) {
1474         return c.getAccessibleContext().getAccessibleIndexInParent();
1475     }
1476 
1477     /**
1478      * Returns the <code>Accessible</code> child contained at the
1479      * local coordinate <code>Point</code>, if one exists.
1480      * Otherwise returns <code>null</code>.
1481      *
1482      * @param c the component
1483      * @param p the local coordinate
1484      * @return the <code>Accessible</code> at the specified location,
1485      *    if it exists; otherwise <code>null</code>
1486      */
1487     public static Accessible getAccessibleAt(Component c, Point p) {
1488         if (c instanceof Container) {
1489             return c.getAccessibleContext().getAccessibleComponent().getAccessibleAt(p);
1490         } else if (c instanceof Accessible) {
1491             Accessible a = (Accessible) c;
1492             if (a != null) {
1493                 AccessibleContext ac = a.getAccessibleContext();
1494                 if (ac != null) {
1495                     AccessibleComponent acmp;
1496                     Point location;
1497                     int nchildren = ac.getAccessibleChildrenCount();
1498                     for (int i=0; i < nchildren; i++) {
1499                         a = ac.getAccessibleChild(i);
1500                         if ((a != null)) {
1501                             ac = a.getAccessibleContext();
1502                             if (ac != null) {
1503                                 acmp = ac.getAccessibleComponent();
1504                                 if ((acmp != null) && (acmp.isShowing())) {
1505                                     location = acmp.getLocation();


1550     public static int getAccessibleChildrenCount(Component c) {
1551         return c.getAccessibleContext().getAccessibleChildrenCount();
1552     }
1553 
1554     /**
1555      * Return the nth Accessible child of the object. <p>
1556      *
1557      * Note: as of the Java 2 platform v1.3, it is recommended that developers call
1558      * Component.AccessibleAWTComponent.getAccessibleIndexInParent() instead
1559      * of using this method.
1560      *
1561      * @param c the component
1562      * @param i zero-based index of child
1563      * @return the nth Accessible child of the object
1564      */
1565     public static Accessible getAccessibleChild(Component c, int i) {
1566         return c.getAccessibleContext().getAccessibleChild(i);
1567     }
1568 
1569     /**
1570      * Return the child <code>Component</code> of the specified
1571      * <code>Component</code> that is the focus owner, if any.
1572      *
1573      * @param c the root of the <code>Component</code> hierarchy to
1574      *        search for the focus owner
1575      * @return the focus owner, or <code>null</code> if there is no focus
1576      *         owner, or if the focus owner is not <code>comp</code>, or a
1577      *         descendant of <code>comp</code>
1578      *
1579      * @see java.awt.KeyboardFocusManager#getFocusOwner
1580      * @deprecated As of 1.4, replaced by
1581      *   <code>KeyboardFocusManager.getFocusOwner()</code>.
1582      */
1583     @Deprecated
1584     public static Component findFocusOwner(Component c) {
1585         Component focusOwner = KeyboardFocusManager.
1586             getCurrentKeyboardFocusManager().getFocusOwner();
1587 
1588         // verify focusOwner is a descendant of c
1589         for (Component temp = focusOwner; temp != null;
1590              temp = (temp instanceof Window) ? null : temp.getParent())
1591         {
1592             if (temp == c) {
1593                 return focusOwner;
1594             }
1595         }
1596 
1597         return null;
1598     }
1599 
1600     /**
1601      * If c is a JRootPane descendant return its JRootPane ancestor.


1631             }
1632             if (p instanceof Applet) {
1633                 applet = p;
1634             }
1635         }
1636         return applet;
1637     }
1638 
1639     static JComponent getPaintingOrigin(JComponent c) {
1640         Container p = c;
1641         while ((p = p.getParent()) instanceof JComponent) {
1642             JComponent jp = (JComponent) p;
1643             if (jp.isPaintingOrigin()) {
1644                 return jp;
1645             }
1646         }
1647         return null;
1648     }
1649 
1650     /**
1651      * Process the key bindings for the <code>Component</code> associated with
1652      * <code>event</code>. This method is only useful if
1653      * <code>event.getComponent()</code> does not descend from
1654      * <code>JComponent</code>, or your are not invoking
1655      * <code>super.processKeyEvent</code> from within your
1656      * <code>JComponent</code> subclass. <code>JComponent</code>
1657      * automatically processes bindings from within its
1658      * <code>processKeyEvent</code> method, hence you rarely need
1659      * to directly invoke this method.
1660      *
1661      * @param event KeyEvent used to identify which bindings to process, as
1662      *              well as which Component has focus.
1663      * @return true if a binding has found and processed
1664      * @since 1.4
1665      */
1666     public static boolean processKeyBindings(KeyEvent event) {
1667         if (event != null) {
1668             if (event.isConsumed()) {
1669                 return false;
1670             }
1671 
1672             Component component = event.getComponent();
1673             boolean pressed = (event.getID() == KeyEvent.KEY_PRESSED);
1674 
1675             if (!isValidKeyEventForKeyBindings(event)) {
1676                 return false;
1677             }
1678             // Find the first JComponent in the ancestor hierarchy, and
1679             // invoke processKeyBindings on it
1680             while (component != null) {
1681                 if (component instanceof JComponent) {
1682                     return ((JComponent)component).processKeyBindings(
1683                                                    event, pressed);
1684                 }
1685                 if ((component instanceof Applet) ||
1686                     (component instanceof Window)) {
1687                     // No JComponents, if Window or Applet parent, process
1688                     // WHEN_IN_FOCUSED_WINDOW bindings.
1689                     return JComponent.processKeyBindingsForAllComponents(
1690                                   event, (Container)component, pressed);
1691                 }
1692                 component = component.getParent();
1693             }
1694         }
1695         return false;
1696     }
1697 
1698     /**
1699      * Returns true if the <code>e</code> is a valid KeyEvent to use in
1700      * processing the key bindings associated with JComponents.
1701      */
1702     static boolean isValidKeyEventForKeyBindings(KeyEvent e) {
1703         return true;
1704     }
1705 
1706     /**
1707      * Invokes <code>actionPerformed</code> on <code>action</code> if
1708      * <code>action</code> is enabled (and non-{@code null}). The command for the
1709      * ActionEvent is determined by:
1710      * <ol>
1711      *   <li>If the action was registered via
1712      *       <code>registerKeyboardAction</code>, then the command string
1713      *       passed in ({@code null} will be used if {@code null} was passed in).
1714      *   <li>Action value with name Action.ACTION_COMMAND_KEY, unless {@code null}.
1715      *   <li>String value of the KeyEvent, unless <code>getKeyChar</code>
1716      *       returns KeyEvent.CHAR_UNDEFINED..
1717      * </ol>
1718      * This will return true if <code>action</code> is non-{@code null} and
1719      * actionPerformed is invoked on it.
1720      *
1721      * @param action an action
1722      * @param ks a key stroke
1723      * @param event a key event
1724      * @param sender a sender
1725      * @param modifiers action modifiers
1726      * @return {@code true} if {@code action} is non-{@code null} and
1727      *         actionPerformed is invoked on it.
1728      *
1729      * @since 1.3
1730      */
1731     public static boolean notifyAction(Action action, KeyStroke ks,
1732                                        KeyEvent event, Object sender,
1733                                        int modifiers) {
1734         if (action == null) {
1735             return false;
1736         }
1737         if (action instanceof UIAction) {
1738             if (!((UIAction)action).isEnabled(sender)) {


1761 
1762         if (commandO != null) {
1763             command = commandO.toString();
1764         }
1765         else if (!stayNull && event.getKeyChar() != KeyEvent.CHAR_UNDEFINED) {
1766             command = String.valueOf(event.getKeyChar());
1767         }
1768         else {
1769             // Do null for undefined chars, or if registerKeyboardAction
1770             // was called with a null.
1771             command = null;
1772         }
1773         action.actionPerformed(new ActionEvent(sender,
1774                         ActionEvent.ACTION_PERFORMED, command, event.getWhen(),
1775                         modifiers));
1776         return true;
1777     }
1778 
1779 
1780     /**
1781      * Convenience method to change the UI InputMap for <code>component</code>
1782      * to <code>uiInputMap</code>. If <code>uiInputMap</code> is {@code null},
1783      * this removes any previously installed UI InputMap.
1784      *
1785      * @param component a component
1786      * @param type a type
1787      * @param uiInputMap an {@code InputMap}
1788      * @since 1.3
1789      */
1790     public static void replaceUIInputMap(JComponent component, int type,
1791                                          InputMap uiInputMap) {
1792         InputMap map = component.getInputMap(type, (uiInputMap != null));
1793 
1794         while (map != null) {
1795             InputMap parent = map.getParent();
1796             if (parent == null || (parent instanceof UIResource)) {
1797                 map.setParent(uiInputMap);
1798                 return;
1799             }
1800             map = parent;
1801         }
1802     }
1803 
1804 
1805     /**
1806      * Convenience method to change the UI ActionMap for <code>component</code>
1807      * to <code>uiActionMap</code>. If <code>uiActionMap</code> is {@code null},
1808      * this removes any previously installed UI ActionMap.
1809      *
1810      * @param component a component
1811      * @param uiActionMap an {@code ActionMap}
1812      * @since 1.3
1813      */
1814     public static void replaceUIActionMap(JComponent component,
1815                                           ActionMap uiActionMap) {
1816         ActionMap map = component.getActionMap((uiActionMap != null));
1817 
1818         while (map != null) {
1819             ActionMap parent = map.getParent();
1820             if (parent == null || (parent instanceof UIResource)) {
1821                 map.setParent(uiActionMap);
1822                 return;
1823             }
1824             map = parent;
1825         }
1826     }
1827 
1828 
1829     /**
1830      * Returns the InputMap provided by the UI for condition
1831      * <code>condition</code> in component <code>component</code>.
1832      * <p>This will return {@code null} if the UI has not installed an InputMap
1833      * of the specified type.
1834      *
1835      * @param component a component
1836      * @param condition a condition
1837      * @return the {@code ActionMap} provided by the UI for {@code condition}
1838      *         in the component, or {@code null} if the UI has not installed
1839      *         an InputMap of the specified type.
1840      * @since 1.3
1841      */
1842     public static InputMap getUIInputMap(JComponent component, int condition) {
1843         InputMap map = component.getInputMap(condition, false);
1844         while (map != null) {
1845             InputMap parent = map.getParent();
1846             if (parent instanceof UIResource) {
1847                 return parent;
1848             }
1849             map = parent;
1850         }
1851         return null;
1852     }
1853 
1854     /**
1855      * Returns the ActionMap provided by the UI
1856      * in component <code>component</code>.
1857      * <p>This will return {@code null} if the UI has not installed an ActionMap.
1858      *
1859      * @param component a component
1860      * @return the {@code ActionMap} provided by the UI in the component,
1861      *         or {@code null} if the UI has not installed an ActionMap.
1862      * @since 1.3
1863      */
1864     public static ActionMap getUIActionMap(JComponent component) {
1865         ActionMap map = component.getActionMap(false);
1866         while (map != null) {
1867             ActionMap parent = map.getParent();
1868             if (parent instanceof UIResource) {
1869                 return parent;
1870             }
1871             map = parent;
1872         }
1873         return null;
1874     }
1875 
1876 


1996 
1997     static Class<?> loadSystemClass(String className) throws ClassNotFoundException {
1998         ReflectUtil.checkPackageAccess(className);
1999         return Class.forName(className, true, Thread.currentThread().
2000                              getContextClassLoader());
2001     }
2002 
2003 
2004    /*
2005      * Convenience function for determining ComponentOrientation.  Helps us
2006      * avoid having Munge directives throughout the code.
2007      */
2008     static boolean isLeftToRight( Component c ) {
2009         return c.getComponentOrientation().isLeftToRight();
2010     }
2011     private SwingUtilities() {
2012         throw new Error("SwingUtilities is just a container for static methods");
2013     }
2014 
2015     /**
2016      * Returns true if the Icon <code>icon</code> is an instance of
2017      * ImageIcon, and the image it contains is the same as <code>image</code>.
2018      */
2019     static boolean doesIconReferenceImage(Icon icon, Image image) {
2020         Image iconImage = (icon != null && (icon instanceof ImageIcon)) ?
2021                            ((ImageIcon)icon).getImage() : null;
2022         return (iconImage == image);
2023     }
2024 
2025     /**
2026      * Returns index of the first occurrence of <code>mnemonic</code>
2027      * within string <code>text</code>. Matching algorithm is not
2028      * case-sensitive.
2029      *
2030      * @param text The text to search through, may be {@code null}
2031      * @param mnemonic The mnemonic to find the character for.
2032      * @return index into the string if exists, otherwise -1
2033      */
2034     static int findDisplayedMnemonicIndex(String text, int mnemonic) {
2035         if (text == null || mnemonic == '\0') {
2036             return -1;
2037         }
2038 
2039         char uc = Character.toUpperCase((char)mnemonic);
2040         char lc = Character.toLowerCase((char)mnemonic);
2041 
2042         int uci = text.indexOf(uc);
2043         int lci = text.indexOf(lc);
2044 
2045         if (uci == -1) {
2046             return lci;
2047         } else if(lci == -1) {
2048             return uci;
2049         } else {
2050             return (lci < uci) ? lci : uci;
2051         }
2052     }
2053 
2054     /**
2055      * Stores the position and size of
2056      * the inner painting area of the specified component
2057      * in <code>r</code> and returns <code>r</code>.
2058      * The position and size specify the bounds of the component,
2059      * adjusted so as not to include the border area (the insets).
2060      * This method is useful for classes
2061      * that implement painting code.
2062      *
2063      * @param c  the JComponent in question; if {@code null}, this method returns {@code null}
2064      * @param r  the Rectangle instance to be modified;
2065      *           may be {@code null}
2066      * @return {@code null} if the Component is {@code null};
2067      *         otherwise, returns the passed-in rectangle (if non-{@code null})
2068      *         or a new rectangle specifying position and size information
2069      *
2070      * @since 1.4
2071      */
2072     public static Rectangle calculateInnerArea(JComponent c, Rectangle r) {
2073         if (c == null) {
2074             return null;
2075         }
2076         Rectangle rect = r;
2077         Insets insets = c.getInsets();




  54 public class SwingUtilities implements SwingConstants
  55 {
  56     // These states are system-wide, rather than AppContext wide.
  57     private static boolean canAccessEventQueue = false;
  58     private static boolean eventQueueTested = false;
  59 
  60     /**
  61      * Indicates if we should change the drop target when a
  62      * {@code TransferHandler} is set.
  63      */
  64     private static boolean suppressDropSupport;
  65 
  66     /**
  67      * Indiciates if we've checked the system property for suppressing
  68      * drop support.
  69      */
  70     private static boolean checkedSuppressDropSupport;
  71 
  72 
  73     /**
  74      * Returns true if {@code setTransferHandler} should change the
  75      * {@code DropTarget}.
  76      */
  77     private static boolean getSuppressDropTarget() {
  78         if (!checkedSuppressDropSupport) {
  79             suppressDropSupport = Boolean.valueOf(
  80                 AccessController.doPrivileged(
  81                     new GetPropertyAction("suppressSwingDropSupport")));
  82             checkedSuppressDropSupport = true;
  83         }
  84         return suppressDropSupport;
  85     }
  86 
  87     /**
  88      * Installs a {@code DropTarget} on the component as necessary for a
  89      * {@code TransferHandler} change.
  90      */
  91     static void installSwingDropTargetAsNecessary(Component c,
  92                                                          TransferHandler t) {
  93 
  94         if (!getSuppressDropTarget()) {
  95             DropTarget dropHandler = c.getDropTarget();


 113      */
 114     public static final boolean isRectangleContainingRectangle(Rectangle a,Rectangle b) {
 115         return b.x >= a.x && (b.x + b.width) <= (a.x + a.width) &&
 116                 b.y >= a.y && (b.y + b.height) <= (a.y + a.height);
 117     }
 118 
 119     /**
 120      * Return the rectangle (0,0,bounds.width,bounds.height) for the component {@code aComponent}
 121      *
 122      * @param aComponent a component
 123      * @return the local bounds for the component {@code aComponent}
 124      */
 125     public static Rectangle getLocalBounds(Component aComponent) {
 126         Rectangle b = new Rectangle(aComponent.getBounds());
 127         b.x = b.y = 0;
 128         return b;
 129     }
 130 
 131 
 132     /**
 133      * Returns the first {@code Window} ancestor of {@code c}, or
 134      * {@code null} if {@code c} is not contained inside a {@code Window}.
 135      *
 136      * @param c {@code Component} to get {@code Window} ancestor
 137      *        of.
 138      * @return the first {@code Window} ancestor of {@code c}, or
 139      *         {@code null} if {@code c} is not contained inside a
 140      *         {@code Window}.
 141      * @since 1.3
 142      */
 143     public static Window getWindowAncestor(Component c) {
 144         for(Container p = c.getParent(); p != null; p = p.getParent()) {
 145             if (p instanceof Window) {
 146                 return (Window)p;
 147             }
 148         }
 149         return null;
 150     }
 151 
 152     /**
 153      * Converts the location {@code x y} to the
 154      * parents coordinate system, returning the location.
 155      */
 156     static Point convertScreenLocationToParent(Container parent,int x, int y) {
 157         for (Container p = parent; p != null; p = p.getParent()) {
 158             if (p instanceof Window) {
 159                 Point point = new Point(x, y);
 160 
 161                 SwingUtilities.convertPointFromScreen(point, parent);
 162                 return point;
 163             }
 164         }
 165         throw new Error("convertScreenLocationToParent: no window ancestor");
 166     }
 167 
 168     /**
 169      * Convert a {@code aPoint} in {@code source} coordinate system to
 170      * {@code destination} coordinate system.
 171      * If {@code source} is {@code null}, {@code aPoint} is assumed to be in {@code destination}'s
 172      * root component coordinate system.
 173      * If {@code destination} is {@code null}, {@code aPoint} will be converted to {@code source}'s
 174      * root component coordinate system.
 175      * If both {@code source} and {@code destination} are {@code null}, return {@code aPoint}
 176      * without any conversion.
 177      *
 178      * @param source the source component
 179      * @param aPoint the point
 180      * @param destination the destination component
 181      *
 182      * @return the converted coordinate
 183      */
 184     public static Point convertPoint(Component source,Point aPoint,Component destination) {
 185         Point p;
 186 
 187         if(source == null && destination == null)
 188             return aPoint;
 189         if(source == null) {
 190             source = getWindowAncestor(destination);
 191             if(source == null)
 192                 throw new Error("Source component not connected to component tree hierarchy");
 193         }
 194         p = new Point(aPoint);
 195         convertPointToScreen(p,source);
 196         if(destination == null) {
 197             destination = getWindowAncestor(source);
 198             if(destination == null)
 199                 throw new Error("Destination component not connected to component tree hierarchy");
 200         }
 201         convertPointFromScreen(p,destination);
 202         return p;
 203     }
 204 
 205     /**
 206      * Convert the point {@code (x,y)} in {@code source} coordinate system to
 207      * {@code destination} coordinate system.
 208      * If {@code source} is {@code null}, {@code (x,y)} is assumed to be in {@code destination}'s
 209      * root component coordinate system.
 210      * If {@code destination} is {@code null}, {@code (x,y)} will be converted to {@code source}'s
 211      * root component coordinate system.
 212      * If both {@code source} and {@code destination} are {@code null}, return {@code (x,y)}
 213      * without any conversion.
 214      *
 215      * @param source the source component
 216      * @param x the x-coordinate of the point
 217      * @param y the y-coordinate of the point
 218      * @param destination the destination component
 219      *
 220      * @return the converted coordinate
 221      */
 222     public static Point convertPoint(Component source,int x, int y,Component destination) {
 223         Point point = new Point(x,y);
 224         return convertPoint(source,point,destination);
 225     }
 226 
 227     /**
 228      * Convert the rectangle {@code aRectangle} in {@code source} coordinate system to
 229      * {@code destination} coordinate system.
 230      * If {@code source} is {@code null}, {@code aRectangle} is assumed to be in {@code destination}'s
 231      * root component coordinate system.
 232      * If {@code destination} is {@code null}, {@code aRectangle} will be converted to {@code source}'s
 233      * root component coordinate system.
 234      * If both {@code source} and {@code destination} are {@code null}, return {@code aRectangle}
 235      * without any conversion.
 236      *
 237      * @param source the source component
 238      * @param aRectangle a rectangle
 239      * @param destination the destination component
 240      *
 241      * @return the converted rectangle
 242      */
 243     public static Rectangle convertRectangle(Component source,Rectangle aRectangle,Component destination) {
 244         Point point = new Point(aRectangle.x,aRectangle.y);
 245         point =  convertPoint(source,point,destination);
 246         return new Rectangle(point.x,point.y,aRectangle.width,aRectangle.height);
 247     }
 248 
 249     /**
 250      * Convenience method for searching above {@code comp} in the
 251      * component hierarchy and returns the first object of class {@code c} it
 252      * finds. Can return {@code null}, if a class {@code c} cannot be found.
 253      *
 254      * @param c the class of a component
 255      * @param comp the component
 256      *
 257      * @return the ancestor of the {@code comp},
 258      *         or {@code null} if {@code c} cannot be found.
 259      */
 260     public static Container getAncestorOfClass(Class<?> c, Component comp)
 261     {
 262         if(comp == null || c == null)
 263             return null;
 264 
 265         Container parent = comp.getParent();
 266         while(parent != null && !(c.isInstance(parent)))
 267             parent = parent.getParent();
 268         return parent;
 269     }
 270 
 271     /**
 272      * Convenience method for searching above {@code comp} in the
 273      * component hierarchy and returns the first object of {@code name} it
 274      * finds. Can return {@code null}, if {@code name} cannot be found.
 275      *
 276      * @param name the name of a component
 277      * @param comp the component
 278      *
 279      * @return the ancestor of the {@code comp},
 280      *         or {@code null} if {@code name} cannot be found.
 281      */
 282     public static Container getAncestorNamed(String name, Component comp) {
 283         if(comp == null || name == null)
 284             return null;
 285 
 286         Container parent = comp.getParent();
 287         while(parent != null && !(name.equals(parent.getName())))
 288             parent = parent.getParent();
 289         return parent;
 290     }
 291 
 292     /**
 293      * Returns the deepest visible descendent Component of {@code parent}
 294      * that contains the location {@code x}, {@code y}.
 295      * If {@code parent} does not contain the specified location,
 296      * then {@code null} is returned.  If {@code parent} is not a
 297      * container, or none of {@code parent}'s visible descendents
 298      * contain the specified location, {@code parent} is returned.
 299      *
 300      * @param parent the root component to begin the search
 301      * @param x the x target location
 302      * @param y the y target location
 303      *
 304      * @return the deepest component
 305      */
 306     public static Component getDeepestComponentAt(Component parent, int x, int y) {
 307         if (!parent.contains(x, y)) {
 308             return null;
 309         }
 310         if (parent instanceof Container) {
 311             Component components[] = ((Container)parent).getComponents();
 312             for (Component comp : components) {
 313                 if (comp != null && comp.isVisible()) {
 314                     Point loc = comp.getLocation();
 315                     if (comp instanceof Container) {
 316                         comp = getDeepestComponentAt(comp, x - loc.x, y - loc.y);
 317                     } else {
 318                         comp = comp.getComponentAt(x - loc.x, y - loc.y);
 319                     }
 320                     if (comp != null && comp.isVisible()) {
 321                         return comp;
 322                     }
 323                 }
 324             }
 325         }
 326         return parent;
 327     }
 328 
 329 
 330     /**
 331      * Returns a MouseEvent similar to {@code sourceEvent} except that its x
 332      * and y members have been converted to {@code destination}'s coordinate
 333      * system.  If {@code source} is {@code null}, {@code sourceEvent} x and y members
 334      * are assumed to be into {@code destination}'s root component coordinate system.
 335      * If {@code destination} is {@code null}, the
 336      * returned MouseEvent will be in {@code source}'s coordinate system.
 337      * {@code sourceEvent} will not be changed. A new event is returned.
 338      * the {@code source} field of the returned event will be set
 339      * to {@code destination} if destination is non-{@code null}
 340      * use the translateMouseEvent() method to translate a mouse event from
 341      * one component to another without changing the source.
 342      *
 343      * @param source the source component
 344      * @param sourceEvent the source mouse event
 345      * @param destination the destination component
 346      *
 347      * @return the new mouse event
 348      */
 349     public static MouseEvent convertMouseEvent(Component source,
 350                                                MouseEvent sourceEvent,
 351                                                Component destination) {
 352         Point p = convertPoint(source,new Point(sourceEvent.getX(),
 353                                                 sourceEvent.getY()),
 354                                destination);
 355         Component newSource;
 356 
 357         if(destination != null)
 358             newSource = destination;
 359         else


 471                     y = pp.y;
 472                 } catch (IllegalComponentStateException icse) {
 473                     x = c.getX();
 474                     y = c.getY();
 475                 }
 476             } else {
 477                 x = c.getX();
 478                 y = c.getY();
 479             }
 480 
 481             p.x -= x;
 482             p.y -= y;
 483 
 484             if(c instanceof java.awt.Window || c instanceof java.applet.Applet)
 485                 break;
 486             c = c.getParent();
 487         } while(c != null);
 488     }
 489 
 490     /**
 491      * Returns the first {@code Window} ancestor of {@code c}, or
 492      * {@code null} if {@code c} is not contained inside a {@code Window}.
 493      * <p>
 494      * Note: This method provides the same functionality as
 495      * {@code getWindowAncestor}.
 496      *
 497      * @param c {@code Component} to get {@code Window} ancestor
 498      *        of.
 499      * @return the first {@code Window} ancestor of {@code c}, or
 500      *         {@code null} if {@code c} is not contained inside a
 501      *         {@code Window}.
 502      */
 503     public static Window windowForComponent(Component c) {
 504         return getWindowAncestor(c);
 505     }
 506 
 507     /**
 508      * Return {@code true} if a component {@code a} descends from a component {@code b}
 509      *
 510      * @param a the first component
 511      * @param b the second component
 512      * @return {@code true} if a component {@code a} descends from a component {@code b}
 513      */
 514     public static boolean isDescendingFrom(Component a,Component b) {
 515         if(a == b)
 516             return true;
 517         for(Container p = a.getParent();p!=null;p=p.getParent())
 518             if(p == b)
 519                 return true;
 520         return false;
 521     }
 522 
 523 
 524     /**
 525      * Convenience to calculate the intersection of two rectangles
 526      * without allocating a new rectangle.
 527      * If the two rectangles don't intersect,
 528      * then the returned rectangle begins at (0,0)
 529      * and has zero width and height.
 530      *
 531      * @param x       the X coordinate of the first rectangle's top-left point
 532      * @param y       the Y coordinate of the first rectangle's top-left point
 533      * @param width   the width of the first rectangle
 534      * @param height  the height of the first rectangle
 535      * @param dest    the second rectangle
 536      *
 537      * @return {@code dest}, modified to specify the intersection
 538      */
 539     public static Rectangle computeIntersection(int x,int y,int width,int height,Rectangle dest) {
 540         int x1 = (x > dest.x) ? x : dest.x;
 541         int x2 = ((x+width) < (dest.x + dest.width)) ? (x+width) : (dest.x + dest.width);
 542         int y1 = (y > dest.y) ? y : dest.y;
 543         int y2 = ((y + height) < (dest.y + dest.height) ? (y+height) : (dest.y + dest.height));
 544 
 545         dest.x = x1;
 546         dest.y = y1;
 547         dest.width = x2 - x1;
 548         dest.height = y2 - y1;
 549 
 550         // If rectangles don't intersect, return zero'd intersection.
 551         if (dest.width < 0 || dest.height < 0) {
 552             dest.x = dest.y = dest.width = dest.height = 0;
 553         }
 554 
 555         return dest;
 556     }
 557 
 558     /**
 559      * Convenience method that calculates the union of two rectangles
 560      * without allocating a new rectangle.
 561      *
 562      * @param x the x-coordinate of the first rectangle
 563      * @param y the y-coordinate of the first rectangle
 564      * @param width the width of the first rectangle
 565      * @param height the height of the first rectangle
 566      * @param dest  the coordinates of the second rectangle; the union
 567      *    of the two rectangles is returned in this rectangle
 568      * @return the {@code dest Rectangle}
 569      */
 570     public static Rectangle computeUnion(int x,int y,int width,int height,Rectangle dest) {
 571         int x1 = (x < dest.x) ? x : dest.x;
 572         int x2 = ((x+width) > (dest.x + dest.width)) ? (x+width) : (dest.x + dest.width);
 573         int y1 = (y < dest.y) ? y : dest.y;
 574         int y2 = ((y+height) > (dest.y + dest.height)) ? (y+height) : (dest.y + dest.height);
 575 
 576         dest.x = x1;
 577         dest.y = y1;
 578         dest.width = (x2 - x1);
 579         dest.height= (y2 - y1);
 580         return dest;
 581     }
 582 
 583     /**
 584      * Convenience returning an array of rect representing the regions within
 585      * {@code rectA} that do not overlap with {@code rectB}. If the
 586      * two Rects do not overlap, returns an empty array
 587      *
 588      * @param rectA the first rectangle
 589      * @param rectB the second rectangle
 590      *
 591      * @return an array of rectangles representing the regions within {@code rectA}
 592      *         that do not overlap with {@code rectB}.
 593      */
 594     public static Rectangle[] computeDifference(Rectangle rectA,Rectangle rectB) {
 595         if (rectB == null || !rectA.intersects(rectB) || isRectangleContainingRectangle(rectB,rectA)) {
 596             return new Rectangle[0];
 597         }
 598 
 599         Rectangle t = new Rectangle();
 600         Rectangle a=null,b=null,c=null,d=null;
 601         Rectangle result[];
 602         int rectCount = 0;
 603 
 604         /* rectA contains rectB */
 605         if (isRectangleContainingRectangle(rectA,rectB)) {


1198 
1199         iconR.x += dx;
1200         iconR.y += dy;
1201 
1202         if (lsb < 0) {
1203             // lsb is negative. Shift the x location so that the text is
1204             // visually drawn at the right location.
1205             textR.x -= lsb;
1206 
1207             textR.width += lsb;
1208         }
1209         if (rsb > 0) {
1210             textR.width -= rsb;
1211         }
1212 
1213         return text;
1214     }
1215 
1216 
1217     /**
1218      * Paints a component to the specified {@code Graphics}.
1219      * This method is primarily useful to render
1220      * {@code Component}s that don't exist as part of the visible
1221      * containment hierarchy, but are used for rendering.  For
1222      * example, if you are doing your own rendering and want to render
1223      * some text (or even HTML), you could make use of
1224      * {@code JLabel}'s text rendering support and have it paint
1225      * directly by way of this method, without adding the label to the
1226      * visible containment hierarchy.
1227      * <p>
1228      * This method makes use of {@code CellRendererPane} to handle
1229      * the actual painting, and is only recommended if you use one
1230      * component for rendering.  If you make use of multiple components
1231      * to handle the rendering, as {@code JTable} does, use
1232      * {@code CellRendererPane} directly.  Otherwise, as described
1233      * below, you could end up with a {@code CellRendererPane}
1234      * per {@code Component}.
1235      * <p>
1236      * If {@code c}'s parent is not a {@code CellRendererPane},
1237      * a new {@code CellRendererPane} is created, {@code c} is
1238      * added to it, and the {@code CellRendererPane} is added to
1239      * {@code p}.  If {@code c}'s parent is a
1240      * {@code CellRendererPane} and the {@code CellRendererPane}s
1241      * parent is not {@code p}, it is added to {@code p}.
1242      * <p>
1243      * The component should either descend from {@code JComponent}
1244      * or be another kind of lightweight component.
1245      * A lightweight component is one whose "lightweight" property
1246      * (returned by the {@code Component}
1247      * {@code isLightweight} method)
1248      * is true. If the Component is not lightweight, bad things map happen:
1249      * crashes, exceptions, painting problems...
1250      *
1251      * @param g  the {@code Graphics} object to draw on
1252      * @param c  the {@code Component} to draw
1253      * @param p  the intermediate {@code Container}
1254      * @param x  an int specifying the left side of the area draw in, in pixels,
1255      *           measured from the left edge of the graphics context
1256      * @param y  an int specifying the top of the area to draw in, in pixels
1257      *           measured down from the top edge of the graphics context
1258      * @param w  an int specifying the width of the area draw in, in pixels
1259      * @param h  an int specifying the height of the area draw in, in pixels
1260      *
1261      * @see CellRendererPane
1262      * @see java.awt.Component#isLightweight
1263      */
1264     public static void paintComponent(Graphics g, Component c, Container p, int x, int y, int w, int h) {
1265         getCellRendererPane(c, p).paintComponent(g, c, p, x, y, w, h,false);
1266     }
1267 
1268     /**
1269      * Paints a component to the specified {@code Graphics}.  This
1270      * is a cover method for
1271      * {@link #paintComponent(Graphics,Component,Container,int,int,int,int)}.
1272      * Refer to it for more information.
1273      *
1274      * @param g  the {@code Graphics} object to draw on
1275      * @param c  the {@code Component} to draw
1276      * @param p  the intermediate {@code Container}
1277      * @param r  the {@code Rectangle} to draw in
1278      *
1279      * @see #paintComponent(Graphics,Component,Container,int,int,int,int)
1280      * @see CellRendererPane
1281      */
1282     public static void paintComponent(Graphics g, Component c, Container p, Rectangle r) {
1283         paintComponent(g, c, p, r.x, r.y, r.width, r.height);
1284     }
1285 
1286 
1287     /*
1288      * Ensures that cell renderer {@code c} has a
1289      * {@code ComponentShell} parent and that
1290      * the shell's parent is p.
1291      */
1292     private static CellRendererPane getCellRendererPane(Component c, Container p) {
1293         Container shell = c.getParent();
1294         if (shell instanceof CellRendererPane) {
1295             if (shell.getParent() != p) {
1296                 p.add(shell);
1297             }
1298         } else {
1299             shell = new CellRendererPane();
1300             shell.add(c);
1301             p.add(shell);
1302         }
1303         return (CellRendererPane)shell;
1304     }
1305 
1306     /**
1307      * A simple minded look and feel change: ask each node in the tree
1308      * to {@code updateUI()} -- that is, to initialize its UI property
1309      * with the current look and feel.
1310      *
1311      * @param c the component
1312      */
1313     public static void updateComponentTreeUI(Component c) {
1314         updateComponentTreeUI0(c);
1315         c.invalidate();
1316         c.validate();
1317         c.repaint();
1318     }
1319 
1320     private static void updateComponentTreeUI0(Component c) {
1321         if (c instanceof JComponent) {
1322             JComponent jc = (JComponent) c;
1323             jc.updateUI();
1324             JPopupMenu jpm =jc.getComponentPopupMenu();
1325             if(jpm != null) {
1326                 updateComponentTreeUI(jpm);
1327             }
1328         }
1329         Component[] children = null;
1330         if (c instanceof JMenu) {
1331             children = ((JMenu)c).getMenuComponents();
1332         }
1333         else if (c instanceof Container) {
1334             children = ((Container)c).getComponents();
1335         }
1336         if (children != null) {
1337             for (Component child : children) {
1338                 updateComponentTreeUI0(child);
1339             }
1340         }
1341     }
1342 
1343 
1344     /**
1345      * Causes <i>doRun.run()</i> to be executed asynchronously on the
1346      * AWT event dispatching thread.  This will happen after all
1347      * pending AWT events have been processed.  This method should
1348      * be used when an application thread needs to update the GUI.
1349      * In the following example the {@code invokeLater} call queues
1350      * the {@code Runnable} object {@code doHelloWorld}
1351      * on the event dispatching thread and
1352      * then prints a message.
1353      * <pre>
1354      * Runnable doHelloWorld = new Runnable() {
1355      *     public void run() {
1356      *         System.out.println("Hello World on " + Thread.currentThread());
1357      *     }
1358      * };
1359      *
1360      * SwingUtilities.invokeLater(doHelloWorld);
1361      * System.out.println("This might well be displayed before the other message.");
1362      * </pre>
1363      * If invokeLater is called from the event dispatching thread --
1364      * for example, from a JButton's ActionListener -- the <i>doRun.run()</i> will
1365      * still be deferred until all pending events have been processed.
1366      * Note that if the <i>doRun.run()</i> throws an uncaught exception
1367      * the event dispatching thread will unwind (not the current thread).
1368      * <p>
1369      * Additional documentation and examples for this method can be
1370      * found in
1371      * <A HREF="http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency in Swing</a>.
1372      * <p>
1373      * As of 1.3 this method is just a cover for {@code java.awt.EventQueue.invokeLater()}.
1374      * <p>
1375      * Unlike the rest of Swing, this method can be invoked from any thread.
1376      *
1377      * @param doRun the instance of {@code Runnable}
1378      * @see #invokeAndWait
1379      */
1380     public static void invokeLater(Runnable doRun) {
1381         EventQueue.invokeLater(doRun);
1382     }
1383 
1384 
1385     /**
1386      * Causes {@code doRun.run()} to be executed synchronously on the
1387      * AWT event dispatching thread.  This call blocks until
1388      * all pending AWT events have been processed and (then)
1389      * {@code doRun.run()} returns. This method should
1390      * be used when an application thread needs to update the GUI.
1391      * It shouldn't be called from the event dispatching thread.
1392      * Here's an example that creates a new application thread
1393      * that uses {@code invokeAndWait} to print a string from the event
1394      * dispatching thread and then, when that's finished, print
1395      * a string from the application thread.
1396      * <pre>
1397      * final Runnable doHelloWorld = new Runnable() {
1398      *     public void run() {
1399      *         System.out.println("Hello World on " + Thread.currentThread());
1400      *     }
1401      * };
1402      *
1403      * Thread appThread = new Thread() {
1404      *     public void run() {
1405      *         try {
1406      *             SwingUtilities.invokeAndWait(doHelloWorld);
1407      *         }
1408      *         catch (Exception e) {
1409      *             e.printStackTrace();
1410      *         }
1411      *         System.out.println("Finished on " + Thread.currentThread());
1412      *     }
1413      * };
1414      * appThread.start();
1415      * </pre>
1416      * Note that if the {@code Runnable.run} method throws an
1417      * uncaught exception
1418      * (on the event dispatching thread) it's caught and rethrown, as
1419      * an {@code InvocationTargetException}, on the caller's thread.
1420      * <p>
1421      * Additional documentation and examples for this method can be
1422      * found in
1423      * <A HREF="http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency in Swing</a>.
1424      * <p>
1425      * As of 1.3 this method is just a cover for
1426      * {@code java.awt.EventQueue.invokeAndWait()}.
1427      *
1428      * @param doRun the instance of {@code Runnable}
1429      * @exception  InterruptedException if we're interrupted while waiting for
1430      *             the event dispatching thread to finish executing
1431      *             {@code doRun.run()}
1432      * @exception  InvocationTargetException  if an exception is thrown
1433      *             while running {@code doRun}
1434      *
1435      * @see #invokeLater
1436      */
1437     public static void invokeAndWait(final Runnable doRun)
1438         throws InterruptedException, InvocationTargetException
1439     {
1440         EventQueue.invokeAndWait(doRun);
1441     }
1442 
1443     /**
1444      * Returns true if the current thread is an AWT event dispatching thread.
1445      * <p>
1446      * As of 1.3 this method is just a cover for
1447      * {@code java.awt.EventQueue.isDispatchThread()}.
1448      *
1449      * @return true if the current thread is an AWT event dispatching thread
1450      */
1451     public static boolean isEventDispatchThread()
1452     {
1453         return EventQueue.isDispatchThread();
1454     }
1455 
1456 
1457     /*
1458      * --- Accessibility Support ---
1459      *
1460      */
1461 
1462     /**
1463      * Get the index of this object in its accessible parent.<p>
1464      *
1465      * Note: as of the Java 2 platform v1.3, it is recommended that developers call
1466      * Component.AccessibleAWTComponent.getAccessibleIndexInParent() instead
1467      * of using this method.
1468      *
1469      * @param c the component
1470      * @return -1 of this object does not have an accessible parent.
1471      * Otherwise, the index of the child in its accessible parent.
1472      */
1473     public static int getAccessibleIndexInParent(Component c) {
1474         return c.getAccessibleContext().getAccessibleIndexInParent();
1475     }
1476 
1477     /**
1478      * Returns the {@code Accessible} child contained at the
1479      * local coordinate {@code Point}, if one exists.
1480      * Otherwise returns {@code null}.
1481      *
1482      * @param c the component
1483      * @param p the local coordinate
1484      * @return the {@code Accessible} at the specified location,
1485      *    if it exists; otherwise {@code null}
1486      */
1487     public static Accessible getAccessibleAt(Component c, Point p) {
1488         if (c instanceof Container) {
1489             return c.getAccessibleContext().getAccessibleComponent().getAccessibleAt(p);
1490         } else if (c instanceof Accessible) {
1491             Accessible a = (Accessible) c;
1492             if (a != null) {
1493                 AccessibleContext ac = a.getAccessibleContext();
1494                 if (ac != null) {
1495                     AccessibleComponent acmp;
1496                     Point location;
1497                     int nchildren = ac.getAccessibleChildrenCount();
1498                     for (int i=0; i < nchildren; i++) {
1499                         a = ac.getAccessibleChild(i);
1500                         if ((a != null)) {
1501                             ac = a.getAccessibleContext();
1502                             if (ac != null) {
1503                                 acmp = ac.getAccessibleComponent();
1504                                 if ((acmp != null) && (acmp.isShowing())) {
1505                                     location = acmp.getLocation();


1550     public static int getAccessibleChildrenCount(Component c) {
1551         return c.getAccessibleContext().getAccessibleChildrenCount();
1552     }
1553 
1554     /**
1555      * Return the nth Accessible child of the object. <p>
1556      *
1557      * Note: as of the Java 2 platform v1.3, it is recommended that developers call
1558      * Component.AccessibleAWTComponent.getAccessibleIndexInParent() instead
1559      * of using this method.
1560      *
1561      * @param c the component
1562      * @param i zero-based index of child
1563      * @return the nth Accessible child of the object
1564      */
1565     public static Accessible getAccessibleChild(Component c, int i) {
1566         return c.getAccessibleContext().getAccessibleChild(i);
1567     }
1568 
1569     /**
1570      * Return the child {@code Component} of the specified
1571      * {@code Component} that is the focus owner, if any.
1572      *
1573      * @param c the root of the {@code Component} hierarchy to
1574      *        search for the focus owner
1575      * @return the focus owner, or {@code null} if there is no focus
1576      *         owner, or if the focus owner is not {@code comp}, or a
1577      *         descendant of {@code comp}
1578      *
1579      * @see java.awt.KeyboardFocusManager#getFocusOwner
1580      * @deprecated As of 1.4, replaced by
1581      *   {@code KeyboardFocusManager.getFocusOwner()}.
1582      */
1583     @Deprecated
1584     public static Component findFocusOwner(Component c) {
1585         Component focusOwner = KeyboardFocusManager.
1586             getCurrentKeyboardFocusManager().getFocusOwner();
1587 
1588         // verify focusOwner is a descendant of c
1589         for (Component temp = focusOwner; temp != null;
1590              temp = (temp instanceof Window) ? null : temp.getParent())
1591         {
1592             if (temp == c) {
1593                 return focusOwner;
1594             }
1595         }
1596 
1597         return null;
1598     }
1599 
1600     /**
1601      * If c is a JRootPane descendant return its JRootPane ancestor.


1631             }
1632             if (p instanceof Applet) {
1633                 applet = p;
1634             }
1635         }
1636         return applet;
1637     }
1638 
1639     static JComponent getPaintingOrigin(JComponent c) {
1640         Container p = c;
1641         while ((p = p.getParent()) instanceof JComponent) {
1642             JComponent jp = (JComponent) p;
1643             if (jp.isPaintingOrigin()) {
1644                 return jp;
1645             }
1646         }
1647         return null;
1648     }
1649 
1650     /**
1651      * Process the key bindings for the {@code Component} associated with
1652      * {@code event}. This method is only useful if
1653      * {@code event.getComponent()} does not descend from
1654      * {@code JComponent}, or your are not invoking
1655      * {@code super.processKeyEvent} from within your
1656      * {@code JComponent} subclass. {@code JComponent}
1657      * automatically processes bindings from within its
1658      * {@code processKeyEvent} method, hence you rarely need
1659      * to directly invoke this method.
1660      *
1661      * @param event KeyEvent used to identify which bindings to process, as
1662      *              well as which Component has focus.
1663      * @return true if a binding has found and processed
1664      * @since 1.4
1665      */
1666     public static boolean processKeyBindings(KeyEvent event) {
1667         if (event != null) {
1668             if (event.isConsumed()) {
1669                 return false;
1670             }
1671 
1672             Component component = event.getComponent();
1673             boolean pressed = (event.getID() == KeyEvent.KEY_PRESSED);
1674 
1675             if (!isValidKeyEventForKeyBindings(event)) {
1676                 return false;
1677             }
1678             // Find the first JComponent in the ancestor hierarchy, and
1679             // invoke processKeyBindings on it
1680             while (component != null) {
1681                 if (component instanceof JComponent) {
1682                     return ((JComponent)component).processKeyBindings(
1683                                                    event, pressed);
1684                 }
1685                 if ((component instanceof Applet) ||
1686                     (component instanceof Window)) {
1687                     // No JComponents, if Window or Applet parent, process
1688                     // WHEN_IN_FOCUSED_WINDOW bindings.
1689                     return JComponent.processKeyBindingsForAllComponents(
1690                                   event, (Container)component, pressed);
1691                 }
1692                 component = component.getParent();
1693             }
1694         }
1695         return false;
1696     }
1697 
1698     /**
1699      * Returns true if the {@code e} is a valid KeyEvent to use in
1700      * processing the key bindings associated with JComponents.
1701      */
1702     static boolean isValidKeyEventForKeyBindings(KeyEvent e) {
1703         return true;
1704     }
1705 
1706     /**
1707      * Invokes {@code actionPerformed} on {@code action} if
1708      * {@code action} is enabled (and non-{@code null}). The command for the
1709      * ActionEvent is determined by:
1710      * <ol>
1711      *   <li>If the action was registered via
1712      *       {@code registerKeyboardAction}, then the command string
1713      *       passed in ({@code null} will be used if {@code null} was passed in).
1714      *   <li>Action value with name Action.ACTION_COMMAND_KEY, unless {@code null}.
1715      *   <li>String value of the KeyEvent, unless {@code getKeyChar}
1716      *       returns KeyEvent.CHAR_UNDEFINED..
1717      * </ol>
1718      * This will return true if {@code action} is non-{@code null} and
1719      * actionPerformed is invoked on it.
1720      *
1721      * @param action an action
1722      * @param ks a key stroke
1723      * @param event a key event
1724      * @param sender a sender
1725      * @param modifiers action modifiers
1726      * @return {@code true} if {@code action} is non-{@code null} and
1727      *         actionPerformed is invoked on it.
1728      *
1729      * @since 1.3
1730      */
1731     public static boolean notifyAction(Action action, KeyStroke ks,
1732                                        KeyEvent event, Object sender,
1733                                        int modifiers) {
1734         if (action == null) {
1735             return false;
1736         }
1737         if (action instanceof UIAction) {
1738             if (!((UIAction)action).isEnabled(sender)) {


1761 
1762         if (commandO != null) {
1763             command = commandO.toString();
1764         }
1765         else if (!stayNull && event.getKeyChar() != KeyEvent.CHAR_UNDEFINED) {
1766             command = String.valueOf(event.getKeyChar());
1767         }
1768         else {
1769             // Do null for undefined chars, or if registerKeyboardAction
1770             // was called with a null.
1771             command = null;
1772         }
1773         action.actionPerformed(new ActionEvent(sender,
1774                         ActionEvent.ACTION_PERFORMED, command, event.getWhen(),
1775                         modifiers));
1776         return true;
1777     }
1778 
1779 
1780     /**
1781      * Convenience method to change the UI InputMap for {@code component}
1782      * to {@code uiInputMap}. If {@code uiInputMap} is {@code null},
1783      * this removes any previously installed UI InputMap.
1784      *
1785      * @param component a component
1786      * @param type a type
1787      * @param uiInputMap an {@code InputMap}
1788      * @since 1.3
1789      */
1790     public static void replaceUIInputMap(JComponent component, int type,
1791                                          InputMap uiInputMap) {
1792         InputMap map = component.getInputMap(type, (uiInputMap != null));
1793 
1794         while (map != null) {
1795             InputMap parent = map.getParent();
1796             if (parent == null || (parent instanceof UIResource)) {
1797                 map.setParent(uiInputMap);
1798                 return;
1799             }
1800             map = parent;
1801         }
1802     }
1803 
1804 
1805     /**
1806      * Convenience method to change the UI ActionMap for {@code component}
1807      * to {@code uiActionMap}. If {@code uiActionMap} is {@code null},
1808      * this removes any previously installed UI ActionMap.
1809      *
1810      * @param component a component
1811      * @param uiActionMap an {@code ActionMap}
1812      * @since 1.3
1813      */
1814     public static void replaceUIActionMap(JComponent component,
1815                                           ActionMap uiActionMap) {
1816         ActionMap map = component.getActionMap((uiActionMap != null));
1817 
1818         while (map != null) {
1819             ActionMap parent = map.getParent();
1820             if (parent == null || (parent instanceof UIResource)) {
1821                 map.setParent(uiActionMap);
1822                 return;
1823             }
1824             map = parent;
1825         }
1826     }
1827 
1828 
1829     /**
1830      * Returns the InputMap provided by the UI for condition
1831      * {@code condition} in component {@code component}.
1832      * <p>This will return {@code null} if the UI has not installed an InputMap
1833      * of the specified type.
1834      *
1835      * @param component a component
1836      * @param condition a condition
1837      * @return the {@code ActionMap} provided by the UI for {@code condition}
1838      *         in the component, or {@code null} if the UI has not installed
1839      *         an InputMap of the specified type.
1840      * @since 1.3
1841      */
1842     public static InputMap getUIInputMap(JComponent component, int condition) {
1843         InputMap map = component.getInputMap(condition, false);
1844         while (map != null) {
1845             InputMap parent = map.getParent();
1846             if (parent instanceof UIResource) {
1847                 return parent;
1848             }
1849             map = parent;
1850         }
1851         return null;
1852     }
1853 
1854     /**
1855      * Returns the ActionMap provided by the UI
1856      * in component {@code component}.
1857      * <p>This will return {@code null} if the UI has not installed an ActionMap.
1858      *
1859      * @param component a component
1860      * @return the {@code ActionMap} provided by the UI in the component,
1861      *         or {@code null} if the UI has not installed an ActionMap.
1862      * @since 1.3
1863      */
1864     public static ActionMap getUIActionMap(JComponent component) {
1865         ActionMap map = component.getActionMap(false);
1866         while (map != null) {
1867             ActionMap parent = map.getParent();
1868             if (parent instanceof UIResource) {
1869                 return parent;
1870             }
1871             map = parent;
1872         }
1873         return null;
1874     }
1875 
1876 


1996 
1997     static Class<?> loadSystemClass(String className) throws ClassNotFoundException {
1998         ReflectUtil.checkPackageAccess(className);
1999         return Class.forName(className, true, Thread.currentThread().
2000                              getContextClassLoader());
2001     }
2002 
2003 
2004    /*
2005      * Convenience function for determining ComponentOrientation.  Helps us
2006      * avoid having Munge directives throughout the code.
2007      */
2008     static boolean isLeftToRight( Component c ) {
2009         return c.getComponentOrientation().isLeftToRight();
2010     }
2011     private SwingUtilities() {
2012         throw new Error("SwingUtilities is just a container for static methods");
2013     }
2014 
2015     /**
2016      * Returns true if the Icon {@code icon} is an instance of
2017      * ImageIcon, and the image it contains is the same as {@code image}.
2018      */
2019     static boolean doesIconReferenceImage(Icon icon, Image image) {
2020         Image iconImage = (icon != null && (icon instanceof ImageIcon)) ?
2021                            ((ImageIcon)icon).getImage() : null;
2022         return (iconImage == image);
2023     }
2024 
2025     /**
2026      * Returns index of the first occurrence of {@code mnemonic}
2027      * within string {@code text}. Matching algorithm is not
2028      * case-sensitive.
2029      *
2030      * @param text The text to search through, may be {@code null}
2031      * @param mnemonic The mnemonic to find the character for.
2032      * @return index into the string if exists, otherwise -1
2033      */
2034     static int findDisplayedMnemonicIndex(String text, int mnemonic) {
2035         if (text == null || mnemonic == '\0') {
2036             return -1;
2037         }
2038 
2039         char uc = Character.toUpperCase((char)mnemonic);
2040         char lc = Character.toLowerCase((char)mnemonic);
2041 
2042         int uci = text.indexOf(uc);
2043         int lci = text.indexOf(lc);
2044 
2045         if (uci == -1) {
2046             return lci;
2047         } else if(lci == -1) {
2048             return uci;
2049         } else {
2050             return (lci < uci) ? lci : uci;
2051         }
2052     }
2053 
2054     /**
2055      * Stores the position and size of
2056      * the inner painting area of the specified component
2057      * in {@code r} and returns {@code r}.
2058      * The position and size specify the bounds of the component,
2059      * adjusted so as not to include the border area (the insets).
2060      * This method is useful for classes
2061      * that implement painting code.
2062      *
2063      * @param c  the JComponent in question; if {@code null}, this method returns {@code null}
2064      * @param r  the Rectangle instance to be modified;
2065      *           may be {@code null}
2066      * @return {@code null} if the Component is {@code null};
2067      *         otherwise, returns the passed-in rectangle (if non-{@code null})
2068      *         or a new rectangle specifying position and size information
2069      *
2070      * @since 1.4
2071      */
2072     public static Rectangle calculateInnerArea(JComponent c, Rectangle r) {
2073         if (c == null) {
2074             return null;
2075         }
2076         Rectangle rect = r;
2077         Insets insets = c.getInsets();


< prev index next >