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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [java/] [awt/] [Component.java] - Blame information for rev 771

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 771 jeremybenn
/* Component.java -- a graphics component
2
   Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2006
3
   Free Software Foundation
4
 
5
This file is part of GNU Classpath.
6
 
7
GNU Classpath is free software; you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation; either version 2, or (at your option)
10
any later version.
11
 
12
GNU Classpath is distributed in the hope that it will be useful, but
13
WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
General Public License for more details.
16
 
17
You should have received a copy of the GNU General Public License
18
along with GNU Classpath; see the file COPYING.  If not, write to the
19
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20
02110-1301 USA.
21
 
22
Linking this library statically or dynamically with other modules is
23
making a combined work based on this library.  Thus, the terms and
24
conditions of the GNU General Public License cover the whole
25
combination.
26
 
27
As a special exception, the copyright holders of this library give you
28
permission to link this library with independent modules to produce an
29
executable, regardless of the license terms of these independent
30
modules, and to copy and distribute the resulting executable under
31
terms of your choice, provided that you also meet, for each linked
32
independent module, the terms and conditions of the license of that
33
module.  An independent module is a module which is not derived from
34
or based on this library.  If you modify this library, you may extend
35
this exception to your version of the library, but you are not
36
obligated to do so.  If you do not wish to do so, delete this
37
exception statement from your version. */
38
 
39
 
40
package java.awt;
41
 
42
//import gnu.java.awt.dnd.peer.gtk.GtkDropTargetContextPeer;
43
 
44
import gnu.java.awt.ComponentReshapeEvent;
45
 
46
import gnu.java.lang.CPStringBuilder;
47
 
48
import java.awt.dnd.DropTarget;
49
import java.awt.event.ActionEvent;
50
import java.awt.event.AdjustmentEvent;
51
import java.awt.event.ComponentEvent;
52
import java.awt.event.ComponentListener;
53
import java.awt.event.FocusEvent;
54
import java.awt.event.FocusListener;
55
import java.awt.event.HierarchyBoundsListener;
56
import java.awt.event.HierarchyEvent;
57
import java.awt.event.HierarchyListener;
58
import java.awt.event.InputEvent;
59
import java.awt.event.InputMethodEvent;
60
import java.awt.event.InputMethodListener;
61
import java.awt.event.KeyEvent;
62
import java.awt.event.KeyListener;
63
import java.awt.event.MouseEvent;
64
import java.awt.event.MouseListener;
65
import java.awt.event.MouseMotionListener;
66
import java.awt.event.MouseWheelEvent;
67
import java.awt.event.MouseWheelListener;
68
import java.awt.event.PaintEvent;
69
import java.awt.event.WindowEvent;
70
import java.awt.im.InputContext;
71
import java.awt.im.InputMethodRequests;
72
import java.awt.image.BufferStrategy;
73
import java.awt.image.ColorModel;
74
import java.awt.image.ImageObserver;
75
import java.awt.image.ImageProducer;
76
import java.awt.image.VolatileImage;
77
import java.awt.peer.ComponentPeer;
78
import java.awt.peer.LightweightPeer;
79
import java.beans.PropertyChangeEvent;
80
import java.beans.PropertyChangeListener;
81
import java.beans.PropertyChangeSupport;
82
import java.io.IOException;
83
import java.io.ObjectInputStream;
84
import java.io.ObjectOutputStream;
85
import java.io.PrintStream;
86
import java.io.PrintWriter;
87
import java.io.Serializable;
88
import java.lang.reflect.Array;
89
import java.util.Collections;
90
import java.util.EventListener;
91
import java.util.HashSet;
92
import java.util.Iterator;
93
import java.util.Locale;
94
import java.util.Set;
95
import java.util.Vector;
96
 
97
import javax.accessibility.Accessible;
98
import javax.accessibility.AccessibleComponent;
99
import javax.accessibility.AccessibleContext;
100
import javax.accessibility.AccessibleRole;
101
import javax.accessibility.AccessibleState;
102
import javax.accessibility.AccessibleStateSet;
103
 
104
/**
105
 * The root of all evil. All graphical representations are subclasses of this
106
 * giant class, which is designed for screen display and user interaction.
107
 * This class can be extended directly to build a lightweight component (one
108
 * not associated with a native window); lightweight components must reside
109
 * inside a heavyweight window.
110
 *
111
 * <p>This class is Serializable, which has some big implications. A user can
112
 * save the state of all graphical components in one VM, and reload them in
113
 * another. Note that this class will only save Serializable listeners, and
114
 * ignore the rest, without causing any serialization exceptions. However, by
115
 * making a listener serializable, and adding it to another element, you link
116
 * in that entire element to the state of this component. To get around this,
117
 * use the idiom shown in the example below - make listeners non-serializable
118
 * in inner classes, rather than using this object itself as the listener, if
119
 * external objects do not need to save the state of this object.
120
 *
121
 * <pre>
122
 * import java.awt.*;
123
 * import java.awt.event.*;
124
 * import java.io.Serializable;
125
 * class MyApp implements Serializable
126
 * {
127
 *   BigObjectThatShouldNotBeSerializedWithAButton bigOne;
128
 *   // Serializing aButton will not suck in an instance of MyApp, with its
129
 *   // accompanying field bigOne.
130
 *   Button aButton = new Button();
131
 *   class MyActionListener implements ActionListener
132
 *   {
133
 *     public void actionPerformed(ActionEvent e)
134
 *     {
135
 *       System.out.println("Hello There");
136
 *     }
137
 *   }
138
 *   MyApp()
139
 *   {
140
 *     aButton.addActionListener(new MyActionListener());
141
 *   }
142
 * }
143
 * </pre>
144
 *
145
 * <p>Status: Incomplete. The event dispatch mechanism is implemented. All
146
 * other methods defined in the J2SE 1.3 API javadoc exist, but are mostly
147
 * incomplete or only stubs; except for methods relating to the Drag and
148
 * Drop, Input Method, and Accessibility frameworks: These methods are
149
 * present but commented out.
150
 *
151
 * @author original author unknown
152
 * @author Eric Blake (ebb9@email.byu.edu)
153
 * @since 1.0
154
 * @status still missing 1.4 support
155
 */
156
public abstract class Component
157
  implements ImageObserver, MenuContainer, Serializable
