KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > swing > SwingUtilities


1 /*
2  * @(#)SwingUtilities.java 1.134 04/06/15
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7 package javax.swing;
8
9 import com.sun.java.swing.SwingUtilities2;
10 import sun.swing.UIAction;
11
12 import java.applet.*;
13
14 import java.awt.*;
15 import java.awt.event.*;
16
17 import java.util.Vector JavaDoc;
18 import java.util.Hashtable JavaDoc;
19
20 import java.lang.reflect.*;
21
22 import javax.accessibility.*;
23 import javax.swing.event.MenuDragMouseEvent JavaDoc;
24 import javax.swing.plaf.UIResource JavaDoc;
25 import javax.swing.text.View JavaDoc;
26
27 import sun.awt.AppContext;
28
29 /**
30  * A collection of utility methods for Swing.
31  *
32  * @version 1.134 06/15/04
33  * @author unknown
34  */

35 public class SwingUtilities implements SwingConstants JavaDoc
36 {
37     // These states are system-wide, rather than AppContext wide.
38
private static boolean canAccessEventQueue = false;
39     private static boolean eventQueueTested = false;
40
41
42     /**
43      * Return true if <code>a</code> contains <code>b</code>
44      */

45     public static final boolean isRectangleContainingRectangle(Rectangle a,Rectangle b) {
46         if (b.x >= a.x && (b.x + b.width) <= (a.x + a.width) &&
47             b.y >= a.y && (b.y + b.height) <= (a.y + a.height)) {
48             return true;
49         }
50         return false;
51     }
52
53     /**
54      * Return the rectangle (0,0,bounds.width,bounds.height) for the component <code>aComponent</code>
55      */

56     public static Rectangle getLocalBounds(Component aComponent) {
57         Rectangle b = new Rectangle(aComponent.getBounds());
58         b.x = b.y = 0;
59         return b;
60     }
61
62
63     /**
64      * Returns the first <code>Window </code> ancestor of <code>c</code>, or
65      * null if <code>c</code> is not contained inside a <code>Window</code>.
66      *
67      * @param c <code>Component</code> to get <code>Window</code> ancestor
68      * of.
69      * @return the first <code>Window </code> ancestor of <code>c</code>, or
70      * null if <code>c</code> is not contained inside a
71      * <code>Window</code>.
72      */

73     public static Window getWindowAncestor(Component c) {
74         for(Container p = c.getParent(); p != null; p = p.getParent()) {
75             if (p instanceof Window) {
76                 return (Window)p;
77             }
78         }
79         return null;
80     }
81
82     /**
83      * Converts the location <code>x</code> <code>y</code> to the
84      * parents coordinate system, returning the location.
85      */

86     static Point convertScreenLocationToParent(Container parent,int x, int y) {
87         for (Container p = parent; p != null; p = p.getParent()) {
88             if (p instanceof Window) {
89                 Point point = new Point(x, y);
90
91                 SwingUtilities.convertPointFromScreen(point, parent);
92                 return point;
93             }
94         }
95         throw new Error JavaDoc("convertScreenLocationToParent: no window ancestor");
96     }
97
98     /**
99      * Convert a <code>aPoint</code> in <code>source</code> coordinate system to
100      * <code>destination</code> coordinate system.
101      * If <code>source></code>is null,<code>aPoint</code> is assumed to be in <code>destination</code>'s
102      * root component coordinate system.
103      * If <code>destination</code>is null, <code>aPoint</code> will be converted to <code>source</code>'s
104      * root component coordinate system.
105      * If both <code>source</code> and <code>destination</code> are null, return <code>aPoint</code>
106      * without any conversion.
107      */

108     public static Point convertPoint(Component source,Point aPoint,Component destination) {
109         Point p;
110
111         if(source == null && destination == null)
112             return aPoint;
113         if(source == null) {
114             source = getWindowAncestor(destination);
115             if(source == null)
116                 throw new Error JavaDoc("Source component not connected to component tree hierarchy");
117         }
118         p = new Point(aPoint);
119         convertPointToScreen(p,source);
120         if(destination == null) {
121             destination = getWindowAncestor(source);
122             if(destination == null)
123                 throw new Error JavaDoc("Destination component not connected to component tree hierarchy");
124         }
125         convertPointFromScreen(p,destination);
126         return p;
127     }
128
129     /**
130      * Convert the point <code>(x,y)</code> in <code>source</code> coordinate system to
131      * <code>destination</code> coordinate system.
132      * If <code>source></code>is null,<code>(x,y)</code> is assumed to be in <code>destination</code>'s
133      * root component coordinate system.
134      * If <code>destination</code>is null, <code>(x,y)</code> will be converted to <code>source</code>'s
135      * root component coordinate system.
136      * If both <code>source</code> and <code>destination</code> are null, return <code>(x,y)</code>
137      * without any conversion.
138      */

139     public static Point convertPoint(Component source,int x, int y,Component destination) {
140         Point point = new Point(x,y);
141         return convertPoint(source,point,destination);
142     }
143
144     /**
145      * Convert the rectangle <code>aRectangle</code> in <code>source</code> coordinate system to
146      * <code>destination</code> coordinate system.
147      * If <code>source></code>is null,<code>aRectangle</code> is assumed to be in <code>destination</code>'s
148      * root component coordinate system.
149      * If <code>destination</code>is null, <code>aRectangle</code> will be converted to <code>source</code>'s
150      * root component coordinate system.
151      * If both <code>source</code> and <code>destination</code> are null, return <code>aRectangle</code>
152      * without any conversion.
153      */

154     public static Rectangle convertRectangle(Component source,Rectangle aRectangle,Component destination) {
155         Point point = new Point(aRectangle.x,aRectangle.y);
156         point = convertPoint(source,point,destination);
157         return new Rectangle(point.x,point.y,aRectangle.width,aRectangle.height);
158     }
159
160     /**
161      * Convenience method for searching above <code>comp</code> in the
162      * component hierarchy and returns the first object of class <code>c</code> it
163      * finds. Can return null, if a class <code>c</code> cannot be found.
164      */

165     public static Container getAncestorOfClass(Class JavaDoc<?> c, Component comp)
166     {
167         if(comp == null || c == null)
168             return null;
169
170         Container parent = comp.getParent();
171         while(parent != null && !(c.isInstance(parent)))
172             parent = parent.getParent();
173         return parent;
174     }
175
176     /**
177      * Convenience method for searching above <code>comp</code> in the
178      * component hierarchy and returns the first object of <code>name</code> it
179      * finds. Can return null, if <code>name</code> cannot be found.
180      */

181     public static Container getAncestorNamed(String JavaDoc name, Component comp) {
182         if(comp == null || name == null)
183             return null;
184
185         Container parent = comp.getParent();
186         while(parent != null && !(name.equals(parent.getName())))
187             parent = parent.getParent();
188         return parent;
189     }
190
191     /**
192      * Returns the deepest visible descendent Component of <code>parent</code>
193      * that contains the location <code>x</code>, <code>y</code>.
194      * If <code>parent</code> does not contain the specified location,
195      * then <code>null</code> is returned. If <code>parent</code> is not a
196      * container, or none of <code>parent</code>'s visible descendents
197      * contain the specified location, <code>parent</code> is returned.
198      *
199      * @param parent the root component to begin the search
200      * @param x the x target location
201      * @param y the y target location
202      */

203     public static Component getDeepestComponentAt(Component parent, int x, int y) {
204         if (!parent.contains(x, y)) {
205             return null;
206         }
207         if (parent instanceof Container) {
208             Component components[] = ((Container)parent).getComponents();
209             for (int i = 0 ; i < components.length ; i++) {
210                 Component comp = components[i];
211                 if (comp != null && comp.isVisible()) {
212                     Point loc = comp.getLocation();
213                     if (comp instanceof Container) {
214                         comp = getDeepestComponentAt(comp, x - loc.x, y - loc.y);
215                     } else {
216                         comp = comp.getComponentAt(x - loc.x, y - loc.y);
217                     }
218                     if (comp != null && comp.isVisible()) {
219                         return comp;
220                     }
221                 }
222             }
223         }
224         return parent;
225     }
226
227
228     /**
229      * Returns a MouseEvent similar to <code>sourceEvent</code> except that its x
230      * and y members have been converted to <code>destination</code>'s coordinate
231      * system. If <code>source</code> is null, <code>sourceEvent</code> x and y members
232      * are assumed to be into <code>destination</code>'s root component coordinate system.
233      * If <code>destination</code> is <code>null</code>, the
234      * returned MouseEvent will be in <code>source</code>'s coordinate system.
235      * <code>sourceEvent</code> will not be changed. A new event is returned.
236      * the <code>source</code> field of the returned event will be set
237      * to <code>destination</code> if destination is non null
238      * use the translateMouseEvent() method to translate a mouse event from
239      * one component to another without changing the source.
240      */

241     public static MouseEvent JavaDoc convertMouseEvent(Component source,
242                                                MouseEvent JavaDoc sourceEvent,
243                                                Component destination) {
244         Point p = convertPoint(source,new Point(sourceEvent.getX(),
245                                                 sourceEvent.getY()),
246                                destination);
247         Component newSource;
248
249         if(destination != null)
250             newSource = destination;
251         else
252             newSource = source;
253
254     MouseEvent JavaDoc newEvent;
255     if (sourceEvent instanceof MouseWheelEvent) {
256         MouseWheelEvent sourceWheelEvent = (MouseWheelEvent)sourceEvent;
257         newEvent = new MouseWheelEvent(newSource,
258                        sourceWheelEvent.getID(),
259                        sourceWheelEvent.getWhen(),
260                        sourceWheelEvent.getModifiers(),
261                        p.x,p.y,
262                        sourceWheelEvent.getClickCount(),
263                        sourceWheelEvent.isPopupTrigger(),
264                        sourceWheelEvent.getScrollType(),
265                        sourceWheelEvent.getScrollAmount(),
266                        sourceWheelEvent.getWheelRotation());
267     }
268     else if (sourceEvent instanceof MenuDragMouseEvent JavaDoc) {
269         MenuDragMouseEvent JavaDoc sourceMenuDragEvent = (MenuDragMouseEvent JavaDoc)sourceEvent;
270         newEvent = new MenuDragMouseEvent JavaDoc(newSource,
271                           sourceMenuDragEvent.getID(),
272                           sourceMenuDragEvent.getWhen(),
273                           sourceMenuDragEvent.getModifiers(),
274                           p.x,p.y,
275                           sourceMenuDragEvent.getClickCount(),
276                           sourceMenuDragEvent.isPopupTrigger(),
277                           sourceMenuDragEvent.getPath(),
278                           sourceMenuDragEvent.getMenuSelectionManager());
279     }
280     else {
281         newEvent = new MouseEvent JavaDoc(newSource,
282                       sourceEvent.getID(),
283                       sourceEvent.getWhen(),
284                       sourceEvent.getModifiers(),
285                       p.x,p.y,
286                       sourceEvent.getClickCount(),
287                       sourceEvent.isPopupTrigger());
288     }
289     return newEvent;
290     }
291
292
293     /**
294      * Convert a point from a component's coordinate system to
295      * screen coordinates.
296      *
297      * @param p a Point object (converted to the new coordinate system)
298      * @param c a Component object
299      */

300     public static void convertPointToScreen(Point p,Component c) {
301             Rectangle b;
302             int x,y;
303
304             do {
305                 if(c instanceof JComponent JavaDoc) {
306                     x = ((JComponent JavaDoc)c).getX();
307                     y = ((JComponent JavaDoc)c).getY();
308                 } else if(c instanceof java.applet.Applet JavaDoc ||
309                           c instanceof java.awt.Window JavaDoc) {
310                     try {
311                         Point pp = c.getLocationOnScreen();
312                         x = pp.x;
313                         y = pp.y;
314                     } catch (IllegalComponentStateException icse) {
315             x = c.getX();
316             y = c.getY();
317                     }
318                 } else {
319                     x = c.getX();
320                     y = c.getY();
321                 }
322
323                 p.x += x;
324                 p.y += y;
325
326                 if(c instanceof java.awt.Window JavaDoc || c instanceof java.applet.Applet JavaDoc)
327                     break;
328                 c = c.getParent();
329             } while(c != null);
330         }
331
332     /**
333      * Convert a point from a screen coordinates to a component's
334      * coordinate system
335      *
336      * @param p a Point object (converted to the new coordinate system)
337      * @param c a Component object
338      */

339     public static void convertPointFromScreen(Point p,Component c) {
340         Rectangle b;
341         int x,y;
342
343         do {
344             if(c instanceof JComponent JavaDoc) {
345                 x = ((JComponent JavaDoc)c).getX();
346                 y = ((JComponent JavaDoc)c).getY();
347             } else if(c instanceof java.applet.Applet JavaDoc ||
348                        c instanceof java.awt.Window JavaDoc) {
349                 try {
350                     Point pp = c.getLocationOnScreen();
351                     x = pp.x;
352                     y = pp.y;
353                 } catch (IllegalComponentStateException icse) {
354             x = c.getX();
355             y = c.getY();
356                 }
357             } else {
358         x = c.getX();
359         y = c.getY();
360             }
361
362             p.x -= x;
363             p.y -= y;
364
365             if(c instanceof java.awt.Window JavaDoc || c instanceof java.applet.Applet JavaDoc)
366                 break;
367             c = c.getParent();
368         } while(c != null);
369     }
370
371     /**
372      * Returns the first <code>Window </code> ancestor of <code>c</code>, or
373      * null if <code>c</code> is not contained inside a <code>Window</code>.
374      * <p>
375      * Note: This method provides the same functionality as
376      * <code>getWindowAncestor</code>.
377      *
378      * @param c <code>Component</code> to get <code>Window</code> ancestor
379      * of.
380      * @return the first <code>Window </code> ancestor of <code>c</code>, or
381      * null if <code>c</code> is not contained inside a
382      * <code>Window</code>.
383      */

384     public static Window windowForComponent(Component c) {
385         return getWindowAncestor(c);
386     }
387
388     /**
389      * Return <code>true</code> if a component <code>a</code> descends from a component <code>b</code>
390      */

391     public static boolean isDescendingFrom(Component a,Component b) {
392         if(a == b)
393             return true;
394         for(Container p = a.getParent();p!=null;p=p.getParent())
395             if(p == b)
396                 return true;
397         return false;
398     }
399
400
401     /**
402      * Convenience to calculate the intersection of two rectangles
403      * without allocating a new rectangle.
404      * If the two rectangles don't intersect,
405      * then the returned rectangle begins at (0,0)
406      * and has zero width and height.
407      *
408      * @param x the X coordinate of the first rectangle's top-left point
409      * @param y the Y coordinate of the first rectangle's top-left point
410      * @param width the width of the first rectangle
411      * @param height the height of the first rectangle
412      * @param dest the second rectangle
413      *
414      * @return <code>dest</code>, modified to specify the intersection
415      */

416     public static Rectangle computeIntersection(int x,int y,int width,int height,Rectangle dest) {
417         int x1 = (x > dest.x) ? x : dest.x;
418         int x2 = ((x+width) < (dest.x + dest.width)) ? (x+width) : (dest.x + dest.width);
419         int y1 = (y > dest.y) ? y : dest.y;
420         int y2 = ((y + height) < (dest.y + dest.height) ? (y+height) : (dest.y + dest.height));
421
422         dest.x = x1;
423         dest.y = y1;
424         dest.width = x2 - x1;
425         dest.height = y2 - y1;
426
427     // If rectangles don't intersect, return zero'd intersection.
428
if (dest.width < 0 || dest.height < 0) {
429         dest.x = dest.y = dest.width = dest.height = 0;
430     }
431
432         return dest;
433     }
434
435     /**
436      * Convenience method that calculates the union of two rectangles
437      * without allocating a new rectangle.
438      *
439      * @param x the x-coordinate of the first rectangle
440      * @param y the y-coordinate of the first rectangle
441      * @param width the width of the first rectangle
442      * @param height the height of the first rectangle
443      * @param dest the coordinates of the second rectangle; the union
444      * of the two rectangles is returned in this rectangle
445      * @return the <code>dest</code> <code>Rectangle</code>
446      */

447     public static Rectangle computeUnion(int x,int y,int width,int height,Rectangle dest) {
448         int x1 = (x < dest.x) ? x : dest.x;
449         int x2 = ((x+width) > (dest.x + dest.width)) ? (x+width) : (dest.x + dest.width);
450         int y1 = (y < dest.y) ? y : dest.y;
451         int y2 = ((y+height) > (dest.y + dest.height)) ? (y+height) : (dest.y + dest.height);
452
453         dest.x = x1;
454         dest.y = y1;
455         dest.width = (x2 - x1);
456         dest.height= (y2 - y1);
457         return dest;
458     }
459
460     /**
461      * Convenience returning an array of rect representing the regions within
462      * <code>rectA</code> that do not overlap with <code>rectB</code>. If the
463      * two Rects do not overlap, returns an empty array
464      */

465     public static Rectangle[] computeDifference(Rectangle rectA,Rectangle rectB) {
466         if (rectB == null || !rectA.intersects(rectB) || isRectangleContainingRectangle(rectB,rectA)) {
467             return new Rectangle[0];
468         }
469
470         Rectangle t = new Rectangle();
471         Rectangle a=null,b=null,c=null,d=null;
472         Rectangle result[];
473         int rectCount = 0;
474
475         /* rectA contains rectB */
476         if (isRectangleContainingRectangle(rectA,rectB)) {
477             t.x = rectA.x; t.y = rectA.y; t.width = rectB.x - rectA.x; t.height = rectA.height;
478             if(t.width > 0 && t.height > 0) {
479                 a = new Rectangle(t);
480                 rectCount++;
481             }
482
483             t.x = rectB.x; t.y = rectA.y; t.width = rectB.width; t.height = rectB.y - rectA.y;
484             if(t.width > 0 && t.height > 0) {
485                 b = new Rectangle(t);
486                 rectCount++;
487             }
488
489             t.x = rectB.x; t.y = rectB.y + rectB.height; t.width = rectB.width;
490             t.height = rectA.y + rectA.height - (rectB.y + rectB.height);
491             if(t.width > 0 && t.height > 0) {
492                 c = new Rectangle(t);
493                 rectCount++;
494             }
495
496             t.x = rectB.x + rectB.width; t.y = rectA.y; t.width = rectA.x + rectA.width - (rectB.x + rectB.width);
497             t.height = rectA.height;
498             if(t.width > 0 && t.height > 0) {
499                 d = new Rectangle(t);
500                 rectCount++;
501             }
502         } else {
503             /* 1 */
504             if (rectB.x <= rectA.x && rectB.y <= rectA.y) {
505                 if ((rectB.x + rectB.width) > (rectA.x + rectA.width)) {
506
507                     t.x = rectA.x; t.y = rectB.y + rectB.height;
508                     t.width = rectA.width; t.height = rectA.y + rectA.height - (rectB.y + rectB.height);
509                     if(t.width > 0 && t.height > 0) {
510                         a = t;
511                         rectCount++;
512                     }
513                 } else if ((rectB.y + rectB.height) > (rectA.y + rectA.height)) {
514                     t.setBounds((rectB.x + rectB.width), rectA.y,
515                                 (rectA.x + rectA.width) - (rectB.x + rectB.width), rectA.height);
516                     if(t.width > 0 && t.height > 0) {
517                         a = t;
518                         rectCount++;
519                     }
520                 } else {
521                     t.setBounds((rectB.x + rectB.width), rectA.y,
522                                 (rectA.x + rectA.width) - (rectB.x + rectB.width),
523                                 (rectB.y + rectB.height) - rectA.y);
524                     if(t.width > 0 && t.height > 0) {
525                         a = new Rectangle(t);
526                         rectCount++;
527                     }
528
529                     t.setBounds(rectA.x, (rectB.y + rectB.height), rectA.width,
530                                 (rectA.y + rectA.height) - (rectB.y + rectB.height));
531                     if(t.width > 0 && t.height > 0) {
532                         b = new Rectangle(t);
533                         rectCount++;
534                     }
535                 }
536             } else if (rectB.x <= rectA.x && (rectB.y + rectB.height) >= (rectA.y + rectA.height)) {
537                 if ((rectB.x + rectB.width) > (rectA.x + rectA.width)) {
538                     t.setBounds(rectA.x, rectA.y, rectA.width, rectB.y - rectA.y);
539                     if(t.width > 0 && t.height > 0) {
540                         a = t;
541                         rectCount++;
542                     }
543                 } else {
544                     t.setBounds(rectA.x, rectA.y, rectA.width, rectB.y - rectA.y);
545                     if(t.width > 0 && t.height > 0) {
546                         a = new Rectangle(t);
547                         rectCount++;
548                     }
549                     t.setBounds((rectB.x + rectB.width), rectB.y,
550                                 (rectA.x + rectA.width) - (rectB.x + rectB.width),
551                                 (rectA.y + rectA.height) - rectB.y);
552                     if(t.width > 0 && t.height > 0) {
553                         b = new Rectangle(t);
554                         rectCount++;
555                     }
556                 }
557             } else if (rectB.x <= rectA.x) {
558                 if ((rectB.x + rectB.width) >= (rectA.x + rectA.width)) {
559                     t.setBounds(rectA.x, rectA.y, rectA.width, rectB.y - rectA.y);
560                     if(t.width>0 && t.height > 0) {
561                         a = new Rectangle(t);
562                         rectCount++;
563                     }
564
565                     t.setBounds(rectA.x, (rectB.y + rectB.height), rectA.width,
566                                 (rectA.y + rectA.height) - (rectB.y + rectB.height));
567                     if(t.width > 0 && t.height > 0) {
568                         b = new Rectangle(t);
569                         rectCount++;
570                     }
571                 } else {
572                     t.setBounds(rectA.x, rectA.y, rectA.width, rectB.y - rectA.y);
573                     if(t.width > 0 && t.height > 0) {
574                         a = new Rectangle(t);
575                         rectCount++;
576                     }
577
578                     t.setBounds((rectB.x + rectB.width), rectB.y,
579                                 (rectA.x + rectA.width) - (rectB.x + rectB.width),
580                                 rectB.height);
581                     if(t.width > 0 && t.height > 0) {
582                         b = new Rectangle(t);
583                         rectCount++;
584                     }
585
586                     t.setBounds(rectA.x, (rectB.y + rectB.height), rectA.width,
587                                 (rectA.y + rectA.height) - (rectB.y + rectB.height));
588                     if(t.width > 0 && t.height > 0) {
589                         c = new Rectangle(t);
590                         rectCount++;
591                     }
592                 }
593             } else if (rectB.x <= (rectA.x + rectA.width) && (rectB.x + rectB.width) > (rectA.x + rectA.width)) {
594                 if (rectB.y <= rectA.y && (rectB.y + rectB.height) > (rectA.y + rectA.height)) {
595                     t.setBounds(rectA.x, rectA.y, rectB.x - rectA.x, rectA.height);
596                     if(t.width > 0 && t.height > 0) {
597                         a = t;
598                         rectCount++;
599                     }
600                 } else if (rectB.y <= rectA.y) {
601                     t.setBounds(rectA.x, rectA.y, rectB.x - rectA.x,
602                                 (rectB.y + rectB.height) - rectA.y);
603                     if(t.width > 0 && t.height > 0) {
604                         a = new Rectangle(t);
605                         rectCount++;
606                     }
607
608                     t.setBounds(rectA.x, (rectB.y + rectB.height), rectA.width,
609                                 (rectA.y + rectA.height) - (rectB.y + rectB.height));
610                     if(t.width > 0 && t.height > 0) {
611                         b = new Rectangle(t);
612                         rectCount++;
613                     }
614                 } else if ((rectB.y + rectB.height) > (rectA.y + rectA.height)) {
615                     t.setBounds(rectA.x, rectA.y, rectA.width, rectB.y - rectA.y);
616                     if(t.width > 0 && t.height > 0) {
617                         a = new Rectangle(t);
618                         rectCount++;
619                     }
620
621                     t.setBounds(rectA.x, rectB.y, rectB.x - rectA.x,
622                                 (rectA.y + rectA.height) - rectB.y);
623                     if(t.width > 0 && t.height > 0) {
624                         b = new Rectangle(t);
625                         rectCount++;
626                     }
627                 } else {
628                     t.setBounds(rectA.x, rectA.y, rectA.width, rectB.y - rectA.y);
629                     if(t.width > 0 && t.height > 0) {
630                         a = new Rectangle(t);
631                         rectCount++;
632                     }
633
634                     t.setBounds(rectA.x, rectB.y, rectB.x - rectA.x,
635                                 rectB.height);
636                     if(t.width > 0 && t.height > 0) {
637                         b = new Rectangle(t);
638                         rectCount++;
639                     }
640
641                     t.setBounds(rectA.x, (rectB.y + rectB.height), rectA.width,
642                                 (rectA.y + rectA.height) - (rectB.y + rectB.height));
643                     if(t.width > 0 && t.height > 0) {
644                         c = new Rectangle(t);
645                         rectCount++;
646                     }
647                 }
648             } else if (rectB.x >= rectA.x && (rectB.x + rectB.width) <= (rectA.x + rectA.width)) {
649                 if (rectB.y <= rectA.y && (rectB.y + rectB.height) > (rectA.y + rectA.height)) {
650                     t.setBounds(rectA.x, rectA.y, rectB.x - rectA.x, rectA.height);
651                     if(t.width > 0 && t.height > 0) {
652                         a = new Rectangle(t);
653                         rectCount++;
654                     }
655                     t.setBounds((rectB.x + rectB.width), rectA.y,
656                                 (rectA.x + rectA.width) - (rectB.x + rectB.width), rectA.height);
657                     if(t.width > 0 && t.height > 0) {
658                         b = new Rectangle(t);
659                         rectCount++;
660                     }
661                 } else if (rectB.y <= rectA.y) {
662                     t.setBounds(rectA.x, rectA.y, rectB.x - rectA.x, rectA.height);
663                     if(t.width > 0 && t.height > 0) {
664                         a = new Rectangle(t);
665                         rectCount++;
666                     }
667
668                     t.setBounds(rectB.x, (rectB.y + rectB.height),
669                                 rectB.width,
670                                 (rectA.y + rectA.height) - (rectB.y + rectB.height));
671                     if(t.width > 0 && t.height > 0) {
672                         b = new Rectangle(t);
673                         rectCount++;
674                     }
675
676                     t.setBounds((rectB.x + rectB.width), rectA.y,
677                                 (rectA.x + rectA.width) - (rectB.x + rectB.width), rectA.height);
678                     if(t.width > 0 && t.height > 0) {
679                         c = new Rectangle(t);
680                         rectCount++;
681                     }
682                 } else {
683                     t.setBounds(rectA.x, rectA.y, rectB.x - rectA.x, rectA.height);
684                     if(t.width > 0 && t.height > 0) {
685                         a = new Rectangle(t);
686                         rectCount++;
687                     }
688
689                     t.setBounds(rectB.x, rectA.y, rectB.width,
690                                 rectB.y - rectA.y);
691                     if(t.width > 0 && t.height > 0) {
692                         b = new Rectangle(t);
693                         rectCount++;
694                     }
695
696                     t.setBounds((rectB.x + rectB.width), rectA.y,
697                                 (rectA.x + rectA.width) - (rectB.x + rectB.width), rectA.height);
698                     if(t.width > 0 && t.height > 0) {
699                         c = new Rectangle(t);
700                         rectCount++;
701                     }
702                 }
703             }
704         }
705
706         result = new Rectangle[rectCount];
707         rectCount = 0;
708         if(a != null)
709             result[rectCount++] = a;
710         if(b != null)
711             result[rectCount++] = b;
712         if(c != null)
713             result[rectCount++] = c;
714         if(d != null)
715             result[rectCount++] = d;
716         return result;
717     }
718
719     /**
720      * Returns true if the mouse event specifies the left mouse button.
721      *
722      * @param anEvent a MouseEvent object
723      * @return true if the left mouse button was active
724      */

725     public static boolean isLeftMouseButton(MouseEvent JavaDoc anEvent) {
726          return ((anEvent.getModifiers() & InputEvent.BUTTON1_MASK) != 0);
727     }
728
729     /**
730      * Returns true if the mouse event specifies the middle mouse button.
731      *
732      * @param anEvent a MouseEvent object
733      * @return true if the middle mouse button was active
734      */

735     public static boolean isMiddleMouseButton(MouseEvent JavaDoc anEvent) {
736         return ((anEvent.getModifiers() & InputEvent.BUTTON2_MASK) == InputEvent.BUTTON2_MASK);
737     }
738
739     /**
740      * Returns true if the mouse event specifies the right mouse button.
741      *
742      * @param anEvent a MouseEvent object
743      * @return true if the right mouse button was active
744      */

745     public static boolean isRightMouseButton(MouseEvent JavaDoc anEvent) {
746         return ((anEvent.getModifiers() & InputEvent.BUTTON3_MASK) == InputEvent.BUTTON3_MASK);
747     }
748
749     /**
750      * Compute the width of the string using a font with the specified
751      * "metrics" (sizes).
752      *
753      * @param fm a FontMetrics object to compute with
754      * @param str the String to compute
755      * @return an int containing the string width
756      */

757     public static int computeStringWidth(FontMetrics fm,String JavaDoc str) {
758         // You can't assume that a string's width is the sum of its
759
// characters' widths in Java2D -- it may be smaller due to
760 <