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

Subversion Repositories scarts

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

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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