158
{
159
  // Word to the wise - this file is huge. Search for '\f' (^L) for logical
160
  // sectioning by fields, public API, private API, and nested classes.
161
 
162
 
163
  /**
164
   * Compatible with JDK 1.0+.
165
   */
166
  private static final long serialVersionUID = -7644114512714619750L;
167
 
168
  /**
169
   * Constant returned by the <code>getAlignmentY</code> method to indicate
170
   * that the component wishes to be aligned to the top relative to
171
   * other components.
172
   *
173
   * @see #getAlignmentY()
174
   */
175
  public static final float TOP_ALIGNMENT = 0;
176
 
177
  /**
178
   * Constant returned by the <code>getAlignmentY</code> and
179
   * <code>getAlignmentX</code> methods to indicate
180
   * that the component wishes to be aligned to the centdisper relative to
181
   * other components.
182
   *
183
   * @see #getAlignmentX()
184
   * @see #getAlignmentY()
185
   */
186
  public static final float CENTER_ALIGNMENT = 0.5f;
187
 
188
  /**
189
   * Constant returned by the <code>getAlignmentY</code> method to indicate
190
   * that the component wishes to be aligned to the bottom relative to
191
   * other components.
192
   *
193
   * @see #getAlignmentY()
194
   */
195
  public static final float BOTTOM_ALIGNMENT = 1;
196
 
197
  /**
198
   * Constant returned by the <code>getAlignmentX</code> method to indicate
199
   * that the component wishes to be aligned to the right relative to
200
   * other components.
201
   *
202
   * @see #getAlignmentX()
203
   */
204
  public static final float RIGHT_ALIGNMENT = 1;
205
 
206
  /**
207
   * Constant returned by the <code>getAlignmentX</code> method to indicate
208
   * that the component wishes to be aligned to the left relative to
209
   * other components.
210
   *
211
   * @see #getAlignmentX()
212
   */
213
  public static final float LEFT_ALIGNMENT = 0;
214
 
215
  /**
216
   * Make the treelock a String so that it can easily be identified
217
   * in debug dumps. We clone the String in order to avoid a conflict in
218
   * the unlikely event that some other package uses exactly the same string
219
   * as a lock object.
220
   */
221
  static final Object treeLock = new String("AWT_TREE_LOCK");
222
 
223
  /**
224
   * The default maximum size.
225
   */
226
  private static final Dimension DEFAULT_MAX_SIZE
227
                             = new Dimension(Short.MAX_VALUE, Short.MAX_VALUE);
228
 
229
  // Serialized fields from the serialization spec.
230
 
231
  /**
232
   * The x position of the component in the parent's coordinate system.
233
   *
234
   * @see #getLocation()
235
   * @serial the x position
236
   */
237
  int x;
238
 
239
  /**
240
   * The y position of the component in the parent's coordinate system.
241
   *
242
   * @see #getLocation()
243
   * @serial the y position
244
   */
245
  int y;
246
 
247
  /**
248
   * The component width.
249
   *
250
   * @see #getSize()
251
   * @serial the width
252
   */
253
  int width;
254
 
255
  /**
256
   * The component height.
257
   *
258
   * @see #getSize()
259
   * @serial the height
260
   */
261
  int height;
262
 
263
  /**
264
   * The foreground color for the component. This may be null.
265
   *
266
   * @see #getForeground()
267
   * @see #setForeground(Color)
268
   * @serial the foreground color
269
   */
270
  Color foreground;
271
 
272
  /**
273
   * The background color for the component. This may be null.
274
   *
275
   * @see #getBackground()
276
   * @see #setBackground(Color)
277
   * @serial the background color
278
   */
279
  Color background;
280
 
281
  /**
282
   * The default font used in the component. This may be null.
283
   *
284
   * @see #getFont()
285
   * @see #setFont(Font)
286
   * @serial the font
287
   */
288
  Font font;
289
 
290
  /**
291
   * The font in use by the peer, or null if there is no peer.
292
   *
293
   * @serial the peer's font
294
   */
295
  Font peerFont;
296
 
297
  /**
298
   * The cursor displayed when the pointer is over this component. This may
299
   * be null.
300
   *
301
   * @see #getCursor()
302
   * @see #setCursor(Cursor)
303
   */
304
  Cursor cursor;
305
 
306
  /**
307
   * The locale for the component.
308
   *
309
   * @see #getLocale()
310
   * @see #setLocale(Locale)
311
   */
312
  Locale locale = Locale.getDefault ();
313
 
314
  /**
315
   * True if the object should ignore repaint events (usually because it is
316
   * not showing).
317
   *
318
   * @see #getIgnoreRepaint()
319
   * @see #setIgnoreRepaint(boolean)
320
   * @serial true to ignore repaints
321
   * @since 1.4
322
   */
323
  boolean ignoreRepaint;
324
 
325
  /**
326
   * True when the object is visible (although it is only showing if all
327
   * ancestors are likewise visible). For component, this defaults to true.
328
   *
329
   * @see #isVisible()
330
   * @see #setVisible(boolean)
331
   * @serial true if visible
332
   */
333
  boolean visible = true;
334
 
335
  /**
336
   * True if the object is enabled, meaning it can interact with the user.
337
   * For component, this defaults to true.
338
   *
339
   * @see #isEnabled()
340
   * @see #setEnabled(boolean)
341
   * @serial true if enabled
342
   */
343
  boolean enabled = true;
344
 
345
  /**
346
   * True if the object is valid. This is set to false any time a size
347
   * adjustment means the component need to be layed out again.
348
   *
349
   * @see #isValid()
350
   * @see #validate()
351
   * @see #invalidate()
352
   * @serial true if layout is valid
353
   */
354
  boolean valid;
355
 
356
  /**
357
   * The DropTarget for drag-and-drop operations.
358
   *
359
   * @see #getDropTarget()
360
   * @see #setDropTarget(DropTarget)
361
   * @serial the drop target, or null
362
   * @since 1.2
363
   */
364
  DropTarget dropTarget;
365
 
366
  /**
367
   * The list of popup menus for this component.
368
   *
369
   * @see #add(PopupMenu)
370
   * @serial the list of popups
371
   */
372
  Vector popups;
373
 
374
  /**
375
   * The component's name. May be null, in which case a default name is
376
   * generated on the first use.
377
   *
378
   * @see #getName()
379
   * @see #setName(String)
380
   * @serial the name
381
   */
382
  String name;
383
 
384
  /**
385
   * True once the user has set the name. Note that the user may set the name
386
   * to null.
387
   *
388
   * @see #name
389
   * @see #getName()
390
   * @see #setName(String)
391
   * @serial true if the name has been explicitly set
392
   */
393
  boolean nameExplicitlySet;
394
 
395
  /**
396
   * Indicates if the object can be focused. Defaults to true for components.
397
   *
398
   * @see #isFocusable()
399
   * @see #setFocusable(boolean)
400
   * @since 1.4
401
   */
402
  boolean focusable = true;
403
 
404
  /**
405
   * Tracks whether this component's {@link #isFocusTraversable}
406
   * method has been overridden.
407
   *
408
   * @since 1.4
409
   */
410
  int isFocusTraversableOverridden;
411
 
412
  /**
413
   * The focus traversal keys, if not inherited from the parent or
414
   * default keyboard focus manager. These sets will contain only
415
   * AWTKeyStrokes that represent press and release events to use as
416
   * focus control.
417
   *
418
   * @see #getFocusTraversalKeys(int)
419
   * @see #setFocusTraversalKeys(int, Set)
420
   * @since 1.4
421
   */
422
  Set[] focusTraversalKeys;
423
 
424
  /**
425
   * True if focus traversal keys are enabled. This defaults to true for
426
   * Component. If this is true, keystrokes in focusTraversalKeys are trapped
427
   * and processed automatically rather than being passed on to the component.
428
   *
429
   * @see #getFocusTraversalKeysEnabled()
430
   * @see #setFocusTraversalKeysEnabled(boolean)
431
   * @since 1.4
432
   */
433
  boolean focusTraversalKeysEnabled = true;
434
 
435
  /**
436
   * Cached information on the minimum size. Should have been transient.
437
   *
438
   * @serial ignore
439
   */
440
  Dimension minSize;
441
 
442
  /**
443
   * Flag indicating whether the minimum size for the component has been set
444
   * by a call to {@link #setMinimumSize(Dimension)} with a non-null value.
445
   */
446
  boolean minSizeSet;
447
 
448
  /**
449
   * The maximum size for the component.
450
   * @see #setMaximumSize(Dimension)
451
   */
452
  Dimension maxSize;
453
 
454
  /**
455
   * A flag indicating whether the maximum size for the component has been set
456
   * by a call to {@link #setMaximumSize(Dimension)} with a non-null value.
457
   */
458
  boolean maxSizeSet;
459
 
460
  /**
461
   * Cached information on the preferred size. Should have been transient.
462
   *
463
   * @serial ignore
464
   */
465
  Dimension prefSize;
466
 
467
  /**
468
   * Flag indicating whether the preferred size for the component has been set
469
   * by a call to {@link #setPreferredSize(Dimension)} with a non-null value.
470
   */
471
  boolean prefSizeSet;
472
 
473
  /**
474
   * Set to true if an event is to be handled by this component, false if
475
   * it is to be passed up the hierarcy.
476
   *
477
   * @see #dispatchEvent(AWTEvent)
478
   * @serial true to process event locally
479
   */
480
  boolean newEventsOnly;
481
 
482
  /**
483
   * Set by subclasses to enable event handling of particular events, and
484
   * left alone when modifying listeners. For component, this defaults to
485
   * enabling only input methods.
486
   *
487
   * @see #enableInputMethods(boolean)
488
   * @see AWTEvent
489
   * @serial the mask of events to process
490
   */
491
  long eventMask = AWTEvent.INPUT_ENABLED_EVENT_MASK;
492
 
493
  /**
494
   * Describes all registered PropertyChangeListeners.
495
   *
496
   * @see #addPropertyChangeListener(PropertyChangeListener)
497
   * @see #removePropertyChangeListener(PropertyChangeListener)
498
   * @see #firePropertyChange(String, Object, Object)
499
   * @serial the property change listeners
500
   * @since 1.2
501
   */
502
  PropertyChangeSupport changeSupport;
503
 
504
  /**
505
   * True if the component has been packed (layed out).
506
   *
507
   * @serial true if this is packed
508
   */
509
  boolean isPacked;
510
 
511
  /**
512
   * The serialization version for this class. Currently at version 4.
513
   *
514
   * XXX How do we handle prior versions?
515
   *
516
   * @serial the serialization version
517
   */
518
  int componentSerializedDataVersion = 4;
519
 
520
  /**
521
   * The accessible context associated with this component. This is only set
522
   * by subclasses.
523
   *
524
   * @see #getAccessibleContext()
525
   * @serial the accessibility context
526
   * @since 1.2
527
   */
528
  AccessibleContext accessibleContext;
529
 
530
 
531
  // Guess what - listeners are special cased in serialization. See
532
  // readObject and writeObject.
533
 
534
  /** Component listener chain. */
535
  transient ComponentListener componentListener;
536
 
537
  /** Focus listener chain. */
538
  transient FocusListener focusListener;
539
 
540
  /** Key listener chain. */
541
  transient KeyListener keyListener;
542
 
543
  /** Mouse listener chain. */
544
  transient MouseListener mouseListener;
545
 
546
  /** Mouse motion listener chain. */
547
  transient MouseMotionListener mouseMotionListener;
548
 
549
  /**
550
   * Mouse wheel listener chain.
551
   *
552
   * @since 1.4
553
   */
554
  transient MouseWheelListener mouseWheelListener;
555
 
556
  /**
557
   * Input method listener chain.
558
   *
559
   * @since 1.2
560
   */
561
  transient InputMethodListener inputMethodListener;
562
 
563
  /**
564
   * Hierarcy listener chain.
565
   *
566
   * @since 1.3
567
   */
568
  transient HierarchyListener hierarchyListener;
569
 
570
  /**
571
   * Hierarcy bounds listener chain.
572
   *
573
   * @since 1.3
574
   */
575
  transient HierarchyBoundsListener hierarchyBoundsListener;
576
 
577
  // Anything else is non-serializable, and should be declared "transient".
578
 
579
  /** The parent. */
580
  transient Container parent;
581
 
582
  /** The associated native peer. */
583
  transient ComponentPeer peer;
584
 
585
  /** The preferred component orientation. */
586
  transient ComponentOrientation componentOrientation = ComponentOrientation.UNKNOWN;
587
 
588
  /**
589
   * The associated graphics configuration.
590
   *
591
   * @since 1.4
592
   */
593
  transient GraphicsConfiguration graphicsConfig;
594
 
595
  /**
596
   * The buffer strategy for repainting.
597
   *
598
   * @since 1.4
599
   */
600
  transient BufferStrategy bufferStrategy;
601
 
602
  /**
603
   * The number of hierarchy listeners of this container plus all of its
604
   * children. This is needed for efficient handling of HierarchyEvents.
605
   * These must be propagated to all child components with HierarchyListeners
606
   * attached. To avoid traversal of the whole subtree, we keep track of
607
   * the number of HierarchyListeners here and only walk the paths that
608
   * actually have listeners.
609
   */
610
  int numHierarchyListeners;
611
  int numHierarchyBoundsListeners;
612
 
613
  /**
614
   * true if requestFocus was called on this component when its
615
   * top-level ancestor was not focusable.
616
   */
617
  private transient FocusEvent pendingFocusRequest = null;
618
 
619
  /**
620
   * The system properties that affect image updating.
621
   */
622
  private static transient boolean incrementalDraw;
623
  private static transient Long redrawRate;
624
 
625
  static
626
  {
627
    incrementalDraw = Boolean.getBoolean ("awt.image.incrementalDraw");
628
    redrawRate = Long.getLong ("awt.image.redrawrate");
629
  }
630
 
631
  // Public and protected API.
632
 
633
  /**
634
   * Default constructor for subclasses. When Component is extended directly,
635
   * it forms a lightweight component that must be hosted in an opaque native
636
   * container higher in the tree.
637
   */
638
  protected Component()
639
  {
640
    // Nothing to do here.
641
  }
642
 
643
  /**
644
   * Returns the name of this component.
645
   *
646
   * @return the name of this component
647
   * @see #setName(String)
648
   * @since 1.1
649
   */
650
  public String getName()
651
  {
652
    if (name == null && ! nameExplicitlySet)
653
      name = generateName();
654
    return name;
655
  }
656
 
657
  /**
658
   * Sets the name of this component to the specified name (this is a bound
659
   * property with the name 'name').
660
   *
661
   * @param name the new name (<code>null</code> permitted).
662
   * @see #getName()
663
   * @since 1.1
664
   */
665
  public void setName(String name)
666
  {
667
    nameExplicitlySet = true;
668
    String old = this.name;
669
    this.name = name;
670
    firePropertyChange("name", old, name);
671
  }
672
 
673
  /**
674
   * Returns the parent of this component.
675
   *
676
   * @return the parent of this component
677
   */
678
  public Container getParent()
679
  {
680
    return parent;
681
  }
682
 
683
  /**
684
   * Returns the native windowing system peer for this component. Only the
685
   * platform specific implementation code should call this method.
686
   *
687
   * @return the peer for this component
688
   * @deprecated user programs should not directly manipulate peers; use
689
   *             {@link #isDisplayable()} instead
690
   */
691
  // Classpath's Gtk peers rely on this.
692
  public ComponentPeer getPeer()
693
  {
694
    return peer;
695
  }
696
 
697
  /**
698
   * Set the associated drag-and-drop target, which receives events when this
699
   * is enabled.
700
   *
701
   * @param dt the new drop target
702
   * @see #isEnabled()
703
   */
704
  public void setDropTarget(DropTarget dt)
705
  {
706
    this.dropTarget = dt;
707
 
708
    if (peer != null)
709
      dropTarget.addNotify(peer);
710
  }
711
 
712
  /**
713
   * Gets the associated drag-and-drop target, if there is one.
714
   *
715
   * @return the drop target
716
   */
717
  public DropTarget getDropTarget()
718
  {
719
    return dropTarget;
720
  }
721
 
722
  /**
723
   * Returns the graphics configuration of this component, if there is one.
724
   * If it has not been set, it is inherited from the parent.
725
   *
726
   * @return the graphics configuration, or null
727
   * @since 1.3
728
   */
729
  public GraphicsConfiguration getGraphicsConfiguration()
730
  {
731
    GraphicsConfiguration conf = null;
732
    synchronized (getTreeLock())
733
      {
734
        if (graphicsConfig != null)
735
          {
736
            conf = graphicsConfig;
737
          }
738
        else
739
          {
740
            Component par = getParent();
741
            if (par != null)
742
              {
743
                conf = parent.getGraphicsConfiguration();
744
              }
745
          }
746
      }
747
    return conf;
748
  }
749
 
750
  /**
751
   * Returns the object used for synchronization locks on this component
752
   * when performing tree and layout functions.
753
   *
754
   * @return the synchronization lock for this component
755
   */
756
  public final Object getTreeLock()
757
  {
758
    return treeLock;
759
  }
760
 
761
  /**
762
   * Returns the toolkit in use for this component. The toolkit is associated
763
   * with the frame this component belongs to.
764
   *
765
   * @return the toolkit for this component
766
   */
767
  public Toolkit getToolkit()
768
  {
769
    // Only heavyweight peers can handle this.
770
    ComponentPeer p = peer;
771
    Component comp = this;
772
    while (p instanceof LightweightPeer)
773
      {
774
        comp = comp.parent;
775
        p = comp == null ? null : comp.peer;
776
      }
777
 
778
    Toolkit tk = null;
779
    if (p != null)
780
      {
781
        tk = peer.getToolkit();
782
      }
783
    if (tk == null)
784
      tk = Toolkit.getDefaultToolkit();
785
    return tk;
786
  }
787
 
788
  /**
789
   * Tests whether or not this component is valid. A invalid component needs
790
   * to have its layout redone.
791
   *
792
   * @return true if this component is valid
793
   * @see #validate()
794
   * @see #invalidate()
795
   */
796
  public boolean isValid()
797
  {
798
    // Tests show that components are invalid as long as they are not showing, even after validate()
799
    // has been called on them.
800
    return peer != null && valid;
801
  }
802
 
803
  /**
804
   * Tests if the component is displayable. It must be connected to a native
805
   * screen resource.  This reduces to checking that peer is not null.  A
806
   * containment  hierarchy is made displayable when a window is packed or
807
   * made visible.
808
   *
809
   * @return true if the component is displayable
810
   * @see Container#add(Component)
811
   * @see Container#remove(Component)
812
   * @see Window#pack()
813
   * @see Window#show()
814
   * @see Window#dispose()
815
   * @since 1.2
816
   */
817
  public boolean isDisplayable()
818
  {
819
    return peer != null;
820
  }
821
 
822
  /**
823
   * Tests whether or not this component is visible. Except for top-level
824
   * frames, components are initially visible.
825
   *
826
   * @return true if the component is visible
827
   * @see #setVisible(boolean)
828
   */
829
  public boolean isVisible()
830
  {
831
    return visible;
832
  }
833
 
834
  /**
835
   * Tests whether or not this component is actually being shown on
836
   * the screen. This will be true if and only if it this component is
837
   * visible and its parent components are all visible.
838
   *
839
   * @return true if the component is showing on the screen
840
   * @see #setVisible(boolean)
841
   */
842
  public boolean isShowing()
843
  {
844
    Component par = parent;
845
    return visible && peer != null && (par == null || par.isShowing());
846
  }
847
 
848
  /**
849
   * Tests whether or not this component is enabled. Components are enabled
850
   * by default, and must be enabled to receive user input or generate events.
851
   *
852
   * @return true if the component is enabled
853
   * @see #setEnabled(boolean)
854
   */
855
  public boolean isEnabled()
856
  {
857
    return enabled;
858
  }
859
 
860
  /**
861
   * Enables or disables this component. The component must be enabled to
862
   * receive events (except that lightweight components always receive mouse
863
   * events).
864
   *
865
   * @param enabled true to enable this component
866
   *
867
   * @see #isEnabled()
868
   * @see #isLightweight()
869
   *
870
   * @since 1.1
871
   */
872
  public void setEnabled(boolean enabled)
873
  {
874
    enable(enabled);
875
  }
876
 
877
  /**
878
   * Enables this component.
879
   *
880
   * @deprecated use {@link #setEnabled(boolean)} instead
881
   */
882
  public void enable()
883
  {
884
    if (! enabled)
885
      {
886
        // Need to lock the tree here, because the peers are involved.
887
        synchronized (getTreeLock())
888
          {
889
            enabled = true;
890
            ComponentPeer p = peer;
891
            if (p != null)
892
              p.enable();
893
          }
894
      }
895
  }
896
 
897
  /**
898
   * Enables or disables this component.
899
   *
900
   * @param enabled true to enable this component
901
   *
902
   * @deprecated use {@link #setEnabled(boolean)} instead
903
   */
904
  public void enable(boolean enabled)
905
  {
906
    if (enabled)
907
      enable();
908
    else
909
      disable();
910
  }
911
 
912
  /**
913
   * Disables this component.
914
   *
915
   * @deprecated use {@link #setEnabled(boolean)} instead
916
   */
917
  public void disable()
918
  {
919
    if (enabled)
920
      {
921
        // Need to lock the tree here, because the peers are involved.
922
        synchronized (getTreeLock())
923
          {
924
            enabled = false;
925
            ComponentPeer p = peer;
926
            if (p != null)
927
              p.disable();
928
          }
929
      }
930
  }
931
 
932
  /**
933
   * Checks if this image is painted to an offscreen image buffer that is
934
   * later copied to screen (double buffering reduces flicker). This version
935
   * returns false, so subclasses must override it if they provide double
936
   * buffering.
937
   *
938
   * @return true if this is double buffered; defaults to false
939
   */
940
  public boolean isDoubleBuffered()
941
  {
942
    return false;
943
  }
944
 
945
  /**
946
   * Enables or disables input method support for this component. By default,
947
   * components have this enabled. Input methods are given the opportunity
948
   * to process key events before this component and its listeners.
949
   *
950
   * @param enable true to enable input method processing
951
   * @see #processKeyEvent(KeyEvent)
952
   * @since 1.2
953
   */
954
  public void enableInputMethods(boolean enable)
955
  {
956
    if (enable)
957
      eventMask |= AWTEvent.INPUT_ENABLED_EVENT_MASK;
958
    else
959
      eventMask &= ~AWTEvent.INPUT_ENABLED_EVENT_MASK;
960
  }
961
 
962
  /**
963
   * Makes this component visible or invisible. Note that it wtill might
964
   * not show the component, if a parent is invisible.
965
   *
966
   * @param visible true to make this component visible
967
   *
968
   * @see #isVisible()
969
   *
970
   * @since 1.1
971
   */
972
  public void setVisible(boolean visible)
973
  {
974
    // Inspection by subclassing shows that Sun's implementation calls
975
    // show(boolean) which then calls show() or hide(). It is the show()
976
    // method that is overriden in subclasses like Window.
977
    show(visible);
978
  }
979
 
980
  /**
981
   * Makes this component visible on the screen.
982
   *
983
   * @deprecated use {@link #setVisible(boolean)} instead
984
   */
985
  public void show()
986
  {
987
    // We must set visible before showing the peer.  Otherwise the
988
    // peer could post paint events before visible is true, in which
989
    // case lightweight components are not initially painted --
990
    // Container.paint first calls isShowing () before painting itself
991
    // and its children.
992
    if(! visible)
993
      {
994
        // Need to lock the tree here to avoid races and inconsistencies.
995
        synchronized (getTreeLock())
996
          {
997
            visible = true;
998
            // Avoid NullPointerExceptions by creating a local reference.
999
            ComponentPeer currentPeer = peer;
1000
            if (currentPeer != null)
1001
              {
1002
                currentPeer.show();
1003
 
1004
                // Fire HierarchyEvent.
1005
                fireHierarchyEvent(HierarchyEvent.HIERARCHY_CHANGED,
1006
                                   this, parent,
1007
                                   HierarchyEvent.SHOWING_CHANGED);
1008
 
1009
                // The JDK repaints the component before invalidating the parent.
1010
                // So do we.
1011
                if (peer instanceof LightweightPeer)
1012
                  repaint();
1013
              }
1014
 
1015
            // Only post an event if this component actually has a listener
1016
            // or has this event explicitly enabled.
1017
            if (componentListener != null
1018
                || (eventMask & AWTEvent.COMPONENT_EVENT_MASK) != 0)
1019
              {
1020
                ComponentEvent ce =
1021
                  new ComponentEvent(this,ComponentEvent.COMPONENT_SHOWN);
1022
                getToolkit().getSystemEventQueue().postEvent(ce);
1023
              }
1024
          }
1025
 
1026
        // Invalidate the parent if we have one. The component itself must
1027
        // not be invalidated. We also avoid NullPointerException with
1028
        // a local reference here.
1029
        Container currentParent = parent;
1030
        if (currentParent != null)
1031
          currentParent.invalidate();
1032
 
1033
      }
1034
  }
1035
 
1036
  /**
1037
   * Makes this component visible or invisible.
1038
   *
1039
   * @param visible true to make this component visible
1040
   *
1041
   * @deprecated use {@link #setVisible(boolean)} instead
1042
   */
1043
  public void show(boolean visible)
1044
  {
1045
    if (visible)
1046
      show();
1047
    else
1048
      hide();
1049
  }
1050
 
1051
  /**
1052
   * Hides this component so that it is no longer shown on the screen.
1053
   *
1054
   * @deprecated use {@link #setVisible(boolean)} instead
1055
   */
1056
  public void hide()
1057
  {
1058
    if (visible)
1059
      {
1060
        // Need to lock the tree here to avoid races and inconsistencies.
1061
        synchronized (getTreeLock())
1062
          {
1063
            visible = false;
1064
 
1065
            // Avoid NullPointerExceptions by creating a local reference.
1066
            ComponentPeer currentPeer = peer;
1067
            if (currentPeer != null)
1068
              {
1069
                currentPeer.hide();
1070
 
1071
                // Fire hierarchy event.
1072
                fireHierarchyEvent(HierarchyEvent.HIERARCHY_CHANGED,
1073
                                   this, parent,
1074
                                   HierarchyEvent.SHOWING_CHANGED);
1075
                // The JDK repaints the component before invalidating the
1076
                // parent. So do we. This only applies for lightweights.
1077
                if (peer instanceof LightweightPeer)
1078
                  repaint();
1079
              }
1080
 
1081
            // Only post an event if this component actually has a listener
1082
            // or has this event explicitly enabled.
1083
            if (componentListener != null
1084
                || (eventMask & AWTEvent.COMPONENT_EVENT_MASK) != 0)
1085
              {
1086
                ComponentEvent ce =
1087
                  new ComponentEvent(this,ComponentEvent.COMPONENT_HIDDEN);
1088
                getToolkit().getSystemEventQueue().postEvent(ce);
1089
              }
1090
          }
1091
 
1092
        // Invalidate the parent if we have one. The component itself need
1093
        // not be invalidated. We also avoid NullPointerException with
1094
        // a local reference here.
1095
        Container currentParent = parent;
1096
        if (currentParent != null)
1097
          currentParent.invalidate();
1098
 
1099
      }
1100
  }
1101
 
1102
  /**
1103
   * Returns this component's foreground color. If not set, this is inherited
1104
   * from the parent.
1105
   *
1106
   * @return this component's foreground color, or null
1107
   * @see #setForeground(Color)
1108
   */
1109
  public Color getForeground()
1110
  {
1111
    if (foreground != null)
1112
      return foreground;
1113
    return parent == null ? null : parent.getForeground();
1114
  }
1115
 
1116
  /**
1117
   * Sets this component's foreground color to the specified color. This is a
1118
   * bound property.
1119
   *
1120
   * @param c the new foreground color
1121
   * @see #getForeground()
1122
   */
1123
  public void setForeground(Color c)
1124
  {
1125
    if (peer != null)
1126
      peer.setForeground(c);
1127
 
1128
    Color previous = foreground;
1129
    foreground = c;
1130
    firePropertyChange("foreground", previous, c);
1131
  }
1132
 
1133
  /**
1134
   * Tests if the foreground was explicitly set, or just inherited from the
1135
   * parent.
1136
   *
1137
   * @return true if the foreground has been set
1138
   * @since 1.4
1139
   */
1140
  public boolean isForegroundSet()
1141
  {
1142
    return foreground != null;
1143
  }
1144
 
1145
  /**
1146
   * Returns this component's background color. If not set, this is inherited
1147
   * from the parent.
1148
   *
1149
   * @return the background color of the component, or null
1150
   * @see #setBackground(Color)
1151
   */
1152
  public Color getBackground()
1153
  {
1154
    if (background != null)
1155
      return background;
1156
    return parent == null ? null : parent.getBackground();
1157
  }
1158
 
1159
  /**
1160
   * Sets this component's background color to the specified color. The parts
1161
   * of the component affected by the background color may by system dependent.
1162
   * This is a bound property.
1163
   *
1164
   * @param c the new background color
1165
   * @see #getBackground()
1166
   */
1167
  public void setBackground(Color c)
1168
  {
1169
    // return if the background is already set to that color.
1170
    if ((c != null) && c.equals(background))
1171
      return;
1172
 
1173
    Color previous = background;
1174
    background = c;
1175
    if (peer != null && c != null)
1176
      peer.setBackground(c);
1177
    firePropertyChange("background", previous, c);
1178
  }
1179
 
1180
  /**
1181
   * Tests if the background was explicitly set, or just inherited from the
1182
   * parent.
1183
   *
1184
   * @return true if the background has been set
1185
   * @since 1.4
1186
   */
1187
  public boolean isBackgroundSet()
1188
  {
1189
    return background != null;
1190
  }
1191
 
1192
  /**
1193
   * Returns the font in use for this component. If not set, this is inherited
1194
   * from the parent.
1195
   *
1196
   * @return the font for this component
1197
   * @see #setFont(Font)
1198
   */
1199
  public Font getFont()
1200
  {
1201
    return getFontImpl();
1202
  }
1203
 
1204
  /**
1205
   * Implementation of getFont(). This is pulled out of getFont() to prevent
1206
   * client programs from overriding this.
1207
   *
1208
   * @return the font of this component
1209
   */
1210
  private final Font getFontImpl()
1211
  {
1212
    Font f = font;
1213
    if (f == null)
1214
      {
1215
        Component p = parent;
1216
        if (p != null)
1217
          f = p.getFontImpl();
1218
        else
1219
          {
1220
            // It is important to return null here and not some kind of default
1221
            // font, otherwise the Swing UI would not install its fonts because
1222
            // it keeps non-UIResource fonts.
1223
            f = null;
1224
          }
1225
      }
1226
    return f;
1227
  }
1228
 
1229
  /**
1230
   * Sets the font for this component to the specified font. This is a bound
1231
   * property.
1232
   *
1233
   * @param f the new font for this component
1234
   *
1235
   * @see #getFont()
1236
   */
1237
  public void setFont(Font f)
1238
  {
1239
    Font oldFont;
1240
    Font newFont;
1241
    // Synchronize on the tree because getFontImpl() relies on the hierarchy
1242
    // not beeing changed.
1243
    synchronized (getTreeLock())
1244
      {
1245
        // Synchronize on this here to guarantee thread safety wrt to the
1246
        // property values.
1247
        synchronized (this)
1248
          {
1249
            oldFont = font;
1250
            font = f;
1251
            newFont = f;
1252
          }
1253
        // Create local variable here for thread safety.
1254
        ComponentPeer p = peer;
1255
        if (p != null)
1256
          {
1257
            // The peer receives the real font setting, which can depend on
1258
            // the parent font when this component's font has been set to null.
1259
            f = getFont();
1260
            if (f != null)
1261
              {
1262
                p.setFont(f);
1263
                peerFont = f;
1264
              }
1265
          }
1266
      }
1267
 
1268
    // Fire property change event.
1269
    firePropertyChange("font", oldFont, newFont);
1270
 
1271
    // Invalidate when necessary as font changes can change the size of the
1272
    // component.
1273
    if (valid)
1274
      invalidate();
1275
  }
1276
 
1277
  /**
1278
   * Tests if the font was explicitly set, or just inherited from the parent.
1279
   *
1280
   * @return true if the font has been set
1281
   * @since 1.4
1282
   */
1283
  public boolean isFontSet()
1284
  {
1285
    return font != null;
1286
  }
1287
 
1288
  /**
1289
   * Returns the locale for this component. If this component does not
1290
   * have a locale, the locale of the parent component is returned.
1291
   *
1292
   * @return the locale for this component
1293
   * @throws IllegalComponentStateException if it has no locale or parent
1294
   * @see #setLocale(Locale)
1295
   * @since 1.1
1296
   */
1297
  public Locale getLocale()
1298
  {
1299
    if (locale != null)
1300
      return locale;
1301
    if (parent == null)
1302
      throw new IllegalComponentStateException
1303
        ("Component has no parent: can't determine Locale");
1304
    return parent.getLocale();
1305
  }
1306
 
1307
  /**
1308
   * Sets the locale for this component to the specified locale. This is a
1309
   * bound property.
1310
   *
1311
   * @param newLocale the new locale for this component
1312
   */
1313
  public void setLocale(Locale newLocale)
1314
  {
1315
    if (locale == newLocale)
1316
      return;
1317
 
1318
    Locale oldLocale = locale;
1319
    locale = newLocale;
1320
    firePropertyChange("locale", oldLocale, newLocale);
1321
    // New writing/layout direction or more/less room for localized labels.
1322
    invalidate();
1323
  }
1324
 
1325
  /**
1326
   * Returns the color model of the device this componet is displayed on.
1327
   *
1328
   * @return this object's color model
1329
   * @see Toolkit#getColorModel()
1330
   */
1331
  public ColorModel getColorModel()
1332
  {
1333
    GraphicsConfiguration config = getGraphicsConfiguration();
1334
    return config != null ? config.getColorModel()
1335
      : getToolkit().getColorModel();
1336
  }
1337
 
1338
  /**
1339
   * Returns the location of this component's top left corner relative to
1340
   * its parent component. This may be outdated, so for synchronous behavior,
1341
   * you should use a component listner.
1342
   *
1343
   * @return the location of this component
1344
   * @see #setLocation(int, int)
1345
   * @see #getLocationOnScreen()
1346
   * @since 1.1
1347
   */
1348
  public Point getLocation()
1349
  {
1350
    return location ();
1351
  }
1352
 
1353
  /**
1354
   * Returns the location of this component's top left corner in screen
1355
   * coordinates.
1356
   *
1357
   * @return the location of this component in screen coordinates
1358
   * @throws IllegalComponentStateException if the component is not showing
1359
   */
1360
  public Point getLocationOnScreen()
1361
  {
1362
    if (! isShowing())
1363
      throw new IllegalComponentStateException("component "
1364
                                               + getClass().getName()
1365
                                               + " not showing");
1366
 
1367
    // Need to lock the tree here. We get crazy races and explosions when
1368
    // the tree changes while we are trying to find the location of this
1369
    // component.
1370
    synchronized (getTreeLock())
1371
      {
1372
        // Only a heavyweight peer can answer the question for the screen
1373
        // location. So we are going through the hierarchy until we find
1374
        // one and add up the offsets while doing so.
1375
        int offsX = 0;
1376
        int offsY = 0;
1377
        ComponentPeer p = peer;
1378
        Component comp = this;
1379
        while (p instanceof LightweightPeer)
1380
          {
1381
            offsX += comp.x;
1382
            offsY += comp.y;
1383
            comp = comp.parent;
1384
            p = comp == null ? null: comp.peer;
1385
          }
1386
        // Now we have a heavyweight component.
1387
        assert ! (p instanceof LightweightPeer);
1388
        Point loc = p.getLocationOnScreen();
1389
        loc.x += offsX;
1390
        loc.y += offsY;
1391
        return loc;
1392
      }
1393
  }
1394
 
1395
  /**
1396
   * Returns the location of this component's top left corner relative to
1397
   * its parent component.
1398
   *
1399
   * @return the location of this component
1400
   * @deprecated use {@link #getLocation()} instead
1401
   */
1402
  public Point location()
1403
  {
1404
    return new Point (x, y);
1405
  }
1406
 
1407
  /**
1408
   * Moves this component to the specified location, relative to the parent's
1409
   * coordinates. The coordinates are the new upper left corner of this
1410
   * component.
1411
   *
1412
   * @param x the new X coordinate of this component
1413
   * @param y the new Y coordinate of this component
1414
   * @see #getLocation()
1415
   * @see #setBounds(int, int, int, int)
1416
   */
1417
  public void setLocation(int x, int y)
1418
  {
1419
    move (x, y);
1420
  }
1421
 
1422
  /**
1423
   * Moves this component to the specified location, relative to the parent's
1424
   * coordinates. The coordinates are the new upper left corner of this
1425
   * component.
1426
   *
1427
   * @param x the new X coordinate of this component
1428
   * @param y the new Y coordinate of this component
1429
   * @deprecated use {@link #setLocation(int, int)} instead
1430
   */
1431
  public void move(int x, int y)
1432
  {
1433
    setBounds(x, y, this.width, this.height);
1434
  }
1435
 
1436
  /**
1437
   * Moves this component to the specified location, relative to the parent's
1438
   * coordinates. The coordinates are the new upper left corner of this
1439
   * component.
1440
   *
1441
   * @param p new coordinates for this component
1442
   * @throws NullPointerException if p is null
1443
   * @see #getLocation()
1444
   * @see #setBounds(int, int, int, int)
1445
   * @since 1.1
1446
   */
1447
  public void setLocation(Point p)
1448
  {
1449
    setLocation(p.x, p.y);
1450
  }
1451
 
1452
  /**
1453
   * Returns the size of this object.
1454
   *
1455
   * @return the size of this object
1456
   * @see #setSize(int, int)
1457
   * @since 1.1
1458
   */
1459
  public Dimension getSize()
1460
  {
1461
    return size ();
1462
  }
1463
 
1464
  /**
1465
   * Returns the size of this object.
1466
   *
1467
   * @return the size of this object
1468
   * @deprecated use {@link #getSize()} instead
1469
   */
1470
  public Dimension size()
1471
  {
1472
    return new Dimension (width, height);
1473
  }
1474
 
1475
  /**
1476
   * Sets the size of this component to the specified width and height.
1477
   *
1478
   * @param width the new width of this component
1479
   * @param height the new height of this component
1480
   * @see #getSize()
1481
   * @see #setBounds(int, int, int, int)
1482
   */
1483
  public void setSize(int width, int height)
1484
  {
1485
    resize (width, height);
1486
  }
1487
 
1488
  /**
1489
   * Sets the size of this component to the specified value.
1490
   *
1491
   * @param width the new width of the component
1492
   * @param height the new height of the component
1493
   * @deprecated use {@link #setSize(int, int)} instead
1494
   */
1495
  public void resize(int width, int height)
1496
  {
1497
    setBounds(this.x, this.y, width, height);
1498
  }
1499
 
1500
  /**
1501
   * Sets the size of this component to the specified value.
1502
   *
1503
   * @param d the new size of this component
1504
   * @throws NullPointerException if d is null
1505
   * @see #setSize(int, int)
1506
   * @see #setBounds(int, int, int, int)
1507
   * @since 1.1
1508
   */
1509
  public void setSize(Dimension d)
1510
  {
1511
    resize (d);
1512
  }
1513
 
1514
  /**
1515
   * Sets the size of this component to the specified value.
1516
   *
1517
   * @param d the new size of this component
1518
   * @throws NullPointerException if d is null
1519
   * @deprecated use {@link #setSize(Dimension)} instead
1520
   */
1521
  public void resize(Dimension d)
1522
  {
1523
    resize (d.width, d.height);
1524
  }
1525
 
1526
  /**
1527
   * Returns a bounding rectangle for this component. Note that the
1528
   * returned rectange is relative to this component's parent, not to
1529
   * the screen.
1530
   *
1531
   * @return the bounding rectangle for this component
1532
   * @see #setBounds(int, int, int, int)
1533
   * @see #getLocation()
1534
   * @see #getSize()
1535
   */
1536
  public Rectangle getBounds()
1537
  {
1538
    return bounds ();
1539
  }
1540
 
1541
  /**
1542
   * Returns a bounding rectangle for this component. Note that the
1543
   * returned rectange is relative to this component's parent, not to
1544
   * the screen.
1545
   *
1546
   * @return the bounding rectangle for this component
1547
   * @deprecated use {@link #getBounds()} instead
1548
   */
1549
  public Rectangle bounds()
1550
  {
1551
    return new Rectangle (x, y, width, height);
1552
  }
1553
 
1554
  /**
1555
   * Sets the bounding rectangle for this component to the specified values.
1556
   * Note that these coordinates are relative to the parent, not to the screen.
1557
   *
1558
   * @param x the X coordinate of the upper left corner of the rectangle
1559
   * @param y the Y coordinate of the upper left corner of the rectangle
1560
   * @param w the width of the rectangle
1561
   * @param h the height of the rectangle
1562
   * @see #getBounds()
1563
   * @see #setLocation(int, int)
1564
   * @see #setLocation(Point)
1565
   * @see #setSize(int, int)
1566
   * @see #setSize(Dimension)
1567
   * @since 1.1
1568
   */
1569
  public void setBounds(int x, int y, int w, int h)
1570
  {
1571
    reshape (x, y, w, h);
1572
  }
1573
 
1574
  /**
1575
   * Sets the bounding rectangle for this component to the specified values.
1576
   * Note that these coordinates are relative to the parent, not to the screen.
1577
   *
1578
   * @param x the X coordinate of the upper left corner of the rectangle
1579
   * @param y the Y coordinate of the upper left corner of the rectangle
1580
   * @param width the width of the rectangle
1581
   * @param height the height of the rectangle
1582
   * @deprecated use {@link #setBounds(int, int, int, int)} instead
1583
   */
1584
  public void reshape(int x, int y, int width, int height)
1585
  {
1586
    // We need to lock the tree here, otherwise we risk races and
1587
    // inconsistencies.
1588
    synchronized (getTreeLock())
1589
      {
1590
        int oldx = this.x;
1591
        int oldy = this.y;
1592
        int oldwidth = this.width;
1593
        int oldheight = this.height;
1594
 
1595
        boolean resized = oldwidth != width || oldheight != height;
1596
        boolean moved = oldx != x || oldy != y;
1597
 
1598
        if (resized || moved)
1599
          {
1600
            // Update the fields.
1601
            this.x = x;
1602
            this.y = y;
1603
            this.width = width;
1604
            this.height = height;
1605
 
1606
            if (peer != null)
1607
              {
1608
                peer.setBounds (x, y, width, height);
1609
                if (resized)
1610
                  invalidate();
1611
                if (parent != null && parent.valid)
1612
                  parent.invalidate();
1613
              }
1614
 
1615
            // Send some events to interested listeners.
1616
            notifyReshape(resized, moved);
1617
 
1618
            // Repaint this component and the parent if appropriate.
1619
            if (parent != null && peer instanceof LightweightPeer
1620
                && isShowing())
1621
              {
1622
                // The parent repaints the area that we occupied before.
1623
                parent.repaint(oldx, oldy, oldwidth, oldheight);
1624
                // This component repaints the area that we occupy now.
1625
                repaint();
1626
              }
1627
          }
1628
      }
1629
  }
1630
 
1631
  /**
1632
   * Sends notification to interested listeners about resizing and/or moving
1633
   * the component. If this component has interested
1634
   * component listeners or the corresponding event mask enabled, then
1635
   * COMPONENT_MOVED and/or COMPONENT_RESIZED events are posted to the event
1636
   * queue.
1637
   *
1638
   * @param resized true if the component has been resized, false otherwise
1639
   * @param moved true if the component has been moved, false otherwise
1640
   */
1641
  void notifyReshape(boolean resized, boolean moved)
1642
  {
1643
    // Only post an event if this component actually has a listener
1644
    // or has this event explicitly enabled.
1645
    if (componentListener != null
1646
        || (eventMask & AWTEvent.COMPONENT_EVENT_MASK) != 0)
1647
      {
1648
        // Fire component event on this component.
1649
        if (moved)
1650
          {
1651
            ComponentEvent ce = new ComponentEvent(this,
1652
                                               ComponentEvent.COMPONENT_MOVED);
1653
            getToolkit().getSystemEventQueue().postEvent(ce);
1654
          }
1655
        if (resized)
1656
          {
1657
            ComponentEvent ce = new ComponentEvent(this,
1658
                                             ComponentEvent.COMPONENT_RESIZED);
1659
            getToolkit().getSystemEventQueue().postEvent(ce);
1660
          }
1661
      }
1662
  }
1663
 
1664
  /**
1665
   * Sets the bounding rectangle for this component to the specified
1666
   * rectangle. Note that these coordinates are relative to the parent, not
1667
   * to the screen.
1668
   *
1669
   * @param r the new bounding rectangle
1670
   * @throws NullPointerException if r is null
1671
   * @see #getBounds()
1672
   * @see #setLocation(Point)
1673
   * @see #setSize(Dimension)
1674
   * @since 1.1
1675
   */
1676
  public void setBounds(Rectangle r)
1677
  {
1678
    setBounds (r.x, r.y, r.width, r.height);
1679
  }
1680
 
1681
  /**
1682
   * Gets the x coordinate of the upper left corner. This is more efficient
1683
   * than getBounds().x or getLocation().x.
1684
   *
1685
   * @return the current x coordinate
1686
   * @since 1.2
1687
   */
1688
  public int getX()
1689
  {
1690
    return x;
1691
  }
1692
 
1693
  /**
1694
   * Gets the y coordinate of the upper left corner. This is more efficient
1695
   * than getBounds().y or getLocation().y.
1696
   *
1697
   * @return the current y coordinate
1698
   * @since 1.2
1699
   */
1700
  public int getY()
1701
  {
1702
    return y;
1703
  }
1704
 
1705
  /**
1706
   * Gets the width of the component. This is more efficient than
1707
   * getBounds().width or getSize().width.
1708
   *
1709
   * @return the current width
1710
   * @since 1.2
1711
   */
1712
  public int getWidth()
1713
  {
1714
    return width;
1715
  }
1716
 
1717
  /**
1718
   * Gets the height of the component. This is more efficient than
1719
   * getBounds().height or getSize().height.
1720
   *
1721
   * @return the current width
1722
   * @since 1.2
1723
   */
1724
  public int getHeight()
1725
  {
1726
    return height;
1727
  }
1728
 
1729
  /**
1730
   * Returns the bounds of this component. This allows reuse of an existing
1731
   * rectangle, if r is non-null.
1732
   *
1733
   * @param r the rectangle to use, or null
1734
   * @return the bounds
1735
   */
1736
  public Rectangle getBounds(Rectangle r)
1737
  {
1738
    if (r == null)
1739
      r = new Rectangle();
1740
    r.x = x;
1741
    r.y = y;
1742
    r.width = width;
1743
    r.height = height;
1744
    return r;
1745
  }
1746
 
1747
  /**
1748
   * Returns the size of this component. This allows reuse of an existing
1749
   * dimension, if d is non-null.
1750
   *
1751
   * @param d the dimension to use, or null
1752
   * @return the size
1753
   */
1754
  public Dimension getSize(Dimension d)
1755
  {
1756
    if (d == null)
1757
      d = new Dimension();
1758
    d.width = width;
1759
    d.height = height;
1760
    return d;
1761
  }
1762
 
1763
  /**
1764
   * Returns the location of this component. This allows reuse of an existing
1765
   * point, if p is non-null.
1766
   *
1767
   * @param p the point to use, or null
1768
   * @return the location
1769
   */
1770
  public Point getLocation(Point p)
1771
  {
1772
    if (p == null)
1773
      p = new Point();
1774
    p.x = x;
1775
    p.y = y;
1776
    return p;
1777
  }
1778
 
1779
  /**
1780
   * Tests if this component is opaque. All "heavyweight" (natively-drawn)
1781
   * components are opaque. A component is opaque if it draws all pixels in
1782
   * the bounds; a lightweight component is partially transparent if it lets
1783
   * pixels underneath show through. Subclasses that guarantee that all pixels
1784
   * will be drawn should override this.
1785
   *
1786
   * @return true if this is opaque
1787
   * @see #isLightweight()
1788
   * @since 1.2
1789
   */
1790
  public boolean isOpaque()
1791
  {
1792
    return ! isLightweight();
1793
  }
1794
 
1795
  /**
1796
   * Return whether the component is lightweight. That means the component has
1797
   * no native peer, but is displayable. This applies to subclasses of
1798
   * Component not in this package, such as javax.swing.
1799
   *
1800
   * @return true if the component has a lightweight peer
1801
   * @see #isDisplayable()
1802
   * @since 1.2
1803
   */
1804
  public boolean isLightweight()
1805
  {
1806
    return peer instanceof LightweightPeer;
1807
  }
1808
 
1809
  /**
1810
   * Returns the component's preferred size.
1811
   *
1812
   * @return the component's preferred size
1813
   * @see #getMinimumSize()
1814
   * @see #setPreferredSize(Dimension)
1815
   * @see LayoutManager
1816
   */
1817
  public Dimension getPreferredSize()
1818
  {
1819
    return preferredSize();
1820
  }
1821
 
1822
  /**
1823
   * Sets the preferred size that will be returned by
1824
   * {@link #getPreferredSize()} always, and sends a
1825
   * {@link PropertyChangeEvent} (with the property name 'preferredSize') to
1826
   * all registered listeners.
1827
   *
1828
   * @param size  the preferred size (<code>null</code> permitted).
1829
   *
1830
   * @since 1.5
1831
   *
1832
   * @see #getPreferredSize()
1833
   */
1834
  public void setPreferredSize(Dimension size)
1835
  {
1836
    Dimension old = prefSizeSet ? prefSize : null;
1837
    prefSize = size;
1838
    prefSizeSet = (size != null);
1839
    firePropertyChange("preferredSize", old, size);
1840
  }
1841
 
1842
  /**
1843
   * Returns <code>true</code> if the current preferred size is not
1844
   * <code>null</code> and was set by a call to
1845
   * {@link #setPreferredSize(Dimension)}, otherwise returns <code>false</code>.
1846
   *
1847
   * @return A boolean.
1848
   *
1849
   * @since 1.5
1850
   */
1851
  public boolean isPreferredSizeSet()
1852
  {
1853
    return prefSizeSet;
1854
  }
1855
 
1856
  /**
1857
   * Returns the component's preferred size.
1858
   *
1859
   * @return the component's preferred size
1860
   * @deprecated use {@link #getPreferredSize()} instead
1861
   */
1862
  public Dimension preferredSize()
1863
  {
1864
    // Create a new Dimension object, so that the application doesn't mess
1865
    // with the actual values.
1866
    return new Dimension(preferredSizeImpl());
1867
  }
1868
 
1869
  /**
1870
   * The actual calculation is pulled out of preferredSize() so that
1871
   * we can call it from Container.preferredSize() and avoid creating a
1872
   * new intermediate Dimension object.
1873
   *
1874
   * @return the preferredSize of the component
1875
   */
1876
  Dimension preferredSizeImpl()
1877
  {
1878
    Dimension size = prefSize;
1879
    // Try to use a cached value.
1880
    if (size == null || !(valid || prefSizeSet))
1881
      {
1882
        // We need to lock here, because the calculation depends on the
1883
        // component structure not changing.
1884
        synchronized (getTreeLock())
1885
          {
1886
            ComponentPeer p = peer;
1887
            if (p != null)
1888
              size = peer.preferredSize();
1889
            else
1890
              size = minimumSizeImpl();
1891
          }
1892
      }
1893
    return size;
1894
  }
1895
 
1896
  /**
1897
   * Returns the component's minimum size.
1898
   *
1899
   * @return the component's minimum size
1900
   * @see #getPreferredSize()
1901
   * @see #setMinimumSize(Dimension)
1902
   * @see LayoutManager
1903
   */
1904
  public Dimension getMinimumSize()
1905
  {
1906
    return minimumSize();
1907
  }
1908
 
1909
  /**
1910
   * Sets the minimum size that will be returned by {@link #getMinimumSize()}
1911
   * always, and sends a {@link PropertyChangeEvent} (with the property name
1912
   * 'minimumSize') to all registered listeners.
1913
   *
1914
   * @param size  the minimum size (<code>null</code> permitted).
1915
   *
1916
   * @since 1.5
1917
   *
1918
   * @see #getMinimumSize()
1919
   */
1920
  public void setMinimumSize(Dimension size)
1921
  {
1922
    Dimension old = minSizeSet ? minSize : null;
1923
    minSize = size;
1924
    minSizeSet = (size != null);
1925
    firePropertyChange("minimumSize", old, size);
1926
  }
1927
 
1928
  /**
1929
   * Returns <code>true</code> if the current minimum size is not
1930
   * <code>null</code> and was set by a call to
1931
   * {@link #setMinimumSize(Dimension)}, otherwise returns <code>false</code>.
1932
   *
1933
   * @return A boolean.
1934
   *
1935
   * @since 1.5
1936
   */
1937
  public boolean isMinimumSizeSet()
1938
  {
1939
    return minSizeSet;
1940
  }
1941
 
1942
  /**
1943
   * Returns the component's minimum size.
1944
   *
1945
   * @return the component's minimum size
1946
   * @deprecated use {@link #getMinimumSize()} instead
1947
   */
1948
  public Dimension minimumSize()
1949
  {
1950
    // Create a new Dimension object, so that the application doesn't mess
1951
    // with the actual values.
1952
    return new Dimension(minimumSizeImpl());
1953
  }
1954
 
1955
  /**
1956
   * The actual calculation is pulled out of minimumSize() so that
1957
   * we can call it from Container.preferredSize() and
1958
   * Component.preferredSizeImpl and avoid creating a
1959
   * new intermediate Dimension object.
1960
   *
1961
   * @return the minimum size of the component
1962
   */
1963
  Dimension minimumSizeImpl()
1964
  {
1965
    Dimension size = minSize;
1966
    if (size == null || !(valid || minSizeSet))
1967
      {
1968
        // We need to lock here, because the calculation depends on the
1969
        // component structure not changing.
1970
        synchronized (getTreeLock())
1971
          {
1972
            ComponentPeer p = peer;
1973
            if (p != null)
1974
              size = peer.minimumSize();
1975
            else
1976
              size = size();
1977
          }
1978
      }
1979
    return size;
1980
  }
1981
 
1982
  /**
1983
   * Returns the component's maximum size.
1984
   *
1985
   * @return the component's maximum size
1986
   * @see #getMinimumSize()
1987
   * @see #setMaximumSize(Dimension)
1988
   * @see #getPreferredSize()
1989
   * @see LayoutManager
1990
   */
1991
  public Dimension getMaximumSize()
1992
  {
1993
    return new Dimension(maximumSizeImpl());
1994
  }
1995
 
1996
  /**
1997
   * This is pulled out from getMaximumSize(), so that we can access it
1998
   * from Container.getMaximumSize() without creating an additional
1999
   * intermediate Dimension object.
2000
   *
2001
   * @return the maximum size of the component
2002
   */
2003
  Dimension maximumSizeImpl()
2004
  {
2005
    Dimension size;
2006
    if (maxSizeSet)
2007
      size = maxSize;
2008
    else
2009
      size = DEFAULT_MAX_SIZE;
2010
    return size;
2011
  }
2012
 
2013
  /**
2014
   * Sets the maximum size that will be returned by {@link #getMaximumSize()}
2015
   * always, and sends a {@link PropertyChangeEvent} (with the property name
2016
   * 'maximumSize') to all registered listeners.
2017
   *
2018
   * @param size  the maximum size (<code>null</code> permitted).
2019
   *
2020
   * @since 1.5
2021
   *
2022
   * @see #getMaximumSize()
2023
   */
2024
  public void setMaximumSize(Dimension size)
2025
  {
2026
    Dimension old = maxSizeSet ? maxSize : null;
2027
    maxSize = size;
2028
    maxSizeSet = (size != null);
2029
    firePropertyChange("maximumSize", old, size);
2030
  }
2031
 
2032
  /**
2033
   * Returns <code>true</code> if the current maximum size is not
2034
   * <code>null</code> and was set by a call to
2035
   * {@link #setMaximumSize(Dimension)}, otherwise returns <code>false</code>.
2036
   *
2037
   * @return A boolean.
2038
   *
2039
   * @since 1.5
2040
   */
2041
  public boolean isMaximumSizeSet()
2042
  {
2043
    return maxSizeSet;
2044
  }
2045
 
2046
  /**
2047
   * Returns the preferred horizontal alignment of this component. The value
2048
   * returned will be between {@link #LEFT_ALIGNMENT} and
2049
   * {@link #RIGHT_ALIGNMENT}, inclusive.
2050
   *
2051
   * @return the preferred horizontal alignment of this component
2052
   */
2053
  public float getAlignmentX()
2054
  {
2055
    return CENTER_ALIGNMENT;
2056
  }
2057
 
2058
  /**
2059
   * Returns the preferred vertical alignment of this component. The value
2060
   * returned will be between {@link #TOP_ALIGNMENT} and
2061
   * {@link #BOTTOM_ALIGNMENT}, inclusive.
2062
   *
2063
   * @return the preferred vertical alignment of this component
2064
   */
2065
  public float getAlignmentY()
2066
  {
2067
    return CENTER_ALIGNMENT;
2068
  }
2069
 
2070
  /**
2071
   * Calls the layout manager to re-layout the component. This is called
2072
   * during validation of a container in most cases.
2073
   *
2074
   * @see #validate()
2075
   * @see LayoutManager
2076
   */
2077
  public void doLayout()
2078
  {
2079
    layout ();
2080
  }
2081
 
2082
  /**
2083
   * Calls the layout manager to re-layout the component. This is called
2084
   * during validation of a container in most cases.
2085
   *
2086
   * @deprecated use {@link #doLayout()} instead
2087
   */
2088
  public void layout()
2089
  {
2090
    // Nothing to do unless we're a container.
2091
  }
2092
 
2093
  /**
2094
   * Called to ensure that the layout for this component is valid. This is
2095
   * usually called on containers.
2096
   *
2097
   * @see #invalidate()
2098
   * @see #doLayout()
2099
   * @see LayoutManager
2100
   * @see Container#validate()
2101
   */
2102
  public void validate()
2103
  {
2104
    if (! valid)
2105
      {
2106
        // Synchronize on the tree here as this might change the layout
2107
        // of the hierarchy.
2108
        synchronized (getTreeLock())
2109
          {
2110
            // Create local variables for thread safety.
2111
            ComponentPeer p = peer;
2112
            if (p != null)
2113
              {
2114
                // Possibly update the peer's font.
2115
                Font newFont = getFont();
2116
                Font oldFont = peerFont;
2117
                // Only update when the font really changed.
2118
                if (newFont != oldFont
2119
                    && (oldFont == null || ! oldFont.equals(newFont)))
2120
                  {
2121
                    p.setFont(newFont);
2122
                    peerFont = newFont;
2123
                  }
2124
                // Let the peer perform any layout.
2125
                p.layout();
2126
              }
2127
          }
2128
        valid = true;
2129
      }
2130
  }
2131
 
2132
  /**
2133
   * Invalidates this component and all of its parent components. This will
2134
   * cause them to have their layout redone. This is called frequently, so
2135
   * make it fast.
2136
   */
2137
  public void invalidate()
2138
  {
2139
    // Need to lock here, to avoid races and other ugly stuff when doing
2140
    // layout or structure changes in other threads.
2141
    synchronized (getTreeLock())
2142
      {
2143
        // Invalidate.
2144
        valid = false;
2145
 
2146
        // Throw away cached layout information.
2147
        if (! minSizeSet)
2148
          minSize = null;
2149
        if (! prefSizeSet)
2150
          prefSize = null;
2151
        if (! maxSizeSet)
2152
          maxSize = null;
2153
 
2154
        // Also invalidate the parent, if it hasn't already been invalidated.
2155
        if (parent != null && parent.isValid())
2156
          parent.invalidate();
2157
      }
2158
  }
2159
 
2160
  /**
2161
   * Returns a graphics object for this component. Returns <code>null</code>
2162
   * if this component is not currently displayed on the screen.
2163
   *
2164
   * @return a graphics object for this component
2165
   * @see #paint(Graphics)
2166
   */
2167
  public Graphics getGraphics()
2168
  {
2169
    // Only heavyweight peers can handle this.
2170
    ComponentPeer p = peer;
2171
    Graphics g = null;
2172
    if (p instanceof LightweightPeer)
2173
      {
2174
        if (parent != null)
2175
          {
2176
            g = parent.getGraphics();
2177
            if (g != null)
2178
              {
2179
                g.translate(x, y);
2180
                g.setClip(0, 0, width, height);
2181
                g.setFont(getFont());
2182
              }
2183
          }
2184
      }
2185
    else
2186
      {
2187
        if (p != null)
2188
          g = p.getGraphics();
2189
      }
2190
    return g;
2191
  }
2192
 
2193
  /**
2194
   * Returns the font metrics for the specified font in this component.
2195
   *
2196
   * @param font the font to retrieve metrics for
2197
   * @return the font metrics for the specified font
2198
   * @throws NullPointerException if font is null
2199
   * @see #getFont()
2200
   * @see Toolkit#getFontMetrics(Font)
2201
   */
2202
  public FontMetrics getFontMetrics(Font font)
2203
  {
2204
    ComponentPeer p = peer;
2205
    Component comp = this;
2206
    while (p instanceof LightweightPeer)
2207
      {
2208
        comp = comp.parent;
2209
        p = comp == null ? null : comp.peer;
2210
      }
2211
 
2212
    return p == null ? getToolkit().getFontMetrics(font)
2213
           : p.getFontMetrics(font);
2214
  }
2215
 
2216
  /**
2217
   * Sets the cursor for this component to the specified cursor. The cursor
2218
   * is displayed when the point is contained by the component, and the
2219
   * component is visible, displayable, and enabled. This is inherited by
2220
   * subcomponents unless they set their own cursor.
2221
   *
2222
   * @param cursor the new cursor for this component
2223
   * @see #isEnabled()
2224
   * @see #isShowing()
2225
   * @see #getCursor()
2226
   * @see #contains(int, int)
2227
   * @see Toolkit#createCustomCursor(Image, Point, String)
2228
   */
2229
  public void setCursor(Cursor cursor)
2230
  {
2231
    this.cursor = cursor;
2232
 
2233
    // Only heavyweight peers handle this.
2234
    ComponentPeer p = peer;
2235
    Component comp = this;
2236
    while (p instanceof LightweightPeer)
2237
      {
2238
        comp = comp.parent;
2239
        p = comp == null ? null : comp.peer;
2240
      }
2241
 
2242
    if (p != null)
2243
      p.setCursor(cursor);
2244
  }
2245
 
2246
  /**
2247
   * Returns the cursor for this component. If not set, this is inherited
2248
   * from the parent, or from Cursor.getDefaultCursor().
2249
   *
2250
   * @return the cursor for this component
2251
   */
2252
  public Cursor getCursor()
2253
  {
2254
    if (cursor != null)
2255
      return cursor;
2256
    return parent != null ? parent.getCursor() : Cursor.getDefaultCursor();
2257
  }
2258
 
2259
  /**
2260
   * Tests if the cursor was explicitly set, or just inherited from the parent.
2261
   *
2262
   * @return true if the cursor has been set
2263
   * @since 1.4
2264
   */
2265
  public boolean isCursorSet()
2266
  {
2267
    return cursor != null;
2268
  }
2269
 
2270
  /**
2271
   * Paints this component on the screen. The clipping region in the graphics
2272
   * context will indicate the region that requires painting. This is called
2273
   * whenever the component first shows, or needs to be repaired because
2274
   * something was temporarily drawn on top. It is not necessary for
2275
   * subclasses to call <code>super.paint(g)</code>. Components with no area
2276
   * are not painted.
2277
   *
2278
   * @param g the graphics context for this paint job
2279
   * @see #update(Graphics)
2280
   */
2281
  public void paint(Graphics g)
2282
  {
2283
    // This is a callback method and is meant to be overridden by subclasses
2284
    // that want to perform custom painting.
2285
  }
2286
 
2287
  /**
2288
   * Updates this component. This is called for heavyweight components in
2289
   * response to {@link #repaint()}. The default implementation simply forwards
2290
   * to {@link #paint(Graphics)}. The coordinates of the graphics are
2291
   * relative to this component. Subclasses should call either
2292
   * <code>super.update(g)</code> or <code>paint(g)</code>.
2293
   *
2294
   * @param g the graphics context for this update
2295
   *
2296
   * @see #paint(Graphics)
2297
   * @see #repaint()
2298
   */
2299
  public void update(Graphics g)
2300
  {
2301
    // Note 1: We used to clear the background here for lightweights and
2302
    // toplevel components. Tests show that this is not what the JDK does
2303
    // here. Note that there is some special handling and background
2304
    // clearing code in Container.update(Graphics).
2305
 
2306
    // Note 2 (for peer implementors): The JDK doesn't seem call update() for
2307
    // toplevel components, even when an UPDATE event is sent (as a result
2308
    // of repaint).
2309
    paint(g);
2310
  }
2311
 
2312
  /**
2313
   * Paints this entire component, including any sub-components.
2314
   *
2315
   * @param g the graphics context for this paint job
2316
   *
2317
   * @see #paint(Graphics)
2318
   */
2319
  public void paintAll(Graphics g)
2320
  {
2321
    if (isShowing())
2322
      {
2323
        validate();
2324
        if (peer instanceof LightweightPeer)
2325
          paint(g);
2326
        else
2327
          peer.paint(g);
2328
      }
2329
  }
2330
 
2331
  /**
2332
   * Repaint this entire component. The <code>update()</code> method
2333
   * on this component will be called as soon as possible.
2334
   *
2335
   * @see #update(Graphics)
2336
   * @see #repaint(long, int, int, int, int)
2337
   */
2338
  public void repaint()
2339
  {
2340
    repaint(0, 0, 0, width, height);
2341
  }
2342
 
2343
  /**
2344
   * Repaint this entire component. The <code>update()</code> method on this
2345
   * component will be called in approximate the specified number of
2346
   * milliseconds.
2347
   *
2348
   * @param tm milliseconds before this component should be repainted
2349
   * @see #paint(Graphics)
2350
   * @see #repaint(long, int, int, int, int)
2351
   */
2352
  public void repaint(long tm)
2353
  {
2354
    repaint(tm, 0, 0, width, height);
2355
  }
2356
 
2357
  /**
2358
   * Repaints the specified rectangular region within this component. The
2359
   * <code>update</code> method on this component will be called as soon as
2360
   * possible. The coordinates are relative to this component.
2361
   *
2362
   * @param x the X coordinate of the upper left of the region to repaint
2363
   * @param y the Y coordinate of the upper left of the region to repaint
2364
   * @param w the width of the region to repaint
2365
   * @param h the height of the region to repaint
2366
   * @see #update(Graphics)
2367
   * @see #repaint(long, int, int, int, int)
2368
   */
2369
  public void repaint(int x, int y, int w, int h)
2370
  {
2371
    repaint(0, x, y, w, h);
2372
  }
2373
 
2374
  /**
2375
   * Repaints the specified rectangular region within this component. The
2376
   * <code>update</code> method on this component will be called in
2377
   * approximately the specified number of milliseconds. The coordinates
2378
   * are relative to this component.
2379
   *
2380
   * @param tm milliseconds before this component should be repainted
2381
   * @param x the X coordinate of the upper left of the region to repaint
2382
   * @param y the Y coordinate of the upper left of the region to repaint
2383
   * @param width the width of the region to repaint
2384
   * @param height the height of the region to repaint
2385
   * @see #update(Graphics)
2386
   */
2387
  public void repaint(long tm, int x, int y, int width, int height)
2388
  {
2389
    // The repaint() call has previously been delegated to
2390
    // {@link ComponentPeer.repaint()}. Testing on the JDK using some
2391
    // dummy peers show that this methods is never called. I think it makes
2392
    // sense to actually perform the tasks below here, since it's pretty
2393
    // much peer independent anyway, and makes sure only heavyweights are
2394
    // bothered by this.
2395
    ComponentPeer p = peer;
2396
 
2397
    // Let the nearest heavyweight parent handle repainting for lightweight
2398
    // components.
2399
    // We need to recursivly call repaint() on the parent here, since
2400
    // a (lightweight) parent component might have overridden repaint()
2401
    // to perform additional custom tasks.
2402
 
2403
    if (p instanceof LightweightPeer)
2404
      {
2405
        // We perform some boundary checking to restrict the paint
2406
        // region to this component.
2407
        if (parent != null)
2408
          {
2409
            int px = this.x + Math.max(0, x);
2410
            int py = this.y + Math.max(0, y);
2411
            int pw = Math.min(this.width, width);
2412
            int ph = Math.min(this.height, height);
2413
            parent.repaint(tm, px, py, pw, ph);
2414
          }
2415
      }
2416
    else
2417
      {
2418
        // Now send an UPDATE event to the heavyweight component that we've found.
2419
        if (isVisible() && p != null && width > 0 && height > 0)
2420
          {
2421
            PaintEvent pe = new PaintEvent(this, PaintEvent.UPDATE,
2422
                                           new Rectangle(x, y, width, height));
2423
            getToolkit().getSystemEventQueue().postEvent(pe);
2424
          }
2425
      }
2426
  }
2427
 
2428
  /**
2429
   * Prints this component. This method is provided so that printing can be
2430
   * done in a different manner from painting. However, the implementation
2431
   * in this class simply calls the <code>paint()</code> method.
2432
   *
2433
   * @param g the graphics context of the print device
2434
   *
2435
   * @see #paint(Graphics)
2436
   */
2437
  public void print(Graphics g)
2438
  {
2439
    paint(g);
2440
  }
2441
 
2442
  /**
2443
   * Prints this component, including all sub-components.
2444
   *
2445
   * @param g the graphics context of the print device
2446
   *
2447
   * @see #paintAll(Graphics)
2448
   */
2449
  public void printAll(Graphics g)
2450
  {
2451
    if( peer != null )
2452
      peer.print( g );
2453
    paintAll( g );
2454
  }
2455
 
2456
  /**
2457
   * Called when an image has changed so that this component is repainted.
2458
   * This incrementally draws an image as more bits are available, when
2459
   * possible. Incremental drawing is enabled if the system property
2460
   * <code>awt.image.incrementalDraw</code> is not present or is true, in which
2461
   * case the redraw rate is set to 100ms or the value of the system property
2462
   * <code>awt.image.redrawrate</code>.
2463
   *
2464
   * <p>The coordinate system used depends on the particular flags.
2465
   *
2466
   * @param img the image that has been updated
2467
   * @param flags tlags as specified in <code>ImageObserver</code>
2468
   * @param x the X coordinate
2469
   * @param y the Y coordinate
2470
   * @param w the width
2471
   * @param h the height
2472
   * @return false if the image is completely loaded, loading has been
2473
   * aborted, or an error has occurred.  true if more updates are
2474
   * required.
2475
   * @see ImageObserver
2476
   * @see Graphics#drawImage(Image, int, int, Color, ImageObserver)
2477
   * @see Graphics#drawImage(Image, int, int, ImageObserver)
2478
   * @see Graphics#drawImage(Image, int, int, int, int, Color, ImageObserver)
2479
   * @see Graphics#drawImage(Image, int, int, int, int, ImageObserver)
2480
   * @see ImageObserver#imageUpdate(Image, int, int, int, int, int)
2481
   */
2482
  public boolean imageUpdate(Image img, int flags, int x, int y, int w, int h)
2483
  {
2484
    if ((flags & (FRAMEBITS | ALLBITS)) != 0)
2485
      repaint();
2486
    else if ((flags & SOMEBITS) != 0)
2487
      {
2488
        if (incrementalDraw)
2489
          {
2490
            if (redrawRate != null)
2491
              {
2492
                long tm = redrawRate.longValue();
2493
                if (tm < 0)
2494
                  tm = 0;
2495
                repaint(tm);
2496
              }
2497
            else
2498
              repaint(100);
2499
          }
2500
      }
2501
    return (flags & (ALLBITS | ABORT | ERROR)) == 0;
2502
  }
2503
 
2504
  /**
2505
   * Creates an image from the specified producer.
2506
   *
2507
   * @param producer the image procedure to create the image from
2508
   * @return the resulting image
2509
   */
2510
  public Image createImage(ImageProducer producer)
2511
  {
2512
    // Only heavyweight peers can handle this.
2513
    ComponentPeer p = peer;
2514
    Component comp = this;
2515
    while (p instanceof LightweightPeer)
2516
      {
2517
        comp = comp.parent;
2518
        p = comp == null ? null : comp.peer;
2519
      }
2520
 
2521
    // Sun allows producer to be null.
2522
    Image im;
2523
    if (p != null)
2524
      im = p.createImage(producer);
2525
    else
2526
      im = getToolkit().createImage(producer);
2527
    return im;
2528
  }
2529
 
2530
  /**
2531
   * Creates an image with the specified width and height for use in
2532
   * double buffering. Headless environments do not support images.
2533
   *
2534
   * @param width the width of the image
2535
   * @param height the height of the image
2536
   * @return the requested image, or null if it is not supported
2537
   */
2538
  public Image createImage (int width, int height)
2539
  {
2540
    Image returnValue = null;
2541
    if (!GraphicsEnvironment.isHeadless ())
2542
      {
2543
        // Only heavyweight peers can handle this.
2544
        ComponentPeer p = peer;
2545
        Component comp = this;
2546
        while (p instanceof LightweightPeer)
2547
          {
2548
            comp = comp.parent;
2549
            p = comp == null ? null : comp.peer;
2550
          }
2551
 
2552
        if (p != null)
2553
          returnValue = p.createImage(width, height);
2554
      }
2555
    return returnValue;
2556
  }
2557
 
2558
  /**
2559
   * Creates an image with the specified width and height for use in
2560
   * double buffering. Headless environments do not support images.
2561
   *
2562
   * @param width the width of the image
2563
   * @param height the height of the image
2564
   * @return the requested image, or null if it is not supported
2565
   * @since 1.4
2566
   */
2567
  public VolatileImage createVolatileImage(int width, int height)
2568
  {
2569
    // Only heavyweight peers can handle this.
2570
    ComponentPeer p = peer;
2571
    Component comp = this;
2572
    while (p instanceof LightweightPeer)
2573
      {
2574
        comp = comp.parent;
2575
        p = comp == null ? null : comp.peer;
2576
      }
2577
 
2578
    VolatileImage im = null;
2579
    if (p != null)
2580
      im = p.createVolatileImage(width, height);
2581
    return im;
2582
  }
2583
 
2584
  /**
2585
   * Creates an image with the specified width and height for use in
2586
   * double buffering. Headless environments do not support images. The image
2587
   * will support the specified capabilities.
2588
   *
2589
   * @param width the width of the image
2590
   * @param height the height of the image
2591
   * @param caps the requested capabilities
2592
   * @return the requested image, or null if it is not supported
2593
   * @throws AWTException if a buffer with the capabilities cannot be created
2594
   * @since 1.4
2595
   */
2596
  public VolatileImage createVolatileImage(int width, int height,
2597
                                           ImageCapabilities caps)
2598
    throws AWTException
2599
  {
2600
    // Only heavyweight peers can handle this.
2601
    ComponentPeer p = peer;
2602
    Component comp = this;
2603
    while (p instanceof LightweightPeer)
2604
      {
2605
        comp = comp.parent;
2606
        p = comp == null ? null : comp.peer;
2607
      }
2608
 
2609
    VolatileImage im = null;
2610
    if (p != null)
2611
      im = peer.createVolatileImage(width, height);
2612
    return im;
2613
  }
2614
 
2615
  /**
2616
   * Prepares the specified image for rendering on this component.
2617
   *
2618
   * @param image the image to prepare for rendering
2619
   * @param observer the observer to notify of image preparation status
2620
   * @return true if the image is already fully prepared
2621
   * @throws NullPointerException if image is null
2622
   */
2623
  public boolean prepareImage(Image image, ImageObserver observer)
2624
  {
2625
    return prepareImage(image, image.getWidth(observer),
2626
                        image.getHeight(observer), observer);
2627
  }
2628
 
2629
  /**
2630
   * Prepares the specified image for rendering on this component at the
2631
   * specified scaled width and height
2632
   *
2633
   * @param image the image to prepare for rendering
2634
   * @param width the scaled width of the image
2635
   * @param height the scaled height of the image
2636
   * @param observer the observer to notify of image preparation status
2637
   * @return true if the image is already fully prepared
2638
   */
2639
  public boolean prepareImage(Image image, int width, int height,
2640
                              ImageObserver observer)
2641
  {
2642
    // Only heavyweight peers handle this.
2643
    ComponentPeer p = peer;
2644
    Component comp = this;
2645
    while (p instanceof LightweightPeer)
2646
      {
2647
        comp = comp.parent;
2648
        p = comp == null ? null : comp.peer;
2649
      }
2650
 
2651
    boolean retval;
2652
    if (p != null)
2653
        retval = p.prepareImage(image, width, height, observer);
2654
    else
2655
        retval = getToolkit().prepareImage(image, width, height, observer);
2656
    return retval;
2657
  }
2658
 
2659
  /**
2660
   * Returns the status of the loading of the specified image. The value
2661
   * returned will be those flags defined in <code>ImageObserver</code>.
2662
   *
2663
   * @param image the image to check on
2664
   * @param observer the observer to notify of image loading progress
2665
   * @return the image observer flags indicating the status of the load
2666
   * @see #prepareImage(Image, int, int, ImageObserver)
2667
   * @see Toolkit#checkImage(Image, int, int, ImageObserver)
2668
   * @throws NullPointerException if image is null
2669
   */
2670
  public int checkImage(Image image, ImageObserver observer)
2671
  {
2672
    return checkImage(image, -1, -1, observer);
2673
  }
2674
 
2675
  /**
2676
   * Returns the status of the loading of the specified image. The value
2677
   * returned will be those flags defined in <code>ImageObserver</code>.
2678
   *
2679
   * @param image the image to check on
2680
   * @param width the scaled image width
2681
   * @param height the scaled image height
2682
   * @param observer the observer to notify of image loading progress
2683
   * @return the image observer flags indicating the status of the load
2684
   * @see #prepareImage(Image, int, int, ImageObserver)
2685
   * @see Toolkit#checkImage(Image, int, int, ImageObserver)
2686
   */
2687
  public int checkImage(Image image, int width, int height,
2688
                        ImageObserver observer)
2689
  {
2690
    // Only heavyweight peers handle this.
2691
    ComponentPeer p = peer;
2692
    Component comp = this;
2693
    while (p instanceof LightweightPeer)
2694
      {
2695
        comp = comp.parent;
2696
        p = comp == null ? null : comp.peer;
2697
      }
2698
 
2699
    int retval;
2700
    if (p != null)
2701
      retval = p.checkImage(image, width, height, observer);
2702
    else
2703
      retval = getToolkit().checkImage(image, width, height, observer);
2704
    return retval;
2705
  }
2706
 
2707
  /**
2708
   * Sets whether paint messages delivered by the operating system should be
2709
   * ignored. This does not affect messages from AWT, except for those
2710
   * triggered by OS messages. Setting this to true can allow faster
2711
   * performance in full-screen mode or page-flipping.
2712
   *
2713
   * @param ignoreRepaint the new setting for ignoring repaint events
2714
   * @see #getIgnoreRepaint()
2715
   * @see BufferStrategy
2716
   * @see GraphicsDevice#setFullScreenWindow(Window)
2717
   * @since 1.4
2718
   */
2719
  public void setIgnoreRepaint(boolean ignoreRepaint)
2720
  {
2721
    this.ignoreRepaint = ignoreRepaint;
2722
  }
2723
 
2724
  /**
2725
   * Test whether paint events from the operating system are ignored.
2726
   *
2727
   * @return the status of ignoring paint events
2728
   * @see #setIgnoreRepaint(boolean)
2729
   * @since 1.4
2730
   */
2731
  public boolean getIgnoreRepaint()
2732
  {
2733
    return ignoreRepaint;
2734
  }
2735
 
2736
  /**
2737
   * Tests whether or not the specified point is contained within this
2738
   * component. Coordinates are relative to this component.
2739
   *
2740
   * @param x the X coordinate of the point to test
2741
   * @param y the Y coordinate of the point to test
2742
   * @return true if the point is within this component
2743
   * @see #getComponentAt(int, int)
2744
   */
2745
  public boolean contains(int x, int y)
2746
  {
2747
    return inside (x, y);
2748
  }
2749
 
2750
  /**
2751
   * Tests whether or not the specified point is contained within this
2752
   * component. Coordinates are relative to this component.
2753
   *
2754
   * @param x the X coordinate of the point to test
2755
   * @param y the Y coordinate of the point to test
2756
   * @return true if the point is within this component
2757
   * @deprecated use {@link #contains(int, int)} instead
2758
   */
2759
  public boolean inside(int x, int y)
2760
  {
2761
    return x >= 0 && y >= 0 && x < width && y < height;
2762
  }
2763
 
2764
  /**
2765
   * Tests whether or not the specified point is contained within this
2766
   * component. Coordinates are relative to this component.
2767
   *
2768
   * @param p the point to test
2769
   * @return true if the point is within this component
2770
   * @throws NullPointerException if p is null
2771
   * @see #getComponentAt(Point)
2772
   * @since 1.1
2773
   */
2774
  public boolean contains(Point p)
2775
  {
2776
    return contains (p.x, p.y);
2777
  }
2778
 
2779
  /**
2780
   * Returns the component occupying the position (x,y). This will either
2781
   * be this component, an immediate child component, or <code>null</code>
2782
   * if neither of the first two occupies the specified location.
2783
   *
2784
   * @param x the X coordinate to search for components at
2785
   * @param y the Y coordinate to search for components at
2786
   * @return the component at the specified location, or null
2787
   * @see #contains(int, int)
2788
   */
2789
  public Component getComponentAt(int x, int y)
2790
  {
2791
    return locate (x, y);
2792
  }
2793
 
2794
  /**
2795
   * Returns the component occupying the position (x,y). This will either
2796
   * be this component, an immediate child component, or <code>null</code>
2797
   * if neither of the first two occupies the specified location.
2798
   *
2799
   * @param x the X coordinate to search for components at
2800
   * @param y the Y coordinate to search for components at
2801
   * @return the component at the specified location, or null
2802
   * @deprecated use {@link #getComponentAt(int, int)} instead
2803
   */
2804
  public Component locate(int x, int y)
2805
  {
2806
    return contains (x, y) ? this : null;
2807
  }
2808
 
2809
  /**
2810
   * Returns the component occupying the position (x,y). This will either
2811
   * be this component, an immediate child component, or <code>null</code>
2812
   * if neither of the first two occupies the specified location.
2813
   *
2814
   * @param p the point to search for components at
2815
   * @return the component at the specified location, or null
2816
   * @throws NullPointerException if p is null
2817
   * @see #contains(Point)
2818
   * @since 1.1
2819
   */
2820
  public Component getComponentAt(Point p)
2821
  {
2822
    return getComponentAt (p.x, p.y);
2823
  }
2824
 
2825
  /**
2826
   * AWT 1.0 event delivery.
2827
   *
2828
   * Deliver an AWT 1.0 event to this Component.  This method simply
2829
   * calls {@link #postEvent}.
2830
   *
2831
   * @param e the event to deliver
2832
   * @deprecated use {@link #dispatchEvent (AWTEvent)} instead
2833
   */
2834
  public void deliverEvent (Event e)
2835
  {
2836
    postEvent (e);
2837
  }
2838
 
2839
  /**
2840
   * Forwards AWT events to processEvent() if:<ul>
2841
   * <li>Events have been enabled for this type of event via
2842
   * <code>enableEvents()</code></li>,
2843
   * <li>There is at least one registered listener for this type of event</li>
2844
   * </ul>
2845
   *
2846
   * @param e the event to dispatch
2847
   */
2848
  public final void dispatchEvent(AWTEvent e)
2849
  {
2850
    // Some subclasses in the AWT package need to override this behavior,
2851
    // hence the use of dispatchEventImpl().
2852
    dispatchEventImpl(e);
2853
  }
2854
 
2855
  /**
2856
   * By default, no old mouse events should be ignored.
2857
   * This can be overridden by subclasses.
2858
   *
2859
   * @return false, no mouse events are ignored.
2860
   */
2861
  static boolean ignoreOldMouseEvents()
2862
  {
2863
    return false;
2864
  }
2865
 
2866
  /**
2867
   * AWT 1.0 event handler.
2868
   *
2869
   * This method simply calls handleEvent and returns the result.
2870
   *
2871
   * @param e the event to handle
2872
   * @return true if the event was handled, false otherwise
2873
   * @deprecated use {@link #dispatchEvent(AWTEvent)} instead
2874
   */
2875
  public boolean postEvent (Event e)
2876
  {
2877
    boolean handled = handleEvent (e);
2878
 
2879
    if (!handled && getParent() != null)
2880
      // FIXME: need to translate event coordinates to parent's
2881
      // coordinate space.
2882
      handled = getParent ().postEvent (e);
2883
 
2884
    return handled;
2885
  }
2886
 
2887
  /**
2888
   * Adds the specified listener to this component. This is harmless if the
2889
   * listener is null, but if the listener has already been registered, it
2890
   * will now be registered twice.
2891
   *
2892
   * @param listener the new listener to add
2893
   * @see ComponentEvent
2894
   * @see #removeComponentListener(ComponentListener)
2895
   * @see #getComponentListeners()
2896
   * @since 1.1
2897
   */
2898
  public synchronized void addComponentListener(ComponentListener listener)
2899
  {
2900
    if (listener != null)
2901
      {
2902
        componentListener = AWTEventMulticaster.add(componentListener,
2903
                                                    listener);
2904
        newEventsOnly = true;
2905
      }
2906
  }
2907
 
2908
  /**
2909
   * Removes the specified listener from the component. This is harmless if
2910
   * the listener was not previously registered.
2911
   *
2912
   * @param listener the listener to remove
2913
   * @see ComponentEvent
2914
   * @see #addComponentListener(ComponentListener)
2915
   * @see #getComponentListeners()
2916
   * @since 1.1
2917
   */
2918
  public synchronized void removeComponentListener(ComponentListener listener)
2919
  {
2920
    componentListener = AWTEventMulticaster.remove(componentListener, listener);
2921
  }
2922
 
2923
  /**
2924
   * Returns an array of all specified listeners registered on this component.
2925
   *
2926
   * @return an array of listeners
2927
   * @see #addComponentListener(ComponentListener)
2928
   * @see #removeComponentListener(ComponentListener)
2929
   * @since 1.4
2930
   */
2931
  public synchronized ComponentListener[] getComponentListeners()
2932
  {
2933
    return (ComponentListener[])
2934
      AWTEventMulticaster.getListeners(componentListener,
2935
                                       ComponentListener.class);
2936
  }
2937
 
2938
  /**
2939
   * Adds the specified listener to this component. This is harmless if the
2940
   * listener is null, but if the listener has already been registered, it
2941
   * will now be registered twice.
2942
   *
2943
   * @param listener the new listener to add
2944
   * @see FocusEvent
2945
   * @see #removeFocusListener(FocusListener)
2946
   * @see #getFocusListeners()
2947
   * @since 1.1
2948
   */
2949
  public synchronized void addFocusListener(FocusListener listener)
2950
  {
2951
    if (listener != null)
2952
      {
2953
        focusListener = AWTEventMulticaster.add(focusListener, listener);
2954
        newEventsOnly = true;
2955
      }
2956
  }
2957
 
2958
  /**
2959
   * Removes the specified listener from the component. This is harmless if
2960
   * the listener was not previously registered.
2961
   *
2962
   * @param listener the listener to remove
2963
   * @see FocusEvent
2964
   * @see #addFocusListener(FocusListener)
2965
   * @see #getFocusListeners()
2966
   * @since 1.1
2967
   */
2968
  public synchronized void removeFocusListener(FocusListener listener)
2969
  {
2970
    focusListener = AWTEventMulticaster.remove(focusListener, listener);
2971
  }
2972
 
2973
  /**
2974
   * Returns an array of all specified listeners registered on this component.
2975
   *
2976
   * @return an array of listeners
2977
   * @see #addFocusListener(FocusListener)
2978
   * @see #removeFocusListener(FocusListener)
2979
   * @since 1.4
2980
   */
2981
  public synchronized FocusListener[] getFocusListeners()
2982
  {
2983
    return (FocusListener[])
2984
      AWTEventMulticaster.getListeners(focusListener, FocusListener.class);
2985
  }
2986
 
2987
  /**
2988
   * Adds the specified listener to this component. This is harmless if the
2989
   * listener is null, but if the listener has already been registered, it
2990
   * will now be registered twice.
2991
   *
2992
   * @param listener the new listener to add
2993
   * @see HierarchyEvent
2994
   * @see #removeHierarchyListener(HierarchyListener)
2995
   * @see #getHierarchyListeners()
2996
   * @since 1.3
2997
   */
2998
  public synchronized void addHierarchyListener(HierarchyListener listener)
2999
  {
3000
    if (listener != null)
3001
      {
3002
        hierarchyListener = AWTEventMulticaster.add(hierarchyListener,
3003
                                                    listener);
3004
        newEventsOnly = true;
3005
        // Need to lock the tree, otherwise we might end up inconsistent.
3006
        synchronized (getTreeLock())
3007
        {
3008
          numHierarchyListeners++;
3009
          if (parent != null)
3010
            parent.updateHierarchyListenerCount(AWTEvent.HIERARCHY_EVENT_MASK,
3011
                                                1);
3012
        }
3013
      }
3014
  }
3015
 
3016
  /**
3017
   * Removes the specified listener from the component. This is harmless if
3018
   * the listener was not previously registered.
3019
   *
3020
   * @param listener the listener to remove
3021
   * @see HierarchyEvent
3022
   * @see #addHierarchyListener(HierarchyListener)
3023
   * @see #getHierarchyListeners()
3024
   * @since 1.3
3025
   */
3026
  public synchronized void removeHierarchyListener(HierarchyListener listener)
3027
  {
3028
    hierarchyListener = AWTEventMulticaster.remove(hierarchyListener, listener);
3029
 
3030
    // Need to lock the tree, otherwise we might end up inconsistent.
3031
    synchronized (getTreeLock())
3032
      {
3033
        numHierarchyListeners--;
3034
        if (parent != null)
3035
          parent.updateHierarchyListenerCount(AWTEvent.HIERARCHY_EVENT_MASK,
3036
                                              -1);
3037
      }
3038
  }
3039
 
3040
  /**
3041
   * Returns an array of all specified listeners registered on this component.
3042
   *
3043
   * @return an array of listeners
3044
   * @see #addHierarchyListener(HierarchyListener)
3045
   * @see #removeHierarchyListener(HierarchyListener)
3046
   * @since 1.4
3047
   */
3048
  public synchronized HierarchyListener[] getHierarchyListeners()
3049
  {
3050
    return (HierarchyListener[])
3051
      AWTEventMulticaster.getListeners(hierarchyListener,
3052
                                       HierarchyListener.class);
3053
  }
3054
 
3055
  /**
3056
   * Adds the specified listener to this component. This is harmless if the
3057
   * listener is null, but if the listener has already been registered, it
3058
   * will now be registered twice.
3059
   *
3060
   * @param listener the new listener to add
3061
   * @see HierarchyEvent
3062
   * @see #removeHierarchyBoundsListener(HierarchyBoundsListener)
3063
   * @see #getHierarchyBoundsListeners()
3064
   * @since 1.3
3065
   */
3066
  public synchronized void
3067
    addHierarchyBoundsListener(HierarchyBoundsListener listener)
3068
  {
3069
    if (listener != null)
3070
      {
3071
        hierarchyBoundsListener =
3072
          AWTEventMulticaster.add(hierarchyBoundsListener, listener);
3073
        newEventsOnly = true;
3074
 
3075
        // Need to lock the tree, otherwise we might end up inconsistent.
3076
        synchronized (getTreeLock())
3077
        {
3078
          numHierarchyBoundsListeners++;
3079
          if (parent != null)
3080
            parent.updateHierarchyListenerCount
3081
                                     (AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK, 1);
3082
        }
3083
      }
3084
  }
3085
 
3086
  /**
3087
   * Removes the specified listener from the component. This is harmless if
3088
   * the listener was not previously registered.
3089
   *
3090
   * @param listener the listener to remove
3091
   * @see HierarchyEvent
3092
   * @see #addHierarchyBoundsListener(HierarchyBoundsListener)
3093
   * @see #getHierarchyBoundsListeners()
3094
   * @since 1.3
3095
   */
3096
  public synchronized void
3097
    removeHierarchyBoundsListener(HierarchyBoundsListener listener)
3098
  {
3099
    hierarchyBoundsListener =
3100
      AWTEventMulticaster.remove(hierarchyBoundsListener, listener);
3101
 
3102
    // Need to lock the tree, otherwise we might end up inconsistent.
3103
    synchronized (getTreeLock())
3104
      {
3105
        numHierarchyBoundsListeners--;
3106
        if (parent != null)
3107
          parent.updateHierarchyListenerCount
3108
                                         (AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK,
3109
                                          -1);
3110
      }
3111
  }
3112
 
3113
  /**
3114
   * Returns an array of all specified listeners registered on this component.
3115
   *
3116
   * @return an array of listeners
3117
   * @see #addHierarchyBoundsListener(HierarchyBoundsListener)
3118
   * @see #removeHierarchyBoundsListener(HierarchyBoundsListener)
3119
   * @since 1.4
3120
   */
3121
  public synchronized HierarchyBoundsListener[] getHierarchyBoundsListeners()
3122
  {
3123
    return (HierarchyBoundsListener[])
3124
      AWTEventMulticaster.getListeners(hierarchyBoundsListener,
3125
                                       HierarchyBoundsListener.class);
3126
  }
3127
 
3128
  /**
3129
   * Fires a HierarchyEvent or HierarchyChangeEvent on this component.
3130
   *
3131
   * @param id the event id
3132
   * @param changed the changed component
3133
   * @param parent the parent
3134
   * @param flags the event flags
3135
   */
3136
  void fireHierarchyEvent(int id, Component changed, Container parent,
3137
                          long flags)
3138
  {
3139
    boolean enabled = false;
3140
    switch (id)
3141
    {
3142
      case HierarchyEvent.HIERARCHY_CHANGED:
3143
        enabled = hierarchyListener != null
3144
                  || (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0;
3145
        break;
3146
      case HierarchyEvent.ANCESTOR_MOVED:
3147
      case HierarchyEvent.ANCESTOR_RESIZED:
3148
        enabled = hierarchyBoundsListener != null
3149
                  || (eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0;
3150
        break;
3151
      default:
3152
        assert false : "Should not reach here";
3153
    }
3154
    if (enabled)
3155
      {
3156
        HierarchyEvent ev = new HierarchyEvent(this, id, changed, parent,
3157
                                               flags);
3158
        dispatchEvent(ev);
3159
      }
3160
  }
3161
 
3162
  /**
3163
   * Adds the specified listener to this component. This is harmless if the
3164
   * listener is null, but if the listener has already been registered, it
3165
   * will now be registered twice.
3166
   *
3167
   * @param listener the new listener to add
3168
   * @see KeyEvent
3169
   * @see #removeKeyListener(KeyListener)
3170
   * @see #getKeyListeners()
3171
   * @since 1.1
3172
   */
3173
  public synchronized void addKeyListener(KeyListener listener)
3174
  {
3175
    if (listener != null)
3176
      {
3177
        keyListener = AWTEventMulticaster.add(keyListener, listener);
3178
        newEventsOnly = true;
3179
      }
3180
  }
3181
 
3182
  /**
3183
   * Removes the specified listener from the component. This is harmless if
3184
   * the listener was not previously registered.
3185
   *
3186
   * @param listener the listener to remove
3187
   * @see KeyEvent
3188
   * @see #addKeyListener(KeyListener)
3189
   * @see #getKeyListeners()
3190
   * @since 1.1
3191
   */
3192
  public synchronized void removeKeyListener(KeyListener listener)
3193
  {
3194
    keyListener = AWTEventMulticaster.remove(keyListener, listener);
3195
  }
3196
 
3197
  /**
3198
   * Returns an array of all specified listeners registered on this component.
3199
   *
3200
   * @return an array of listeners
3201
   * @see #addKeyListener(KeyListener)
3202
   * @see #removeKeyListener(KeyListener)
3203
   * @since 1.4
3204
   */
3205
  public synchronized KeyListener[] getKeyListeners()
3206
  {
3207
    return (KeyListener[])
3208
      AWTEventMulticaster.getListeners(keyListener, KeyListener.class);
3209
  }
3210
 
3211
  /**
3212
   * Adds the specified listener to this component. This is harmless if the
3213
   * listener is null, but if the listener has already been registered, it
3214
   * will now be registered twice.
3215
   *
3216
   * @param listener the new listener to add
3217
   * @see MouseEvent
3218
   * @see #removeMouseListener(MouseListener)
3219
   * @see #getMouseListeners()
3220
   * @since 1.1
3221
   */
3222
  public synchronized void addMouseListener(MouseListener listener)
3223
  {
3224
    if (listener != null)
3225
      {
3226
        mouseListener = AWTEventMulticaster.add(mouseListener, listener);
3227
        newEventsOnly = true;
3228
      }
3229
  }
3230
 
3231
  /**
3232
   * Removes the specified listener from the component. This is harmless if
3233
   * the listener was not previously registered.
3234
   *
3235
   * @param listener the listener to remove
3236
   * @see MouseEvent
3237
   * @see #addMouseListener(MouseListener)
3238
   * @see #getMouseListeners()
3239
   * @since 1.1
3240
   */
3241
  public synchronized void removeMouseListener(MouseListener listener)
3242
  {
3243
    mouseListener = AWTEventMulticaster.remove(mouseListener, listener);
3244
  }
3245
 
3246
  /**
3247
   * Returns an array of all specified listeners registered on this component.
3248
   *
3249
   * @return an array of listeners
3250
   * @see #addMouseListener(MouseListener)
3251
   * @see #removeMouseListener(MouseListener)
3252
   * @since 1.4
3253
   */
3254
  public synchronized MouseListener[] getMouseListeners()
3255
  {
3256
    return (MouseListener[])
3257
      AWTEventMulticaster.getListeners(mouseListener, MouseListener.class);
3258
  }
3259
 
3260
  /**
3261
   * Adds the specified listener to this component. This is harmless if the
3262
   * listener is null, but if the listener has already been registered, it
3263
   * will now be registered twice.
3264
   *
3265
   * @param listener the new listener to add
3266
   * @see MouseEvent
3267
   * @see #removeMouseMotionListener(MouseMotionListener)
3268
   * @see #getMouseMotionListeners()
3269
   * @since 1.1
3270
   */
3271
  public synchronized void addMouseMotionListener(MouseMotionListener listener)
3272
  {
3273
    if (listener != null)
3274
      {
3275
        mouseMotionListener = AWTEventMulticaster.add(mouseMotionListener,
3276
                                                      listener);
3277
        newEventsOnly = true;
3278
      }
3279
  }
3280
 
3281
  /**
3282
   * Removes the specified listener from the component. This is harmless if
3283
   * the listener was not previously registered.
3284
   *
3285
   * @param listener the listener to remove
3286
   * @see MouseEvent
3287
   * @see #addMouseMotionListener(MouseMotionListener)
3288
   * @see #getMouseMotionListeners()
3289
   * @since 1.1
3290
   */
3291
  public synchronized void removeMouseMotionListener(MouseMotionListener listener)
3292
  {
3293
    mouseMotionListener = AWTEventMulticaster.remove(mouseMotionListener, listener);
3294
  }
3295
 
3296
  /**
3297
   * Returns an array of all specified listeners registered on this component.
3298
   *
3299
   * @return an array of listeners
3300
   * @see #addMouseMotionListener(MouseMotionListener)
3301
   * @see #removeMouseMotionListener(MouseMotionListener)
3302
   * @since 1.4
3303
   */
3304
  public synchronized MouseMotionListener[] getMouseMotionListeners()
3305
  {
3306
    return (MouseMotionListener[])
3307
      AWTEventMulticaster.getListeners(mouseMotionListener,
3308
                                       MouseMotionListener.class);
3309
  }
3310
 
3311
  /**
3312
   * Adds the specified listener to this component. This is harmless if the
3313
   * listener is null, but if the listener has already been registered, it
3314
   * will now be registered twice.
3315
   *
3316
   * @param listener the new listener to add
3317
   * @see MouseEvent
3318
   * @see MouseWheelEvent
3319
   * @see #removeMouseWheelListener(MouseWheelListener)
3320
   * @see #getMouseWheelListeners()
3321
   * @since 1.4
3322
   */
3323
  public synchronized void addMouseWheelListener(MouseWheelListener listener)
3324
  {
3325
    if (listener != null)
3326
      {
3327
        mouseWheelListener = AWTEventMulticaster.add(mouseWheelListener,
3328
                                                     listener);
3329
        newEventsOnly = true;
3330
      }
3331
  }
3332
 
3333
  /**
3334
   * Removes the specified listener from the component. This is harmless if
3335
   * the listener was not previously registered.
3336
   *
3337
   * @param listener the listener to remove
3338
   * @see MouseEvent
3339
   * @see MouseWheelEvent
3340
   * @see #addMouseWheelListener(MouseWheelListener)
3341
   * @see #getMouseWheelListeners()
3342
   * @since 1.4
3343
   */
3344
  public synchronized void removeMouseWheelListener(MouseWheelListener listener)
3345
  {
3346
    mouseWheelListener = AWTEventMulticaster.remove(mouseWheelListener, listener);
3347
  }
3348
 
3349
  /**
3350
   * Returns an array of all specified listeners registered on this component.
3351
   *
3352
   * @return an array of listeners
3353
   * @see #addMouseWheelListener(MouseWheelListener)
3354
   * @see #removeMouseWheelListener(MouseWheelListener)
3355
   * @since 1.4
3356
   */
3357
  public synchronized MouseWheelListener[] getMouseWheelListeners()
3358
  {
3359
    return (MouseWheelListener[])
3360
      AWTEventMulticaster.getListeners(mouseWheelListener,
3361
                                       MouseWheelListener.class);
3362
  }
3363
 
3364
  /**
3365
   * Adds the specified listener to this component. This is harmless if the
3366
   * listener is null, but if the listener has already been registered, it
3367
   * will now be registered twice.
3368
   *
3369
   * @param listener the new listener to add
3370
   * @see InputMethodEvent
3371
   * @see #removeInputMethodListener(InputMethodListener)
3372
   * @see #getInputMethodListeners()
3373
   * @see #getInputMethodRequests()
3374
   * @since 1.2
3375
   */
3376
  public synchronized void addInputMethodListener(InputMethodListener listener)
3377
  {
3378
    if (listener != null)
3379
      {
3380
        inputMethodListener = AWTEventMulticaster.add(inputMethodListener,
3381
                                                      listener);
3382
        newEventsOnly = true;
3383
      }
3384
  }
3385
 
3386
  /**
3387
   * Removes the specified listener from the component. This is harmless if
3388
   * the listener was not previously registered.
3389
   *
3390
   * @param listener the listener to remove
3391
   * @see InputMethodEvent
3392
   * @see #addInputMethodListener(InputMethodListener)
3393
   * @see #getInputMethodRequests()
3394
   * @since 1.2
3395
   */
3396
  public synchronized void removeInputMethodListener(InputMethodListener listener)
3397
  {
3398
    inputMethodListener = AWTEventMulticaster.remove(inputMethodListener, listener);
3399
  }
3400
 
3401
  /**
3402
   * Returns an array of all specified listeners registered on this component.
3403
   *
3404
   * @return an array of listeners
3405
   * @see #addInputMethodListener(InputMethodListener)
3406
   * @see #removeInputMethodListener(InputMethodListener)
3407
   * @since 1.4
3408
   */
3409
  public synchronized InputMethodListener[] getInputMethodListeners()
3410
  {
3411
    return (InputMethodListener[])
3412
      AWTEventMulticaster.getListeners(inputMethodListener,
3413
                                       InputMethodListener.class);
3414
  }
3415
 
3416
  /**
3417
   * Returns all registered {@link EventListener}s of the given
3418
   * <code>listenerType</code>.
3419
   *
3420
   * @param listenerType the class of listeners to filter (<code>null</code>
3421
   *                     not permitted).
3422
   *
3423
   * @return An array of registered listeners.
3424
   *
3425
   * @throws ClassCastException if <code>listenerType</code> does not implement
3426
   *                            the {@link EventListener} interface.
3427
   * @throws NullPointerException if <code>listenerType</code> is
3428
   *                              <code>null</code>.
3429
   *
3430
   * @see #getComponentListeners()
3431
   * @see #getFocusListeners()
3432
   * @see #getHierarchyListeners()
3433
   * @see #getHierarchyBoundsListeners()
3434
   * @see #getKeyListeners()
3435
   * @see #getMouseListeners()
3436
   * @see #getMouseMotionListeners()
3437
   * @see #getMouseWheelListeners()
3438
   * @see #getInputMethodListeners()
3439
   * @see #getPropertyChangeListeners()
3440
   * @since 1.3
3441
   */
3442
  public <T extends EventListener> T[] getListeners(Class<T> listenerType)
3443
  {
3444
    if (listenerType == ComponentListener.class)
3445
      return (T[]) getComponentListeners();
3446
    if (listenerType == FocusListener.class)
3447
      return (T[]) getFocusListeners();
3448
    if (listenerType == HierarchyListener.class)
3449
      return (T[]) getHierarchyListeners();
3450
    if (listenerType == HierarchyBoundsListener.class)
3451
      return (T[]) getHierarchyBoundsListeners();
3452
    if (listenerType == KeyListener.class)
3453
      return (T[]) getKeyListeners();
3454
    if (listenerType == MouseListener.class)
3455
      return (T[]) getMouseListeners();
3456
    if (listenerType == MouseMotionListener.class)
3457
      return (T[]) getMouseMotionListeners();
3458
    if (listenerType == MouseWheelListener.class)
3459
      return (T[]) getMouseWheelListeners();
3460
    if (listenerType == InputMethodListener.class)
3461
      return (T[]) getInputMethodListeners();
3462
    if (listenerType == PropertyChangeListener.class)
3463
      return (T[]) getPropertyChangeListeners();
3464
    return (T[]) Array.newInstance(listenerType, 0);
3465
  }
3466
 
3467
  /**
3468
   * Returns the input method request handler, for subclasses which support
3469
   * on-the-spot text input. By default, input methods are handled by AWT,
3470
   * and this returns null.
3471
   *
3472
   * @return the input method handler, null by default
3473
   * @since 1.2
3474
   */
3475
  public InputMethodRequests getInputMethodRequests()
3476
  {
3477
    return null;
3478
  }
3479
 
3480
  /**
3481
   * Gets the input context of this component, which is inherited from the
3482
   * parent unless this is overridden.
3483
   *
3484
   * @return the text input context
3485
   * @since 1.2
3486
   */
3487
  public InputContext getInputContext()
3488
  {
3489
    return parent == null ? null : parent.getInputContext();
3490
  }
3491
 
3492
  /**
3493
   * Enables the specified events. The events to enable are specified
3494
   * by OR-ing together the desired masks from <code>AWTEvent</code>.
3495
   *
3496
   * <p>Events are enabled by default when a listener is attached to the
3497
   * component for that event type. This method can be used by subclasses
3498
   * to ensure the delivery of a specified event regardless of whether
3499
   * or not a listener is attached.
3500
   *
3501
   * @param eventsToEnable the desired events to enable
3502
   * @see #processEvent(AWTEvent)
3503
   * @see #disableEvents(long)
3504
   * @see AWTEvent
3505
   * @since 1.1
3506
   */
3507
  protected final void enableEvents(long eventsToEnable)
3508
  {
3509
    // Update the counter for hierarchy (bounds) listeners.
3510
    if ((eventsToEnable & AWTEvent.HIERARCHY_EVENT_MASK) != 0
3511
        && (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) == 0)
3512
      {
3513
        // Need to lock the tree, otherwise we might end up inconsistent.
3514
        synchronized (getTreeLock())
3515
          {
3516
            numHierarchyListeners++;
3517
            if (parent != null)
3518
              parent.updateHierarchyListenerCount
3519
                                                (AWTEvent.HIERARCHY_EVENT_MASK,
3520
                                                 1);
3521
          }
3522
      }
3523
    if ((eventsToEnable & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0
3524
        && (eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) == 0)
3525
      {
3526
        // Need to lock the tree, otherwise we might end up inconsistent.
3527
        synchronized (getTreeLock())
3528
          {
3529
            numHierarchyBoundsListeners++;
3530
            if (parent != null)
3531
              parent.updateHierarchyListenerCount
3532
                                         (AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK,
3533
                                          1);
3534
          }
3535
      }
3536
 
3537
    eventMask |= eventsToEnable;
3538
    newEventsOnly = true;
3539
 
3540
    // Only heavyweight peers handle this.
3541
    ComponentPeer p = peer;
3542
    Component comp = this;
3543
    while (p instanceof LightweightPeer)
3544
      {
3545
        comp = comp.parent;
3546
        p = comp == null ? null : comp.peer;
3547
      }
3548
 
3549
    if (p != null)
3550
      p.setEventMask(eventMask);
3551
 
3552
  }
3553
 
3554
  /**
3555
   * Disables the specified events. The events to disable are specified
3556
   * by OR-ing together the desired masks from <code>AWTEvent</code>.
3557
   *
3558
   * @param eventsToDisable the desired events to disable
3559
   * @see #enableEvents(long)
3560
   * @since 1.1
3561
   */
3562
  protected final void disableEvents(long eventsToDisable)
3563
  {
3564
    // Update the counter for hierarchy (bounds) listeners.
3565
    if ((eventsToDisable & AWTEvent.HIERARCHY_EVENT_MASK) != 0
3566
        && (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0)
3567
      {
3568
        // Need to lock the tree, otherwise we might end up inconsistent.
3569
        synchronized (getTreeLock())
3570
          {
3571
            numHierarchyListeners--;
3572
            if (parent != null)
3573
              parent.updateHierarchyListenerCount
3574
                                                (AWTEvent.HIERARCHY_EVENT_MASK,
3575
                                                 -1);
3576
          }
3577
      }
3578
    if ((eventsToDisable & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0
3579
        && (eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0)
3580
      {
3581
        // Need to lock the tree, otherwise we might end up inconsistent.
3582
        synchronized (getTreeLock())
3583
          {
3584
            numHierarchyBoundsListeners--;
3585
            if (parent != null)
3586
              parent.updateHierarchyListenerCount
3587
                                         (AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK,
3588
                                          -1);
3589
          }
3590
      }
3591
 
3592
    eventMask &= ~eventsToDisable;
3593
 
3594
    // Only heavyweight peers handle this.
3595
    ComponentPeer p = peer;
3596
    Component comp = this;
3597
    while (p instanceof LightweightPeer)
3598
      {
3599
        comp = comp.parent;
3600
        p = comp == null ? null : comp.peer;
3601
      }
3602
 
3603
    if (p != null)
3604
      p.setEventMask(eventMask);
3605
 
3606
  }
3607
 
3608
  /**
3609
   * This is called by the EventQueue if two events with the same event id
3610
   * and owner component are queued. Returns a new combined event, or null if
3611
   * no combining is done. The coelesced events are currently mouse moves
3612
   * (intermediate ones are discarded) and paint events (a merged paint is
3613
   * created in place of the two events).
3614
   *
3615
   * @param existingEvent the event on the queue
3616
   * @param newEvent the new event that might be entered on the queue
3617
   * @return null if both events are kept, or the replacement coelesced event
3618
   */
3619
  protected AWTEvent coalesceEvents(AWTEvent existingEvent, AWTEvent newEvent)
3620
  {
3621
    AWTEvent coalesced = null;
3622
    switch (existingEvent.id)
3623
      {
3624
      case MouseEvent.MOUSE_MOVED:
3625
      case MouseEvent.MOUSE_DRAGGED:
3626
        // Just drop the old (intermediate) event and return the new one.
3627
        MouseEvent me1 = (MouseEvent) existingEvent;
3628
        MouseEvent me2 = (MouseEvent) newEvent;
3629
        if (me1.getModifiers() == me2.getModifiers())
3630
          coalesced = newEvent;
3631
        break;
3632
      case PaintEvent.PAINT:
3633
      case PaintEvent.UPDATE:
3634
        // For heavyweights the EventQueue should ask the peer.
3635
        if (peer == null || peer instanceof LightweightPeer)
3636
          {
3637
            PaintEvent pe1 = (PaintEvent) existingEvent;
3638
            PaintEvent pe2 = (PaintEvent) newEvent;
3639
            Rectangle r1 = pe1.getUpdateRect();
3640
            Rectangle r2 = pe2.getUpdateRect();
3641
            if (r1.contains(r2))
3642
              coalesced = existingEvent;
3643
            else if (r2.contains(r1))
3644
              coalesced = newEvent;
3645
          }
3646
        else
3647
          {
3648
            // Replace the event and let the heavyweight figure out the expanding
3649
            // of the repaint area.
3650
            coalesced = newEvent;
3651
          }
3652
        break;
3653
      default:
3654
        coalesced = null;
3655
      }
3656
    return coalesced;
3657
  }
3658
 
3659
  /**
3660
   * Processes the specified event. In this class, this method simply
3661
   * calls one of the more specific event handlers.
3662
   *
3663
   * @param e the event to process
3664
   * @throws NullPointerException if e is null
3665
   * @see #processComponentEvent(ComponentEvent)
3666
   * @see #processFocusEvent(FocusEvent)
3667
   * @see #processKeyEvent(KeyEvent)
3668
   * @see #processMouseEvent(MouseEvent)
3669
   * @see #processMouseMotionEvent(MouseEvent)
3670
   * @see #processInputMethodEvent(InputMethodEvent)
3671
   * @see #processHierarchyEvent(HierarchyEvent)
3672
   * @see #processMouseWheelEvent(MouseWheelEvent)
3673
   * @since 1.1
3674
   */
3675
  protected void processEvent(AWTEvent e)
3676
  {
3677
    /* Note: the order of these if statements are
3678
       important. Subclasses must be checked first. Eg. MouseEvent
3679
       must be checked before ComponentEvent, since a MouseEvent
3680
       object is also an instance of a ComponentEvent. */
3681
 
3682
    if (e instanceof FocusEvent)
3683
      processFocusEvent((FocusEvent) e);
3684
    else if (e instanceof MouseWheelEvent)
3685
      processMouseWheelEvent((MouseWheelEvent) e);
3686
    else if (e instanceof MouseEvent)
3687
      {
3688
        if (e.id == MouseEvent.MOUSE_MOVED
3689
            || e.id == MouseEvent.MOUSE_DRAGGED)
3690
          processMouseMotionEvent((MouseEvent) e);
3691
        else
3692
          processMouseEvent((MouseEvent) e);
3693
      }
3694
    else if (e instanceof KeyEvent)
3695
      processKeyEvent((KeyEvent) e);
3696
    else if (e instanceof InputMethodEvent)
3697
      processInputMethodEvent((InputMethodEvent) e);
3698
    else if (e instanceof ComponentEvent)
3699
      processComponentEvent((ComponentEvent) e);
3700
    else if (e instanceof HierarchyEvent)
3701
      {
3702
        if (e.id == HierarchyEvent.HIERARCHY_CHANGED)
3703
          processHierarchyEvent((HierarchyEvent) e);
3704
        else
3705
          processHierarchyBoundsEvent((HierarchyEvent) e);
3706
      }
3707
  }
3708
 
3709
  /**
3710
   * Called when a component event is dispatched and component events are
3711
   * enabled. This method passes the event along to any listeners
3712
   * that are attached.
3713
   *
3714
   * @param e the <code>ComponentEvent</code> to process
3715
   * @throws NullPointerException if e is null
3716
   * @see ComponentListener
3717
   * @see #addComponentListener(ComponentListener)
3718
   * @see #enableEvents(long)
3719
   * @since 1.1
3720
   */
3721
  protected void processComponentEvent(ComponentEvent e)
3722
  {
3723
    if (componentListener == null)
3724
      return;
3725
    switch (e.id)
3726
      {
3727
      case ComponentEvent.COMPONENT_HIDDEN:
3728
        componentListener.componentHidden(e);
3729
        break;
3730
      case ComponentEvent.COMPONENT_MOVED:
3731
        componentListener.componentMoved(e);
3732
        break;
3733
      case ComponentEvent.COMPONENT_RESIZED:
3734
        componentListener.componentResized(e);
3735
        break;
3736
      case ComponentEvent.COMPONENT_SHOWN:
3737
        componentListener.componentShown(e);
3738
        break;
3739
      }
3740
  }
3741
 
3742
  /**
3743
   * Called when a focus event is dispatched and component events are
3744
   * enabled. This method passes the event along to any listeners
3745
   * that are attached.
3746
   *
3747
   * @param e the <code>FocusEvent</code> to process
3748
   * @throws NullPointerException if e is null
3749
   * @see FocusListener
3750
   * @see #addFocusListener(FocusListener)
3751
   * @see #enableEvents(long)
3752
   * @since 1.1
3753
   */
3754
  protected void processFocusEvent(FocusEvent e)
3755
  {
3756
    if (focusListener == null)
3757
      return;
3758
 
3759
    switch (e.id)
3760
      {
3761
        case FocusEvent.FOCUS_GAINED:
3762
          focusListener.focusGained(e);
3763
        break;
3764
        case FocusEvent.FOCUS_LOST:
3765
          focusListener.focusLost(e);
3766
        break;
3767
      }
3768
  }
3769
 
3770
  /**
3771
   * Called when a key event is dispatched and component events are
3772
   * enabled. This method passes the event along to any listeners
3773
   * that are attached.
3774
   *
3775
   * @param e the <code>KeyEvent</code> to process
3776
   * @throws NullPointerException if e is null
3777
   * @see KeyListener
3778
   * @see #addKeyListener(KeyListener)
3779
   * @see #enableEvents(long)
3780
   * @since 1.1
3781
   */
3782
  protected void processKeyEvent(KeyEvent e)
3783
  {
3784
    if (keyListener == null)
3785
      return;
3786
    switch (e.id)
3787
      {
3788
        case KeyEvent.KEY_PRESSED:
3789
          keyListener.keyPressed(e);
3790
        break;
3791
        case KeyEvent.KEY_RELEASED:
3792
          keyListener.keyReleased(e);
3793
        break;
3794
        case KeyEvent.KEY_TYPED:
3795
          keyListener.keyTyped(e);
3796
        break;
3797
      }
3798
  }
3799
 
3800
  /**
3801
   * Called when a regular mouse event is dispatched and component events are
3802
   * enabled. This method passes the event along to any listeners
3803
   * that are attached.
3804
   *
3805
   * @param e the <code>MouseEvent</code> to process
3806
   * @throws NullPointerException if e is null
3807
   * @see MouseListener
3808
   * @see #addMouseListener(MouseListener)
3809
   * @see #enableEvents(long)
3810
   * @since 1.1
3811
   */
3812
  protected void processMouseEvent(MouseEvent e)
3813
  {
3814
    if (mouseListener == null)
3815
      return;
3816
    switch (e.id)
3817
      {
3818
        case MouseEvent.MOUSE_CLICKED:
3819
          mouseListener.mouseClicked(e);
3820
        break;
3821
        case MouseEvent.MOUSE_ENTERED:
3822
          if( isLightweight() )
3823
            setCursor( getCursor() );
3824
          mouseListener.mouseEntered(e);
3825
        break;
3826
        case MouseEvent.MOUSE_EXITED:
3827
          mouseListener.mouseExited(e);
3828
        break;
3829
        case MouseEvent.MOUSE_PRESSED:
3830
          mouseListener.mousePressed(e);
3831
        break;
3832
        case MouseEvent.MOUSE_RELEASED:
3833
          mouseListener.mouseReleased(e);
3834
        break;
3835
      }
3836
  }
3837
 
3838
  /**
3839
   * Called when a mouse motion event is dispatched and component events are
3840
   * enabled. This method passes the event along to any listeners
3841
   * that are attached.
3842
   *
3843
   * @param e the <code>MouseMotionEvent</code> to process
3844
   * @throws NullPointerException if e is null
3845
   * @see MouseMotionListener
3846
   * @see #addMouseMotionListener(MouseMotionListener)
3847
   * @see #enableEvents(long)
3848
   * @since 1.1
3849
   */
3850
  protected void processMouseMotionEvent(MouseEvent e)
3851
  {
3852
    if (mouseMotionListener == null)
3853
      return;
3854
    switch (e.id)
3855
      {
3856
        case MouseEvent.MOUSE_DRAGGED:
3857
          mouseMotionListener.mouseDragged(e);
3858
        break;
3859
        case MouseEvent.MOUSE_MOVED:
3860
          mouseMotionListener.mouseMoved(e);
3861
        break;
3862
      }
3863
      e.consume();
3864
  }
3865
 
3866
  /**
3867
   * Called when a mouse wheel event is dispatched and component events are
3868
   * enabled. This method passes the event along to any listeners that are
3869
   * attached.
3870
   *
3871
   * @param e the <code>MouseWheelEvent</code> to process
3872
   * @throws NullPointerException if e is null
3873
   * @see MouseWheelListener
3874
   * @see #addMouseWheelListener(MouseWheelListener)
3875
   * @see #enableEvents(long)
3876
   * @since 1.4
3877
   */
3878
  protected void processMouseWheelEvent(MouseWheelEvent e)
3879
  {
3880
    if (mouseWheelListener != null
3881
        && e.id == MouseEvent.MOUSE_WHEEL)
3882
    {
3883
      mouseWheelListener.mouseWheelMoved(e);
3884
      e.consume();
3885
    }
3886
  }
3887
 
3888
  /**
3889
   * Called when an input method event is dispatched and component events are
3890
   * enabled. This method passes the event along to any listeners that are
3891
   * attached.
3892
   *
3893
   * @param e the <code>InputMethodEvent</code> to process
3894
   * @throws NullPointerException if e is null
3895
   * @see InputMethodListener
3896
   * @see #addInputMethodListener(InputMethodListener)
3897
   * @see #enableEvents(long)
3898
   * @since 1.2
3899
   */
3900
  protected void processInputMethodEvent(InputMethodEvent e)
3901
  {
3902
    if (inputMethodListener == null)
3903
      return;
3904
    switch (e.id)
3905
      {
3906
        case InputMethodEvent.CARET_POSITION_CHANGED:
3907
          inputMethodListener.caretPositionChanged(e);
3908
        break;
3909
        case InputMethodEvent.INPUT_METHOD_TEXT_CHANGED:
3910
          inputMethodListener.inputMethodTextChanged(e);
3911
        break;
3912
      }
3913
  }
3914
 
3915
  /**
3916
   * Called when a hierarchy change event is dispatched and component events
3917
   * are enabled. This method passes the event along to any listeners that are
3918
   * attached.
3919
   *
3920
   * @param e the <code>HierarchyEvent</code> to process
3921
   * @throws NullPointerException if e is null
3922
   * @see HierarchyListener
3923
   * @see #addHierarchyListener(HierarchyListener)
3924
   * @see #enableEvents(long)
3925
   * @since 1.3
3926
   */
3927
  protected void processHierarchyEvent(HierarchyEvent e)
3928
  {
3929
    if (hierarchyListener == null)
3930
      return;
3931
    if (e.id == HierarchyEvent.HIERARCHY_CHANGED)
3932
      hierarchyListener.hierarchyChanged(e);
3933
  }
3934
 
3935
  /**
3936
   * Called when a hierarchy bounds event is dispatched and component events
3937
   * are enabled. This method passes the event along to any listeners that are
3938
   * attached.
3939
   *
3940
   * @param e the <code>HierarchyEvent</code> to process
3941
   * @throws NullPointerException if e is null
3942
   * @see HierarchyBoundsListener
3943
   * @see #addHierarchyBoundsListener(HierarchyBoundsListener)
3944
   * @see #enableEvents(long)
3945
   * @since 1.3
3946
   */
3947
  protected void processHierarchyBoundsEvent(HierarchyEvent e)
3948
  {
3949
    if (hierarchyBoundsListener == null)
3950
      return;
3951
    switch (e.id)
3952
      {
3953
        case HierarchyEvent.ANCESTOR_MOVED:
3954
          hierarchyBoundsListener.ancestorMoved(e);
3955
        break;
3956
        case HierarchyEvent.ANCESTOR_RESIZED:
3957
          hierarchyBoundsListener.ancestorResized(e);
3958
        break;
3959
      }
3960
  }
3961
 
3962
  /**
3963
   * AWT 1.0 event handler.
3964
   *
3965
   * This method calls one of the event-specific handler methods.  For
3966
   * example for key events, either {@link #keyDown(Event,int)}
3967
   * or {@link #keyUp(Event,int)} is called.  A derived
3968
   * component can override one of these event-specific methods if it
3969
   * only needs to handle certain event types.  Otherwise it can
3970
   * override handleEvent itself and handle any event.
3971
   *
3972
   * @param evt the event to handle
3973
   * @return true if the event was handled, false otherwise
3974
   * @deprecated use {@link #processEvent(AWTEvent)} instead
3975
   */
3976
  public boolean handleEvent (Event evt)
3977
  {
3978
    switch (evt.id)
3979
      {
3980
        // Handle key events.
3981
      case Event.KEY_ACTION:
3982
      case Event.KEY_PRESS:
3983
        return keyDown (evt, evt.key);
3984
      case Event.KEY_ACTION_RELEASE:
3985
      case Event.KEY_RELEASE:
3986
        return keyUp (evt, evt.key);
3987
 
3988
        // Handle mouse events.
3989
      case Event.MOUSE_DOWN:
3990
        return mouseDown (evt, evt.x, evt.y);
3991
      case Event.MOUSE_UP:
3992
        return mouseUp (evt, evt.x, evt.y);
3993
      case Event.MOUSE_MOVE:
3994
        return mouseMove (evt, evt.x, evt.y);
3995
      case Event.MOUSE_DRAG:
3996
        return mouseDrag (evt, evt.x, evt.y);
3997
      case Event.MOUSE_ENTER:
3998
        return mouseEnter (evt, evt.x, evt.y);
3999
      case Event.MOUSE_EXIT:
4000
        return mouseExit (evt, evt.x, evt.y);
4001
 
4002
        // Handle focus events.
4003
      case Event.GOT_FOCUS:
4004
        return gotFocus (evt, evt.arg);
4005
      case Event.LOST_FOCUS:
4006
        return lostFocus (evt, evt.arg);
4007
 
4008
        // Handle action event.
4009
      case Event.ACTION_EVENT:
4010
        return action (evt, evt.arg);
4011
      }
4012
    // Unknown event.
4013
    return false;
4014
  }
4015
 
4016
  /**
4017
   * AWT 1.0 MOUSE_DOWN event handler.  This method is meant to be
4018
   * overridden by components providing their own MOUSE_DOWN handler.
4019
   * The default implementation simply returns false.
4020
   *
4021
   * @param evt the event to handle
4022
   * @param x the x coordinate, ignored
4023
   * @param y the y coordinate, ignored
4024
   * @return false
4025
   * @deprecated use {@link #processMouseEvent(MouseEvent)} instead
4026
   */
4027
  public boolean mouseDown(Event evt, int x, int y)
4028
  {
4029
    return false;
4030
  }
4031
 
4032
  /**
4033
   * AWT 1.0 MOUSE_DRAG event handler.  This method is meant to be
4034
   * overridden by components providing their own MOUSE_DRAG handler.
4035
   * The default implementation simply returns false.
4036
   *
4037
   * @param evt the event to handle
4038
   * @param x the x coordinate, ignored
4039
   * @param y the y coordinate, ignored
4040
   * @return false
4041
   * @deprecated use {@link #processMouseMotionEvent(MouseEvent)} instead
4042
   */
4043
  public boolean mouseDrag(Event evt, int x, int y)
4044
  {
4045
    return false;
4046
  }
4047
 
4048
  /**
4049
   * AWT 1.0 MOUSE_UP event handler.  This method is meant to be
4050
   * overridden by components providing their own MOUSE_UP handler.
4051
   * The default implementation simply returns false.
4052
   *
4053
   * @param evt the event to handle
4054
   * @param x the x coordinate, ignored
4055
   * @param y the y coordinate, ignored
4056
   * @return false
4057
   * @deprecated use {@link #processMouseEvent(MouseEvent)} instead
4058
   */
4059
  public boolean mouseUp(Event evt, int x, int y)
4060
  {
4061
    return false;
4062
  }
4063
 
4064
  /**
4065
   * AWT 1.0 MOUSE_MOVE event handler.  This method is meant to be
4066
   * overridden by components providing their own MOUSE_MOVE handler.
4067
   * The default implementation simply returns false.
4068
   *
4069
   * @param evt the event to handle
4070
   * @param x the x coordinate, ignored
4071
   * @param y the y coordinate, ignored
4072
   * @return false
4073
   * @deprecated use {@link #processMouseMotionEvent(MouseEvent)} instead
4074
   */
4075
  public boolean mouseMove(Event evt, int x, int y)
4076
  {
4077
    return false;
4078
  }
4079
 
4080
  /**
4081
   * AWT 1.0 MOUSE_ENTER event handler.  This method is meant to be
4082
   * overridden by components providing their own MOUSE_ENTER handler.
4083
   * The default implementation simply returns false.
4084
   *
4085
   * @param evt the event to handle
4086
   * @param x the x coordinate, ignored
4087
   * @param y the y coordinate, ignored
4088
   * @return false
4089
   * @deprecated use {@link #processMouseEvent(MouseEvent)} instead
4090
   */
4091
  public boolean mouseEnter(Event evt, int x, int y)
4092
  {
4093
    return false;
4094
  }
4095
 
4096
  /**
4097
   * AWT 1.0 MOUSE_EXIT event handler.  This method is meant to be
4098
   * overridden by components providing their own MOUSE_EXIT handler.
4099
   * The default implementation simply returns false.
4100
   *
4101
   * @param evt the event to handle
4102
   * @param x the x coordinate, ignored
4103
   * @param y the y coordinate, ignored
4104
   * @return false
4105
   * @deprecated use {@link #processMouseEvent(MouseEvent)} instead
4106
   */
4107
  public boolean mouseExit(Event evt, int x, int y)
4108
  {
4109
    return false;
4110
  }
4111
 
4112
  /**
4113
   * AWT 1.0 KEY_PRESS and KEY_ACTION event handler.  This method is
4114
   * meant to be overridden by components providing their own key
4115
   * press handler.  The default implementation simply returns false.
4116
   *
4117
   * @param evt the event to handle
4118
   * @param key the key pressed, ignored
4119
   * @return false
4120
   * @deprecated use {@link #processKeyEvent(KeyEvent)} instead
4121
   */
4122
  public boolean keyDown(Event evt, int key)
4123
  {
4124
    return false;
4125
  }
4126
 
4127
  /**
4128
   * AWT 1.0 KEY_RELEASE and KEY_ACTION_RELEASE event handler.  This
4129
   * method is meant to be overridden by components providing their
4130
   * own key release handler.  The default implementation simply
4131
   * returns false.
4132
   *
4133
   * @param evt the event to handle
4134
   * @param key the key pressed, ignored
4135
   * @return false
4136
   * @deprecated use {@link #processKeyEvent(KeyEvent)} instead
4137
   */
4138
  public boolean keyUp(Event evt, int key)
4139
  {
4140
    return false;
4141
  }
4142
 
4143
  /**
4144
   * AWT 1.0 ACTION_EVENT event handler.  This method is meant to be
4145
   * overridden by components providing their own action event
4146
   * handler.  The default implementation simply returns false.
4147
   *
4148
   * @param evt the event to handle
4149
   * @param what the object acted on, ignored
4150
   * @return false
4151
   * @deprecated in classes which support actions, use
4152
   *             <code>processActionEvent(ActionEvent)</code> instead
4153
   */
4154
  public boolean action(Event evt, Object what)
4155
  {
4156
    return false;
4157
  }
4158
 
4159
  /**
4160
   * Called when the parent of this Component is made visible or when
4161
   * the Component is added to an already visible Container and needs
4162
   * to be shown.  A native peer - if any - is created at this
4163
   * time. This method is called automatically by the AWT system and
4164
   * should not be called by user level code.
4165
   *
4166
   * @see #isDisplayable()
4167
   * @see #removeNotify()
4168
   */
4169
  public void addNotify()
4170
  {
4171
    // We need to lock the tree here to avoid races and inconsistencies.
4172
    synchronized (getTreeLock())
4173
      {
4174
        if (peer == null)
4175
          peer = getToolkit().createComponent(this);
4176
        else if (parent != null && parent.isLightweight())
4177
          new HeavyweightInLightweightListener(parent);
4178
        // Now that all the children has gotten their peers, we should
4179
        // have the event mask needed for this component and its
4180
        //lightweight subcomponents.
4181
        peer.setEventMask(eventMask);
4182
 
4183
        // We used to leave the invalidate() to the peer. However, I put it
4184
        // back here for 2 reasons: 1) The RI does call invalidate() from
4185
        // addNotify(); 2) The peer shouldn't be bother with validation too
4186
        // much.
4187
        invalidate();
4188
 
4189
        if (dropTarget != null)
4190
          dropTarget.addNotify(peer);
4191
 
4192
        // Fetch the peerFont for later installation in validate().
4193
        peerFont = getFont();
4194
 
4195
        // Notify hierarchy listeners.
4196
        long flags = HierarchyEvent.DISPLAYABILITY_CHANGED;
4197
        if (isHierarchyVisible())
4198
          flags |= HierarchyEvent.SHOWING_CHANGED;
4199
        fireHierarchyEvent(HierarchyEvent.HIERARCHY_CHANGED, this, parent,
4200
                           flags);
4201
      }
4202
  }
4203
 
4204
  /**
4205
   * Called to inform this component is has been removed from its
4206
   * container. Its native peer - if any - is destroyed at this time.
4207
   * This method is called automatically by the AWT system and should
4208
   * not be called by user level code.
4209
   *
4210
   * @see #isDisplayable()
4211
   * @see #addNotify()
4212
   */
4213
  public void removeNotify()
4214
  {
4215
    // We need to lock the tree here to avoid races and inconsistencies.
4216
    synchronized (getTreeLock())
4217
      {
4218
        // We null our peer field before disposing of it, such that if we're
4219
        // not the event dispatch thread and the dispatch thread is awoken by
4220
        // the dispose call, there will be no race checking the peer's null
4221
        // status.
4222
 
4223
        ComponentPeer tmp = peer;
4224
        peer = null;
4225
        peerFont = null;
4226
        if (tmp != null)
4227
          {
4228
            tmp.hide();
4229
            tmp.dispose();
4230
          }
4231
 
4232
        // Notify hierarchy listeners.
4233
        long flags = HierarchyEvent.DISPLAYABILITY_CHANGED;
4234
        if (isHierarchyVisible())
4235
          flags |= HierarchyEvent.SHOWING_CHANGED;
4236
        fireHierarchyEvent(HierarchyEvent.HIERARCHY_CHANGED, this, parent,
4237
                           flags);
4238
      }
4239
  }
4240
 
4241
  /**
4242
   * AWT 1.0 GOT_FOCUS event handler.  This method is meant to be
4243
   * overridden by components providing their own GOT_FOCUS handler.
4244
   * The default implementation simply returns false.
4245
   *
4246
   * @param evt the event to handle
4247
   * @param what the Object focused, ignored
4248
   * @return false
4249
   * @deprecated use {@link #processFocusEvent(FocusEvent)} instead
4250
   */
4251
  public boolean gotFocus(Event evt, Object what)
4252
  {
4253
    return false;
4254
  }
4255
 
4256
  /**
4257
   * AWT 1.0 LOST_FOCUS event handler.  This method is meant to be
4258
   * overridden by components providing their own LOST_FOCUS handler.
4259
   * The default implementation simply returns false.
4260
   *
4261
   * @param evt the event to handle
4262
   * @param what the Object focused, ignored
4263
   * @return false
4264
   * @deprecated use {@link #processFocusEvent(FocusEvent)} instead
4265
   */
4266
  public boolean lostFocus(Event evt, Object what)
4267
  {
4268
    return false;
4269
  }
4270
 
4271
  /**
4272
   * Tests whether or not this component is in the group that can be
4273
   * traversed using the keyboard traversal mechanism (such as the TAB key).
4274
   *
4275
   * @return true if the component is traversed via the TAB key
4276
   * @see #setFocusable(boolean)
4277
   * @since 1.1
4278
   * @deprecated use {@link #isFocusable()} instead
4279
   */
4280
  public boolean isFocusTraversable()
4281
  {
4282
    return enabled && visible && (peer == null || isLightweight() || peer.isFocusTraversable());
4283
  }
4284
 
4285
  /**
4286
   * Tests if this component can receive focus.
4287
   *
4288
   * @return true if this component can receive focus
4289
   * @since 1.4
4290
   */
4291
  public boolean isFocusable()
4292
  {
4293
    return focusable;
4294
  }
4295
 
4296
  /**
4297
   * Specify whether this component can receive focus. This method also
4298
   * sets the {@link #isFocusTraversableOverridden} field to 1, which
4299
   * appears to be the undocumented way {@link
4300
   * DefaultFocusTraversalPolicy#accept(Component)} determines whether to
4301
   * respect the {@link #isFocusable()} method of the component.
4302
   *
4303
   * @param focusable the new focusable status
4304
   * @since 1.4
4305
   */
4306
  public void setFocusable(boolean focusable)
4307
  {
4308
    firePropertyChange("focusable", this.focusable, focusable);
4309
    this.focusable = focusable;
4310
    this.isFocusTraversableOverridden = 1;
4311
  }
4312
 
4313
  /**
4314
   * Sets the focus traversal keys for one of the three focus
4315
   * traversal directions supported by Components:
4316
   * {@link KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS},
4317
   * {@link KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS}, or
4318
   * {@link KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS}. Normally, the
4319
   * default values should match the operating system's native
4320
   * choices. To disable a given traversal, use
4321
   * <code>Collections.EMPTY_SET</code>. The event dispatcher will
4322
   * consume PRESSED, RELEASED, and TYPED events for the specified
4323
   * key, although focus can only transfer on PRESSED or RELEASED.
4324
   *
4325
   * <p>The defaults are:
4326
   * <table>
4327
   *   <th><td>Identifier</td><td>Meaning</td><td>Default</td></th>
4328
   *   <tr><td>KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS</td>
4329
   *     <td>Normal forward traversal</td>
4330
   *     <td>TAB on KEY_PRESSED, Ctrl-TAB on KEY_PRESSED</td></tr>
4331
   *   <tr><td>KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS</td>
4332
   *     <td>Normal backward traversal</td>
4333
   *     <td>Shift-TAB on KEY_PRESSED, Ctrl-Shift-TAB on KEY_PRESSED</td></tr>
4334
   *   <tr><td>KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS</td>
4335
   *     <td>Go up a traversal cycle</td><td>None</td></tr>
4336
   * </table>
4337
   *
4338
   * If keystrokes is null, this component's focus traversal key set
4339
   * is inherited from one of its ancestors.  If none of its ancestors
4340
   * has its own set of focus traversal keys, the focus traversal keys
4341
   * are set to the defaults retrieved from the current
4342
   * KeyboardFocusManager.  If not null, the set must contain only
4343
   * AWTKeyStrokes that are not already focus keys and are not
4344
   * KEY_TYPED events.
4345
   *
4346
   * @param id one of FORWARD_TRAVERSAL_KEYS, BACKWARD_TRAVERSAL_KEYS, or
4347
   *        UP_CYCLE_TRAVERSAL_KEYS
4348
   * @param keystrokes a set of keys, or null
4349
   * @throws IllegalArgumentException if id or keystrokes is invalid
4350
   * @see #getFocusTraversalKeys(int)
4351
   * @see KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS
4352
   * @see KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS
4353
   * @see KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS
4354
   * @since 1.4
4355
   */
4356
  public void setFocusTraversalKeys(int id,
4357
                                    Set<? extends AWTKeyStroke> keystrokes)
4358
  {
4359
    if (keystrokes == null)
4360
      {
4361
        Container parent = getParent ();
4362
 
4363
        while (parent != null)
4364
          {
4365
            if (parent.areFocusTraversalKeysSet (id))
4366
              {
4367
                keystrokes = parent.getFocusTraversalKeys (id);
4368
                break;
4369
              }
4370
            parent = parent.getParent ();
4371
          }
4372
 
4373
        if (keystrokes == null)
4374
          keystrokes = KeyboardFocusManager.getCurrentKeyboardFocusManager ().
4375
            getDefaultFocusTraversalKeys (id);
4376
      }
4377
 
4378
    Set sa;
4379
    Set sb;
4380
    String name;
4381
    switch (id)
4382
      {
4383
      case KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS:
4384
        sa = getFocusTraversalKeys
4385
          (KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS);
4386
        sb = getFocusTraversalKeys
4387
          (KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS);
4388
        name = "forwardFocusTraversalKeys";
4389
        break;
4390
      case KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS:
4391
        sa = getFocusTraversalKeys
4392
          (KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
4393
        sb = getFocusTraversalKeys
4394
          (KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS);
4395
        name = "backwardFocusTraversalKeys";
4396
        break;
4397
      case KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS:
4398
        sa = getFocusTraversalKeys
4399
          (KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
4400
        sb = getFocusTraversalKeys
4401
          (KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS);
4402
        name = "upCycleFocusTraversalKeys";
4403
        break;
4404
      default:
4405
        throw new IllegalArgumentException ();
4406
      }
4407
 
4408
    int i = keystrokes.size ();
4409
    Iterator iter = keystrokes.iterator ();
4410
 
4411
    while (--i >= 0)
4412
      {
4413
        Object o = iter.next ();
4414
        if (!(o instanceof AWTKeyStroke)
4415
            || sa.contains (o) || sb.contains (o)
4416
            || ((AWTKeyStroke) o).keyCode == KeyEvent.VK_UNDEFINED)
4417
          throw new IllegalArgumentException ();
4418
      }
4419
 
4420
    if (focusTraversalKeys == null)
4421
      focusTraversalKeys = new Set[3];
4422
 
4423
    keystrokes = Collections.unmodifiableSet (new HashSet (keystrokes));
4424
    firePropertyChange (name, focusTraversalKeys[id], keystrokes);
4425
 
4426
    focusTraversalKeys[id] = keystrokes;
4427
  }
4428
 
4429
  /**
4430
   * Returns the set of keys for a given focus traversal action, as
4431
   * defined in <code>setFocusTraversalKeys</code>.  If not set, this
4432
   * is inherited from the parent component, which may have gotten it
4433
   * from the KeyboardFocusManager.
4434
   *
4435
   * @param id one of FORWARD_TRAVERSAL_KEYS, BACKWARD_TRAVERSAL_KEYS,
4436
   * or UP_CYCLE_TRAVERSAL_KEYS
4437
   *
4438
   * @return set of traversal keys
4439
   *
4440
   * @throws IllegalArgumentException if id is invalid
4441
   *
4442
   * @see #setFocusTraversalKeys (int, Set)
4443
   * @see KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS
4444
   * @see KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS
4445
   * @see KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS
4446
   *
4447
   * @since 1.4
4448
   */
4449
  public Set<AWTKeyStroke> getFocusTraversalKeys (int id)
4450
  {
4451
    if (id != KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS &&
4452
        id != KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS &&
4453
        id != KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS)
4454
      throw new IllegalArgumentException();
4455
 
4456
    Set<AWTKeyStroke> s = null;
4457
 
4458
    if (focusTraversalKeys != null)
4459
      s = focusTraversalKeys[id];
4460
 
4461
    if (s == null && parent != null)
4462
      s = parent.getFocusTraversalKeys (id);
4463
 
4464
    return s == null ? (KeyboardFocusManager.getCurrentKeyboardFocusManager()
4465
                        .getDefaultFocusTraversalKeys(id)) : s;
4466
  }
4467
 
4468
  /**
4469
   * Tests whether the focus traversal keys for a given action are explicitly
4470
   * set or inherited.
4471
   *
4472
   * @param id one of FORWARD_TRAVERSAL_KEYS, BACKWARD_TRAVERSAL_KEYS,
4473
   * or UP_CYCLE_TRAVERSAL_KEYS
4474
   * @return true if that set is explicitly specified
4475
   * @throws IllegalArgumentException if id is invalid
4476
   * @see #getFocusTraversalKeys (int)
4477
   * @see KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS
4478
   * @see KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS
4479
   * @see KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS
4480
   * @since 1.4
4481
   */
4482
  public boolean areFocusTraversalKeysSet (int id)
4483
  {
4484
    if (id != KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS &&
4485
        id != KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS &&
4486
        id != KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS)
4487
      throw new IllegalArgumentException ();
4488
 
4489
    return focusTraversalKeys != null && focusTraversalKeys[id] != null;
4490
  }
4491
 
4492
  /**
4493
   * Enable or disable focus traversal keys on this Component.  If
4494
   * they are, then the keyboard focus manager consumes and acts on
4495
   * key press and release events that trigger focus traversal, and
4496
   * discards the corresponding key typed events.  If focus traversal
4497
   * keys are disabled, then all key events that would otherwise
4498
   * trigger focus traversal are sent to this Component.
4499
   *
4500
   * @param focusTraversalKeysEnabled the new value of the flag
4501
   * @see #getFocusTraversalKeysEnabled ()
4502
   * @see #setFocusTraversalKeys (int, Set)
4503
   * @see #getFocusTraversalKeys (int)
4504
   * @since 1.4
4505
   */
4506
  public void setFocusTraversalKeysEnabled (boolean focusTraversalKeysEnabled)
4507
  {
4508
    firePropertyChange ("focusTraversalKeysEnabled",
4509
                        this.focusTraversalKeysEnabled,
4510
                        focusTraversalKeysEnabled);
4511
    this.focusTraversalKeysEnabled = focusTraversalKeysEnabled;
4512
  }
4513
 
4514
  /**
4515
   * Check whether or not focus traversal keys are enabled on this
4516
   * Component.  If they are, then the keyboard focus manager consumes
4517
   * and acts on key press and release events that trigger focus
4518
   * traversal, and discards the corresponding key typed events.  If
4519
   * focus traversal keys are disabled, then all key events that would
4520
   * otherwise trigger focus traversal are sent to this Component.
4521
   *
4522
   * @return true if focus traversal keys are enabled
4523
   * @see #setFocusTraversalKeysEnabled (boolean)
4524
   * @see #setFocusTraversalKeys (int, Set)
4525
   * @see #getFocusTraversalKeys (int)
4526
   * @since 1.4
4527
   */
4528
  public boolean getFocusTraversalKeysEnabled ()
4529
  {
4530
    return focusTraversalKeysEnabled;
4531
  }
4532
 
4533
  /**
4534
   * Request that this Component be given the keyboard input focus and
4535
   * that its top-level ancestor become the focused Window.
4536
   *
4537
   * For the request to be granted, the Component must be focusable,
4538
   * displayable and showing and the top-level Window to which it
4539
   * belongs must be focusable.  If the request is initially denied on
4540
   * the basis that the top-level Window is not focusable, the request
4541
   * will be remembered and granted when the Window does become
4542
   * focused.
4543
   *
4544
   * Never assume that this Component is the focus owner until it
4545
   * receives a FOCUS_GAINED event.
4546
   *
4547
   * The behaviour of this method is platform-dependent.
4548
   * {@link #requestFocusInWindow()} should be used instead.
4549
   *
4550
   * @see #requestFocusInWindow ()
4551
   * @see FocusEvent
4552
   * @see #addFocusListener (FocusListener)
4553
   * @see #isFocusable ()
4554
   * @see #isDisplayable ()
4555
   * @see KeyboardFocusManager#clearGlobalFocusOwner ()
4556
   */
4557
  public void requestFocus ()
4558
  {
4559
    requestFocusImpl(false, true);
4560
  }
4561
 
4562
  /**
4563
   * Request that this Component be given the keyboard input focus and
4564
   * that its top-level ancestor become the focused Window.
4565
   *
4566
   * For the request to be granted, the Component must be focusable,
4567
   * displayable and showing and the top-level Window to which it
4568
   * belongs must be focusable.  If the request is initially denied on
4569
   * the basis that the top-level Window is not focusable, the request
4570
   * will be remembered and granted when the Window does become
4571
   * focused.
4572
   *
4573
   * Never assume that this Component is the focus owner until it
4574
   * receives a FOCUS_GAINED event.
4575
   *
4576
   * The behaviour of this method is platform-dependent.
4577
   * {@link #requestFocusInWindow()} should be used instead.
4578
   *
4579
   * If the return value is false, the request is guaranteed to fail.
4580
   * If the return value is true, the request will succeed unless it
4581
   * is vetoed or something in the native windowing system intervenes,
4582
   * preventing this Component's top-level ancestor from becoming
4583
   * focused.  This method is meant to be called by derived
4584
   * lightweight Components that want to avoid unnecessary repainting
4585
   * when they know a given focus transfer need only be temporary.
4586
   *
4587
   * @param temporary true if the focus request is temporary
4588
   * @return true if the request has a chance of success
4589
   * @see #requestFocusInWindow ()
4590
   * @see FocusEvent
4591
   * @see #addFocusListener (FocusListener)
4592
   * @see #isFocusable ()
4593
   * @see #isDisplayable ()
4594
   * @see KeyboardFocusManager#clearGlobalFocusOwner ()
4595
   * @since 1.4
4596
   */
4597
  protected boolean requestFocus (boolean temporary)
4598
  {
4599
    return requestFocusImpl(temporary, true);
4600
  }
4601
 
4602
  /**
4603
   * Request that this component be given the keyboard input focus, if
4604
   * its top-level ancestor is the currently focused Window.  A
4605
   * <code>FOCUS_GAINED</code> event will be fired if and only if this
4606
   * request is successful. To be successful, the component must be
4607
   * displayable, showing, and focusable, and its ancestor top-level
4608
   * Window must be focused.
4609
   *
4610
   * If the return value is false, the request is guaranteed to fail.
4611
   * If the return value is true, the request will succeed unless it
4612
   * is vetoed or something in the native windowing system intervenes,
4613
   * preventing this Component's top-level ancestor from becoming
4614
   * focused.
4615
   *
4616
   * @return true if the request has a chance of success
4617
   * @see #requestFocus ()
4618
   * @see FocusEvent
4619
   * @see #addFocusListener (FocusListener)
4620
   * @see #isFocusable ()
4621
   * @see #isDisplayable ()
4622
   * @see KeyboardFocusManager#clearGlobalFocusOwner ()
4623
   * @since 1.4
4624
   */
4625
  public boolean requestFocusInWindow ()
4626
  {
4627
    return requestFocusImpl(false, false);
4628
  }
4629
 
4630
  /**
4631
   * Request that this component be given the keyboard input focus, if
4632
   * its top-level ancestor is the currently focused Window.  A
4633
   * <code>FOCUS_GAINED</code> event will be fired if and only if this
4634
   * request is successful. To be successful, the component must be
4635
   * displayable, showing, and focusable, and its ancestor top-level
4636
   * Window must be focused.
4637
   *
4638
   * If the return value is false, the request is guaranteed to fail.
4639
   * If the return value is true, the request will succeed unless it
4640
   * is vetoed or something in the native windowing system intervenes,
4641
   * preventing this Component's top-level ancestor from becoming
4642
   * focused.  This method is meant to be called by derived
4643
   * lightweight Components that want to avoid unnecessary repainting
4644
   * when they know a given focus transfer need only be temporary.
4645
   *
4646
   * @param temporary true if the focus request is temporary
4647
   * @return true if the request has a chance of success
4648
   * @see #requestFocus ()
4649
   * @see FocusEvent
4650
   * @see #addFocusListener (FocusListener)
4651
   * @see #isFocusable ()
4652
   * @see #isDisplayable ()
4653
   * @see KeyboardFocusManager#clearGlobalFocusOwner ()
4654
   * @since 1.4
4655
   */
4656
  protected boolean requestFocusInWindow (boolean temporary)
4657
  {
4658
    return requestFocusImpl(temporary, false);
4659
  }
4660
 
4661
  /**
4662
   * Helper method for all 4 requestFocus variants.
4663
   *
4664
   * @param temporary indicates if the focus change is temporary
4665
   * @param focusWindow indicates if the window focus may be changed
4666
   *
4667
   * @return <code>false</code> if the request has been definitely denied,
4668
   *         <code>true</code> otherwise
4669
   */
4670
  private boolean requestFocusImpl(boolean temporary, boolean focusWindow)
4671
  {
4672
    boolean retval = false;
4673
 
4674
    // Don't try to focus non-focusable and non-visible components.
4675
    if (isFocusable() && isVisible())
4676
      {
4677
        ComponentPeer myPeer = peer;
4678
        if (peer != null)
4679
          {
4680
            // Find Window ancestor and find out if we're showing while
4681
            // doing this.
4682
            boolean showing = true;
4683
            Component window = this;
4684
            while (! (window instanceof Window))
4685
              {
4686
                if (! window.isVisible())
4687
                  showing = false;
4688
                window = window.parent;
4689
              }
4690
            // Don't allow focus when there is no window or the window
4691
            // is not focusable.
4692
            if (window != null && ((Window) window).isFocusableWindow()
4693
                && showing)
4694
              {
4695
                // Search for nearest heavy ancestor (including this
4696
                // component).
4697
                Component heavyweightParent = this;
4698
                while (heavyweightParent.peer instanceof LightweightPeer)
4699
                  heavyweightParent = heavyweightParent.parent;
4700
 
4701
                // Don't allow focus on lightweight components without
4702
                // visible heavyweight ancestor
4703
                if (heavyweightParent != null && heavyweightParent.isVisible())
4704
                  {
4705
                    // Don't allow focus when heavyweightParent has no peer.
4706
                    myPeer = heavyweightParent.peer;
4707
                    if (myPeer != null)
4708
                      {
4709
                        // Register lightweight focus request.
4710
                        if (heavyweightParent != this)
4711
                          {
4712
                            KeyboardFocusManager
4713
                            .addLightweightFocusRequest(heavyweightParent,
4714
                                                        this);
4715
                          }
4716
 
4717
                        // Try to focus the component.
4718
                        long time = EventQueue.getMostRecentEventTime();
4719
                        boolean success = myPeer.requestFocus(this, temporary,
4720
                                                              focusWindow,
4721
                                                              time);
4722
                        if (! success)
4723
                          {
4724
                            // Dequeue key events if focus request failed.
4725
                            KeyboardFocusManager kfm =
4726
                              KeyboardFocusManager.getCurrentKeyboardFocusManager();
4727
                            kfm.dequeueKeyEvents(time, this);
4728
                          }
4729
                        retval = success;
4730
                      }
4731
                  }
4732
              }
4733
          }
4734
      }
4735
    return retval;
4736
  }
4737
 
4738
  /**
4739
   * Transfers focus to the next component in the focus traversal
4740
   * order, as though this were the current focus owner.
4741
   *
4742
   * @see #requestFocus()
4743
   * @since 1.1
4744
   */
4745
  public void transferFocus ()
4746
  {
4747
    nextFocus ();
4748
  }
4749
 
4750
  /**
4751
   * Returns the root container that owns the focus cycle where this
4752
   * component resides. A focus cycle root is in two cycles, one as
4753
   * the ancestor, and one as the focusable element; this call always
4754
   * returns the ancestor.
4755
   *
4756
   * @return the ancestor container that owns the focus cycle
4757
   * @since 1.4
4758
   */
4759
  public Container getFocusCycleRootAncestor ()
4760
  {
4761
    Container parent = getParent ();
4762
 
4763
    while (parent != null && !parent.isFocusCycleRoot())
4764
      parent = parent.getParent ();
4765
 
4766
    return parent;
4767
  }
4768
 
4769
  /**
4770
   * Tests if the container is the ancestor of the focus cycle that
4771
   * this component belongs to.
4772
   *
4773
   * @param c the container to test
4774
   * @return true if c is the focus cycle root
4775
   * @since 1.4
4776
   */
4777
  public boolean isFocusCycleRoot (Container c)
4778
  {
4779
    return c == getFocusCycleRootAncestor ();
4780
  }
4781
 
4782
  /**
4783
   * AWT 1.0 focus event processor.  Transfers focus to the next
4784
   * component in the focus traversal order, as though this were the
4785
   * current focus owner.
4786
   *
4787
   * @deprecated use {@link #transferFocus ()} instead
4788
   */
4789
  public void nextFocus ()
4790
  {
4791
    // Find the nearest valid (== showing && focusable && enabled) focus
4792
    // cycle root ancestor and the focused component in it.
4793
    Container focusRoot = getFocusCycleRootAncestor();
4794
    Component focusComp = this;
4795
    while (focusRoot != null
4796
           && ! (focusRoot.isShowing() && focusRoot.isFocusable()
4797
                 && focusRoot.isEnabled()))
4798
      {
4799
        focusComp = focusRoot;
4800
        focusRoot = focusComp.getFocusCycleRootAncestor();
4801
      }
4802
 
4803
    if (focusRoot != null)
4804
      {
4805
        // First try to get the componentBefore from the policy.
4806
        FocusTraversalPolicy policy = focusRoot.getFocusTraversalPolicy();
4807
        Component nextFocus = policy.getComponentAfter(focusRoot, focusComp);
4808
 
4809
        // If this fails, then ask for the defaultComponent.
4810
        if (nextFocus == null)
4811
          nextFocus = policy.getDefaultComponent(focusRoot);
4812
 
4813
        // Request focus on this component, if not null.
4814
        if (nextFocus != null)
4815
          nextFocus.requestFocus();
4816
      }
4817
  }
4818
 
4819
  /**
4820
   * Transfers focus to the previous component in the focus traversal
4821
   * order, as though this were the current focus owner.
4822
   *
4823
   * @see #requestFocus ()
4824
   * @since 1.4
4825
   */
4826
  public void transferFocusBackward ()
4827
  {
4828
    // Find the nearest valid (== showing && focusable && enabled) focus
4829
    // cycle root ancestor and the focused component in it.
4830
    Container focusRoot = getFocusCycleRootAncestor();
4831
    Component focusComp = this;
4832
    while (focusRoot != null
4833
           && ! (focusRoot.isShowing() && focusRoot.isFocusable()
4834
                 && focusRoot.isEnabled()))
4835
      {
4836
        focusComp = focusRoot;
4837
        focusRoot = focusComp.getFocusCycleRootAncestor();
4838
      }
4839
 
4840
    if (focusRoot != null)
4841
      {
4842
        // First try to get the componentBefore from the policy.
4843
        FocusTraversalPolicy policy = focusRoot.getFocusTraversalPolicy();
4844
        Component nextFocus = policy.getComponentBefore(focusRoot, focusComp);
4845
 
4846
        // If this fails, then ask for the defaultComponent.
4847
        if (nextFocus == null)
4848
          nextFocus = policy.getDefaultComponent(focusRoot);
4849
 
4850
        // Request focus on this component, if not null.
4851
        if (nextFocus != null)
4852
          nextFocus.requestFocus();
4853
      }
4854
  }
4855
 
4856
  /**
4857
   * Transfers focus to the focus cycle root of this component.
4858
   * However, if this is a Window, the default focus owner in the
4859
   * window in the current focus cycle is focused instead.
4860
   *
4861
   * @see #requestFocus()
4862
   * @see #isFocusCycleRoot(Container)
4863
   * @since 1.4
4864
   */
4865
  public void transferFocusUpCycle ()
4866
  {
4867
    // Find the nearest focus cycle root ancestor that is itself
4868
    // focusable, showing and enabled.
4869
    Container focusCycleRoot = getFocusCycleRootAncestor();
4870
    while (focusCycleRoot != null &&
4871
           ! (focusCycleRoot.isShowing() && focusCycleRoot.isFocusable()
4872
              && focusCycleRoot.isEnabled()))
4873
      {
4874
        focusCycleRoot = focusCycleRoot.getFocusCycleRootAncestor();
4875
      }
4876
 
4877
    KeyboardFocusManager fm =
4878
      KeyboardFocusManager.getCurrentKeyboardFocusManager();
4879
 
4880
    if (focusCycleRoot != null)
4881
      {
4882
        // If we found a focus cycle root, then we make this the new
4883
        // focused component, and make it's focus cycle root the new
4884
        // global focus cycle root. If the found root has no focus cycle
4885
        // root ancestor itself, then the component will be both the focused
4886
        // component and the new global focus cycle root.
4887
        Container focusCycleAncestor =
4888
          focusCycleRoot.getFocusCycleRootAncestor();
4889
        Container globalFocusCycleRoot;
4890
        if (focusCycleAncestor == null)
4891
          globalFocusCycleRoot = focusCycleRoot;
4892
        else
4893
          globalFocusCycleRoot = focusCycleAncestor;
4894
 
4895
        fm.setGlobalCurrentFocusCycleRoot(globalFocusCycleRoot);
4896
        focusCycleRoot.requestFocus();
4897
      }
4898
    else
4899
      {
4900
        // If this component has no applicable focus cycle root, we try
4901
        // find the nearest window and set this as the new global focus cycle
4902
        // root and the default focus component of this window the new focused
4903
        // component.
4904
        Container cont;
4905
        if (this instanceof Container)
4906
          cont = (Container) this;
4907
        else
4908
          cont = getParent();
4909
 
4910
        while (cont != null && !(cont instanceof Window))
4911
          cont = cont.getParent();
4912
 
4913
        if (cont != null)
4914
          {
4915
            FocusTraversalPolicy policy = cont.getFocusTraversalPolicy();
4916
            Component focusComp = policy.getDefaultComponent(cont);
4917
            if (focusComp != null)
4918
              {
4919
                fm.setGlobalCurrentFocusCycleRoot(cont);
4920
                focusComp.requestFocus();
4921
              }
4922
          }
4923
      }
4924
  }
4925
 
4926
  /**
4927
   * Tests if this component is the focus owner. Use {@link
4928
   * #isFocusOwner ()} instead.
4929
   *
4930
   * @return true if this component owns focus
4931
   * @since 1.2
4932
   */
4933
  public boolean hasFocus ()
4934
  {
4935
    KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
4936
 
4937
    Component focusOwner = manager.getFocusOwner ();
4938
 
4939
    return this == focusOwner;
4940
  }
4941
 
4942
  /**
4943
   * Tests if this component is the focus owner.
4944
   *
4945
   * @return true if this component owns focus
4946
   * @since 1.4
4947
   */
4948
  public boolean isFocusOwner()
4949
  {
4950
    return hasFocus ();
4951
  }
4952
 
4953
  /**
4954
   * Adds the specified popup menu to this component.
4955
   *
4956
   * @param popup the popup menu to be added
4957
   *
4958
   * @see #remove(MenuComponent)
4959
   *
4960
   * @since 1.1
4961
   */
4962
  public synchronized void add(PopupMenu popup)
4963
  {
4964
    if (popups == null)
4965
      popups = new Vector();
4966
    popups.add(popup);
4967
 
4968
    if (popup.parent != null)
4969
      popup.parent.remove(popup);
4970
    popup.parent = this;
4971
    if (peer != null)
4972
      popup.addNotify();
4973
  }
4974
 
4975
  /**
4976
   * Removes the specified popup menu from this component.
4977
   *
4978
   * @param popup the popup menu to remove
4979
   * @see #add(PopupMenu)
4980
   * @since 1.1
4981
   */
4982
  public synchronized void remove(MenuComponent popup)
4983
  {
4984
    if (popups != null)
4985
      popups.remove(popup);
4986
  }
4987
 
4988
  /**
4989
   * Returns a debugging string representing this component. The string may
4990
   * be empty but not null.
4991
   *
4992
   * @return a string representing this component
4993
   */
4994
  protected String paramString()
4995
  {
4996
    CPStringBuilder param = new CPStringBuilder();
4997
    String name = getName();
4998
    if (name != null)
4999
      param.append(name).append(",");
5000
    param.append(x).append(",").append(y).append(",").append(width)
5001
      .append("x").append(height);
5002
    if (! isValid())
5003
      param.append(",invalid");
5004
    if (! isVisible())
5005
      param.append(",invisible");
5006
    if (! isEnabled())
5007
      param.append(",disabled");
5008
    if (! isOpaque())
5009
      param.append(",translucent");
5010
    if (isDoubleBuffered())
5011
      param.append(",doublebuffered");
5012
    if (parent == null)
5013
      param.append(",parent=null");
5014
    else
5015
      param.append(",parent=").append(parent.getName());
5016
    return param.toString();
5017
  }
5018
 
5019
  /**
5020
   * Returns a string representation of this component. This is implemented
5021
   * as <code>getClass().getName() + '[' + paramString() + ']'</code>.
5022
   *
5023
   * @return a string representation of this component
5024
   */
5025
  public String toString()
5026
  {
5027
    return getClass().getName() + '[' + paramString() + ']';
5028
  }
5029
 
5030
  /**
5031
   * Prints a listing of this component to <code>System.out</code>.
5032
   *
5033
   * @see #list(PrintStream)
5034
   */
5035
  public void list()
5036
  {
5037
    list(System.out, 0);
5038
  }
5039
 
5040
  /**
5041
   * Prints a listing of this component to the specified print stream.
5042
   *
5043
   * @param out the <code>PrintStream</code> to print to
5044
   */
5045
  public void list(PrintStream out)
5046
  {
5047
    list(out, 0);
5048
  }
5049
 
5050
  /**
5051
   * Prints a listing of this component to the specified print stream,
5052
   * starting at the specified indentation point.
5053
   *
5054
   * @param out the <code>PrintStream</code> to print to
5055
   * @param indent the indentation point
5056
   */
5057
  public void list(PrintStream out, int indent)
5058
  {
5059
    for (int i = 0; i < indent; ++i)
5060
      out.print(' ');
5061
    out.println(toString());
5062
  }
5063
 
5064
  /**
5065
   * Prints a listing of this component to the specified print writer.
5066
   *
5067
   * @param out the <code>PrintWrinter</code> to print to
5068
   * @since 1.1
5069
   */
5070
  public void list(PrintWriter out)
5071
  {
5072
    list(out, 0);
5073
  }
5074
 
5075
  /**
5076
   * Prints a listing of this component to the specified print writer,
5077
   * starting at the specified indentation point.
5078
   *
5079
   * @param out the <code>PrintWriter</code> to print to
5080
   * @param indent the indentation point
5081
   * @since 1.1
5082
   */
5083
  public void list(PrintWriter out, int indent)
5084
  {
5085
    for (int i = 0; i < indent; ++i)
5086
      out.print(' ');
5087
    out.println(toString());
5088
  }
5089
 
5090
  /**
5091
   * Adds the specified property listener to this component. This is harmless
5092
   * if the listener is null, but if the listener has already been registered,
5093
   * it will now be registered twice. The property listener ignores inherited
5094
   * properties. Recognized properties include:<br>
5095
   * <ul>
5096
   * <li>the font (<code>"font"</code>)</li>
5097
   * <li>the background color (<code>"background"</code>)</li>
5098
   * <li>the foreground color (<code>"foreground"</code>)</li>
5099
   * <li>the focusability (<code>"focusable"</code>)</li>
5100
   * <li>the focus key traversal enabled state
5101
   *     (<code>"focusTraversalKeysEnabled"</code>)</li>
5102
   * <li>the set of forward traversal keys
5103
   *     (<code>"forwardFocusTraversalKeys"</code>)</li>
5104
   * <li>the set of backward traversal keys
5105
   *     (<code>"backwardFocusTraversalKeys"</code>)</li>
5106
   * <li>the set of up-cycle traversal keys
5107
   *     (<code>"upCycleFocusTraversalKeys"</code>)</li>
5108
   * </ul>
5109
   *
5110
   * @param listener the new listener to add
5111
   * @see #removePropertyChangeListener(PropertyChangeListener)
5112
   * @see #getPropertyChangeListeners()
5113
   * @see #addPropertyChangeListener(String, PropertyChangeListener)
5114
   * @since 1.1
5115
   */
5116
  public void addPropertyChangeListener(PropertyChangeListener listener)
5117
  {
5118
    if (changeSupport == null)
5119
      changeSupport = new PropertyChangeSupport(this);
5120
    changeSupport.addPropertyChangeListener(listener);
5121
  }
5122
 
5123
  /**
5124
   * Removes the specified property listener from the component. This is
5125
   * harmless if the listener was not previously registered.
5126
   *
5127
   * @param listener the listener to remove
5128
   * @see #addPropertyChangeListener(PropertyChangeListener)
5129
   * @see #getPropertyChangeListeners()
5130
   * @see #removePropertyChangeListener(String, PropertyChangeListener)
5131
   * @since 1.1
5132
   */
5133
  public void removePropertyChangeListener(PropertyChangeListener listener)
5134
  {
5135
    if (changeSupport != null)
5136
      changeSupport.removePropertyChangeListener(listener);
5137
  }
5138
 
5139
  /**
5140
   * Returns an array of all specified listeners registered on this component.
5141
   *
5142
   * @return an array of listeners
5143
   * @see #addPropertyChangeListener(PropertyChangeListener)
5144
   * @see #removePropertyChangeListener(PropertyChangeListener)
5145
   * @see #getPropertyChangeListeners(String)
5146
   * @since 1.4
5147
   */
5148
  public PropertyChangeListener[] getPropertyChangeListeners()
5149
  {
5150
    return changeSupport == null ? new PropertyChangeListener[0]
5151
      : changeSupport.getPropertyChangeListeners();
5152
  }
5153
 
5154
  /**
5155
   * Adds the specified property listener to this component. This is harmless
5156
   * if the listener is null, but if the listener has already been registered,
5157
   * it will now be registered twice. The property listener ignores inherited
5158
   * properties. The listener is keyed to a single property. Recognized
5159
   * properties include:<br>
5160
   * <ul>
5161
   * <li>the font (<code>"font"</code>)</li>
5162
   * <li>the background color (<code>"background"</code>)</li>
5163
   * <li>the foreground color (<code>"foreground"</code>)</li>
5164
   * <li>the focusability (<code>"focusable"</code>)</li>
5165
   * <li>the focus key traversal enabled state
5166
   *     (<code>"focusTraversalKeysEnabled"</code>)</li>
5167
   * <li>the set of forward traversal keys
5168
   *     (<code>"forwardFocusTraversalKeys"</code>)</li>
5169
p   * <li>the set of backward traversal keys
5170
   *     (<code>"backwardFocusTraversalKeys"</code>)</li>
5171
   * <li>the set of up-cycle traversal keys
5172
   *     (<code>"upCycleFocusTraversalKeys"</code>)</li>
5173
   * </ul>
5174
   *
5175
   * @param propertyName the property name to filter on
5176
   * @param listener the new listener to add
5177
   * @see #removePropertyChangeListener(String, PropertyChangeListener)
5178
   * @see #getPropertyChangeListeners(String)
5179
   * @see #addPropertyChangeListener(PropertyChangeListener)
5180
   * @since 1.1
5181
   */
5182
  public void addPropertyChangeListener(String propertyName,
5183
                                        PropertyChangeListener listener)
5184
  {
5185
    if (changeSupport == null)
5186
      changeSupport = new PropertyChangeSupport(this);
5187
    changeSupport.addPropertyChangeListener(propertyName, listener);
5188
  }
5189
 
5190
  /**
5191
   * Removes the specified property listener on a particular property from
5192
   * the component. This is harmless if the listener was not previously
5193
   * registered.
5194
   *
5195
   * @param propertyName the property name to filter on
5196
   * @param listener the listener to remove
5197
   * @see #addPropertyChangeListener(String, PropertyChangeListener)
5198
   * @see #getPropertyChangeListeners(String)
5199
   * @see #removePropertyChangeListener(PropertyChangeListener)
5200
   * @since 1.1
5201
   */
5202
  public void removePropertyChangeListener(String propertyName,
5203
                                           PropertyChangeListener listener)
5204
  {
5205
    if (changeSupport != null)
5206
      changeSupport.removePropertyChangeListener(propertyName, listener);
5207
  }
5208
 
5209
  /**
5210
   * Returns an array of all specified listeners on the named property that
5211
   * are registered on this component.
5212
   *
5213
   * @return an array of listeners
5214
   * @see #addPropertyChangeListener(String, PropertyChangeListener)
5215
   * @see #removePropertyChangeListener(String, PropertyChangeListener)
5216
   * @see #getPropertyChangeListeners()
5217
   * @since 1.4
5218
   */
5219
  public PropertyChangeListener[] getPropertyChangeListeners(String property)
5220
  {
5221
    return changeSupport == null ? new PropertyChangeListener[0]
5222
      : changeSupport.getPropertyChangeListeners(property);
5223
  }
5224
 
5225
  /**
5226
   * Report a change in a bound property to any registered property listeners.
5227
   *
5228
   * @param propertyName the property that changed
5229
   * @param oldValue the old property value
5230
   * @param newValue the new property value
5231
   */
5232
  protected void firePropertyChange(String propertyName, Object oldValue,
5233
                                    Object newValue)
5234
  {
5235
    if (changeSupport != null)
5236
      changeSupport.firePropertyChange(propertyName, oldValue, newValue);
5237
  }
5238
 
5239
  /**
5240
   * Report a change in a bound property to any registered property listeners.
5241
   *
5242
   * @param propertyName the property that changed
5243
   * @param oldValue the old property value
5244
   * @param newValue the new property value
5245
   */
5246
  protected void firePropertyChange(String propertyName, boolean oldValue,
5247
                                    boolean newValue)
5248
  {
5249
    if (changeSupport != null)
5250
      changeSupport.firePropertyChange(propertyName, oldValue, newValue);
5251
  }
5252
 
5253
  /**
5254
   * Report a change in a bound property to any registered property listeners.
5255
   *
5256
   * @param propertyName the property that changed
5257
   * @param oldValue the old property value
5258
   * @param newValue the new property value
5259
   */
5260
  protected void firePropertyChange(String propertyName, int oldValue,
5261
                                    int newValue)
5262
  {
5263
    if (changeSupport != null)
5264
      changeSupport.firePropertyChange(propertyName, oldValue, newValue);
5265
  }
5266
 
5267
  /**
5268
   * Report a change in a bound property to any registered property listeners.
5269
   *
5270
   * @param propertyName the property that changed
5271
   * @param oldValue the old property value
5272
   * @param newValue the new property value
5273
   *
5274
   * @since 1.5
5275
   */
5276
  public void firePropertyChange(String propertyName, byte oldValue,
5277
                                    byte newValue)
5278
  {
5279
    if (changeSupport != null)
5280
      changeSupport.firePropertyChange(propertyName, new Byte(oldValue),
5281
                                       new Byte(newValue));
5282
  }
5283
 
5284
  /**
5285
   * Report a change in a bound property to any registered property listeners.
5286
   *
5287
   * @param propertyName the property that changed
5288
   * @param oldValue the old property value
5289
   * @param newValue the new property value
5290
   *
5291
   * @since 1.5
5292
   */
5293
  public void firePropertyChange(String propertyName, char oldValue,
5294
                                    char newValue)
5295
  {
5296
    if (changeSupport != null)
5297
      changeSupport.firePropertyChange(propertyName, new Character(oldValue),
5298
                                       new Character(newValue));
5299
  }
5300
 
5301
  /**
5302
   * Report a change in a bound property to any registered property listeners.
5303
   *
5304
   * @param propertyName the property that changed
5305
   * @param oldValue the old property value
5306
   * @param newValue the new property value
5307
   *
5308
   * @since 1.5
5309
   */
5310
  public void firePropertyChange(String propertyName, short oldValue,
5311
                                    short newValue)
5312
  {
5313
    if (changeSupport != null)
5314
      changeSupport.firePropertyChange(propertyName, new Short(oldValue),
5315
                                       new Short(newValue));
5316
  }
5317
 
5318
  /**
5319
   * Report a change in a bound property to any registered property listeners.
5320
   *
5321
   * @param propertyName the property that changed
5322
   * @param oldValue the old property value
5323
   * @param newValue the new property value
5324
   *
5325
   * @since 1.5
5326
   */
5327
  public void firePropertyChange(String propertyName, long oldValue,
5328
                                    long newValue)
5329
  {
5330
    if (changeSupport != null)
5331
      changeSupport.firePropertyChange(propertyName, new Long(oldValue),
5332
                                       new Long(newValue));
5333
  }
5334
 
5335
  /**
5336
   * Report a change in a bound property to any registered property listeners.
5337
   *
5338
   * @param propertyName the property that changed
5339
   * @param oldValue the old property value
5340
   * @param newValue the new property value
5341
   *
5342
   * @since 1.5
5343
   */
5344
  public void firePropertyChange(String propertyName, float oldValue,
5345
                                    float newValue)
5346
  {
5347
    if (changeSupport != null)
5348
      changeSupport.firePropertyChange(propertyName, new Float(oldValue),
5349
                                       new Float(newValue));
5350
  }
5351
 
5352
 
5353
  /**
5354
   * Report a change in a bound property to any registered property listeners.
5355
   *
5356
   * @param propertyName the property that changed
5357
   * @param oldValue the old property value
5358
   * @param newValue the new property value
5359
   *
5360
   * @since 1.5
5361
   */
5362
  public void firePropertyChange(String propertyName, double oldValue,
5363
                                 double newValue)
5364
  {
5365
    if (changeSupport != null)
5366
      changeSupport.firePropertyChange(propertyName, new Double(oldValue),
5367
                                       new Double(newValue));
5368
  }
5369
 
5370
  /**
5371
   * Sets the text layout orientation of this component. New components default
5372
   * to UNKNOWN (which behaves like LEFT_TO_RIGHT). This method affects only
5373
   * the current component, while
5374
   * {@link #applyComponentOrientation(ComponentOrientation)} affects the
5375
   * entire hierarchy.
5376
   *
5377
   * @param o the new orientation (<code>null</code> is accepted)
5378
   * @see #getComponentOrientation()
5379
   */
5380
  public void setComponentOrientation(ComponentOrientation o)
5381
  {
5382
 
5383
    ComponentOrientation oldOrientation = componentOrientation;
5384
    componentOrientation = o;
5385
    firePropertyChange("componentOrientation", oldOrientation, o);
5386
  }
5387
 
5388
  /**
5389
   * Determines the text layout orientation used by this component.
5390
   *
5391
   * @return the component orientation (this can be <code>null</code>)
5392
   * @see #setComponentOrientation(ComponentOrientation)
5393
   */
5394
  public ComponentOrientation getComponentOrientation()
5395
  {
5396
    return componentOrientation;
5397
  }
5398
 
5399
  /**
5400
   * Sets the text layout orientation of this component. New components default
5401
   * to UNKNOWN (which behaves like LEFT_TO_RIGHT). This method affects the
5402
   * entire hierarchy, while
5403
   * {@link #setComponentOrientation(ComponentOrientation)} affects only the
5404
   * current component.
5405
   *
5406
   * @param o the new orientation
5407
   * @throws NullPointerException if o is null
5408
   * @see #getComponentOrientation()
5409
   * @since 1.4
5410
   */
5411
  public void applyComponentOrientation(ComponentOrientation o)
5412
  {
5413
    setComponentOrientation(o);
5414
  }
5415
 
5416
  /**
5417
   * Returns the accessibility framework context of this class. Component is
5418
   * not accessible, so the default implementation returns null. Subclasses
5419
   * must override this behavior, and return an appropriate subclass of
5420
   * {@link AccessibleAWTComponent}.
5421
   *
5422
   * @return the accessibility context
5423
   */
5424
  public AccessibleContext getAccessibleContext()
5425
  {
5426
    return null;
5427
  }
5428
 
5429
 
5430
  // Helper methods; some are package visible for use by subclasses.
5431
 
5432
  /**
5433
   * Subclasses should override this to return unique component names like
5434
   * "menuitem0".
5435
   *
5436
   * @return the generated name for this component
5437
   */
5438
  String generateName()
5439
  {
5440
    // Component is abstract.
5441
    return null;
5442
  }
5443
 
5444
  /**
5445
   * Sets the peer for this component.
5446
   *
5447
   * @param peer the new peer
5448
   */
5449
  final void setPeer(ComponentPeer peer)
5450
  {
5451
    this.peer = peer;
5452
  }
5453
 
5454
  /**
5455
   * Translate an AWT 1.1 event ({@link AWTEvent}) into an AWT 1.0
5456
   * event ({@link Event}).
5457
   *
5458
   * @param e an AWT 1.1 event to translate
5459
   *
5460
   * @return an AWT 1.0 event representing e
5461
   */
5462
  static Event translateEvent (AWTEvent e)
5463
  {
5464
    Object target = e.getSource ();
5465
    Event translated = null;
5466
 
5467
    if (e instanceof WindowEvent)
5468
      {
5469
        WindowEvent we = (WindowEvent) e;
5470
        int id = we.id;
5471
        int newId = 0;
5472
 
5473
        switch (id)
5474
          {
5475
          case WindowEvent.WINDOW_DEICONIFIED:
5476
            newId = Event.WINDOW_DEICONIFY;
5477
            break;
5478
          case WindowEvent.WINDOW_CLOSED:
5479
          case WindowEvent.WINDOW_CLOSING:
5480
            newId = Event.WINDOW_DESTROY;
5481
            break;
5482
          case WindowEvent.WINDOW_ICONIFIED:
5483
            newId = Event.WINDOW_ICONIFY;
5484
            break;
5485
          case WindowEvent.WINDOW_GAINED_FOCUS:
5486
            newId = Event.GOT_FOCUS;
5487
            break;
5488
          case WindowEvent.WINDOW_LOST_FOCUS:
5489
            newId = Event.LOST_FOCUS;
5490
            break;
5491
          default:
5492
            return null;
5493
          }
5494
 
5495
        translated = new Event(target, 0, newId, 0, 0, 0, 0);
5496
      }
5497
    else if (e instanceof InputEvent)
5498
      {
5499
        InputEvent ie = (InputEvent) e;
5500
        long when = ie.getWhen ();
5501
 
5502
        int oldID = 0;
5503
        int id = e.getID ();
5504
 
5505
        int oldMods = 0;
5506
        int mods = ie.getModifiersEx ();
5507
 
5508
        if ((mods & InputEvent.BUTTON2_DOWN_MASK) != 0)
5509
          oldMods |= Event.META_MASK;
5510
        else if ((mods & InputEvent.BUTTON3_DOWN_MASK) != 0)
5511
          oldMods |= Event.ALT_MASK;
5512
 
5513
        if ((mods & InputEvent.SHIFT_DOWN_MASK) != 0)
5514
          oldMods |= Event.SHIFT_MASK;
5515
 
5516
        if ((mods & InputEvent.CTRL_DOWN_MASK) != 0)
5517
          oldMods |= Event.CTRL_MASK;
5518
 
5519
        if ((mods & InputEvent.META_DOWN_MASK) != 0)
5520
          oldMods |= Event.META_MASK;
5521
 
5522
        if ((mods & InputEvent.ALT_DOWN_MASK) != 0)
5523
          oldMods |= Event.ALT_MASK;
5524
 
5525
        if (e instanceof MouseEvent && !ignoreOldMouseEvents())
5526
          {
5527
            if (id == MouseEvent.MOUSE_PRESSED)
5528
              oldID = Event.MOUSE_DOWN;
5529
            else if (id == MouseEvent.MOUSE_RELEASED)
5530
              oldID = Event.MOUSE_UP;
5531
            else if (id == MouseEvent.MOUSE_MOVED)
5532
              oldID = Event.MOUSE_MOVE;
5533
            else if (id == MouseEvent.MOUSE_DRAGGED)
5534
              oldID = Event.MOUSE_DRAG;
5535
            else if (id == MouseEvent.MOUSE_ENTERED)
5536
              oldID = Event.MOUSE_ENTER;
5537
            else if (id == MouseEvent.MOUSE_EXITED)
5538
              oldID = Event.MOUSE_EXIT;
5539
            else
5540
              // No analogous AWT 1.0 mouse event.
5541
              return null;
5542
 
5543
            MouseEvent me = (MouseEvent) e;
5544
 
5545
            translated = new Event (target, when, oldID,
5546
                                    me.getX (), me.getY (), 0, oldMods);
5547
          }
5548
        else if (e instanceof KeyEvent)
5549
          {
5550
            if (id == KeyEvent.KEY_PRESSED)
5551
              oldID = Event.KEY_PRESS;
5552
            else if (e.getID () == KeyEvent.KEY_RELEASED)
5553
              oldID = Event.KEY_RELEASE;
5554
            else
5555
              // No analogous AWT 1.0 key event.
5556
              return null;
5557
 
5558
            int oldKey = 0;
5559
            int newKey = ((KeyEvent) e).getKeyCode ();
5560
            switch (newKey)
5561
              {
5562
              case KeyEvent.VK_BACK_SPACE:
5563
                oldKey = Event.BACK_SPACE;
5564
                break;
5565
              case KeyEvent.VK_CAPS_LOCK:
5566
                oldKey = Event.CAPS_LOCK;
5567
                break;
5568
              case KeyEvent.VK_DELETE:
5569
                oldKey = Event.DELETE;
5570
                break;
5571
              case KeyEvent.VK_DOWN:
5572
              case KeyEvent.VK_KP_DOWN:
5573
                oldKey = Event.DOWN;
5574
                break;
5575
              case KeyEvent.VK_END:
5576
                oldKey = Event.END;
5577
                break;
5578
              case KeyEvent.VK_ENTER:
5579
                oldKey = Event.ENTER;
5580
                break;
5581
              case KeyEvent.VK_ESCAPE:
5582
                oldKey = Event.ESCAPE;
5583
                break;
5584
              case KeyEvent.VK_F1:
5585
                oldKey = Event.F1;
5586
                break;
5587
              case KeyEvent.VK_F10:
5588
                oldKey = Event.F10;
5589
                break;
5590
              case KeyEvent.VK_F11:
5591
                oldKey = Event.F11;
5592
                break;
5593
              case KeyEvent.VK_F12:
5594
                oldKey = Event.F12;
5595
                break;
5596
              case KeyEvent.VK_F2:
5597
                oldKey = Event.F2;
5598
                break;
5599
              case KeyEvent.VK_F3:
5600
                oldKey = Event.F3;
5601
                break;
5602
              case KeyEvent.VK_F4:
5603
                oldKey = Event.F4;
5604
                break;
5605
              case KeyEvent.VK_F5:
5606
                oldKey = Event.F5;
5607
                break;
5608
              case KeyEvent.VK_F6:
5609
                oldKey = Event.F6;
5610
                break;
5611
              case KeyEvent.VK_F7:
5612
                oldKey = Event.F7;
5613
                break;
5614
              case KeyEvent.VK_F8:
5615
                oldKey = Event.F8;
5616
                break;
5617
              case KeyEvent.VK_F9:
5618
                oldKey = Event.F9;
5619
                break;
5620
              case KeyEvent.VK_HOME:
5621
                oldKey = Event.HOME;
5622
                break;
5623
              case KeyEvent.VK_INSERT:
5624
                oldKey = Event.INSERT;
5625
                break;
5626
              case KeyEvent.VK_LEFT:
5627
              case KeyEvent.VK_KP_LEFT:
5628
                oldKey = Event.LEFT;
5629
                break;
5630
              case KeyEvent.VK_NUM_LOCK:
5631
                oldKey = Event.NUM_LOCK;
5632
                break;
5633
              case KeyEvent.VK_PAUSE:
5634
                oldKey = Event.PAUSE;
5635
                break;
5636
              case KeyEvent.VK_PAGE_DOWN:
5637
                oldKey = Event.PGDN;
5638
                break;
5639
              case KeyEvent.VK_PAGE_UP:
5640
                oldKey = Event.PGUP;
5641
                break;
5642
              case KeyEvent.VK_PRINTSCREEN:
5643
                oldKey = Event.PRINT_SCREEN;
5644
                break;
5645
              case KeyEvent.VK_RIGHT:
5646
              case KeyEvent.VK_KP_RIGHT:
5647
                oldKey = Event.RIGHT;
5648
                break;
5649
              case KeyEvent.VK_SCROLL_LOCK:
5650
                oldKey = Event.SCROLL_LOCK;
5651
                break;
5652
              case KeyEvent.VK_TAB:
5653
                oldKey = Event.TAB;
5654
                break;
5655
              case KeyEvent.VK_UP:
5656
              case KeyEvent.VK_KP_UP:
5657
                oldKey = Event.UP;
5658
                break;
5659
              default:
5660
                oldKey = ((KeyEvent) e).getKeyChar();
5661
              }
5662
 
5663
            translated = new Event (target, when, oldID,
5664
                                    0, 0, oldKey, oldMods);
5665
          }
5666
      }
5667
    else if (e instanceof AdjustmentEvent)
5668
      {
5669
        AdjustmentEvent ae = (AdjustmentEvent) e;
5670
        int type = ae.getAdjustmentType();
5671
        int oldType;
5672
        if (type == AdjustmentEvent.BLOCK_DECREMENT)
5673
          oldType = Event.SCROLL_PAGE_UP;
5674
        else if (type == AdjustmentEvent.BLOCK_INCREMENT)
5675
          oldType = Event.SCROLL_PAGE_DOWN;
5676
        else if (type == AdjustmentEvent.TRACK)
5677
          oldType = Event.SCROLL_ABSOLUTE;
5678
        else if (type == AdjustmentEvent.UNIT_DECREMENT)
5679
          oldType = Event.SCROLL_LINE_UP;
5680
        else if (type == AdjustmentEvent.UNIT_INCREMENT)
5681
          oldType = Event.SCROLL_LINE_DOWN;
5682
        else
5683
          oldType = type;
5684
        translated = new Event(target, oldType, new Integer(ae.getValue()));
5685
      }
5686
    else if (e instanceof ActionEvent)
5687
      translated = new Event (target, Event.ACTION_EVENT,
5688
                              ((ActionEvent) e).getActionCommand ());
5689
 
5690
    return translated;
5691
  }
5692
 
5693
  /**
5694
   * Implementation of dispatchEvent. Allows trusted package classes
5695
   * to dispatch additional events first.  This implementation first
5696
   * translates <code>e</code> to an AWT 1.0 event and sends the
5697
   * result to {@link #postEvent}.  If the AWT 1.0 event is not
5698
   * handled, and events of type <code>e</code> are enabled for this
5699
   * component, e is passed on to {@link #processEvent}.
5700
   *
5701
   * @param e the event to dispatch
5702
   */
5703
  void dispatchEventImpl(AWTEvent e)
5704
  {
5705
    // Update the component's knowledge about the size.
5706
    // Important: Please look at the big comment in ComponentReshapeEvent
5707
    // to learn why we did it this way. If you change this code, make
5708
    // sure that the peer->AWT bounds update still works.
5709
    // (for instance: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29448 )
5710
    if (e instanceof ComponentReshapeEvent)
5711
      {
5712
        ComponentReshapeEvent reshape = (ComponentReshapeEvent) e;
5713
        x = reshape.x;
5714
        y = reshape.y;
5715
        width = reshape.width;
5716
        height = reshape.height;
5717
        return;
5718
      }
5719
 
5720
    // Retarget focus events before dispatching it to the KeyboardFocusManager
5721
    // in order to handle lightweight components properly.
5722
    boolean dispatched = false;
5723
    if (! e.isFocusManagerEvent)
5724
      {
5725
        e = KeyboardFocusManager.retargetFocusEvent(e);
5726
        dispatched = KeyboardFocusManager.getCurrentKeyboardFocusManager()
5727
                                          .dispatchEvent(e);
5728
      }
5729
 
5730
    if (! dispatched)
5731
      {
5732
        // Give toolkit a chance to dispatch the event
5733
        // to globally registered listeners.
5734
        Toolkit.getDefaultToolkit().globalDispatchEvent(e);
5735
 
5736
        if (newEventsOnly)
5737
          {
5738
            if (eventTypeEnabled(e.id))
5739
              processEvent(e);
5740
          }
5741
        else
5742
          {
5743
            Event oldEvent = translateEvent(e);
5744
            if (oldEvent != null)
5745
              postEvent (oldEvent);
5746
          }
5747
        if (peer != null)
5748
          peer.handleEvent(e);
5749
      }
5750
  }
5751
 
5752
  /**
5753
   * Tells whether or not an event type is enabled.
5754
   */
5755
  boolean eventTypeEnabled (int type)
5756
  {
5757
    if (type > AWTEvent.RESERVED_ID_MAX)
5758
      return true;
5759
 
5760
    switch (type)
5761
      {
5762
      case HierarchyEvent.HIERARCHY_CHANGED:
5763
        return (hierarchyListener != null
5764
            || (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0);
5765
 
5766
      case HierarchyEvent.ANCESTOR_MOVED:
5767
      case HierarchyEvent.ANCESTOR_RESIZED:
5768
        return (hierarchyBoundsListener != null
5769
            || (eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0);
5770
 
5771
      case ComponentEvent.COMPONENT_HIDDEN:
5772
      case ComponentEvent.COMPONENT_MOVED:
5773
      case ComponentEvent.COMPONENT_RESIZED:
5774
      case ComponentEvent.COMPONENT_SHOWN:
5775
        return (componentListener != null
5776
                || (eventMask & AWTEvent.COMPONENT_EVENT_MASK) != 0);
5777
 
5778
      case KeyEvent.KEY_PRESSED:
5779
      case KeyEvent.KEY_RELEASED:
5780
      case KeyEvent.KEY_TYPED:
5781
        return (keyListener != null
5782
                || (eventMask & AWTEvent.KEY_EVENT_MASK) != 0);
5783
 
5784
      case MouseEvent.MOUSE_CLICKED:
5785
      case MouseEvent.MOUSE_ENTERED:
5786
      case MouseEvent.MOUSE_EXITED:
5787
      case MouseEvent.MOUSE_PRESSED:
5788
      case MouseEvent.MOUSE_RELEASED:
5789
        return (mouseListener != null
5790
                || (eventMask & AWTEvent.MOUSE_EVENT_MASK) != 0);
5791
      case MouseEvent.MOUSE_MOVED:
5792
      case MouseEvent.MOUSE_DRAGGED:
5793
        return (mouseMotionListener != null
5794
                || (eventMask & AWTEvent.MOUSE_MOTION_EVENT_MASK) != 0);
5795
      case MouseEvent.MOUSE_WHEEL:
5796
        return (mouseWheelListener != null
5797
                || (eventMask & AWTEvent.MOUSE_WHEEL_EVENT_MASK) != 0);
5798
 
5799
      case FocusEvent.FOCUS_GAINED:
5800
      case FocusEvent.FOCUS_LOST:
5801
        return (focusListener != null
5802
                || (eventMask & AWTEvent.FOCUS_EVENT_MASK) != 0);
5803
 
5804
      case InputMethodEvent.INPUT_METHOD_TEXT_CHANGED:
5805
      case InputMethodEvent.CARET_POSITION_CHANGED:
5806
        return (inputMethodListener != null
5807
                || (eventMask & AWTEvent.INPUT_METHOD_EVENT_MASK) != 0);
5808
 
5809
      case PaintEvent.PAINT:
5810
      case PaintEvent.UPDATE:
5811
        return (eventMask & AWTEvent.PAINT_EVENT_MASK) != 0;
5812
 
5813
      default:
5814
        return false;
5815
      }
5816
  }
5817
 
5818
  /**
5819
   * Returns <code>true</code> when this component and all of its ancestors
5820
   * are visible, <code>false</code> otherwise.
5821
   *
5822
   * @return <code>true</code> when this component and all of its ancestors
5823
   *         are visible, <code>false</code> otherwise
5824
   */
5825
  boolean isHierarchyVisible()
5826
  {
5827
    boolean visible = isVisible();
5828
    Component comp = parent;
5829
    while (comp != null && visible)
5830
      {
5831
        comp = comp.parent;
5832
        if (comp != null)
5833
          visible = visible && comp.isVisible();
5834
      }
5835
    return visible;
5836
  }
5837
 
5838
  /**
5839
   * Returns the mouse pointer position relative to this Component's
5840
   * top-left corner.
5841
   *
5842
   * @return relative mouse pointer position
5843
   *
5844
   * @throws HeadlessException if in a headless environment
5845
   */
5846
  public Point getMousePosition() throws HeadlessException
5847
  {
5848
    return getMousePositionHelper(true);
5849
  }
5850
 
5851
  Point getMousePositionHelper(boolean allowChildren) throws HeadlessException
5852
  {
5853
    if (GraphicsEnvironment.isHeadless())
5854
      throw new HeadlessException("can't get mouse position"
5855
                                  + " in headless environment");
5856
    if (!isShowing())
5857
      return null;
5858
 
5859
    Component parent = this;
5860
    int windowRelativeXOffset = 0;
5861
    int windowRelativeYOffset = 0;
5862
    while (parent != null && !(parent instanceof Window))
5863
      {
5864
        windowRelativeXOffset += parent.getX();
5865
        windowRelativeYOffset += parent.getY();
5866
        parent = parent.getParent();
5867
      }
5868
    if (parent == null)
5869
      return null;
5870
 
5871
    Window window = (Window) parent;
5872
    if (!Toolkit.getDefaultToolkit()
5873
        .getMouseInfoPeer().isWindowUnderMouse(window))
5874
      return null;
5875
 
5876
    PointerInfo info = MouseInfo.getPointerInfo();
5877
    Point mouseLocation = info.getLocation();
5878
    Point windowLocation = window.getLocationOnScreen();
5879
 
5880
    int x = mouseLocation.x - windowLocation.x;
5881
    int y = mouseLocation.y - windowLocation.y;
5882
 
5883
    if (!mouseOverComponent(window.getComponentAt(x, y), allowChildren))
5884
      return null;
5885
 
5886
    return new Point(x - windowRelativeXOffset, y - windowRelativeYOffset);
5887
  }
5888
 
5889
  boolean mouseOverComponent(Component component, boolean allowChildren)
5890
  {
5891
    return component == this;
5892
  }
5893
 
5894
  /**
5895
   * This method is used to implement transferFocus(). CHILD is the child
5896
   * making the request. This is overridden by Container; when called for an
5897
   * ordinary component there is no child and so we always return null.
5898
   *
5899
   * FIXME: is this still needed, in light of focus traversal policies?
5900
   *
5901
   * @param child the component making the request
5902
   * @return the next component to focus on
5903
   */
5904
  Component findNextFocusComponent(Component child)
5905
  {
5906
    return null;
5907
  }
5908
 
5909
  /**
5910
   * Deserializes this component. This regenerates all serializable listeners
5911
   * which were registered originally.
5912
   *
5913
   * @param s the stream to read from
5914
   * @throws ClassNotFoundException if deserialization fails
5915
   * @throws IOException if the stream fails
5916
   */
5917
  private void readObject(ObjectInputStream s)
5918
    throws ClassNotFoundException, IOException
5919
  {
5920
    s.defaultReadObject();
5921
    String key = (String) s.readObject();
5922
    while (key != null)
5923
      {
5924
        Object listener = s.readObject();
5925
        if ("componentL".equals(key))
5926
          addComponentListener((ComponentListener) listener);
5927
        else if ("focusL".equals(key))
5928
          addFocusListener((FocusListener) listener);
5929
        else if ("keyL".equals(key))
5930
          addKeyListener((KeyListener) listener);
5931
        else if ("mouseL".equals(key))
5932
          addMouseListener((MouseListener) listener);
5933
        else if ("mouseMotionL".equals(key))
5934
          addMouseMotionListener((MouseMotionListener) listener);
5935
        else if ("inputMethodL".equals(key))
5936
          addInputMethodListener((InputMethodListener) listener);
5937
        else if ("hierarchyL".equals(key))
5938
          addHierarchyListener((HierarchyListener) listener);
5939
        else if ("hierarchyBoundsL".equals(key))
5940
          addHierarchyBoundsListener((HierarchyBoundsListener) listener);
5941
        else if ("mouseWheelL".equals(key))
5942
          addMouseWheelListener((MouseWheelListener) listener);
5943
        key = (String) s.readObject();
5944
      }
5945
  }
5946
 
5947
  /**
5948
   * Serializes this component. This ignores all listeners which do not
5949
   * implement Serializable, but includes those that do.
5950
   *
5951
   * @param s the stream to write to
5952
   * @throws IOException if the stream fails
5953
   */
5954
  private void writeObject(ObjectOutputStream s) throws IOException
5955
  {
5956
    s.defaultWriteObject();
5957
    AWTEventMulticaster.save(s, "componentL", componentListener);
5958
    AWTEventMulticaster.save(s, "focusL", focusListener);
5959
    AWTEventMulticaster.save(s, "keyL", keyListener);
5960
    AWTEventMulticaster.save(s, "mouseL", mouseListener);
5961
    AWTEventMulticaster.save(s, "mouseMotionL", mouseMotionListener);
5962
    AWTEventMulticaster.save(s, "inputMethodL", inputMethodListener);
5963
    AWTEventMulticaster.save(s, "hierarchyL", hierarchyListener);
5964
    AWTEventMulticaster.save(s, "hierarchyBoundsL", hierarchyBoundsListener);
5965
    AWTEventMulticaster.save(s, "mouseWheelL", mouseWheelListener);
5966
    s.writeObject(null);
5967
  }
5968
 
5969
 
5970
  // Nested classes.
5971
 
5972
  /**
5973
   * This class fixes the bounds for a Heavyweight component that
5974
   * is placed inside a Lightweight container. When the lightweight is
5975
   * moved or resized, setBounds for the lightweight peer does nothing.
5976
   * Therefore, it was never moved on the screen. This class is
5977
   * attached to the lightweight, and it adjusts the position and size
5978
   * of the peer when notified.
5979
   * This is the same for show and hide.
5980
   */
5981
  class HeavyweightInLightweightListener
5982
      implements ComponentListener
5983
  {
5984
 
5985
    /**
5986
     * Constructor. Adds component listener to lightweight parent.
5987
     *
5988
     * @param parent - the lightweight container.
5989
     */
5990
    public HeavyweightInLightweightListener(Container parent)
5991
    {
5992
      parent.addComponentListener(this);
5993
    }
5994
 
5995
    /**
5996
     * This method is called when the component is resized.
5997
     *
5998
     * @param event the <code>ComponentEvent</code> indicating the resize
5999
     */
6000
    public void componentResized(ComponentEvent event)
6001
    {
6002
      // Nothing to do here, componentMoved will be called.
6003
    }
6004
 
6005
    /**
6006
     * This method is called when the component is moved.
6007
     *
6008
     * @param event the <code>ComponentEvent</code> indicating the move
6009
     */
6010
    public void componentMoved(ComponentEvent event)
6011
    {
6012
      if (peer != null)
6013
        peer.setBounds(x, y, width, height);
6014
    }
6015
 
6016
    /**
6017
     * This method is called when the component is made visible.
6018
     *
6019
     * @param event the <code>ComponentEvent</code> indicating the visibility
6020
     */
6021
    public void componentShown(ComponentEvent event)
6022
    {
6023
      if (isShowing())
6024
        peer.show();
6025
    }
6026
 
6027
    /**
6028
     * This method is called when the component is hidden.
6029
     *
6030
     * @param event the <code>ComponentEvent</code> indicating the visibility
6031
     */
6032
    public void componentHidden(ComponentEvent event)
6033
    {
6034
      if (isShowing())
6035
        peer.hide();
6036
    }
6037
  }
6038
 
6039
  /**
6040
   * This class provides accessibility support for subclasses of container.
6041
   *
6042
   * @author Eric Blake (ebb9@email.byu.edu)
6043
   * @since 1.3
6044
   * @status updated to 1.4
6045
   */
6046
  protected abstract class AccessibleAWTComponent extends AccessibleContext
6047
    implements Serializable, AccessibleComponent
6048
  {
6049
    /**
6050
     * Compatible with JDK 1.3+.
6051
     */
6052
    private static final long serialVersionUID = 642321655757800191L;
6053
 
6054
    /**
6055
     * Converts show/hide events to PropertyChange events, and is registered
6056
     * as a component listener on this component.
6057
     *
6058
     * @serial the component handler
6059
     */
6060
    protected ComponentListener accessibleAWTComponentHandler
6061
      = new AccessibleAWTComponentHandler();
6062
 
6063
    /**
6064
     * Converts focus events to PropertyChange events, and is registered
6065
     * as a focus listener on this component.
6066
     *
6067
     * @serial the focus handler
6068
     */
6069
    protected FocusListener accessibleAWTFocusHandler
6070
      = new AccessibleAWTFocusHandler();
6071
 
6072
    /**
6073
     * The default constructor.
6074
     */
6075
    protected AccessibleAWTComponent()
6076
    {
6077
      Component.this.addComponentListener(accessibleAWTComponentHandler);
6078
      Component.this.addFocusListener(accessibleAWTFocusHandler);
6079
    }
6080
 
6081
    /**
6082
     * Adds a global property change listener to the accessible component.
6083
     *
6084
     * @param l the listener to add
6085
     * @see #ACCESSIBLE_NAME_PROPERTY
6086
     * @see #ACCESSIBLE_DESCRIPTION_PROPERTY
6087
     * @see #ACCESSIBLE_STATE_PROPERTY
6088
     * @see #ACCESSIBLE_VALUE_PROPERTY
6089
     * @see #ACCESSIBLE_SELECTION_PROPERTY
6090
     * @see #ACCESSIBLE_TEXT_PROPERTY
6091
     * @see #ACCESSIBLE_VISIBLE_DATA_PROPERTY
6092
     */
6093
    public void addPropertyChangeListener(PropertyChangeListener l)
6094
    {
6095
      Component.this.addPropertyChangeListener(l);
6096
      super.addPropertyChangeListener(l);
6097
    }
6098
 
6099
    /**
6100
     * Removes a global property change listener from this accessible
6101
     * component.
6102
     *
6103
     * @param l the listener to remove
6104
     */
6105
    public void removePropertyChangeListener(PropertyChangeListener l)
6106
    {
6107
      Component.this.removePropertyChangeListener(l);
6108
      super.removePropertyChangeListener(l);
6109
    }
6110
 
6111
    /**
6112
     * Returns the accessible name of this component. It is almost always
6113
     * wrong to return getName(), since it is not localized. In fact, for
6114
     * things like buttons, this should be the text of the button, not the
6115
     * name of the object. The tooltip text might also be appropriate.
6116
     *
6117
     * @return the name
6118
     * @see #setAccessibleName(String)
6119
     */
6120
    public String getAccessibleName()
6121
    {
6122
      return accessibleName;
6123
    }
6124
 
6125
    /**
6126
     * Returns a brief description of this accessible context. This should
6127
     * be localized.
6128
     *
6129
     * @return a description of this component
6130
     * @see #setAccessibleDescription(String)
6131
     */
6132
    public String getAccessibleDescription()
6133
    {
6134
      return accessibleDescription;
6135
    }
6136
 
6137
    /**
6138
     * Returns the role of this component.
6139
     *
6140
     * @return the accessible role
6141
     */
6142
    public AccessibleRole getAccessibleRole()
6143
    {
6144
      return AccessibleRole.AWT_COMPONENT;
6145
    }
6146
 
6147
    /**
6148
     * Returns a state set describing this component's state.
6149
     *
6150
     * @return a new state set
6151
     * @see AccessibleState
6152
     */
6153
    public AccessibleStateSet getAccessibleStateSet()
6154
    {
6155
      AccessibleStateSet s = new AccessibleStateSet();
6156
      if (Component.this.isEnabled())
6157
        s.add(AccessibleState.ENABLED);
6158
      if (isFocusable())
6159
        s.add(AccessibleState.FOCUSABLE);
6160
      if (isFocusOwner())
6161
        s.add(AccessibleState.FOCUSED);
6162
      // Note: While the java.awt.Component has an 'opaque' property, it
6163
      // seems that it is not added to the accessible state set here, even
6164
      // if this property is true. However, it is handled for
6165
      // javax.swing.JComponent, so we add it there.
6166
      if (Component.this.isShowing())
6167
        s.add(AccessibleState.SHOWING);
6168
      if (Component.this.isVisible())
6169
        s.add(AccessibleState.VISIBLE);
6170
      return s;
6171
    }
6172
 
6173
    /**
6174
     * Returns the parent of this component, if it is accessible.
6175
     *
6176
     * @return the accessible parent
6177
     */
6178
    public Accessible getAccessibleParent()
6179
    {
6180
      if (accessibleParent == null)
6181
        {
6182
          Container parent = getParent();
6183
          accessibleParent = parent instanceof Accessible
6184
            ? (Accessible) parent : null;
6185
        }
6186
      return accessibleParent;
6187
    }
6188
 
6189
    /**
6190
     * Returns the index of this component in its accessible parent.
6191
     *
6192
     * @return the index, or -1 if the parent is not accessible
6193
     * @see #getAccessibleParent()
6194
     */
6195
    public int getAccessibleIndexInParent()
6196
    {
6197
      if (getAccessibleParent() == null)
6198
        return -1;
6199
      AccessibleContext context
6200
        = ((Component) accessibleParent).getAccessibleContext();
6201
      if (context == null)
6202
        return -1;
6203
      for (int i = context.getAccessibleChildrenCount(); --i >= 0; )
6204
        if (context.getAccessibleChild(i) == Component.this)
6205
          return i;
6206
      return -1;
6207
    }
6208
 
6209
    /**
6210
     * Returns the number of children of this component which implement
6211
     * Accessible. Subclasses must override this if they can have children.
6212
     *
6213
     * @return the number of accessible children, default 0
6214
     */
6215
    public int getAccessibleChildrenCount()
6216
    {
6217
      return 0;
6218
    }
6219
 
6220
    /**
6221
     * Returns the ith accessible child. Subclasses must override this if
6222
     * they can have children.
6223
     *
6224
     * @return the ith accessible child, or null
6225
     * @see #getAccessibleChildrenCount()
6226
     */
6227
    public Accessible getAccessibleChild(int i)
6228
    {
6229
      return null;
6230
    }
6231
 
6232
    /**
6233
     * Returns the locale of this component.
6234
     *
6235
     * @return the locale
6236
     * @throws IllegalComponentStateException if the locale is unknown
6237
     */
6238
    public Locale getLocale()
6239
    {
6240
      return Component.this.getLocale();
6241
    }
6242
 
6243
    /**
6244
     * Returns this, since it is an accessible component.
6245
     *
6246
     * @return the accessible component
6247
     */
6248
    public AccessibleComponent getAccessibleComponent()
6249
    {
6250
      return this;
6251
    }
6252
 
6253
    /**
6254
     * Gets the background color.
6255
     *
6256
     * @return the background color
6257
     * @see #setBackground(Color)
6258
     */
6259
    public Color getBackground()
6260
    {
6261
      return Component.this.getBackground();
6262
    }
6263
 
6264
    /**
6265
     * Sets the background color.
6266
     *
6267
     * @param c the background color
6268
     * @see #getBackground()
6269
     * @see #isOpaque()
6270
     */
6271
    public void setBackground(Color c)
6272
    {
6273
      Component.this.setBackground(c);
6274
    }
6275
 
6276
    /**
6277
     * Gets the foreground color.
6278
     *
6279
     * @return the foreground color
6280
     * @see #setForeground(Color)
6281
     */
6282
    public Color getForeground()
6283
    {
6284
      return Component.this.getForeground();
6285
    }
6286
 
6287
    /**
6288
     * Sets the foreground color.
6289
     *
6290
     * @param c the foreground color
6291
     * @see #getForeground()
6292
     */
6293
    public void setForeground(Color c)
6294
    {
6295
      Component.this.setForeground(c);
6296
    }
6297
 
6298
    /**
6299
     * Gets the cursor.
6300
     *
6301
     * @return the cursor
6302
     * @see #setCursor(Cursor)
6303
     */
6304
    public Cursor getCursor()
6305
    {
6306
      return Component.this.getCursor();
6307
    }
6308
 
6309
    /**
6310
     * Sets the cursor.
6311
     *
6312
     * @param cursor the cursor
6313
     * @see #getCursor()
6314
     */
6315
    public void setCursor(Cursor cursor)
6316
    {
6317
      Component.this.setCursor(cursor);
6318
    }
6319
 
6320
    /**
6321
     * Gets the font.
6322
     *
6323
     * @return the font
6324
     * @see #setFont(Font)
6325
     */
6326
    public Font getFont()
6327
    {
6328
      return Component.this.getFont();
6329
    }
6330
 
6331
    /**
6332
     * Sets the font.
6333
     *
6334
     * @param f the font
6335
     * @see #getFont()
6336
     */
6337
    public void setFont(Font f)
6338
    {
6339
      Component.this.setFont(f);
6340
    }
6341
 
6342
    /**
6343
     * Gets the font metrics for a font.
6344
     *
6345
     * @param f the font to look up
6346
     * @return its metrics
6347
     * @throws NullPointerException if f is null
6348
     * @see #getFont()
6349
     */
6350
    public FontMetrics getFontMetrics(Font f)
6351
    {
6352
      return Component.this.getFontMetrics(f);
6353
    }
6354
 
6355
    /**
6356
     * Tests if the component is enabled.
6357
     *
6358
     * @return true if the component is enabled
6359
     * @see #setEnabled(boolean)
6360
     * @see #getAccessibleStateSet()
6361
     * @see AccessibleState#ENABLED
6362
     */
6363
    public boolean isEnabled()
6364
    {
6365
      return Component.this.isEnabled();
6366
    }
6367
 
6368
    /**
6369
     * Set whether the component is enabled.
6370
     *
6371
     * @param b the new enabled status
6372
     * @see #isEnabled()
6373
     */
6374
    public void setEnabled(boolean b)
6375
    {
6376
      Component.this.setEnabled(b);
6377
    }
6378
 
6379
    /**
6380
     * Test whether the component is visible (not necesarily showing).
6381
     *
6382
     * @return true if it is visible
6383
     * @see #setVisible(boolean)
6384
     * @see #getAccessibleStateSet()
6385
     * @see AccessibleState#VISIBLE
6386
     */
6387
    public boolean isVisible()
6388
    {
6389
      return Component.this.isVisible();
6390
    }
6391
 
6392
    /**
6393
     * Sets the visibility of this component.
6394
     *
6395
     * @param b the desired visibility
6396
     * @see #isVisible()
6397
     */
6398
    public void setVisible(boolean b)
6399
    {
6400
      Component.this.setVisible(b);
6401
    }
6402
 
6403
    /**
6404
     * Tests if the component is showing.
6405
     *
6406
     * @return true if this is showing
6407
     */
6408
    public boolean isShowing()
6409
    {
6410
      return Component.this.isShowing();
6411
    }
6412
 
6413
    /**
6414
     * Tests if the point is contained in this component.
6415
     *
6416
     * @param p the point to check
6417
     * @return true if it is contained
6418
     * @throws NullPointerException if p is null
6419
     */
6420
    public boolean contains(Point p)
6421
    {
6422
      return Component.this.contains(p.x, p.y);
6423
    }
6424
 
6425
    /**
6426
     * Returns the location of this object on the screen, or null if it is
6427
     * not showing.
6428
     *
6429
     * @return the location relative to screen coordinates, if showing
6430
     * @see #getBounds()
6431
     * @see #getLocation()
6432
     */
6433
    public Point getLocationOnScreen()
6434
    {
6435
      return Component.this.isShowing() ? Component.this.getLocationOnScreen()
6436
        : null;
6437
    }
6438
 
6439
    /**
6440
     * Returns the location of this object relative to its parent's coordinate
6441
     * system, or null if it is not showing.
6442
     *
6443
     * @return the location
6444
     * @see #getBounds()
6445
     * @see #getLocationOnScreen()
6446
     */
6447
    public Point getLocation()
6448
    {
6449
      return Component.this.getLocation();
6450
    }
6451
 
6452
    /**
6453
     * Sets the location of this relative to its parent's coordinate system.
6454
     *
6455
     * @param p the location
6456
     * @throws NullPointerException if p is null
6457
     * @see #getLocation()
6458
     */
6459
    public void setLocation(Point p)
6460
    {
6461
      Component.this.setLocation(p.x, p.y);
6462
    }
6463
 
6464
    /**
6465
     * Gets the bounds of this component, or null if it is not on screen.
6466
     *
6467
     * @return the bounds
6468
     * @see #contains(Point)
6469
     * @see #setBounds(Rectangle)
6470
     */
6471
    public Rectangle getBounds()
6472
    {
6473
      return Component.this.getBounds();
6474
    }
6475
 
6476
    /**
6477
     * Sets the bounds of this component.
6478
     *
6479
     * @param r the bounds
6480
     * @throws NullPointerException if r is null
6481
     * @see #getBounds()
6482
     */
6483
    public void setBounds(Rectangle r)
6484
    {
6485
      Component.this.setBounds(r.x, r.y, r.width, r.height);
6486
    }
6487
 
6488
    /**
6489
     * Gets the size of this component, or null if it is not showing.
6490
     *
6491
     * @return the size
6492
     * @see #setSize(Dimension)
6493
     */
6494
    public Dimension getSize()
6495
    {
6496
      return Component.this.getSize();
6497
    }
6498
 
6499
    /**
6500
     * Sets the size of this component.
6501
     *
6502
     * @param d the size
6503
     * @throws NullPointerException if d is null
6504
     * @see #getSize()
6505
     */
6506
    public void setSize(Dimension d)
6507
    {
6508
      Component.this.setSize(d.width, d.height);
6509
    }
6510
 
6511
    /**
6512
     * Returns the Accessible child at a point relative to the coordinate
6513
     * system of this component, if one exists, or null. Since components
6514
     * have no children, subclasses must override this to get anything besides
6515
     * null.
6516
     *
6517
     * @param p the point to check
6518
     * @return the accessible child at that point
6519
     * @throws NullPointerException if p is null
6520
     */
6521
    public Accessible getAccessibleAt(Point p)
6522
    {
6523
      return null;
6524
    }
6525
 
6526
    /**
6527
     * Tests whether this component can accept focus.
6528
     *
6529
     * @return true if this is focus traversable
6530
     * @see #getAccessibleStateSet ()
6531
     * @see AccessibleState#FOCUSABLE
6532
     * @see AccessibleState#FOCUSED
6533
     */
6534
    public boolean isFocusTraversable ()
6535
    {
6536
      return Component.this.isFocusTraversable ();
6537
    }
6538
 
6539
    /**
6540
     * Requests focus for this component.
6541
     *
6542
     * @see #isFocusTraversable ()
6543
     */
6544
    public void requestFocus ()
6545
    {
6546
      Component.this.requestFocus ();
6547
    }
6548
 
6549
    /**
6550
     * Adds a focus listener.
6551
     *
6552
     * @param l the listener to add
6553
     */
6554
    public void addFocusListener(FocusListener l)
6555
    {
6556
      Component.this.addFocusListener(l);
6557
    }
6558
 
6559
    /**
6560
     * Removes a focus listener.
6561
     *
6562
     * @param l the listener to remove
6563
     */
6564
    public void removeFocusListener(FocusListener l)
6565
    {
6566
      Component.this.removeFocusListener(l);
6567
    }
6568
 
6569
    /**
6570
     * Converts component changes into property changes.
6571
     *
6572
     * @author Eric Blake (ebb9@email.byu.edu)
6573
     * @since 1.3
6574
     * @status updated to 1.4
6575
     */
6576
    protected class AccessibleAWTComponentHandler implements ComponentListener
6577
    {
6578
      /**
6579
       * Default constructor.
6580
       */
6581
      protected AccessibleAWTComponentHandler()
6582
      {
6583
        // Nothing to do here.
6584
      }
6585
 
6586
      /**
6587
       * Convert a component hidden to a property change.
6588
       *
6589
       * @param e the event to convert
6590
       */
6591
      public void componentHidden(ComponentEvent e)
6592
      {
6593
        AccessibleAWTComponent.this.firePropertyChange
6594
          (ACCESSIBLE_STATE_PROPERTY, AccessibleState.VISIBLE, null);
6595
      }
6596
 
6597
      /**
6598
       * Convert a component shown to a property change.
6599
       *
6600
       * @param e the event to convert
6601
       */
6602
      public void componentShown(ComponentEvent e)
6603
      {
6604
        AccessibleAWTComponent.this.firePropertyChange
6605
          (ACCESSIBLE_STATE_PROPERTY, null, AccessibleState.VISIBLE);
6606
      }
6607
 
6608
      /**
6609
       * Moving a component does not affect properties.
6610
       *
6611
       * @param e ignored
6612
       */
6613
      public void componentMoved(ComponentEvent e)
6614
      {
6615
        // Nothing to do here.
6616
      }
6617
 
6618
      /**
6619
       * Resizing a component does not affect properties.
6620
       *
6621
       * @param e ignored
6622
       */
6623
      public void componentResized(ComponentEvent e)
6624
      {
6625
        // Nothing to do here.
6626
      }
6627
    } // class AccessibleAWTComponentHandler
6628
 
6629
    /**
6630
     * Converts focus changes into property changes.
6631
     *
6632
     * @author Eric Blake (ebb9@email.byu.edu)
6633
     * @since 1.3
6634
     * @status updated to 1.4
6635
     */
6636
    protected class AccessibleAWTFocusHandler implements FocusListener
6637
    {
6638
      /**
6639
       * Default constructor.
6640
       */
6641
      protected AccessibleAWTFocusHandler()
6642
      {
6643
        // Nothing to do here.
6644
      }
6645
 
6646
      /**
6647
       * Convert a focus gained to a property change.
6648
       *
6649
       * @param e the event to convert
6650
       */
6651
      public void focusGained(FocusEvent e)
6652
      {
6653
        AccessibleAWTComponent.this.firePropertyChange
6654
          (ACCESSIBLE_STATE_PROPERTY, null, AccessibleState.FOCUSED);
6655
      }
6656
 
6657
      /**
6658
       * Convert a focus lost to a property change.
6659
       *
6660
       * @param e the event to convert
6661
       */
6662
      public void focusLost(FocusEvent e)
6663
      {
6664
        AccessibleAWTComponent.this.firePropertyChange
6665
          (ACCESSIBLE_STATE_PROPERTY, AccessibleState.FOCUSED, null);
6666
      }
6667
    } // class AccessibleAWTComponentHandler
6668
  } // class AccessibleAWTComponent
6669
 
6670
  /**
6671
   * This class provides support for blitting offscreen surfaces to a
6672
   * component.
6673
   *
6674
   * @see BufferStrategy
6675
   *
6676
   * @since 1.4
6677
   */
6678
  protected class BltBufferStrategy extends BufferStrategy
6679
  {
6680
    /**
6681
     * The capabilities of the image buffer.
6682
     */
6683
    protected BufferCapabilities caps;
6684
 
6685
    /**
6686
     * The back buffers used in this strategy.
6687
     */
6688
    protected VolatileImage[] backBuffers;
6689
 
6690
    /**
6691
     * Whether or not the image buffer resources are allocated and
6692
     * ready to be drawn into.
6693
     */
6694
    protected boolean validatedContents;
6695
 
6696
    /**
6697
     * The width of the back buffers.
6698
     */
6699
    protected int width;
6700
 
6701
    /**
6702
     * The height of the back buffers.
6703
     */
6704
    protected int height;
6705
 
6706
    /**
6707
     * The front buffer.
6708
     */
6709
    private VolatileImage frontBuffer;
6710
 
6711
    /**
6712
     * Creates a blitting buffer strategy.
6713
     *
6714
     * @param numBuffers the number of buffers, including the front
6715
     * buffer
6716
     * @param caps the capabilities of this strategy
6717
     */
6718
    protected BltBufferStrategy(int numBuffers, BufferCapabilities caps)
6719
    {
6720
      this.caps = caps;
6721
      createBackBuffers(numBuffers - 1);
6722
      width = getWidth();
6723
      height = getHeight();
6724
    }
6725
 
6726
    /**
6727
     * Initializes the backBuffers field with an array of numBuffers
6728
     * VolatileImages.
6729
     *
6730
     * @param numBuffers the number of backbuffers to create
6731
     */
6732
    protected void createBackBuffers(int numBuffers)
6733
    {
6734
      GraphicsConfiguration c =
6735
        GraphicsEnvironment.getLocalGraphicsEnvironment()
6736
        .getDefaultScreenDevice().getDefaultConfiguration();
6737
 
6738
      backBuffers = new VolatileImage[numBuffers];
6739
 
6740
      for (int i = 0; i < numBuffers; i++)
6741
        backBuffers[i] = c.createCompatibleVolatileImage(width, height);
6742
    }
6743
 
6744
    /**
6745
     * Retrieves the capabilities of this buffer strategy.
6746
     *
6747
     * @return the capabilities of this buffer strategy
6748
     */
6749
    public BufferCapabilities getCapabilities()
6750
    {
6751
      return caps;
6752
    }
6753
 
6754
    /**
6755
     * Retrieves a graphics object that can be used to draw into this
6756
     * strategy's image buffer.
6757
     *
6758
     * @return a graphics object
6759
     */
6760
    public Graphics getDrawGraphics()
6761
    {
6762
      // Return the backmost buffer's graphics.
6763
      return backBuffers[0].getGraphics();
6764
    }
6765
 
6766
    /**
6767
     * Bring the contents of the back buffer to the front buffer.
6768
     */
6769
    public void show()
6770
    {
6771
      GraphicsConfiguration c =
6772
        GraphicsEnvironment.getLocalGraphicsEnvironment()
6773
        .getDefaultScreenDevice().getDefaultConfiguration();
6774
 
6775
      // draw the front buffer.
6776
      getGraphics().drawImage(backBuffers[backBuffers.length - 1],
6777
                              width, height, null);
6778
 
6779
      BufferCapabilities.FlipContents f = getCapabilities().getFlipContents();
6780
 
6781
      // blit the back buffers.
6782
      for (int i = backBuffers.length - 1; i > 0 ; i--)
6783
        backBuffers[i] = backBuffers[i - 1];
6784
 
6785
      // create new backmost buffer.
6786
      if (f == BufferCapabilities.FlipContents.UNDEFINED)
6787
        backBuffers[0] = c.createCompatibleVolatileImage(width, height);
6788
 
6789
      // create new backmost buffer and clear it to the background
6790
      // color.
6791
      if (f == BufferCapabilities.FlipContents.BACKGROUND)
6792
        {
6793
          backBuffers[0] = c.createCompatibleVolatileImage(width, height);
6794
          backBuffers[0].getGraphics().clearRect(0, 0, width, height);
6795
        }
6796
 
6797
      // FIXME: set the backmost buffer to the prior contents of the
6798
      // front buffer.  How do we retrieve the contents of the front
6799
      // buffer?
6800
      //
6801
      //      if (f == BufferCapabilities.FlipContents.PRIOR)
6802
 
6803
      // set the backmost buffer to a copy of the new front buffer.
6804
      if (f == BufferCapabilities.FlipContents.COPIED)
6805
        backBuffers[0] = backBuffers[backBuffers.length - 1];
6806
    }
6807
 
6808
    /**
6809
     * Re-create the image buffer resources if they've been lost.
6810
     */
6811
    protected void revalidate()
6812
    {
6813
      GraphicsConfiguration c =
6814
        GraphicsEnvironment.getLocalGraphicsEnvironment()
6815
        .getDefaultScreenDevice().getDefaultConfiguration();
6816
 
6817
      for (int i = 0; i < backBuffers.length; i++)
6818
        {
6819
          int result = backBuffers[i].validate(c);
6820
          if (result == VolatileImage.IMAGE_INCOMPATIBLE)
6821
            backBuffers[i] = c.createCompatibleVolatileImage(width, height);
6822
        }
6823
      validatedContents = true;
6824
    }
6825
 
6826
    /**
6827
     * Returns whether or not the image buffer resources have been
6828
     * lost.
6829
     *
6830
     * @return true if the resources have been lost, false otherwise
6831
     */
6832
    public boolean contentsLost()
6833
    {
6834
      for (int i = 0; i < backBuffers.length; i++)
6835
        {
6836
          if (backBuffers[i].contentsLost())
6837
            {
6838
              validatedContents = false;
6839
              return true;
6840
            }
6841
        }
6842
      // we know that the buffer resources are valid now because we
6843
      // just checked them
6844
      validatedContents = true;
6845
      return false;
6846
    }
6847
 
6848
    /**
6849
     * Returns whether or not the image buffer resources have been
6850
     * restored.
6851
     *
6852
     * @return true if the resources have been restored, false
6853
     * otherwise
6854
     */
6855
    public boolean contentsRestored()
6856
    {
6857
      GraphicsConfiguration c =
6858
        GraphicsEnvironment.getLocalGraphicsEnvironment()
6859
        .getDefaultScreenDevice().getDefaultConfiguration();
6860
 
6861
      boolean imageRestored = false;
6862
 
6863
      for (int i = 0; i < backBuffers.length; i++)
6864
        {
6865
          int result = backBuffers[i].validate(c);
6866
          if (result == VolatileImage.IMAGE_RESTORED)
6867
            imageRestored = true;
6868
          else if (result == VolatileImage.IMAGE_INCOMPATIBLE)
6869
            return false;
6870
        }
6871
      // we know that the buffer resources are valid now because we
6872
      // just checked them
6873
      validatedContents = true;
6874
      return imageRestored;
6875
    }
6876
  }
6877
 
6878
  /**
6879
   * This class provides support for flipping component buffers. It
6880
   * can only be used on Canvases and Windows.
6881
   *
6882
   * @since 1.4
6883
   */
6884
  protected class FlipBufferStrategy extends BufferStrategy
6885
  {
6886
    /**
6887
     * The number of buffers.
6888
     */
6889
    protected int numBuffers;
6890
 
6891
    /**
6892
     * The capabilities of this buffering strategy.
6893
     */
6894
    protected BufferCapabilities caps;
6895
 
6896
    /**
6897
     * An Image reference to the drawing buffer.
6898
     */
6899
    protected Image drawBuffer;
6900
 
6901
    /**
6902
     * A VolatileImage reference to the drawing buffer.
6903
     */
6904
    protected VolatileImage drawVBuffer;
6905
 
6906
    /**
6907
     * Whether or not the image buffer resources are allocated and
6908
     * ready to be drawn into.
6909
     */
6910
    protected boolean validatedContents;
6911
 
6912
    /**
6913
     * The width of the back buffer.
6914
     */
6915
    private int width;
6916
 
6917
    /**
6918
     * The height of the back buffer.
6919
     */
6920
    private int height;
6921
 
6922
    /**
6923
     * Creates a flipping buffer strategy.  The only supported
6924
     * strategy for FlipBufferStrategy itself is a double-buffer page
6925
     * flipping strategy.  It forms the basis for more complex derived
6926
     * strategies.
6927
     *
6928
     * @param numBuffers the number of buffers
6929
     * @param caps the capabilities of this buffering strategy
6930
     *
6931
     * @throws AWTException if the requested
6932
     * number-of-buffers/capabilities combination is not supported
6933
     */
6934
    protected FlipBufferStrategy(int numBuffers, BufferCapabilities caps)
6935
      throws AWTException
6936
    {
6937
      this.caps = caps;
6938
      width = getWidth();
6939
      height = getHeight();
6940
 
6941
      if (numBuffers > 1)
6942
        createBuffers(numBuffers, caps);
6943
      else
6944
        {
6945
          drawVBuffer = peer.createVolatileImage(width, height);
6946
          drawBuffer = drawVBuffer;
6947
        }
6948
    }
6949
 
6950
    /**
6951
     * Creates a multi-buffer flipping strategy.  The number of
6952
     * buffers must be greater than one and the buffer capabilities
6953
     * must specify page flipping.
6954
     *
6955
     * @param numBuffers the number of flipping buffers; must be
6956
     * greater than one
6957
     * @param caps the buffering capabilities; caps.isPageFlipping()
6958
     * must return true
6959
     *
6960
     * @throws IllegalArgumentException if numBuffers is not greater
6961
     * than one or if the page flipping capability is not requested
6962
     *
6963
     * @throws AWTException if the requested flipping strategy is not
6964
     * supported
6965
     */
6966
    protected void createBuffers(int numBuffers, BufferCapabilities caps)
6967
      throws AWTException
6968
    {
6969
      if (numBuffers <= 1)
6970
        throw new IllegalArgumentException("FlipBufferStrategy.createBuffers:"
6971
                                           + " numBuffers must be greater than"
6972
                                           + " one.");
6973
 
6974
      if (!caps.isPageFlipping())
6975
        throw new IllegalArgumentException("FlipBufferStrategy.createBuffers:"
6976
                                           + " flipping must be a specified"
6977
                                           + " capability.");
6978
 
6979
      peer.createBuffers(numBuffers, caps);
6980
    }
6981
 
6982
    /**
6983
     * Return a direct reference to the back buffer image.
6984
     *
6985
     * @return a direct reference to the back buffer image.
6986
     */
6987
    protected Image getBackBuffer()
6988
    {
6989
      return peer.getBackBuffer();
6990
    }
6991
 
6992
    /**
6993
     * Perform a flip operation to transfer the contents of the back
6994
     * buffer to the front buffer.
6995
     */
6996
    protected void flip(BufferCapabilities.FlipContents flipAction)
6997
    {
6998
      peer.flip(flipAction);
6999
    }
7000
 
7001
    /**
7002
     * Release the back buffer's resources.
7003
     */
7004
    protected void destroyBuffers()
7005
    {
7006
      peer.destroyBuffers();
7007
    }
7008
 
7009
    /**
7010
     * Retrieves the capabilities of this buffer strategy.
7011
     *
7012
     * @return the capabilities of this buffer strategy
7013
     */
7014
    public BufferCapabilities getCapabilities()
7015
    {
7016
      return caps;
7017
    }
7018
 
7019
    /**
7020
     * Retrieves a graphics object that can be used to draw into this
7021
     * strategy's image buffer.
7022
     *
7023
     * @return a graphics object
7024
     */
7025
    public Graphics getDrawGraphics()
7026
    {
7027
      return drawVBuffer.getGraphics();
7028
    }
7029
 
7030
    /**
7031
     * Re-create the image buffer resources if they've been lost.
7032
     */
7033
    protected void revalidate()
7034
    {
7035
      GraphicsConfiguration c =
7036
        GraphicsEnvironment.getLocalGraphicsEnvironment()
7037
        .getDefaultScreenDevice().getDefaultConfiguration();
7038
 
7039
      if (drawVBuffer.validate(c) == VolatileImage.IMAGE_INCOMPATIBLE)
7040
        drawVBuffer = peer.createVolatileImage(width, height);
7041
      validatedContents = true;
7042
    }
7043
 
7044
    /**
7045
     * Returns whether or not the image buffer resources have been
7046
     * lost.
7047
     *
7048
     * @return true if the resources have been lost, false otherwise
7049
     */
7050
    public boolean contentsLost()
7051
    {
7052
      if (drawVBuffer.contentsLost())
7053
        {
7054
          validatedContents = false;
7055
          return true;
7056
        }
7057
      // we know that the buffer resources are valid now because we
7058
      // just checked them
7059
      validatedContents = true;
7060
      return false;
7061
    }
7062
 
7063
    /**
7064
     * Returns whether or not the image buffer resources have been
7065
     * restored.
7066
     *
7067
     * @return true if the resources have been restored, false
7068
     * otherwise
7069
     */
7070
    public boolean contentsRestored()
7071
    {
7072
      GraphicsConfiguration c =
7073
        GraphicsEnvironment.getLocalGraphicsEnvironment()
7074
        .getDefaultScreenDevice().getDefaultConfiguration();
7075
 
7076
      int result = drawVBuffer.validate(c);
7077
 
7078
      boolean imageRestored = false;
7079
 
7080
      if (result == VolatileImage.IMAGE_RESTORED)
7081
        imageRestored = true;
7082
      else if (result == VolatileImage.IMAGE_INCOMPATIBLE)
7083
        return false;
7084
 
7085
      // we know that the buffer resources are valid now because we
7086
      // just checked them
7087
      validatedContents = true;
7088
      return imageRestored;
7089
    }
7090
 
7091
    /**
7092
     * Bring the contents of the back buffer to the front buffer.
7093
     */
7094
    public void show()
7095
    {
7096
      flip(caps.getFlipContents());
7097
    }
7098
  }
7099
}

powered by: WebSVN 2.1.0

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