OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [libjava/] [classpath/] [gnu/] [java/] [awt/] [AWTUtilities.java] - Blame information for rev 14

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 14 jlechner
/* AWTUtilities.java -- Common utility methods for AWT and Swing.
2
   Copyright (C) 2005  Free Software Foundation, Inc.
3
 
4
This file is part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2, or (at your option)
9
any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; see the file COPYING.  If not, write to the
18
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
02110-1301 USA.
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
independent module, the terms and conditions of the license of that
32
module.  An independent module is a module which is not derived from
33
or based on this library.  If you modify this library, you may extend
34
this exception to your version of the library, but you are not
35
obligated to do so.  If you do not wish to do so, delete this
36
exception statement from your version. */
37
 
38
package gnu.java.awt;
39
 
40
import java.applet.Applet;
41
import java.awt.Component;
42
import java.awt.Container;
43
import java.awt.Font;
44
import java.awt.FontMetrics;
45
import java.awt.Insets;
46
import java.awt.Point;
47
import java.awt.Rectangle;
48
import java.awt.Toolkit;
49
import java.awt.Window;
50
import java.awt.event.MouseEvent;
51
import java.util.AbstractSequentialList;
52
import java.util.List;
53
import java.util.ListIterator;
54
import java.util.NoSuchElementException;
55
import java.util.WeakHashMap;
56
import java.lang.reflect.InvocationTargetException;
57
 
58
/**
59
 * This class mirrors the javax.swing.SwingUtilities class. It
60
 * provides commonly needed functionalities for AWT classes without
61
 * the need to reference classes in the javax.swing package.
62
 */
