1 /* Component.java -- a graphics component
2 Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2006
3 Free Software Foundation
4
5 This file is part of GNU Classpath.
6
7 GNU Classpath is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GNU Classpath is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU Classpath; see the file COPYING. If not, write to the
19 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 02110-1301 USA.
21
22 Linking this library statically or dynamically with other modules is
23 making a combined work based on this library. Thus, the terms and
24 conditions of the GNU General Public License cover the whole
25 combination.
26
27 As a special exception, the copyright holders of this library give you
28 permission to link this library with independent modules to produce an
29 executable, regardless of the license terms of these independent
30 modules, and to copy and distribute the resulting executable under
31 terms of your choice, provided that you also meet, for each linked
32 independent module, the terms and conditions of the license of that
33 module. An independent module is a module which is not derived from
34 or based on this library. If you modify this library, you may extend
35 this exception to your version of the library, but you are not
36 obligated to do so. If you do not wish to do so, delete this
37 exception statement from your version. */
38
39
40 package java.awt;
41
42 import java.awt.dnd.DropTarget;
43 import java.awt.event.ActionEvent;
44 import java.awt.event.AdjustmentEvent;
45 import java.awt.event.ComponentEvent;
46 import java.awt.event.ComponentListener;
47 import java.awt.event.FocusEvent;
48 import java.awt.event.FocusListener;
49 import java.awt.event.HierarchyBoundsListener;
50 import java.awt.event.HierarchyEvent;
51 import java.awt.event.HierarchyListener;
52 import java.awt.event.InputEvent;
53 import java.awt.event.InputMethodEvent;
54 import java.awt.event.InputMethodListener;
55 import java.awt.event.KeyEvent;
56 import java.awt.event.KeyListener;
57 import java.awt.event.MouseEvent;
58 import java.awt.event.MouseListener;
59 import java.awt.event.MouseMotionListener;
60 import java.awt.event.MouseWheelEvent;
61 import java.awt.event.MouseWheelListener;
62 import java.awt.event.PaintEvent;
63 import java.awt.event.WindowEvent;
64 import java.awt.im.InputContext;
65 import java.awt.im.InputMethodRequests;
66 import java.awt.image.BufferStrategy;
67 import java.awt.image.ColorModel;
68 import java.awt.image.ImageObserver;
69 import java.awt.image.ImageProducer;
70 import java.awt.image.VolatileImage;
71 import java.awt.peer.ComponentPeer;
72 import java.awt.peer.LightweightPeer;
73 import java.beans.PropertyChangeListener;
74 import java.beans.PropertyChangeSupport;
75 import java.io.IOException;
76 import java.io.ObjectInputStream;
77 import java.io.ObjectOutputStream;
78 import java.io.PrintStream;
79 import java.io.PrintWriter;
80 import java.io.Serializable;
81 import java.lang.reflect.Array;
82 import java.util.Collections;
83 import java.util.EventListener;
84 import java.util.HashSet;
85 import java.util.Iterator;
86 import java.util.Locale;
87 import java.util.Set;
88 import java.util.Vector;
89
90 import javax.accessibility.Accessible;
91 import javax.accessibility.AccessibleComponent;
92 import javax.accessibility.AccessibleContext;
93 import javax.accessibility.AccessibleRole;
94 import javax.accessibility.AccessibleState;
95 import javax.accessibility.AccessibleStateSet;
96
97 /**
98 * The root of all evil. All graphical representations are subclasses of this
99 * giant class, which is designed for screen display and user interaction.
100 * This class can be extended directly to build a lightweight component (one
101 * not associated with a native window); lightweight components must reside
102 * inside a heavyweight window.
103 *
104 * <p>This class is Serializable, which has some big implications. A user can
105 * save the state of all graphical components in one VM, and reload them in
106 * another. Note that this class will only save Serializable listeners, and
107 * ignore the rest, without causing any serialization exceptions. However, by
108 * making a listener serializable, and adding it to another element, you link
109 * in that entire element to the state of this component. To get around this,
110 * use the idiom shown in the example below - make listeners non-serializable
111 * in inner classes, rather than using this object itself as the listener, if
112 * external objects do not need to save the state of this object.
113 *
114 * <pre>
115 * import java.awt.*;
116 * import java.awt.event.*;
117 * import java.io.Serializable;
118 * class MyApp implements Serializable
119 * {
120 * BigObjectThatShouldNotBeSerializedWithAButton bigOne;
121 * // Serializing aButton will not suck in an instance of MyApp, with its
122 * // accompanying field bigOne.
123 * Button aButton = new Button();
124 * class MyActionListener implements ActionListener
125 * {
126 * public void actionPerformed(ActionEvent e)
127 * {
128 * System.out.println("Hello There");
129 * }
130 * }
131 * MyApp()
132 * {
133 * aButton.addActionListener(new MyActionListener());
134 * }
135 * }
136 * </pre>
137 *
138 * <p>Status: Incomplete. The event dispatch mechanism is implemented. All
139 * other methods defined in the J2SE 1.3 API javadoc exist, but are mostly
140 * incomplete or only stubs; except for methods relating to the Drag and
141 * Drop, Input Method, and Accessibility frameworks: These methods are
142 * present but commented out.
143 *
144 * @author original author unknown
145 * @author Eric Blake (ebb9@email.byu.edu)
146 * @since 1.0
147 * @status still missing 1.4 support
148 */
149 public abstract class Component
150 implements ImageObserver, MenuContainer, Serializable
151 {
152 // Word to the wise - this file is huge. Search for '\f' (^L) for logical
153 // sectioning by fields, public API, private API, and nested classes.
154
155
156 /**
157 * Compatible with JDK 1.0+.
158 */
159 private static final long serialVersionUID = -7644114512714619750L;
160
161 /**
162 * Constant returned by the <code>getAlignmentY</code> method to indicate
163 * that the component wishes to be aligned to the top relative to
164 * other components.
165 *
166 * @see #getAlignmentY()
167 */
168 public static final float TOP_ALIGNMENT = 0;
169
170 /**
171 * Constant returned by the <code>getAlignmentY</code> and
172 * <code>getAlignmentX</code> methods to indicate
173 * that the component wishes to be aligned to the center relative to
174 * other components.
175 *
176 * @see #getAlignmentX()
177 * @see #getAlignmentY()
178 */
179 public static final float CENTER_ALIGNMENT = 0.5f;
180
181 /**
182 * Constant returned by the <code>getAlignmentY</code> method to indicate
183 * that the component wishes to be aligned to the bottom relative to
184 * other components.
185 *
186 * @see #getAlignmentY()
187 */
188 public static final float BOTTOM_ALIGNMENT = 1;
189
190 /**
191 * Constant returned by the <code>getAlignmentX</code> method to indicate
192 * that the component wishes to be aligned to the right relative to
193 * other components.
194 *
195 * @see #getAlignmentX()
196 */
197 public static final float RIGHT_ALIGNMENT = 1;
198
199 /**
200 * Constant returned by the <code>getAlignmentX</code> method to indicate
201 * that the component wishes to be aligned to the left relative to
202 * other components.
203 *
204 * @see #getAlignmentX()
205 */
206 public static final float LEFT_ALIGNMENT = 0;
207
208 /**
209 * Make the treelock a String so that it can easily be identified
210 * in debug dumps. We clone the String in order to avoid a conflict in
211 * the unlikely event that some other package uses exactly the same string
212 * as a lock object.
213 */
214 static final Object treeLock = new String("AWT_TREE_LOCK");
215
216 // Serialized fields from the serialization spec.
217
218 /**
219 * The x position of the component in the parent's coordinate system.
220 *
221 * @see #getLocation()
222 * @serial the x position
223 */
224 int x;
225
226 /**
227 * The y position of the component in the parent's coordinate system.
228 *
229 * @see #getLocation()
230 * @serial the y position
231 */
232 int y;
233
234 /**
235 * The component width.
236 *
237 * @see #getSize()
238 * @serial the width
239 */
240 int width;
241
242 /**
243 * The component height.
244 *
245 * @see #getSize()
246 * @serial the height
247 */
248 int height;
249
250 /**
251 * The foreground color for the component. This may be null.
252 *
253 * @see #getForeground()
254 * @see #setForeground(Color)
255 * @serial the foreground color
256 */
257 Color foreground;
258
259 /**
260 * The background color for the component. This may be null.
261 *
262 * @see #getBackground()
263 * @see #setBackground(Color)
264 * @serial the background color
265 */
266 Color background;
267
268 /**
269 * The default font used in the component. This may be null.
270 *
271 * @see #getFont()
272 * @see #setFont(Font)
273 * @serial the font
274 */
275 Font font;
276
277 /**
278 * The font in use by the peer, or null if there is no peer.
279 *
280 * @serial the peer's font
281 */
282 Font peerFont;
283
284 /**
285 * The cursor displayed when the pointer is over this component. This may
286 * be null.
287 *
288 * @see #getCursor()
289 * @see #setCursor(Cursor)
290 */
291 Cursor cursor;
292
293 /**
294 * The locale for the component.
295 *
296 * @see #getLocale()
297 * @see #setLocale(Locale)
298 */
299 Locale locale = Locale.getDefault ();
300
301 /**
302 * True if the object should ignore repaint events (usually because it is
303 * not showing).
304 *
305 * @see #getIgnoreRepaint()
306 * @see #setIgnoreRepaint(boolean)
307 * @serial true to ignore repaints
308 * @since 1.4
309 */
310 boolean ignoreRepaint;
311
312 /**
313 * True when the object is visible (although it is only showing if all
314 * ancestors are likewise visible). For component, this defaults to true.
315 *
316 * @see #isVisible()
317 * @see #setVisible(boolean)
318 * @serial true if visible
319 */
320 boolean visible = true;
321
322 /**
323 * True if the object is enabled, meaning it can interact with the user.
324 * For component, this defaults to true.
325 *
326 * @see #isEnabled()
327 * @see #setEnabled(boolean)
328 * @serial true if enabled
329 */
330 boolean enabled = true;
331
332 /**
333 * True if the object is valid. This is set to false any time a size
334 * adjustment means the component need to be layed out again.
335 *
336 * @see #isValid()
337 * @see #validate()
338 * @see #invalidate()
339 * @serial true if layout is valid
340 */
341 boolean valid;
342
343 /**
344 * The DropTarget for drag-and-drop operations.
345 *
346 * @see #getDropTarget()
347 * @see #setDropTarget(DropTarget)
348 * @serial the drop target, or null
349 * @since 1.2
350 */
351 DropTarget dropTarget;
352
353 /**
354 * The list of popup menus for this component.
355 *
356 * @see #add(PopupMenu)
357 * @serial the list of popups
358 */
359 Vector popups;
360
361 /**
362 * The component's name. May be null, in which case a default name is
363 * generated on the first use.
364 *
365 * @see #getName()
366 * @see #setName(String)
367 * @serial the name
368 */
369 String name;
370
371 /**
372 * True once the user has set the name. Note that the user may set the name
373 * to null.
374 *
375 * @see #name
376 * @see #getName()
377 * @see #setName(String)
378 * @serial true if the name has been explicitly set
379 */
380 boolean nameExplicitlySet;
381
382 /**
383 * Indicates if the object can be focused. Defaults to true for components.
384 *
385 * @see #isFocusable()
386 * @see #setFocusable(boolean)
387 * @since 1.4
388 */
389 boolean focusable = true;
390
391 /**
392 * Tracks whether this component's {@link #isFocusTraversable}
393 * method has been overridden.
394 *
395 * @since 1.4
396 */
397 int isFocusTraversableOverridden;
398
399 /**
400 * The focus traversal keys, if not inherited from the parent or
401 * default keyboard focus manager. These sets will contain only
402 * AWTKeyStrokes that represent press and release events to use as
403 * focus control.
404 *
405 * @see #getFocusTraversalKeys(int)
406 * @see #setFocusTraversalKeys(int, Set)
407 * @since 1.4
408 */
409 Set[] focusTraversalKeys;
410
411 /**
412 * True if focus traversal keys are enabled. This defaults to true for
413 * Component. If this is true, keystrokes in focusTraversalKeys are trapped
414 * and processed automatically rather than being passed on to the component.
415 *
416 * @see #getFocusTraversalKeysEnabled()
417 * @see #setFocusTraversalKeysEnabled(boolean)
418 * @since 1.4
419 */
420 boolean focusTraversalKeysEnabled = true;
421
422 /**
423 * Cached information on the minimum size. Should have been transient.
424 *
425 * @serial ignore
426 */
427 Dimension minSize;
428
429 /**
430 * Cached information on the preferred size. Should have been transient.
431 *
432 * @serial ignore
433 */
434 Dimension prefSize;
435
436 /**
437 * Set to true if an event is to be handled by this component, false if
438 * it is to be passed up the hierarcy.
439 *
440 * @see #dispatchEvent(AWTEvent)
441 * @serial true to process event locally
442 */
443 boolean newEventsOnly;
444
445 /**
446 * Set by subclasses to enable event handling of particular events, and
447 * left alone when modifying listeners. For component, this defaults to
448 * enabling only input methods.
449 *
450 * @see #enableInputMethods(boolean)
451 * @see AWTEvent
452 * @serial the mask of events to process
453 */
454 long eventMask = AWTEvent.INPUT_ENABLED_EVENT_MASK;
455
456 /**
457 * Describes all registered PropertyChangeListeners.
458 *
459 * @see #addPropertyChangeListener(PropertyChangeListener)
460 * @see #removePropertyChangeListener(PropertyChangeListener)
461 * @see #firePropertyChange(String, Object, Object)
462 * @serial the property change listeners
463 * @since 1.2
464 */
465 PropertyChangeSupport changeSupport;
466
467 /**
468 * True if the component has been packed (layed out).
469 *
470 * @serial true if this is packed
471 */
472 boolean isPacked;
473
474 /**
475 * The serialization version for this class. Currently at version 4.
476 *
477 * XXX How do we handle prior versions?
478 *
479 * @serial the serialization version
480 */
481 int componentSerializedDataVersion = 4;
482
483 /**
484 * The accessible context associated with this component. This is only set
485 * by subclasses.
486 *
487 * @see #getAccessibleContext()
488 * @serial the accessibility context
489 * @since 1.2
490 */
491 AccessibleContext accessibleContext;
492
493
494 // Guess what - listeners are special cased in serialization. See
495 // readObject and writeObject.
496
497 /** Component listener chain. */
498 transient ComponentListener componentListener;
499
500 /** Focus listener chain. */
501 transient FocusListener focusListener;
502
503 /** Key listener chain. */
504 transient KeyListener keyListener;
505
506 /** Mouse listener chain. */
507 transient MouseListener mouseListener;
508
509 /** Mouse motion listener chain. */
510 transient MouseMotionListener mouseMotionListener;
511
512 /**
513 * Mouse wheel listener chain.
514 *
515 * @since 1.4
516 */
517 transient MouseWheelListener mouseWheelListener;
518
519 /**
520 * Input method listener chain.
521 *
522 * @since 1.2
523 */
524 transient InputMethodListener inputMethodListener;
525
526 /**
527 * Hierarcy listener chain.
528 *
529 * @since 1.3
530 */
531 transient HierarchyListener hierarchyListener;
532
533 /**
534 * Hierarcy bounds listener chain.
535 *
536 * @since 1.3
537 */
538 transient HierarchyBoundsListener hierarchyBoundsListener;
539
540 // Anything else is non-serializable, and should be declared "transient".
541
542 /** The parent. */
543 transient Container parent;
544
545 /** The associated native peer. */
546 transient ComponentPeer peer;
547
548 /** The preferred component orientation. */
549 transient ComponentOrientation orientation = ComponentOrientation.UNKNOWN;
550
551 /**
552 * The associated graphics configuration.
553 *
554 * @since 1.4
555 */
556 transient GraphicsConfiguration graphicsConfig;
557
558 /**
559 * The buffer strategy for repainting.
560 *
561 * @since 1.4
562 */
563 transient BufferStrategy bufferStrategy;
564
565 /**
566 * true if requestFocus was called on this component when its
567 * top-level ancestor was not focusable.
568 */
569 private transient FocusEvent pendingFocusRequest = null;
570
571 /**
572 * The system properties that affect image updating.
573 */
574 private static transient boolean incrementalDraw;
575 private static transient Long redrawRate;
576
577 static
578 {
579 incrementalDraw = Boolean.getBoolean ("awt.image.incrementalDraw");
580 redrawRate = Long.getLong ("awt.image.redrawrate");
581 }
582
583 // Public and protected API.
584
585 /**
586 * Default constructor for subclasses. When Component is extended directly,
587 * it forms a lightweight component that must be hosted in an opaque native
588 * container higher in the tree.
589 */
590 protected Component()
591 {
592 // Nothing to do here.
593 }
594
595 /**
596 * Returns the name of this component.
597 *
598 * @return the name of this component
599 * @see #setName(String)
600 * @since 1.1
601 */
602 public String getName()
603 {
604 if (name == null && ! nameExplicitlySet)
605 name = generateName();
606 return name;
607 }
608
609 /**
610 * Sets the name of this component to the specified name.
611 *
612 * @param name the new name of this component
613 * @see #getName()
614 * @since 1.1
615 */
616 public void setName(String name)
617 {
618 nameExplicitlySet = true;
619 this.name = name;
620 }
621
622 /**
623 * Returns the parent of this component.
624 *
625 * @return the parent of this component
626 */
627 public Container getParent()
628 {
629 return parent;
630 }
631
632 /**
633 * Returns the native windowing system peer for this component. Only the
634 * platform specific implementation code should call this method.
635 *
636 * @return the peer for this component
637 * @deprecated user programs should not directly manipulate peers; use
638 * {@link #isDisplayable()} instead
639 */
640 // Classpath's Gtk peers rely on this.
641 public ComponentPeer getPeer()
642 {
643 return peer;
644 }
645
646 /**
647 * Set the associated drag-and-drop target, which receives events when this
648 * is enabled.
649 *
650 * @param dt the new drop target
651 * @see #isEnabled()
652 */
653 public void setDropTarget(DropTarget dt)
654 {
655 this.dropTarget = dt;
656 }
657
658 /**
659 * Gets the associated drag-and-drop target, if there is one.
660 *
661 * @return the drop target
662 */
663 public DropTarget getDropTarget()
664 {
665 return dropTarget;
666 }
667
668 /**
669 * Returns the graphics configuration of this component, if there is one.
670 * If it has not been set, it is inherited from the parent.
671 *
672 * @return the graphics configuration, or null
673 * @since 1.3
674 */
675 public GraphicsConfiguration getGraphicsConfiguration()
676 {
677 return getGraphicsConfigurationImpl();
678 }
679
680 /**
681 * Returns the object used for synchronization locks on this component
682 * when performing tree and layout functions.
683 *
684 * @return the synchronization lock for this component
685 */
686 public final Object getTreeLock()
687 {
688 return treeLock;
689 }
690
691 /**
692 * Returns the toolkit in use for this component. The toolkit is associated
693 * with the frame this component belongs to.
694 *
695 * @return the toolkit for this component
696 */
697 public Toolkit getToolkit()
698 {
699 if (peer != null)
700 {
701 Toolkit tk = peer.getToolkit();
702 if (tk != null)
703 return tk;
704 }
705 // Get toolkit for lightweight component.
706 if (parent != null)
707 return parent.getToolkit();
708 return Toolkit.getDefaultToolkit();
709 }
710
711 /**
712 * Tests whether or not this component is valid. A invalid component needs
713 * to have its layout redone.
714 *
715 * @return true if this component is valid
716 * @see #validate()
717 * @see #invalidate()
718 */
719 public boolean isValid()
720 {
721 return valid;
722 }
723
724 /**
725 * Tests if the component is displayable. It must be connected to a native
726 * screen resource. This reduces to checking that peer is not null. A
727 * containment hierarchy is made displayable when a window is packed or
728 * made visible.
729 *
730 * @return true if the component is displayable
731 * @see Container#add(Component)
732 * @see Container#remove(Component)
733 * @see Window#pack()
734 * @see Window#show()
735 * @see Window#dispose()
736 * @since 1.2
737 */
738 public boolean isDisplayable()
739 {
740 return peer != null;
741 }
742
743 /**
744 * Tests whether or not this component is visible. Except for top-level
745 * frames, components are initially visible.
746 *
747 * @return true if the component is visible
748 * @see #setVisible(boolean)
749 */
750 public boolean isVisible()
751 {
752 return visible;
753 }
754
755 /**
756 * Tests whether or not this component is actually being shown on
757 * the screen. This will be true if and only if it this component is
758 * visible and its parent components are all visible.
759 *
760 * @return true if the component is showing on the screen
761 * @see #setVisible(boolean)
762 */
763 public boolean isShowing()
764 {
765 if (! visible || peer == null)
766 return false;
767
768 return parent == null ? false : parent.isShowing();
769 }
770
771 /**
772 * Tests whether or not this component is enabled. Components are enabled
773 * by default, and must be enabled to receive user input or generate events.
774 *
775 * @return true if the component is enabled
776 * @see #setEnabled(boolean)
777 */
778 public boolean isEnabled()
779 {
780 return enabled;
781 }
782
783 /**
784 * Enables or disables this component. The component must be enabled to
785 * receive events (except that lightweight components always receive mouse
786 * events).
787 *
788 * @param enabled true to enable this component
789 *
790 * @see #isEnabled()
791 * @see #isLightweight()
792 *
793 * @since 1.1
794 */
795 public void setEnabled(boolean enabled)
796 {
797 enable(enabled);
798 }
799
800 /**
801 * Enables this component.
802 *
803 * @deprecated use {@link #setEnabled(boolean)} instead
804 */
805 public void enable()
806 {
807 this.enabled = true;
808 if (peer != null)
809 peer.setEnabled (true);
810 }
811
812 /**
813 * Enables or disables this component.
814 *
815 * @param enabled true to enable this component
816 *
817 * @deprecated use {@link #setEnabled(boolean)} instead
818 */
819 public void enable(boolean enabled)
820 {
821 if (enabled)
822 enable();
823 else
824 disable();
825 }
826
827 /**
828 * Disables this component.
829 *
830 * @deprecated use {@link #setEnabled(boolean)} instead
831 */
832 public void disable()
833 {
834 this.enabled = false;
835 if (peer != null)
836 peer.setEnabled (false);
837 }
838
839 /**
840 * Checks if this image is painted to an offscreen image buffer that is
841 * later copied to screen (double buffering reduces flicker). This version
842 * returns false, so subclasses must override it if they provide double
843 * buffering.
844 *
845 * @return true if this is double buffered; defaults to false
846 */
847 public boolean isDoubleBuffered()
848 {
849 return false;
850 }
851
852 /**
853 * Enables or disables input method support for this component. By default,
854 * components have this enabled. Input methods are given the opportunity
855 * to process key events before this component and its listeners.
856 *
857 * @param enable true to enable input method processing
858 * @see #processKeyEvent(KeyEvent)
859 * @since 1.2
860 */
861 public void enableInputMethods(boolean enable)
862 {
863 if (enable)
864 eventMask |= AWTEvent.INPUT_ENABLED_EVENT_MASK;
865 else
866 eventMask &= ~AWTEvent.INPUT_ENABLED_EVENT_MASK;
867 }
868
869 /**
870 * Makes this component visible or invisible. Note that it wtill might
871 * not show the component, if a parent is invisible.
872 *
873 * @param visible true to make this component visible
874 *
875 * @see #isVisible()
876 *
877 * @since 1.1
878 */
879 public void setVisible(boolean visible)
880 {
881 // Inspection by subclassing shows that Sun's implementation calls
882 // show(boolean) which then calls show() or hide(). It is the show()
883 // method that is overriden in subclasses like Window.
884 show(visible);
885 }
886
887 /**
888 * Makes this component visible on the screen.
889 *
890 * @deprecated use {@link #setVisible(boolean)} instead
891 */
892 public void show()
893 {
894 // We must set visible before showing the peer. Otherwise the
895 // peer could post paint events before visible is true, in which
896 // case lightweight components are not initially painted --
897 // Container.paint first calls isShowing () before painting itself
898 // and its children.
899 if(!isVisible())
900 {
901 this.visible = true;
902 // Avoid NullPointerExceptions by creating a local reference.
903 ComponentPeer currentPeer=peer;
904 if (currentPeer != null)
905 currentPeer.show();
906
907 // The JDK repaints the component before invalidating the parent.
908 // So do we.
909 if (isShowing() && isLightweight())
910 repaint();
911 // Invalidate the parent if we have one. The component itself must
912 // not be invalidated. We also avoid NullPointerException with
913 // a local reference here.
914 Container currentParent = parent;
915 if (currentParent != null)
916 currentParent.invalidate();
917
918 ComponentEvent ce =
919 new ComponentEvent(this,ComponentEvent.COMPONENT_SHOWN);
920 getToolkit().getSystemEventQueue().postEvent(ce);
921 }
922 }
923
924 /**
925 * Makes this component visible or invisible.
926 *
927 * @param visible true to make this component visible
928 *
929 * @deprecated use {@link #setVisible(boolean)} instead
930 */
931 public void show(boolean visible)
932 {
933 if (visible)
934 show();
935 else
936 hide();
937 }
938
939 /**
940 * Hides this component so that it is no longer shown on the screen.
941 *
942 * @deprecated use {@link #setVisible(boolean)} instead
943 */
944 public void hide()
945 {
946 if (isVisible())
947 {
948 // Avoid NullPointerExceptions by creating a local reference.
949 ComponentPeer currentPeer=peer;
950 if (currentPeer != null)
951 currentPeer.setVisible(false);
952 boolean wasShowing = isShowing();
953 this.visible = false;
954
955 // The JDK repaints the component before invalidating the parent.
956 // So do we.
957 if (wasShowing)
958 repaint();
959 // Invalidate the parent if we have one. The component itself must
960 // not be invalidated. We also avoid NullPointerException with
961 // a local reference here.
962 Container currentParent = parent;
963 if (currentParent != null)
964 currentParent.invalidate();
965
966 ComponentEvent ce =
967 new ComponentEvent(this,ComponentEvent.COMPONENT_HIDDEN);
968 getToolkit().getSystemEventQueue().postEvent(ce);
969 }
970 }
971
972 /**
973 * Returns this component's foreground color. If not set, this is inherited
974 * from the parent.
975 *
976 * @return this component's foreground color, or null
977 * @see #setForeground(Color)
978 */
979 public Color getForeground()
980 {
981 if (foreground != null)
982 return foreground;
983 return parent == null ? null : parent.getForeground();
984 }
985
986 /**
987 * Sets this component's foreground color to the specified color. This is a
988 * bound property.
989 *
990 * @param c the new foreground color
991 * @see #getForeground()
992 */
993 public void setForeground(Color c)
994 {
995 if (peer != null)
996 peer.setForeground(c);
997
998 Color previous = foreground;
999 foreground = c;
1000 firePropertyChange("foreground", previous, c);
1001 }
1002
1003 /**
1004 * Tests if the foreground was explicitly set, or just inherited from the
1005 * parent.
1006 *
1007 * @return true if the foreground has been set
1008 * @since 1.4
1009 */
1010 public boolean isForegroundSet()
1011 {
1012 return foreground != null;
1013 }
1014
1015 /**
1016 * Returns this component's background color. If not set, this is inherited
1017 * from the parent.
1018 *
1019 * @return the background color of the component, or null
1020 * @see #setBackground(Color)
1021 */
1022 public Color getBackground()
1023 {
1024 if (background != null)
1025 return background;
1026 return parent == null ? null : parent.getBackground();
1027 }
1028
1029 /**
1030 * Sets this component's background color to the specified color. The parts
1031 * of the component affected by the background color may by system dependent.
1032 * This is a bound property.
1033 *
1034 * @param c the new background color
1035 * @see #getBackground()
1036 */
1037 public void setBackground(Color c)
1038 {
1039 // return if the background is already set to that color.
1040 if ((c != null) && c.equals(background))
1041 return;
1042
1043 Color previous = background;
1044 background = c;
1045 if (peer != null && c != null)
1046 peer.setBackground(c);
1047 firePropertyChange("background", previous, c);
1048 }
1049
1050 /**
1051 * Tests if the background was explicitly set, or just inherited from the
1052 * parent.
1053 *
1054 * @return true if the background has been set
1055 * @since 1.4
1056 */
1057 public boolean isBackgroundSet()
1058 {
1059 return background != null;
1060 }
1061
1062 /**
1063 * Returns the font in use for this component. If not set, this is inherited
1064 * from the parent.
1065 *
1066 * @return the font for this component
1067 * @see #setFont(Font)
1068 */
1069 public Font getFont()
1070 {
1071 Font f = font;
1072 if (f != null)
1073 return f;
1074
1075 Component p = parent;
1076 if (p != null)
1077 return p.getFont();
1078 return null;
1079 }
1080
1081 /**
1082 * Sets the font for this component to the specified font. This is a bound
1083 * property.
1084 *
1085 * @param newFont the new font for this component
1086 *
1087 * @see #getFont()
1088 */
1089 public void setFont(Font newFont)
1090 {
1091 if((newFont != null && (font == null || !font.equals(newFont)))
1092 || newFont == null)
1093 {
1094 Font oldFont = font;
1095 font = newFont;
1096 if (peer != null)
1097 peer.setFont(font);
1098 firePropertyChange("font", oldFont, newFont);
1099 invalidate();
1100 }
1101 }
1102
1103 /**
1104 * Tests if the font was explicitly set, or just inherited from the parent.
1105 *
1106 * @return true if the font has been set
1107 * @since 1.4
1108 */
1109 public boolean isFontSet()
1110 {
1111 return font != null;
1112 }
1113
1114 /**
1115 * Returns the locale for this component. If this component does not
1116 * have a locale, the locale of the parent component is returned.
1117 *
1118 * @return the locale for this component
1119 * @throws IllegalComponentStateException if it has no locale or parent
1120 * @see #setLocale(Locale)
1121 * @since 1.1
1122 */
1123 public Locale getLocale()
1124 {
1125 if (locale != null)
1126 return locale;
1127 if (parent == null)
1128 throw new IllegalComponentStateException
1129 ("Component has no parent: can't determine Locale");
1130 return parent.getLocale();
1131 }
1132
1133 /**
1134 * Sets the locale for this component to the specified locale. This is a
1135 * bound property.
1136 *
1137 * @param newLocale the new locale for this component
1138 */
1139 public void setLocale(Locale newLocale)
1140 {
1141 if (locale == newLocale)
1142 return;
1143
1144 Locale oldLocale = locale;
1145 locale = newLocale;
1146 firePropertyChange("locale", oldLocale, newLocale);
1147 // New writing/layout direction or more/less room for localized labels.
1148 invalidate();
1149 }
1150
1151 /**
1152 * Returns the color model of the device this componet is displayed on.
1153 *
1154 * @return this object's color model
1155 * @see Toolkit#getColorModel()
1156 */
1157 public ColorModel getColorModel()
1158 {
1159 GraphicsConfiguration config = getGraphicsConfiguration();
1160 return config != null ? config.getColorModel()
1161 : getToolkit().getColorModel();
1162 }
1163
1164 /**
1165 * Returns the location of this component's top left corner relative to
1166 * its parent component. This may be outdated, so for synchronous behavior,
1167 * you should use a component listner.
1168 *
1169 * @return the location of this component
1170 * @see #setLocation(int, int)
1171 * @see #getLocationOnScreen()
1172 * @since 1.1
1173 */
1174 public Point getLocation()
1175 {
1176 return location ();
1177 }
1178
1179 /**
1180 * Returns the location of this component's top left corner in screen
1181 * coordinates.
1182 *
1183 * @return the location of this component in screen coordinates
1184 * @throws IllegalComponentStateException if the component is not showing
1185 */
1186 public Point getLocationOnScreen()
1187 {
1188 if (! isShowing())
1189 throw new IllegalComponentStateException("component "
1190 + getClass().getName()
1191 + " not showing");
1192 // We know peer != null here.
1193 return peer.getLocationOnScreen();
1194 }
1195
1196 /**
1197 * Returns the location of this component's top left corner relative to
1198 * its parent component.
1199 *
1200 * @return the location of this component
1201 * @deprecated use {@link #getLocation()} instead
1202 */
1203 public Point location()
1204 {
1205 return new Point (x, y);
1206 }
1207
1208 /**
1209 * Moves this component to the specified location, relative to the parent's
1210 * coordinates. The coordinates are the new upper left corner of this
1211 * component.
1212 *
1213 * @param x the new X coordinate of this component
1214 * @param y the new Y coordinate of this component
1215 * @see #getLocation()
1216 * @see #setBounds(int, int, int, int)
1217 */
1218 public void setLocation(int x, int y)
1219 {
1220 move (x, y);
1221 }
1222
1223 /**
1224 * Moves this component to the specified location, relative to the parent's
1225 * coordinates. The coordinates are the new upper left corner of this
1226 * component.
1227 *
1228 * @param x the new X coordinate of this component
1229 * @param y the new Y coordinate of this component
1230 * @deprecated use {@link #setLocation(int, int)} instead
1231 */
1232 public void move(int x, int y)
1233 {
1234 setBounds(x, y, this.width, this.height);
1235 }
1236
1237 /**
1238 * Moves this component to the specified location, relative to the parent's
1239 * coordinates. The coordinates are the new upper left corner of this
1240 * component.
1241 *
1242 * @param p new coordinates for this component
1243 * @throws NullPointerException if p is null
1244 * @see #getLocation()
1245 * @see #setBounds(int, int, int, int)
1246 * @since 1.1
1247 */
1248 public void setLocation(Point p)
1249 {
1250 setLocation(p.x, p.y);
1251 }
1252
1253 /**
1254 * Returns the size of this object.
1255 *
1256 * @return the size of this object
1257 * @see #setSize(int, int)
1258 * @since 1.1
1259 */
1260 public Dimension getSize()
1261 {
1262 return size ();
1263 }
1264
1265 /**
1266 * Returns the size of this object.
1267 *
1268 * @return the size of this object
1269 * @deprecated use {@link #getSize()} instead
1270 */
1271 public Dimension size()
1272 {
1273 return new Dimension (width, height);
1274 }
1275
1276 /**
1277 * Sets the size of this component to the specified width and height.
1278 *
1279 * @param width the new width of this component
1280 * @param height the new height of this component
1281 * @see #getSize()
1282 * @see #setBounds(int, int, int, int)
1283 */
1284 public void setSize(int width, int height)
1285 {
1286 resize (width, height);
1287 }
1288
1289 /**
1290 * Sets the size of this component to the specified value.
1291 *
1292 * @param width the new width of the component
1293 * @param height the new height of the component
1294 * @deprecated use {@link #setSize(int, int)} instead
1295 */
1296 public void resize(int width, int height)
1297 {
1298 setBounds(this.x, this.y, width, height);
1299 }
1300
1301 /**
1302 * Sets the size of this component to the specified value.
1303 *
1304 * @param d the new size of this component
1305 * @throws NullPointerException if d is null
1306 * @see #setSize(int, int)
1307 * @see #setBounds(int, int, int, int)
1308 * @since 1.1
1309 */
1310 public void setSize(Dimension d)
1311 {
1312 resize (d);
1313 }
1314
1315 /**
1316 * Sets the size of this component to the specified value.
1317 *
1318 * @param d the new size of this component
1319 * @throws NullPointerException if d is null
1320 * @deprecated use {@link #setSize(Dimension)} instead
1321 */
1322 public void resize(Dimension d)
1323 {
1324 resize (d.width, d.height);
1325 }
1326
1327 /**
1328 * Returns a bounding rectangle for this component. Note that the
1329 * returned rectange is relative to this component's parent, not to
1330 * the screen.
1331 *
1332 * @return the bounding rectangle for this component
1333 * @see #setBounds(int, int, int, int)
1334 * @see #getLocation()
1335 * @see #getSize()
1336 */
1337 public Rectangle getBounds()
1338 {
1339 return bounds ();
1340 }
1341
1342 /**
1343 * Returns a bounding rectangle for this component. Note that the
1344 * returned rectange is relative to this component's parent, not to
1345 * the screen.
1346 *
1347 * @return the bounding rectangle for this component
1348 * @deprecated use {@link #getBounds()} instead
1349 */
1350 public Rectangle bounds()
1351 {
1352 return new Rectangle (x, y, width, height);
1353 }
1354
1355 /**
1356 * Sets the bounding rectangle for this component to the specified values.
1357 * Note that these coordinates are relative to the parent, not to the screen.
1358 *
1359 * @param x the X coordinate of the upper left corner of the rectangle
1360 * @param y the Y coordinate of the upper left corner of the rectangle
1361 * @param w the width of the rectangle
1362 * @param h the height of the rectangle
1363 * @see #getBounds()
1364 * @see #setLocation(int, int)
1365 * @see #setLocation(Point)
1366 * @see #setSize(int, int)
1367 * @see #setSize(Dimension)
1368 * @since 1.1
1369 */
1370 public void setBounds(int x, int y, int w, int h)
1371 {
1372 reshape (x, y, w, h);
1373 }
1374
1375 /**
1376 * Sets the bounding rectangle for this component to the specified values.
1377 * Note that these coordinates are relative to the parent, not to the screen.
1378 *
1379 * @param x the X coordinate of the upper left corner of the rectangle
1380 * @param y the Y coordinate of the upper left corner of the rectangle
1381 * @param width the width of the rectangle
1382 * @param height the height of the rectangle
1383 * @deprecated use {@link #setBounds(int, int, int, int)} instead
1384 */
1385 public void reshape(int x, int y, int width, int height)
1386 {
1387 int oldx = this.x;
1388 int oldy = this.y;
1389 int oldwidth = this.width;
1390 int oldheight = this.height;
1391
1392 if (this.x == x && this.y == y && this.width == width
1393 && this.height == height)
1394 return;
1395
1396 invalidate();
1397
1398 this.x = x;
1399 this.y = y;
1400 this.width = width;
1401 this.height = height;
1402 if (peer != null)
1403 peer.setBounds (x, y, width, height);
1404
1405 // Erase old bounds and repaint new bounds for lightweights.
1406 if (isLightweight() && isShowing())
1407 {
1408 if (parent != null)
1409 {
1410 Rectangle oldBounds = new Rectangle(oldx, oldy, oldwidth,
1411 oldheight);
1412 Rectangle newBounds = new Rectangle(x, y, width, height);
1413 Rectangle destroyed = oldBounds.union(newBounds);
1414 if (!destroyed.isEmpty())
1415 parent.repaint(0, destroyed.x, destroyed.y, destroyed.width,
1416 destroyed.height);
1417 }
1418 }
1419
1420 // Only post event if this component is visible and has changed size.
1421 if (isShowing ()
1422 && (oldx != x || oldy != y))
1423 {
1424 ComponentEvent ce = new ComponentEvent(this,
1425 ComponentEvent.COMPONENT_MOVED);
1426 getToolkit().getSystemEventQueue().postEvent(ce);
1427 }
1428 if (isShowing ()
1429 && (oldwidth != width || oldheight != height))
1430 {
1431 ComponentEvent ce = new ComponentEvent(this,
1432 ComponentEvent.COMPONENT_RESIZED);
1433 getToolkit().getSystemEventQueue().postEvent(ce);
1434 }
1435 }
1436
1437 /**
1438 * Sets the bounding rectangle for this component to the specified
1439 * rectangle. Note that these coordinates are relative to the parent, not
1440 * to the screen.
1441 *
1442 * @param r the new bounding rectangle
1443 * @throws NullPointerException if r is null
1444 * @see #getBounds()
1445 * @see #setLocation(Point)
1446 * @see #setSize(Dimension)
1447 * @since 1.1
1448 */
1449 public void setBounds(Rectangle r)
1450 {
1451 setBounds (r.x, r.y, r.width, r.height);
1452 }
1453
1454 /**
1455 * Gets the x coordinate of the upper left corner. This is more efficient
1456 * than getBounds().x or getLocation().x.
1457 *
1458 * @return the current x coordinate
1459 * @since 1.2
1460 */
1461 public int getX()
1462 {
1463 return x;
1464 }
1465
1466 /**
1467 * Gets the y coordinate of the upper left corner. This is more efficient
1468 * than getBounds().y or getLocation().y.
1469 *
1470 * @return the current y coordinate
1471 * @since 1.2
1472 */
1473 public int getY()
1474 {
1475 return y;
1476 }
1477
1478 /**
1479 * Gets the width of the component. This is more efficient than
1480 * getBounds().width or getSize().width.
1481 *
1482 * @return the current width
1483 * @since 1.2
1484 */
1485 public int getWidth()
1486 {
1487 return width;
1488 }
1489
1490 /**
1491 * Gets the height of the component. This is more efficient than
1492 * getBounds().height or getSize().height.
1493 *
1494 * @return the current width
1495 * @since 1.2
1496 */
1497 public int getHeight()
1498 {
1499 return height;
1500 }
1501
1502 /**
1503 * Returns the bounds of this component. This allows reuse of an existing
1504 * rectangle, if r is non-null.
1505 *
1506 * @param r the rectangle to use, or null
1507 * @return the bounds
1508 */
1509 public Rectangle getBounds(Rectangle r)
1510 {
1511 if (r == null)
1512 r = new Rectangle();
1513 r.x = x;
1514 r.y = y;
1515 r.width = width;
1516 r.height = height;
1517 return r;
1518 }
1519
1520 /**
1521 * Returns the size of this component. This allows reuse of an existing
1522 * dimension, if d is non-null.
1523 *
1524 * @param d the dimension to use, or null
1525 * @return the size
1526 */
1527 public Dimension getSize(Dimension d)
1528 {
1529 if (d == null)
1530 d = new Dimension();
1531 d.width = width;
1532 d.height = height;
1533 return d;
1534 }
1535
1536 /**
1537 * Returns the location of this component. This allows reuse of an existing
1538 * point, if p is non-null.
1539 *
1540 * @param p the point to use, or null
1541 * @return the location
1542 */
1543 public Point getLocation(Point p)
1544 {
1545 if (p == null)
1546 p = new Point();
1547 p.x = x;
1548 p.y = y;
1549 return p;
1550 }
1551
1552 /**
1553 * Tests if this component is opaque. All "heavyweight" (natively-drawn)
1554 * components are opaque. A component is opaque if it draws all pixels in
1555 * the bounds; a lightweight component is partially transparent if it lets
1556 * pixels underneath show through. Subclasses that guarantee that all pixels
1557 * will be drawn should override this.
1558 *
1559 * @return true if this is opaque
1560 * @see #isLightweight()
1561 * @since 1.2
1562 */
1563 public boolean isOpaque()
1564 {
1565 return ! isLightweight();
1566 }
1567
1568 /**
1569 * Return whether the component is lightweight. That means the component has
1570 * no native peer, but is displayable. This applies to subclasses of
1571 * Component not in this package, such as javax.swing.
1572 *
1573 * @return true if the component has a lightweight peer
1574 * @see #isDisplayable()
1575 * @since 1.2
1576 */
1577 public boolean isLightweight()
1578 {
1579 return peer instanceof LightweightPeer;
1580 }
1581
1582 /**
1583 * Returns the component's preferred size.
1584 *
1585 * @return the component's preferred size
1586 * @see #getMinimumSize()
1587 * @see LayoutManager
1588 */
1589 public Dimension getPreferredSize()
1590 {
1591 return preferredSize();
1592 }
1593
1594 /**
1595 * Returns the component's preferred size.
1596 *
1597 * @return the component's preferred size
1598 * @deprecated use {@link #getPreferredSize()} instead
1599 */
1600 public Dimension preferredSize()
1601 {
1602 if (prefSize == null)
1603 {
1604 if (peer == null)
1605 prefSize = minimumSize();
1606 else
1607 prefSize = peer.getPreferredSize();
1608 }
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 repaint(0, 0, 0, width, height);
1890 }
1891
1892 /**
1893 * Repaint this entire component. The <code>update()</code> method on this
1894 * component will be called in approximate the specified number of
1895 * milliseconds.
1896 *
1897 * @param tm milliseconds before this component should be repainted
1898 * @see #paint(Graphics)
1899 * @see #repaint(long, int, int, int, int)
1900 */
1901 public void repaint(long tm)
1902 {
1903 repaint(tm, 0, 0, width, height);
1904 }
1905
1906 /**
1907 * Repaints the specified rectangular region within this component. The
1908 * <code>update</code> method on this component will be called as soon as
1909 * possible. The coordinates are relative to this component.
1910 *
1911 * @param x the X coordinate of the upper left of the region to repaint
1912 * @param y the Y coordinate of the upper left of the region to repaint
1913 * @param w the width of the region to repaint
1914 * @param h the height of the region to repaint
1915 * @see #update(Graphics)
1916 * @see #repaint(long, int, int, int, int)
1917 */
1918 public void repaint(int x, int y, int w, int h)
1919 {
1920 repaint(0, x, y, w, h);
1921 }
1922
1923 /**
1924 * Repaints the specified rectangular region within this component. The
1925 * <code>update</code> method on this component will be called in
1926 * approximately the specified number of milliseconds. The coordinates
1927 * are relative to this component.
1928 *
1929 * @param tm milliseconds before this component should be repainted
1930 * @param x the X coordinate of the upper left of the region to repaint
1931 * @param y the Y coordinate of the upper left of the region to repaint
1932 * @param width the width of the region to repaint
1933 * @param height the height of the region to repaint
1934 * @see #update(Graphics)
1935 */
1936 public void repaint(long tm, int x, int y, int width, int height)
1937 {
1938 if (isShowing())
1939 {
1940 ComponentPeer p = peer;
1941 if (p != null)
1942 p.repaint(tm, x, y, width, height);
1943 }
1944 }
1945
1946 /**
1947 * Prints this component. This method is provided so that printing can be
1948 * done in a different manner from painting. However, the implementation
1949 * in this class simply calls the <code>paint()</code> method.
1950 *
1951 * @param g the graphics context of the print device
1952 *
1953 * @see #paint(Graphics)
1954 */
1955 public void print(Graphics g)
1956 {
1957 paint(g);
1958 }
1959
1960 /**
1961 * Prints this component, including all sub-components. This method is
1962 * provided so that printing can be done in a different manner from
1963 * painting. However, the implementation in this class simply calls the
1964 * <code>paintAll()</code> method.
1965 *
1966 * @param g the graphics context of the print device
1967 *
1968 * @see #paintAll(Graphics)
1969 */
1970 public void printAll(Graphics g)
1971 {
1972 paintAll(g);
1973 }
1974
1975 /**
1976 * Called when an image has changed so that this component is repainted.
1977 * This incrementally draws an image as more bits are available, when
1978 * possible. Incremental drawing is enabled if the system property
1979 * <code>awt.image.incrementalDraw</code> is not present or is true, in which
1980 * case the redraw rate is set to 100ms or the value of the system property
1981 * <code>awt.image.redrawrate</code>.
1982 *
1983 * <p>The coordinate system used depends on the particular flags.
1984 *
1985 * @param img the image that has been updated
1986 * @param flags tlags as specified in <code>ImageObserver</code>
1987 * @param x the X coordinate
1988 * @param y the Y coordinate
1989 * @param w the width
1990 * @param h the height
1991 * @return false if the image is completely loaded, loading has been
1992 * aborted, or an error has occurred. true if more updates are
1993 * required.
1994 * @see ImageObserver
1995 * @see Graphics#drawImage(Image, int, int, Color, ImageObserver)
1996 * @see Graphics#drawImage(Image, int, int, ImageObserver)
1997 * @see Graphics#drawImage(Image, int, int, int, int, Color, ImageObserver)
1998 * @see Graphics#drawImage(Image, int, int, int, int, ImageObserver)
1999 * @see ImageObserver#imageUpdate(Image, int, int, int, int, int)
2000 */
2001 public boolean imageUpdate(Image img, int flags, int x, int y, int w, int h)
2002 {
2003 if ((flags & (FRAMEBITS | ALLBITS)) != 0)
2004 repaint();
2005 else if ((flags & SOMEBITS) != 0)
2006 {
2007 if (incrementalDraw)
2008 {
2009 if (redrawRate != null)
2010 {
2011 long tm = redrawRate.longValue();
2012 if (tm < 0)
2013 tm = 0;
2014 repaint(tm);
2015 }
2016 else
2017 repaint(100);
2018 }
2019 }
2020 return (flags & (ALLBITS | ABORT | ERROR)) == 0;
2021 }
2022
2023 /**
2024 * Creates an image from the specified producer.
2025 *
2026 * @param producer the image procedure to create the image from
2027 * @return the resulting image
2028 */
2029 public Image createImage(ImageProducer producer)
2030 {
2031 // Sun allows producer to be null.
2032 if (peer != null)
2033 return peer.createImage(producer);
2034 else
2035 return getToolkit().createImage(producer);
2036 }
2037
2038 /**
2039 * Creates an image with the specified width and height for use in
2040 * double buffering. Headless environments do not support images.
2041 *
2042 * @param width the width of the image
2043 * @param height the height of the image
2044 * @return the requested image, or null if it is not supported
2045 */
2046 public Image createImage (int width, int height)
2047 {
2048 Image returnValue = null;
2049 if (!GraphicsEnvironment.isHeadless ())
2050 {
2051 if (isLightweight () && parent != null)
2052 returnValue = parent.createImage (width, height);
2053 else if (peer != null)
2054 returnValue = peer.createImage (width, height);
2055 }
2056 return returnValue;
2057 }
2058
2059 /**
2060 * Creates an image with the specified width and height for use in
2061 * double buffering. Headless environments do not support images.
2062 *
2063 * @param width the width of the image
2064 * @param height the height of the image
2065 * @return the requested image, or null if it is not supported
2066 * @since 1.4
2067 */
2068 public VolatileImage createVolatileImage(int width, int height)
2069 {
2070 if (GraphicsEnvironment.isHeadless())
2071 return null;
2072 GraphicsConfiguration config = getGraphicsConfiguration();
2073 return config == null ? null
2074 : config.createCompatibleVolatileImage(width, height);
2075 }
2076
2077 /**
2078 * Creates an image with the specified width and height for use in
2079 * double buffering. Headless environments do not support images. The image
2080 * will support the specified capabilities.
2081 *
2082 * @param width the width of the image
2083 * @param height the height of the image
2084 * @param caps the requested capabilities
2085 * @return the requested image, or null if it is not supported
2086 * @throws AWTException if a buffer with the capabilities cannot be created
2087 * @since 1.4
2088 */
2089 public VolatileImage createVolatileImage(int width, int height,
2090 ImageCapabilities caps)
2091 throws AWTException
2092 {
2093 if (GraphicsEnvironment.isHeadless())
2094 return null;
2095 GraphicsConfiguration config = getGraphicsConfiguration();
2096 return config == null ? null
2097 : config.createCompatibleVolatileImage(width, height, caps);
2098 }
2099
2100 /**
2101 * Prepares the specified image for rendering on this component.
2102 *
2103 * @param image the image to prepare for rendering
2104 * @param observer the observer to notify of image preparation status
2105 * @return true if the image is already fully prepared
2106 * @throws NullPointerException if image is null
2107 */
2108 public boolean prepareImage(Image image, ImageObserver observer)
2109 {
2110 return prepareImage(image, image.getWidth(observer),
2111 image.getHeight(observer), observer);
2112 }
2113
2114 /**
2115 * Prepares the specified image for rendering on this component at the
2116 * specified scaled width and height
2117 *
2118 * @param image the image to prepare for rendering
2119 * @param width the scaled width of the image
2120 * @param height the scaled height of the image
2121 * @param observer the observer to notify of image preparation status
2122 * @return true if the image is already fully prepared
2123 */
2124 public boolean prepareImage(Image image, int width, int height,
2125 ImageObserver observer)
2126 {
2127 if (peer != null)
2128 return peer.prepareImage(image, width, height, observer);
2129 else
2130 return getToolkit().prepareImage(image, width, height, observer);
2131 }
2132
2133 /**
2134 * Returns the status of the loading of the specified image. The value
2135 * returned will be those flags defined in <code>ImageObserver</code>.
2136 *
2137 * @param image the image to check on
2138 * @param observer the observer to notify of image loading progress
2139 * @return the image observer flags indicating the status of the load
2140 * @see #prepareImage(Image, int, int, ImageObserver)
2141 * @see Toolkit#checkImage(Image, int, int, ImageObserver)
2142 * @throws NullPointerException if image is null
2143 */
2144 public int checkImage(Image image, ImageObserver observer)
2145 {
2146 return checkImage(image, -1, -1, observer);
2147 }
2148
2149 /**
2150 * Returns the status of the loading of the specified image. The value
2151 * returned will be those flags defined in <code>ImageObserver</code>.
2152 *
2153 * @param image the image to check on
2154 * @param width the scaled image width
2155 * @param height the scaled image height
2156 * @param observer the observer to notify of image loading progress
2157 * @return the image observer flags indicating the status of the load
2158 * @see #prepareImage(Image, int, int, ImageObserver)
2159 * @see Toolkit#checkImage(Image, int, int, ImageObserver)
2160 */
2161 public int checkImage(Image image, int width, int height,
2162 ImageObserver observer)
2163 {
2164 if (peer != null)
2165 return peer.checkImage(image, width, height, observer);
2166 return getToolkit().checkImage(image, width, height, observer);
2167 }
2168
2169 /**
2170 * Sets whether paint messages delivered by the operating system should be
2171 * ignored. This does not affect messages from AWT, except for those
2172 * triggered by OS messages. Setting this to true can allow faster
2173 * performance in full-screen mode or page-flipping.
2174 *
2175 * @param ignoreRepaint the new setting for ignoring repaint events
2176 * @see #getIgnoreRepaint()
2177 * @see BufferStrategy
2178 * @see GraphicsDevice#setFullScreenWindow(Window)
2179 * @since 1.4
2180 */
2181 public void setIgnoreRepaint(boolean ignoreRepaint)
2182 {
2183 this.ignoreRepaint = ignoreRepaint;
2184 }
2185
2186 /**
2187 * Test whether paint events from the operating system are ignored.
2188 *
2189 * @return the status of ignoring paint events
2190 * @see #setIgnoreRepaint(boolean)
2191 * @since 1.4
2192 */
2193 public boolean getIgnoreRepaint()
2194 {
2195 return ignoreRepaint;
2196 }
2197
2198 /**
2199 * Tests whether or not the specified point is contained within this
2200 * component. Coordinates are relative to this component.
2201 *
2202 * @param x the X coordinate of the point to test
2203 * @param y the Y coordinate of the point to test
2204 * @return true if the point is within this component
2205 * @see #getComponentAt(int, int)
2206 */
2207 public boolean contains(int x, int y)
2208 {
2209 return inside (x, y);
2210 }
2211
2212 /**
2213 * Tests whether or not the specified point is contained within this
2214 * component. Coordinates are relative to this component.
2215 *
2216 * @param x the X coordinate of the point to test
2217 * @param y the Y coordinate of the point to test
2218 * @return true if the point is within this component
2219 * @deprecated use {@link #contains(int, int)} instead
2220 */
2221 public boolean inside(int x, int y)
2222 {
2223 return x >= 0 && y >= 0 && x < width && y < height;
2224 }
2225
2226 /**
2227 * Tests whether or not the specified point is contained within this
2228 * component. Coordinates are relative to this component.
2229 *
2230 * @param p the point to test
2231 * @return true if the point is within this component
2232 * @throws NullPointerException if p is null
2233 * @see #getComponentAt(Point)
2234 * @since 1.1
2235 */
2236 public boolean contains(Point p)
2237 {
2238 return contains (p.x, p.y);
2239 }
2240
2241 /**
2242 * Returns the component occupying the position (x,y). This will either
2243 * be this component, an immediate child component, or <code>null</code>
2244 * if neither of the first two occupies the specified location.
2245 *
2246 * @param x the X coordinate to search for components at
2247 * @param y the Y coordinate to search for components at
2248 * @return the component at the specified location, or null
2249 * @see #contains(int, int)
2250 */
2251 public Component getComponentAt(int x, int y)
2252 {
2253 return locate (x, y);
2254 }
2255
2256 /**
2257 * Returns the component occupying the position (x,y). This will either
2258 * be this component, an immediate child component, or <code>null</code>
2259 * if neither of the first two occupies the specified location.
2260 *
2261 * @param x the X coordinate to search for components at
2262 * @param y the Y coordinate to search for components at
2263 * @return the component at the specified location, or null
2264 * @deprecated use {@link #getComponentAt(int, int)} instead
2265 */
2266 public Component locate(int x, int y)
2267 {
2268 return contains (x, y) ? this : null;
2269 }
2270
2271 /**
2272 * Returns the component occupying the position (x,y). This will either
2273 * be this component, an immediate child component, or <code>null</code>
2274 * if neither of the first two occupies the specified location.
2275 *
2276 * @param p the point to search for components at
2277 * @return the component at the specified location, or null
2278 * @throws NullPointerException if p is null
2279 * @see #contains(Point)
2280 * @since 1.1
2281 */
2282 public Component getComponentAt(Point p)
2283 {
2284 return getComponentAt (p.x, p.y);
2285 }
2286
2287 /**
2288 * AWT 1.0 event delivery.
2289 *
2290 * Deliver an AWT 1.0 event to this Component. This method simply
2291 * calls {@link #postEvent}.
2292 *
2293 * @param e the event to deliver
2294 * @deprecated use {@link #dispatchEvent (AWTEvent)} instead
2295 */
2296 public void deliverEvent (Event e)
2297 {
2298 postEvent (e);
2299 }
2300
2301 /**
2302 * Forwards AWT events to processEvent() if:<ul>
2303 * <li>Events have been enabled for this type of event via
2304 * <code>enableEvents()</code></li>,
2305 * <li>There is at least one registered listener for this type of event</li>
2306 * </ul>
2307 *
2308 * @param e the event to dispatch
2309 */
2310 public final void dispatchEvent(AWTEvent e)
2311 {
2312 Event oldEvent = translateEvent(e);
2313 if (oldEvent != null)
2314 postEvent (oldEvent);
2315
2316 // Give toolkit a chance to dispatch the event
2317 // to globally registered listeners.
2318 Toolkit.getDefaultToolkit().globalDispatchEvent(e);
2319
2320 // Some subclasses in the AWT package need to override this behavior,
2321 // hence the use of dispatchEventImpl().
2322 dispatchEventImpl(e);
2323 }
2324
2325 /**
2326 * AWT 1.0 event handler.
2327 *
2328 * This method simply calls handleEvent and returns the result.
2329 *
2330 * @param e the event to handle
2331 * @return true if the event was handled, false otherwise
2332 * @deprecated use {@link #dispatchEvent(AWTEvent)} instead
2333 */
2334 public boolean postEvent (Event e)
2335 {
2336 boolean handled = handleEvent (e);
2337
2338 if (!handled && getParent() != null)
2339 // FIXME: need to translate event coordinates to parent's
2340 // coordinate space.
2341 handled = getParent ().postEvent (e);
2342
2343 return handled;
2344 }
2345
2346 /**
2347 * Adds the specified listener to this component. This is harmless if the
2348 * listener is null, but if the listener has already been registered, it
2349 * will now be registered twice.
2350 *
2351 * @param listener the new listener to add
2352 * @see ComponentEvent
2353 * @see #removeComponentListener(ComponentListener)
2354 * @see #getComponentListeners()
2355 * @since 1.1
2356 */
2357 public synchronized void addComponentListener(ComponentListener listener)
2358 {
2359 componentListener = AWTEventMulticaster.add(componentListener, listener);
2360 if (componentListener != null)
2361 enableEvents(AWTEvent.COMPONENT_EVENT_MASK);
2362 }
2363
2364 /**
2365 * Removes the specified listener from the component. This is harmless if
2366 * the listener was not previously registered.
2367 *
2368 * @param listener the listener to remove
2369 * @see ComponentEvent
2370 * @see #addComponentListener(ComponentListener)
2371 * @see #getComponentListeners()
2372 * @since 1.1
2373 */
2374 public synchronized void removeComponentListener(ComponentListener listener)
2375 {
2376 componentListener = AWTEventMulticaster.remove(componentListener, listener);
2377 }
2378
2379 /**
2380 * Returns an array of all specified listeners registered on this component.
2381 *
2382 * @return an array of listeners
2383 * @see #addComponentListener(ComponentListener)
2384 * @see #removeComponentListener(ComponentListener)
2385 * @since 1.4
2386 */
2387 public synchronized ComponentListener[] getComponentListeners()
2388 {
2389 return (ComponentListener[])
2390 AWTEventMulticaster.getListeners(componentListener,
2391 ComponentListener.class);
2392 }
2393
2394 /**
2395 * Adds the specified listener to this component. This is harmless if the
2396 * listener is null, but if the listener has already been registered, it
2397 * will now be registered twice.
2398 *
2399 * @param listener the new listener to add
2400 * @see FocusEvent
2401 * @see #removeFocusListener(FocusListener)
2402 * @see #getFocusListeners()
2403 * @since 1.1
2404 */
2405 public synchronized void addFocusListener(FocusListener listener)
2406 {
2407 focusListener = AWTEventMulticaster.add(focusListener, listener);
2408 if (focusListener != null)
2409 enableEvents(AWTEvent.FOCUS_EVENT_MASK);
2410 }
2411
2412 /**
2413 * Removes the specified listener from the component. This is harmless if
2414 * the listener was not previously registered.
2415 *
2416 * @param listener the listener to remove
2417 * @see FocusEvent
2418 * @see #addFocusListener(FocusListener)
2419 * @see #getFocusListeners()
2420 * @since 1.1
2421 */
2422 public synchronized void removeFocusListener(FocusListener listener)
2423 {
2424 focusListener = AWTEventMulticaster.remove(focusListener, listener);
2425 }
2426
2427 /**
2428 * Returns an array of all specified listeners registered on this component.
2429 *
2430 * @return an array of listeners
2431 * @see #addFocusListener(FocusListener)
2432 * @see #removeFocusListener(FocusListener)
2433 * @since 1.4
2434 */
2435 public synchronized FocusListener[] getFocusListeners()
2436 {
2437 return (FocusListener[])
2438 AWTEventMulticaster.getListeners(focusListener, FocusListener.class);
2439 }
2440
2441 /**
2442 * Adds the specified listener to this component. This is harmless if the
2443 * listener is null, but if the listener has already been registered, it
2444 * will now be registered twice.
2445 *
2446 * @param listener the new listener to add
2447 * @see HierarchyEvent
2448 * @see #removeHierarchyListener(HierarchyListener)
2449 * @see #getHierarchyListeners()
2450 * @since 1.3
2451 */
2452 public synchronized void addHierarchyListener(HierarchyListener listener)
2453 {
2454 hierarchyListener = AWTEventMulticaster.add(hierarchyListener, listener);
2455 if (hierarchyListener != null)
2456 enableEvents(AWTEvent.HIERARCHY_EVENT_MASK);
2457 }
2458
2459 /**
2460 * Removes the specified listener from the component. This is harmless if
2461 * the listener was not previously registered.
2462 *
2463 * @param listener the listener to remove
2464 * @see HierarchyEvent
2465 * @see #addHierarchyListener(HierarchyListener)
2466 * @see #getHierarchyListeners()
2467 * @since 1.3
2468 */
2469 public synchronized void removeHierarchyListener(HierarchyListener listener)
2470 {
2471 hierarchyListener = AWTEventMulticaster.remove(hierarchyListener, listener);
2472 }
2473
2474 /**
2475 * Returns an array of all specified listeners registered on this component.
2476 *
2477 * @return an array of listeners
2478 * @see #addHierarchyListener(HierarchyListener)
2479 * @see #removeHierarchyListener(HierarchyListener)
2480 * @since 1.4
2481 */
2482 public synchronized HierarchyListener[] getHierarchyListeners()
2483 {
2484 return (HierarchyListener[])
2485 AWTEventMulticaster.getListeners(hierarchyListener,
2486 HierarchyListener.class);
2487 }
2488
2489 /**
2490 * Adds the specified listener to this component. This is harmless if the
2491 * listener is null, but if the listener has already been registered, it
2492 * will now be registered twice.
2493 *
2494 * @param listener the new listener to add
2495 * @see HierarchyEvent
2496 * @see #removeHierarchyBoundsListener(HierarchyBoundsListener)
2497 * @see #getHierarchyBoundsListeners()
2498 * @since 1.3
2499 */
2500 public synchronized void
2501 addHierarchyBoundsListener(HierarchyBoundsListener listener)
2502 {
2503 hierarchyBoundsListener =
2504 AWTEventMulticaster.add(hierarchyBoundsListener, listener);
2505 if (hierarchyBoundsListener != null)
2506 enableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK);
2507 }
2508
2509 /**
2510 * Removes the specified listener from the component. This is harmless if
2511 * the listener was not previously registered.
2512 *
2513 * @param listener the listener to remove
2514 * @see HierarchyEvent
2515 * @see #addHierarchyBoundsListener(HierarchyBoundsListener)
2516 * @see #getHierarchyBoundsListeners()
2517 * @since 1.3
2518 */
2519 public synchronized void
2520 removeHierarchyBoundsListener(HierarchyBoundsListener listener)
2521 {
2522 hierarchyBoundsListener =
2523 AWTEventMulticaster.remove(hierarchyBoundsListener, listener);
2524 }
2525
2526 /**
2527 * Returns an array of all specified listeners registered on this component.
2528 *
2529 * @return an array of listeners
2530 * @see #addHierarchyBoundsListener(HierarchyBoundsListener)
2531 * @see #removeHierarchyBoundsListener(HierarchyBoundsListener)
2532 * @since 1.4
2533 */
2534 public synchronized HierarchyBoundsListener[] getHierarchyBoundsListeners()
2535 {
2536 return (HierarchyBoundsListener[])
2537 AWTEventMulticaster.getListeners(hierarchyBoundsListener,
2538 HierarchyBoundsListener.class);
2539 }
2540
2541 /**
2542 * Adds the specified listener to this component. This is harmless if the
2543 * listener is null, but if the listener has already been registered, it
2544 * will now be registered twice.
2545 *
2546 * @param listener the new listener to add
2547 * @see KeyEvent
2548 * @see #removeKeyListener(KeyListener)
2549 * @see #getKeyListeners()
2550 * @since 1.1
2551 */
2552 public synchronized void addKeyListener(KeyListener listener)
2553 {
2554 keyListener = AWTEventMulticaster.add(keyListener, listener);
2555 if (keyListener != null)
2556 enableEvents(AWTEvent.KEY_EVENT_MASK);
2557 }
2558
2559 /**
2560 * Removes the specified listener from the component. This is harmless if
2561 * the listener was not previously registered.
2562 *
2563 * @param listener the listener to remove
2564 * @see KeyEvent
2565 * @see #addKeyListener(KeyListener)
2566 * @see #getKeyListeners()
2567 * @since 1.1
2568 */
2569 public synchronized void removeKeyListener(KeyListener listener)
2570 {
2571 keyListener = AWTEventMulticaster.remove(keyListener, listener);
2572 }
2573
2574 /**
2575 * Returns an array of all specified listeners registered on this component.
2576 *
2577 * @return an array of listeners
2578 * @see #addKeyListener(KeyListener)
2579 * @see #removeKeyListener(KeyListener)
2580 * @since 1.4
2581 */
2582 public synchronized KeyListener[] getKeyListeners()
2583 {
2584 return (KeyListener[])
2585 AWTEventMulticaster.getListeners(keyListener, KeyListener.class);
2586 }
2587
2588 /**
2589 * Adds the specified listener to this component. This is harmless if the
2590 * listener is null, but if the listener has already been registered, it
2591 * will now be registered twice.
2592 *
2593 * @param listener the new listener to add
2594 * @see MouseEvent
2595 * @see #removeMouseListener(MouseListener)
2596 * @see #getMouseListeners()
2597 * @since 1.1
2598 */
2599 public synchronized void addMouseListener(MouseListener listener)
2600 {
2601 mouseListener = AWTEventMulticaster.add(mouseListener, listener);
2602 if (mouseListener != null)
2603 enableEvents(AWTEvent.MOUSE_EVENT_MASK);
2604 }
2605
2606 /**
2607 * Removes the specified listener from the component. This is harmless if
2608 * the listener was not previously registered.
2609 *
2610 * @param listener the listener to remove
2611 * @see MouseEvent
2612 * @see #addMouseListener(MouseListener)
2613 * @see #getMouseListeners()
2614 * @since 1.1
2615 */
2616 public synchronized void removeMouseListener(MouseListener listener)
2617 {
2618 mouseListener = AWTEventMulticaster.remove(mouseListener, listener);
2619 }
2620
2621 /**
2622 * Returns an array of all specified listeners registered on this component.
2623 *
2624 * @return an array of listeners
2625 * @see #addMouseListener(MouseListener)
2626 * @see #removeMouseListener(MouseListener)
2627 * @since 1.4
2628 */
2629 public synchronized MouseListener[] getMouseListeners()
2630 {
2631 return (MouseListener[])
2632 AWTEventMulticaster.getListeners(mouseListener, MouseListener.class);
2633 }
2634
2635 /**
2636 * Adds the specified listener to this component. This is harmless if the
2637 * listener is null, but if the listener has already been registered, it
2638 * will now be registered twice.
2639 *
2640 * @param listener the new listener to add
2641 * @see MouseEvent
2642 * @see #removeMouseMotionListener(MouseMotionListener)
2643 * @see #getMouseMotionListeners()
2644 * @since 1.1
2645 */
2646 public synchronized void addMouseMotionListener(MouseMotionListener listener)
2647 {
2648 mouseMotionListener = AWTEventMulticaster.add(mouseMotionListener, listener);
2649 if (mouseMotionListener != null)
2650 enableEvents(AWTEvent.MOUSE_MOTION_EVENT_MASK);
2651 }
2652
2653 /**
2654 * Removes the specified listener from the component. This is harmless if
2655 * the listener was not previously registered.
2656 *
2657 * @param listener the listener to remove
2658 * @see MouseEvent
2659 * @see #addMouseMotionListener(MouseMotionListener)
2660 * @see #getMouseMotionListeners()
2661 * @since 1.1
2662 */
2663 public synchronized void removeMouseMotionListener(MouseMotionListener listener)
2664 {
2665 mouseMotionListener = AWTEventMulticaster.remove(mouseMotionListener, listener);
2666 }
2667
2668 /**
2669 * Returns an array of all specified listeners registered on this component.
2670 *
2671 * @return an array of listeners
2672 * @see #addMouseMotionListener(MouseMotionListener)
2673 * @see #removeMouseMotionListener(MouseMotionListener)
2674 * @since 1.4
2675 */
2676 public synchronized MouseMotionListener[] getMouseMotionListeners()
2677 {
2678 return (MouseMotionListener[])
2679 AWTEventMulticaster.getListeners(mouseMotionListener,
2680 MouseMotionListener.class);
2681 }
2682
2683 /**
2684 * Adds the specified listener to this component. This is harmless if the
2685 * listener is null, but if the listener has already been registered, it
2686 * will now be registered twice.
2687 *
2688 * @param listener the new listener to add
2689 * @see MouseEvent
2690 * @see MouseWheelEvent
2691 * @see #removeMouseWheelListener(MouseWheelListener)
2692 * @see #getMouseWheelListeners()
2693 * @since 1.4
2694 */
2695 public synchronized void addMouseWheelListener(MouseWheelListener listener)
2696 {
2697 mouseWheelListener = AWTEventMulticaster.add(mouseWheelListener, listener);
2698 if (mouseWheelListener != null)
2699 enableEvents(AWTEvent.MOUSE_WHEEL_EVENT_MASK);
2700 }
2701
2702 /**
2703 * Removes the specified listener from the component. This is harmless if
2704 * the listener was not previously registered.
2705 *
2706 * @param listener the listener to remove
2707 * @see MouseEvent
2708 * @see MouseWheelEvent
2709 * @see #addMouseWheelListener(MouseWheelListener)
2710 * @see #getMouseWheelListeners()
2711 * @since 1.4
2712 */
2713 public synchronized void removeMouseWheelListener(MouseWheelListener listener)
2714 {
2715 mouseWheelListener = AWTEventMulticaster.remove(mouseWheelListener, listener);
2716 }
2717
2718 /**
2719 * Returns an array of all specified listeners registered on this component.
2720 *
2721 * @return an array of listeners
2722 * @see #addMouseWheelListener(MouseWheelListener)
2723 * @see #removeMouseWheelListener(MouseWheelListener)
2724 * @since 1.4
2725 */
2726 public synchronized MouseWheelListener[] getMouseWheelListeners()
2727 {
2728 return (MouseWheelListener[])
2729 AWTEventMulticaster.getListeners(mouseWheelListener,
2730 MouseWheelListener.class);
2731 }
2732
2733 /**
2734 * Adds the specified listener to this component. This is harmless if the
2735 * listener is null, but if the listener has already been registered, it
2736 * will now be registered twice.
2737 *
2738 * @param listener the new listener to add
2739 * @see InputMethodEvent
2740 * @see #removeInputMethodListener(InputMethodListener)
2741 * @see #getInputMethodListeners()
2742 * @see #getInputMethodRequests()
2743 * @since 1.2
2744 */
2745 public synchronized void addInputMethodListener(InputMethodListener listener)
2746 {
2747 inputMethodListener = AWTEventMulticaster.add(inputMethodListener, listener);
2748 if (inputMethodListener != null)
2749 enableEvents(AWTEvent.INPUT_METHOD_EVENT_MASK);
2750 }
2751
2752 /**
2753 * Removes the specified listener from the component. This is harmless if
2754 * the listener was not previously registered.
2755 *
2756 * @param listener the listener to remove
2757 * @see InputMethodEvent
2758 * @see #addInputMethodListener(InputMethodListener)
2759 * @see #getInputMethodRequests()
2760 * @since 1.2
2761 */
2762 public synchronized void removeInputMethodListener(InputMethodListener listener)
2763 {
2764 inputMethodListener = AWTEventMulticaster.remove(inputMethodListener, listener);
2765 }
2766
2767 /**
2768 * Returns an array of all specified listeners registered on this component.
2769 *
2770 * @return an array of listeners
2771 * @see #addInputMethodListener(InputMethodListener)
2772 * @see #removeInputMethodListener(InputMethodListener)
2773 * @since 1.4
2774 */
2775 public synchronized InputMethodListener[] getInputMethodListeners()
2776 {
2777 return (InputMethodListener[])
2778 AWTEventMulticaster.getListeners(inputMethodListener,
2779 InputMethodListener.class);
2780 }
2781
2782 /**
2783 * Returns all registered {@link EventListener}s of the given
2784 * <code>listenerType</code>.
2785 *
2786 * @param listenerType the class of listeners to filter (<code>null</code>
2787 * not permitted).
2788 *
2789 * @return An array of registered listeners.
2790 *
2791 * @throws ClassCastException if <code>listenerType</code> does not implement
2792 * the {@link EventListener} interface.
2793 * @throws NullPointerException if <code>listenerType</code> is
2794 * <code>null</code>.
2795 *
2796 * @see #getComponentListeners()
2797 * @see #getFocusListeners()
2798 * @see #getHierarchyListeners()
2799 * @see #getHierarchyBoundsListeners()
2800 * @see #getKeyListeners()
2801 * @see #getMouseListeners()
2802 * @see #getMouseMotionListeners()
2803 * @see #getMouseWheelListeners()
2804 * @see #getInputMethodListeners()
2805 * @see #getPropertyChangeListeners()
2806 * @since 1.3
2807 */
2808 public EventListener[] getListeners(Class listenerType)
2809 {
2810 if (listenerType == ComponentListener.class)
2811 return getComponentListeners();
2812 if (listenerType == FocusListener.class)
2813 return getFocusListeners();
2814 if (listenerType == HierarchyListener.class)
2815 return getHierarchyListeners();
2816 if (listenerType == HierarchyBoundsListener.class)
2817 return getHierarchyBoundsListeners();
2818 if (listenerType == KeyListener.class)
2819 return getKeyListeners();
2820 if (listenerType == MouseListener.class)
2821 return getMouseListeners();
2822 if (listenerType == MouseMotionListener.class)
2823 return getMouseMotionListeners();