63
public class AWTUtilities
64
{
65
 
66
  /**
67
   * This List implementation wraps the Component[] returned by
68
   * {@link Container#getComponents()} and iterates over the visible Components
69
   * in that array. This class is used in {@link #getVisibleChildren}.
70
   */
71
  static class VisibleComponentList extends AbstractSequentialList
72
  {
73
    /**
74
     * The ListIterator for this List.
75
     */
76
    class VisibleComponentIterator implements ListIterator
77
    {
78
      /** The current index in the Component[]. */
79
      int index;
80
 
81
      /** The index in the List of visible Components. */
82
      int listIndex;
83
 
84
      /**
85
       * Creates a new VisibleComponentIterator that starts at the specified
86
       * <code>listIndex</code>. The array of Components is searched from
87
       * the beginning to find the matching array index.
88
       *
89
       * @param listIndex the index from where to begin iterating
90
       */
91
      VisibleComponentIterator(int listIndex)
92
      {
93
        this.listIndex = listIndex;
94
        int visibleComponentsFound = 0;
95
        for (index = 0; visibleComponentsFound != listIndex; index++)
96
          {
97
            if (components[index].isVisible())
98
              visibleComponentsFound++;
99
          }
100
      }
101
 
102
      /**
103
       * Returns <code>true</code> if there are more visible components in the
104
       * array, <code>false</code> otherwise.
105
       *
106
       * @return <code>true</code> if there are more visible components in the
107
       *     array, <code>false</code> otherwise
108
       */
109
      public boolean hasNext()
110
      {
111
        boolean hasNext = false;
112
        for (int i = index; i < components.length; i++)
113
          {
114
            if (components[i].isVisible())
115
              {
116
                hasNext = true;
117
                break;
118
              }
119
          }
120
        return hasNext;
121
      }
122
 
123
      /**
124
       * Returns the next visible <code>Component</code> in the List.
125
       *
126
       * @return the next visible <code>Component</code> in the List
127
       *
128
       * @throws if there is no next element
129
       */
130
      public Object next()
131
      {
132
        Object o = null;
133
        for (; index < components.length; index++)
134
          {
135
            if (components[index].isVisible())
136
              {
137
                o = components[index];
138
                break;
139
              }
140
          }
141
        if (o != null)
142
          {
143
            index++;
144
            listIndex++;
145
            return o;
146
          }
147
        else
148
          throw new NoSuchElementException();
149
      }
150
 
151
      /**
152
       * Returns <code>true</code> if there are more visible components in the
153
       * array in the reverse direction, <code>false</code> otherwise.
154
       *
155
       * @return <code>true</code> if there are more visible components in the
156
       *     array in the reverse direction, <code>false</code> otherwise
157
       */
158
      public boolean hasPrevious()
159
      {
160
        boolean hasPrevious = false;
161
        for (int i = index - 1; i >= 0; i--)
162
          {
163
            if (components[i].isVisible())
164
              {
165
                hasPrevious = true;
166
                break;
167
              }
168
          }
169
        return hasPrevious;
170
      }
171
 
172
      /**
173
       * Returns the previous visible <code>Component</code> in the List.
174
       *
175
       * @return the previous visible <code>Component</code> in the List
176
       *
177
       * @throws NoSuchElementException if there is no previous element
178
       */
179
      public Object previous()
180
      {
181
        Object o = null;
182
        for (index--; index >= 0; index--)
183
          {
184
            if (components[index].isVisible())
185
              {
186
                o = components[index];
187
                break;
188
              }
189
          }
190
        if (o != null)
191
          {
192
            listIndex--;
193
            return o;
194
          }
195
        else
196
          throw new NoSuchElementException();
197
      }
198
 
199
      /**
200
       * Returns the index of the next element in the List.
201
       *
202
       * @return the index of the next element in the List
203
       */
204
      public int nextIndex()
205
      {
206
        return listIndex + 1;
207
      }
208
 
209
      /**
210
       * Returns the index of the previous element in the List.
211
       *
212
       * @return the index of the previous element in the List
213
       */
214
      public int previousIndex()
215
      {
216
        return listIndex - 1;
217
      }
218
 
219
      /**
220
       * This operation is not supported because the List is immutable.
221
       *
222
       * @throws UnsupportedOperationException because the List is immutable
223
       */
224
      public void remove()
225
      {
226
        throw new UnsupportedOperationException
227
          ("VisibleComponentList is immutable");
228
      }
229
 
230
      /**
231
       * This operation is not supported because the List is immutable.
232
       *
233
       * @param o not used here
234
       *
235
       * @throws UnsupportedOperationException because the List is immutable
236
       */
237
      public void set(Object o)
238
      {
239
        throw new UnsupportedOperationException
240
          ("VisibleComponentList is immutable");
241
      }
242
 
243
      /**
244
       * This operation is not supported because the List is immutable.
245
       *
246
       * @param o not used here
247
       *
248
       * @throws UnsupportedOperationException because the List is immutable
249
       */
250
      public void add(Object o)
251
      {
252
        throw new UnsupportedOperationException
253
          ("VisibleComponentList is immutable");
254
      }
255
    }
256
 
257
    /**
258
     * The components over which we iterate. Only the visible components
259
     * are returned by this List.
260
     */
261
    Component[] components;
262
 
263
    /**
264
     * Creates a new instance of VisibleComponentList that wraps the specified
265
     * <code>Component[]</code>.
266
     *
267
     * @param c the <code>Component[]</code> to be wrapped.
268
     */
269
    VisibleComponentList(Component[] c)
270
    {
271
      components = c;
272
    }
273
 
274
    /**
275
     * Returns a {@link ListIterator} for iterating over this List.
276
     *
277
     * @return a {@link ListIterator} for iterating over this List
278
     */
279
    public ListIterator listIterator(int index)
280
    {
281
      return new VisibleComponentIterator(index);
282
    }
283
 
284
    /**
285
     * Returns the number of visible components in the wrapped Component[].
286
     *
287
     * @return the number of visible components
288
     */
289
    public int size()
290
    {
291
      int visibleComponents = 0;
292
      for (int i = 0; i < components.length; i++)
293
        if (components[i].isVisible())
294
          visibleComponents++;
295
      return visibleComponents;
296
    }
297
  }
298
 
299
  /**
300
   * The cache for our List instances. We try to hold one instance of
301
   * VisibleComponentList for each Component[] that is requested. Note
302
   * that we use a WeakHashMap for caching, so that the cache itself
303
   * does not keep the array or the List from beeing garbage collected
304
   * if no other objects hold references to it.
305
   */
306
  static WeakHashMap visibleChildrenCache = new WeakHashMap();
307
 
308
  /**
309
   * Returns the visible children of a {@link Container}. This method is
310
   * commonly needed in LayoutManagers, because they only have to layout
311
   * the visible children of a Container.
312
   *
313
   * @param c the Container from which to extract the visible children
314
   *
315
   * @return the visible children of <code>c</code>
316
   */
317
  public static List getVisibleChildren(Container c)
318
  {
319
    Component[] children = c.getComponents();
320
    Object o = visibleChildrenCache.get(children);
321
    VisibleComponentList visibleChildren = null;
322
    if (o == null)
323
      {
324
        visibleChildren = new VisibleComponentList(children);
325
        visibleChildrenCache.put(children, visibleChildren);
326
      }
327
    else
328
      visibleChildren = (VisibleComponentList) o;
329
 
330
    return visibleChildren;
331
  }
332
 
333
  /**
334
   * Calculates the portion of the base rectangle which is inside the
335
   * insets.
336
   *
337
   * @param base The rectangle to apply the insets to
338
   * @param insets The insets to apply to the base rectangle
339
   * @param ret A rectangle to use for storing the return value, or
340
   * <code>null</code>
341
   *
342
   * @return The calculated area inside the base rectangle and its insets,
343
   * either stored in ret or a new Rectangle if ret is <code>null</code>
344
   *
345
   * @see #calculateInnerArea
346
   */
347
  public static Rectangle calculateInsetArea(Rectangle base, Insets insets,
348
                                             Rectangle ret)
349
  {
350
    if (ret == null)
351
      ret = new Rectangle();
352
    ret.setBounds(base.x + insets.left, base.y + insets.top,
353
        base.width - (insets.left + insets.right),
354
        base.height - (insets.top + insets.bottom));
355
    return ret;
356
  }
357
 
358
  /**
359
   * Calculates the bounds of a component in the component's own coordinate
360
   * space. The result has the same height and width as the component's
361
   * bounds, but its location is set to (0,0).
362
   *
363
   * @param aComponent The component to measure
364
   *
365
   * @return The component's bounds in its local coordinate space
366
   */
367
  public static Rectangle getLocalBounds(Component aComponent)
368
  {
369
    Rectangle bounds = aComponent.getBounds();
370
    return new Rectangle(0, 0, bounds.width, bounds.height);
371
  }
372
 
373
  /**
374
   * Returns the font metrics object for a given font. The metrics can be
375
   * used to calculate crude bounding boxes and positioning information,
376
   * for laying out components with textual elements.
377
   *
378
   * @param font The font to get metrics for
379
   *
380
   * @return The font's metrics
381
   *
382
   * @see java.awt.font.GlyphMetrics
383
   */
384
  public static FontMetrics getFontMetrics(Font font)
385
  {
386
    return Toolkit.getDefaultToolkit().getFontMetrics(font);
387
  }
388
 
389
  /**
390
   * Returns the least ancestor of <code>comp</code> which has the
391
   * specified name.
392
   *
393
   * @param name The name to search for
394
   * @param comp The component to search the ancestors of
395
   *
396
   * @return The nearest ancestor of <code>comp</code> with the given
397
   * name, or <code>null</code> if no such ancestor exists
398
   *
399
   * @see java.awt.Component#getName
400
   * @see #getAncestorOfClass
401
   */
402
  public static Container getAncestorNamed(String name, Component comp)
403
  {
404
    while (comp != null && (comp.getName() != name))
405
      comp = comp.getParent();
406
    return (Container) comp;
407
  }
408
 
409
  /**
410
   * Returns the least ancestor of <code>comp</code> which is an instance
411
   * of the specified class.
412
   *
413
   * @param c The class to search for
414
   * @param comp The component to search the ancestors of
415
   *
416
   * @return The nearest ancestor of <code>comp</code> which is an instance
417
   * of the given class, or <code>null</code> if no such ancestor exists
418
   *
419
   * @see #getAncestorOfClass
420
   * @see #windowForComponent
421
   * @see
422
   *
423
   */
424
  public static Container getAncestorOfClass(Class c, Component comp)
425
  {
426
    while (comp != null && (! c.isInstance(comp)))
427
      comp = comp.getParent();
428
    return (Container) comp;
429
  }
430
 
431
  /**
432
   * Equivalent to calling <code>getAncestorOfClass(Window, comp)</code>.
433
   *
434
   * @param comp The component to search for an ancestor window
435
   *
436
   * @return An ancestral window, or <code>null</code> if none exists
437
   */
438
  public static Window windowForComponent(Component comp)
439
  {
440
    return (Window) getAncestorOfClass(Window.class, comp);
441
  }
442
 
443
  /**
444
   * Returns the "root" of the component tree containint <code>comp</code>
445
   * The root is defined as either the <em>least</em> ancestor of
446
   * <code>comp</code> which is a {@link Window}, or the <em>greatest</em>
447
   * ancestor of <code>comp</code> which is a {@link Applet} if no {@link
448
   * Window} ancestors are found.
449
   *
450
   * @param comp The component to search for a root
451
   *
452
   * @return The root of the component's tree, or <code>null</code>
453
   */
454
  public static Component getRoot(Component comp)
455
  {
456
    Applet app = null;
457
    Window win = null;
458
 
459
    while (comp != null)
460
     {
461
      if (win == null && comp instanceof Window)
462
        win = (Window) comp;
463
      else if (comp instanceof Applet)
464
        app = (Applet) comp;
465
      comp = comp.getParent();
466
    }
467
 
468
    if (win != null)
469
      return win;
470
    else
471
      return app;
472
  }
473
 
474
  /**
475
   * Return true if a descends from b, in other words if b is an
476
   * ancestor of a.
477
   *
478
   * @param a The child to search the ancestry of
479
   * @param b The potential ancestor to search for
480
   *
481
   * @return true if a is a descendent of b, false otherwise
482
   */
483
  public static boolean isDescendingFrom(Component a, Component b)
484
  {
485
    while (true)
486
     {
487
      if (a == null || b == null)
488
        return false;
489
      if (a == b)
490
        return true;
491
      a = a.getParent();
492
    }
493
  }
494
 
495
  /**
496
   * Returns the deepest descendent of parent which is both visible and
497
   * contains the point <code>(x,y)</code>. Returns parent when either
498
   * parent is not a container, or has no children which contain
499
   * <code>(x,y)</code>. Returns <code>null</code> when either
500
   * <code>(x,y)</code> is outside the bounds of parent, or parent is
501
   * <code>null</code>.
502
   *
503
   * @param parent The component to search the descendents of
504
   * @param x Horizontal coordinate to search for
505
   * @param y Vertical coordinate to search for
506
   *
507
   * @return A component containing <code>(x,y)</code>, or
508
   * <code>null</code>
509
   *
510
   * @see java.awt.Container#findComponentAt
511
   */
512
  public static Component getDeepestComponentAt(Component parent, int x, int y)
513
  {
514
    if (parent == null || (! parent.contains(x, y)))
515
      return null;
516
 
517
    if (! (parent instanceof Container))
518
      return parent;
519
 
520
    Container c = (Container) parent;
521
    return c.findComponentAt(x, y);
522
  }
523
 
524
  /**
525
   * Converts a point from a component's local coordinate space to "screen"
526
   * coordinates (such as the coordinate space mouse events are delivered
527
   * in). This operation is equivalent to translating the point by the
528
   * location of the component (which is the origin of its coordinate
529
   * space).
530
   *
531
   * @param p The point to convert
532
   * @param c The component which the point is expressed in terms of
533
   *
534
   * @see convertPointFromScreen
535
   */
536
  public static void convertPointToScreen(Point p, Component c)
537
  {
538
    Point c0 = c.getLocationOnScreen();
539
    p.translate(c0.x, c0.y);
540
  }
541
 
542
  /**
543
   * Converts a point from "screen" coordinates (such as the coordinate
544
   * space mouse events are delivered in) to a component's local coordinate
545
   * space. This operation is equivalent to translating the point by the
546
   * negation of the component's location (which is the origin of its
547
   * coordinate space).
548
   *
549
   * @param p The point to convert
550
   * @param c The component which the point should be expressed in terms of
551
   */
552
  public static void convertPointFromScreen(Point p, Component c)
553
  {
554
    Point c0 = c.getLocationOnScreen();
555
    p.translate(-c0.x, -c0.y);
556
  }
557
 
558
  /**
559
   * Converts a point <code>(x,y)</code> from the coordinate space of one
560
   * component to another. This is equivalent to converting the point from
561
   * <code>source</code> space to screen space, then back from screen space
562
   * to <code>destination</code> space. If exactly one of the two
563
   * Components is <code>null</code>, it is taken to refer to the root
564
   * ancestor of the other component. If both are <code>null</code>, no
565
   * transformation is done.
566
   *
567
   * @param source The component which the point is expressed in terms of
568
   * @param x Horizontal coordinate of point to transform
569
   * @param y Vertical coordinate of point to transform
570
   * @param destination The component which the return value will be
571
   * expressed in terms of
572
   *
573
   * @return The point <code>(x,y)</code> converted from the coordinate
574
   *         space of the
575
   * source component to the coordinate space of the destination component
576
   *
577
   * @see #convertPointToScreen
578
   * @see #convertPointFromScreen
579
   * @see #convertRectangle
580
   * @see #getRoot
581
   */
582
  public static Point convertPoint(Component source, int x, int y,
583
                                   Component destination)
584
  {
585
    Point pt = new Point(x, y);
586
 
587
    if (source == null && destination == null)
588
      return pt;
589
 
590
    if (source == null)
591
      source = getRoot(destination);
592
 
593
    if (destination == null)
594
      destination = getRoot(source);
595
 
596
    if (source.isShowing() && destination.isShowing())
597
      {
598
        convertPointToScreen(pt, source);
599
        convertPointFromScreen(pt, destination);
600
      }
601
 
602
    return pt;
603
  }
604
 
605
 
606
  /**
607
   * Converts a rectangle from the coordinate space of one component to
608
   * another. This is equivalent to converting the rectangle from
609
   * <code>source</code> space to screen space, then back from screen space
610
   * to <code>destination</code> space. If exactly one of the two
611
   * Components is <code>null</code>, it is taken to refer to the root
612
   * ancestor of the other component. If both are <code>null</code>, no
613
   * transformation is done.
614
   *
615
   * @param source The component which the rectangle is expressed in terms of
616
   * @param rect The rectangle to convert
617
   * @param destination The component which the return value will be
618
   * expressed in terms of
619
   *
620
   * @return A new rectangle, equal in size to the input rectangle, but
621
   * with its position converted from the coordinate space of the source
622
   * component to the coordinate space of the destination component
623
   *
624
   * @see #convertPointToScreen
625
   * @see #convertPointFromScreen
626
   * @see #convertPoint
627
   * @see #getRoot
628
   */
629
  public static Rectangle convertRectangle(Component source, Rectangle rect,
630
                                           Component destination)
631
  {
632
    Point pt = convertPoint(source, rect.x, rect.y, destination);
633
    return new Rectangle(pt.x, pt.y, rect.width, rect.height);
634
  }
635
 
636
  /**
637
   * Convert a mouse event which refrers to one component to another.  This
638
   * includes changing the mouse event's coordinate space, as well as the
639
   * source property of the event. If <code>source</code> is
640
   * <code>null</code>, it is taken to refer to <code>destination</code>'s
641
   * root component. If <code>destination</code> is <code>null</code>, the
642
   * new event will remain expressed in <code>source</code>'s coordinate
643
   * system.
644
   *
645
   * @param source The component the mouse event currently refers to
646
   * @param sourceEvent The mouse event to convert
647
   * @param destination The component the new mouse event should refer to
648
   *
649
   * @return A new mouse event expressed in terms of the destination
650
   * component's coordinate space, and with the destination component as
651
   * its source
652
   *
653
   * @see #convertPoint
654
   */
655
  public static MouseEvent convertMouseEvent(Component source,
656
                                             MouseEvent sourceEvent,
657
                                             Component destination)
658
  {
659
    Point newpt = convertPoint(source, sourceEvent.getX(), sourceEvent.getY(),
660
                               destination);
661
 
662
    return new MouseEvent(destination, sourceEvent.getID(),
663
                          sourceEvent.getWhen(), sourceEvent.getModifiers(),
664
                          newpt.x, newpt.y, sourceEvent.getClickCount(),
665
                          sourceEvent.isPopupTrigger(),
666
                          sourceEvent.getButton());
667
  }
668
 
669
 
670
  /**
671
   * Calls {@link java.awt.EventQueue.invokeLater} with the
672
   * specified {@link Runnable}.
673
   */
674
  public static void invokeLater(Runnable doRun)
675
  {
676
    java.awt.EventQueue.invokeLater(doRun);
677
  }
678
 
679
  /**
680
   * Calls {@link java.awt.EventQueue.invokeAndWait} with the
681
   * specified {@link Runnable}.
682
   */
683
  public static void invokeAndWait(Runnable doRun)
684
  throws InterruptedException,
685
  InvocationTargetException
686
  {
687
    java.awt.EventQueue.invokeAndWait(doRun);
688
  }
689
 
690
  /**
691
   * Calls {@link java.awt.EventQueue.isEventDispatchThread}.
692
   */
693
  public static boolean isEventDispatchThread()
694
  {
695
    return java.awt.EventQueue.isDispatchThread();
696
  }
697
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.