1. /*
  2. * @(#)Component.java 1.387 04/06/18
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package java.awt;
  8. import java.io.PrintStream;
  9. import java.io.PrintWriter;
  10. import java.util.Vector;
  11. import java.util.Locale;
  12. import java.util.EventListener;
  13. import java.util.Iterator;
  14. import java.util.HashSet;
  15. import java.util.Set;
  16. import java.util.Collections;
  17. import java.awt.peer.ComponentPeer;
  18. import java.awt.peer.ContainerPeer;
  19. import java.awt.peer.LightweightPeer;
  20. import java.awt.image.BufferStrategy;
  21. import java.awt.image.ImageObserver;
  22. import java.awt.image.ImageProducer;
  23. import java.awt.image.ColorModel;
  24. import java.awt.image.VolatileImage;
  25. import java.awt.event.*;
  26. import java.awt.datatransfer.Transferable;
  27. import java.awt.dnd.DnDConstants;
  28. import java.awt.dnd.DragSource;
  29. import java.awt.dnd.DragSourceContext;
  30. import java.awt.dnd.DragSourceListener;
  31. import java.awt.dnd.InvalidDnDOperationException;
  32. import java.io.Serializable;
  33. import java.io.ObjectOutputStream;
  34. import java.io.ObjectInputStream;
  35. import java.io.IOException;
  36. import java.beans.PropertyChangeListener;
  37. import java.beans.PropertyChangeSupport;
  38. import java.awt.event.InputMethodListener;
  39. import java.awt.event.InputMethodEvent;
  40. import java.awt.im.InputContext;
  41. import java.awt.im.InputMethodRequests;
  42. import java.awt.dnd.DropTarget;
  43. import java.lang.reflect.InvocationTargetException;
  44. import java.lang.reflect.Method;
  45. import javax.accessibility.*;
  46. import java.awt.GraphicsConfiguration;
  47. import java.security.AccessController;
  48. import java.security.PrivilegedAction;
  49. import javax.accessibility.*;
  50. import java.util.logging.*;
  51. import sun.security.action.GetPropertyAction;
  52. import sun.awt.AppContext;
  53. import sun.awt.SunToolkit;
  54. import sun.awt.ConstrainableGraphics;
  55. import sun.awt.DebugHelper;
  56. import sun.awt.WindowClosingListener;
  57. import sun.awt.WindowClosingSupport;
  58. import sun.awt.GlobalCursorManager;
  59. import sun.awt.dnd.SunDropTargetEvent;
  60. import sun.awt.im.CompositionArea;
  61. /**
  62. * A <em>component</em> is an object having a graphical representation
  63. * that can be displayed on the screen and that can interact with the
  64. * user. Examples of components are the buttons, checkboxes, and scrollbars
  65. * of a typical graphical user interface. <p>
  66. * The <code>Component</code> class is the abstract superclass of
  67. * the nonmenu-related Abstract Window Toolkit components. Class
  68. * <code>Component</code> can also be extended directly to create a
  69. * lightweight component. A lightweight component is a component that is
  70. * not associated with a native opaque window.
  71. * <p>
  72. * <h3>Serialization</h3>
  73. * It is important to note that only AWT listeners which conform
  74. * to the <code>Serializable</code> protocol will be saved when
  75. * the object is stored. If an AWT object has listeners that
  76. * aren't marked serializable, they will be dropped at
  77. * <code>writeObject</code> time. Developers will need, as always,
  78. * to consider the implications of making an object serializable.
  79. * One situation to watch out for is this:
  80. * <pre>
  81. * import java.awt.*;
  82. * import java.awt.event.*;
  83. * import java.io.Serializable;
  84. *
  85. * class MyApp implements ActionListener, Serializable
  86. * {
  87. * BigObjectThatShouldNotBeSerializedWithAButton bigOne;
  88. * Button aButton = new Button();
  89. *
  90. * MyApp()
  91. * {
  92. * // Oops, now aButton has a listener with a reference
  93. * // to bigOne!
  94. * aButton.addActionListener(this);
  95. * }
  96. *
  97. * public void actionPerformed(ActionEvent e)
  98. * {
  99. * System.out.println("Hello There");
  100. * }
  101. * }
  102. * </pre>
  103. * In this example, serializing <code>aButton</code> by itself
  104. * will cause <code>MyApp</code> and everything it refers to
  105. * to be serialized as well. The problem is that the listener
  106. * is serializable by coincidence, not by design. To separate
  107. * the decisions about <code>MyApp</code> and the
  108. * <code>ActionListener</code> being serializable one can use a
  109. * nested class, as in the following example:
  110. * <pre>
  111. * import java.awt.*;
  112. * import java.awt.event.*;
  113. * import java.io.Serializable;
  114. *
  115. * class MyApp java.io.Serializable
  116. * {
  117. * BigObjectThatShouldNotBeSerializedWithAButton bigOne;
  118. * Button aButton = new Button();
  119. *
  120. * class MyActionListener implements ActionListener
  121. * {
  122. * public void actionPerformed(ActionEvent e)
  123. * {
  124. * System.out.println("Hello There");
  125. * }
  126. * }
  127. *
  128. * MyApp()
  129. * {
  130. * aButton.addActionListener(new MyActionListener());
  131. * }
  132. * }
  133. * </pre>
  134. * <p>
  135. * <b>Note</b>: For more information on the paint mechanisms utilitized
  136. * by AWT and Swing, including information on how to write the most
  137. * efficient painting code, see
  138. * <a href="http://java.sun.com/products/jfc/tsc/articles/painting/index.html">Painting in AWT and Swing</a>.
  139. * <p>
  140. * For details on the focus subsystem, see
  141. * <a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/focus.html">
  142. * How to Use the Focus Subsystem</a>,
  143. * a section in <em>The Java Tutorial</em>, and the
  144. * <a href="../../java/awt/doc-files/FocusSpec.html">Focus Specification</a>
  145. * for more information.
  146. *
  147. * @version 1.387, 06/18/04
  148. * @author Arthur van Hoff
  149. * @author Sami Shaio
  150. */
  151. public abstract class Component implements ImageObserver, MenuContainer,
  152. Serializable
  153. {
  154. private static final Logger focusLog = Logger.getLogger("java.awt.focus.Component");
  155. private static final Logger log = Logger.getLogger("java.awt.Component");
  156. /**
  157. * The peer of the component. The peer implements the component's
  158. * behavior. The peer is set when the <code>Component</code> is
  159. * added to a container that also is a peer.
  160. * @see #addNotify
  161. * @see #removeNotify
  162. */
  163. transient ComponentPeer peer;
  164. /**
  165. * The parent of the object. It may be <code>null</code>
  166. * for top-level components.
  167. * @see #getParent
  168. */
  169. transient Container parent;
  170. /**
  171. * The <code>AppContext</code> of the component. Applets/Plugin may
  172. * change the AppContext.
  173. */
  174. transient AppContext appContext;
  175. /**
  176. * The x position of the component in the parent's coordinate system.
  177. *
  178. * @serial
  179. * @see #getLocation
  180. */
  181. int x;
  182. /**
  183. * The y position of the component in the parent's coordinate system.
  184. *
  185. * @serial
  186. * @see #getLocation
  187. */
  188. int y;
  189. /**
  190. * The width of the component.
  191. *
  192. * @serial
  193. * @see #getSize
  194. */
  195. int width;
  196. /**
  197. * The height of the component.
  198. *
  199. * @serial
  200. * @see #getSize
  201. */
  202. int height;
  203. /**
  204. * The foreground color for this component.
  205. * <code>foreground</code> can be <code>null</code>.
  206. *
  207. * @serial
  208. * @see #getForeground
  209. * @see #setForeground
  210. */
  211. Color foreground;
  212. /**
  213. * The background color for this component.
  214. * <code>background</code> can be <code>null</code>.
  215. *
  216. * @serial
  217. * @see #getBackground
  218. * @see #setBackground
  219. */
  220. Color background;
  221. /**
  222. * The font used by this component.
  223. * The <code>font</code> can be <code>null</code>.
  224. *
  225. * @serial
  226. * @see #getFont
  227. * @see #setFont
  228. */
  229. Font font;
  230. /**
  231. * The font which the peer is currently using.
  232. * (<code>null</code> if no peer exists.)
  233. */
  234. Font peerFont;
  235. /**
  236. * The cursor displayed when pointer is over this component.
  237. * This value can be <code>null</code>.
  238. *
  239. * @serial
  240. * @see #getCursor
  241. * @see #setCursor
  242. */
  243. Cursor cursor;
  244. /**
  245. * The locale for the component.
  246. *
  247. * @serial
  248. * @see #getLocale
  249. * @see #setLocale
  250. */
  251. Locale locale;
  252. /**
  253. * A reference to a <code>GraphicsConfiguration</code> object
  254. * used to describe the characteristics of a graphics
  255. * destination.
  256. * This value can be <code>null</code>.
  257. *
  258. * @since 1.3
  259. * @serial
  260. * @see GraphicsConfiguration
  261. * @see #getGraphicsConfiguration
  262. */
  263. transient GraphicsConfiguration graphicsConfig = null;
  264. /**
  265. * A reference to a <code>BufferStrategy</code> object
  266. * used to manipulate the buffers on this component.
  267. *
  268. * @since 1.4
  269. * @see java.awt.image.BufferStrategy
  270. * @see #getBufferStrategy()
  271. */
  272. transient BufferStrategy bufferStrategy = null;
  273. /**
  274. * True when the object should ignore all repaint events.
  275. *
  276. * @since 1.4
  277. * @serial
  278. * @see #setIgnoreRepaint
  279. * @see #getIgnoreRepaint
  280. */
  281. boolean ignoreRepaint = false;
  282. /**
  283. * True when the object is visible. An object that is not
  284. * visible is not drawn on the screen.
  285. *
  286. * @serial
  287. * @see #isVisible
  288. * @see #setVisible
  289. */
  290. boolean visible = true;
  291. /**
  292. * True when the object is enabled. An object that is not
  293. * enabled does not interact with the user.
  294. *
  295. * @serial
  296. * @see #isEnabled
  297. * @see #setEnabled
  298. */
  299. boolean enabled = true;
  300. /**
  301. * True when the object is valid. An invalid object needs to
  302. * be layed out. This flag is set to false when the object
  303. * size is changed.
  304. *
  305. * @serial
  306. * @see #isValid
  307. * @see #validate
  308. * @see #invalidate
  309. */
  310. boolean valid = false;
  311. /**
  312. * The <code>DropTarget</code> associated with this component.
  313. *
  314. * @since 1.2
  315. * @serial
  316. * @see #setDropTarget
  317. * @see #getDropTarget
  318. */
  319. DropTarget dropTarget;
  320. /**
  321. * @serial
  322. * @see #add
  323. */
  324. Vector popups;
  325. /**
  326. * A component's name.
  327. * This field can be <code>null</code>.
  328. *
  329. * @serial
  330. * @see #getName
  331. * @see #setName(String)
  332. */
  333. private String name;
  334. /**
  335. * A bool to determine whether the name has
  336. * been set explicitly. <code>nameExplicitlySet</code> will
  337. * be false if the name has not been set and
  338. * true if it has.
  339. *
  340. * @serial
  341. * @see #getName
  342. * @see #setName(String)
  343. */
  344. private boolean nameExplicitlySet = false;
  345. /**
  346. * Indicates whether this Component can be focused.
  347. *
  348. * @serial
  349. * @see #setFocusable
  350. * @see #isFocusable
  351. * @since 1.4
  352. */
  353. private boolean focusable = true;
  354. private static final int FOCUS_TRAVERSABLE_UNKNOWN = 0;
  355. private static final int FOCUS_TRAVERSABLE_DEFAULT = 1;
  356. private static final int FOCUS_TRAVERSABLE_SET = 2;
  357. /**
  358. * Tracks whether this Component is relying on default focus travesability.
  359. *
  360. * @serial
  361. * @since 1.4
  362. */
  363. private int isFocusTraversableOverridden = FOCUS_TRAVERSABLE_UNKNOWN;
  364. /**
  365. * The focus traversal keys. These keys will generate focus traversal
  366. * behavior for Components for which focus traversal keys are enabled. If a
  367. * value of null is specified for a traversal key, this Component inherits
  368. * that traversal key from its parent. If all ancestors of this Component
  369. * have null specified for that traversal key, then the current
  370. * KeyboardFocusManager's default traversal key is used.
  371. *
  372. * @serial
  373. * @see #setFocusTraversalKeys
  374. * @see #getFocusTraversalKeys
  375. * @since 1.4
  376. */
  377. Set[] focusTraversalKeys;
  378. private static final String[] focusTraversalKeyPropertyNames = {
  379. "forwardFocusTraversalKeys",
  380. "backwardFocusTraversalKeys",
  381. "upCycleFocusTraversalKeys",
  382. "downCycleFocusTraversalKeys"
  383. };
  384. /**
  385. * Indicates whether focus traversal keys are enabled for this Component.
  386. * Components for which focus traversal keys are disabled receive key
  387. * events for focus traversal keys. Components for which focus traversal
  388. * keys are enabled do not see these events; instead, the events are
  389. * automatically converted to traversal operations.
  390. *
  391. * @serial
  392. * @see #setFocusTraversalKeysEnabled
  393. * @see #getFocusTraversalKeysEnabled
  394. * @since 1.4
  395. */
  396. private boolean focusTraversalKeysEnabled = true;
  397. /**
  398. * The locking object for AWT component-tree and layout operations.
  399. *
  400. * @see #getTreeLock
  401. */
  402. static final Object LOCK = new AWTTreeLock();
  403. static class AWTTreeLock {}
  404. /**
  405. * Minimum size.
  406. * (This field perhaps should have been transient).
  407. *
  408. * @serial
  409. */
  410. Dimension minSize;
  411. /**
  412. * Whether or not setMinimumSize has been invoked with a non-null value.
  413. */
  414. boolean minSizeSet;
  415. /**
  416. * Preferred size.
  417. * (This field perhaps should have been transient).
  418. *
  419. * @serial
  420. */
  421. Dimension prefSize;
  422. /**
  423. * Whether or not setPreferredSize has been invoked with a non-null value.
  424. */
  425. boolean prefSizeSet;
  426. /**
  427. * Maximum size
  428. *
  429. * @serial
  430. */
  431. Dimension maxSize;
  432. /**
  433. * Whether or not setMaximumSize has been invoked with a non-null value.
  434. */
  435. boolean maxSizeSet;
  436. /**
  437. * The orientation for this component.
  438. * @see #getComponentOrientation
  439. * @see #setComponentOrientation
  440. */
  441. transient ComponentOrientation componentOrientation
  442. = ComponentOrientation.UNKNOWN;
  443. /**
  444. * <code>newEventsOnly</code> will be true if the event is
  445. * one of the event types enabled for the component.
  446. * It will then allow for normal processing to
  447. * continue. If it is false the event is passed
  448. * to the component's parent and up the ancestor
  449. * tree until the event has been consumed.
  450. *
  451. * @serial
  452. * @see #dispatchEvent
  453. */
  454. boolean newEventsOnly = false;
  455. transient ComponentListener componentListener;
  456. transient FocusListener focusListener;
  457. transient HierarchyListener hierarchyListener;
  458. transient HierarchyBoundsListener hierarchyBoundsListener;
  459. transient KeyListener keyListener;
  460. transient MouseListener mouseListener;
  461. transient MouseMotionListener mouseMotionListener;
  462. transient MouseWheelListener mouseWheelListener;
  463. transient InputMethodListener inputMethodListener;
  464. transient RuntimeException windowClosingException = null;
  465. /** Internal, constants for serialization */
  466. final static String actionListenerK = "actionL";
  467. final static String adjustmentListenerK = "adjustmentL";
  468. final static String componentListenerK = "componentL";
  469. final static String containerListenerK = "containerL";
  470. final static String focusListenerK = "focusL";
  471. final static String itemListenerK = "itemL";
  472. final static String keyListenerK = "keyL";
  473. final static String mouseListenerK = "mouseL";
  474. final static String mouseMotionListenerK = "mouseMotionL";
  475. final static String mouseWheelListenerK = "mouseWheelL";
  476. final static String textListenerK = "textL";
  477. final static String ownedWindowK = "ownedL";
  478. final static String windowListenerK = "windowL";
  479. final static String inputMethodListenerK = "inputMethodL";
  480. final static String hierarchyListenerK = "hierarchyL";
  481. final static String hierarchyBoundsListenerK = "hierarchyBoundsL";
  482. final static String windowStateListenerK = "windowStateL";
  483. final static String windowFocusListenerK = "windowFocusL";
  484. /**
  485. * The <code>eventMask</code> is ONLY set by subclasses via
  486. * <code>enableEvents</code>.
  487. * The mask should NOT be set when listeners are registered
  488. * so that we can distinguish the difference between when
  489. * listeners request events and subclasses request them.
  490. * One bit is used to indicate whether input methods are
  491. * enabled; this bit is set by <code>enableInputMethods</code> and is
  492. * on by default.
  493. *
  494. * @serial
  495. * @see #enableInputMethods
  496. * @see AWTEvent
  497. */
  498. long eventMask = AWTEvent.INPUT_METHODS_ENABLED_MASK;
  499. private static final DebugHelper dbg = DebugHelper.create(Component.class);
  500. /**
  501. * Static properties for incremental drawing.
  502. * @see #imageUpdate
  503. */
  504. static boolean isInc;
  505. static int incRate;
  506. static {
  507. /* ensure that the necessary native libraries are loaded */
  508. Toolkit.loadLibraries();
  509. /* initialize JNI field and method ids */
  510. if (!GraphicsEnvironment.isHeadless()) {
  511. initIDs();
  512. }
  513. String s = (String) java.security.AccessController.doPrivileged(
  514. new GetPropertyAction("awt.image.incrementaldraw"));
  515. isInc = (s == null || s.equals("true"));
  516. s = (String) java.security.AccessController.doPrivileged(
  517. new GetPropertyAction("awt.image.redrawrate"));
  518. incRate = (s != null) ? Integer.parseInt(s) : 100;
  519. }
  520. /**
  521. * Ease-of-use constant for <code>getAlignmentY()</code>.
  522. * Specifies an alignment to the top of the component.
  523. * @see #getAlignmentY
  524. */
  525. public static final float TOP_ALIGNMENT = 0.0f;
  526. /**
  527. * Ease-of-use constant for <code>getAlignmentY</code> and
  528. * <code>getAlignmentX</code>. Specifies an alignment to
  529. * the center of the component
  530. * @see #getAlignmentX
  531. * @see #getAlignmentY
  532. */
  533. public static final float CENTER_ALIGNMENT = 0.5f;
  534. /**
  535. * Ease-of-use constant for <code>getAlignmentY</code>.
  536. * Specifies an alignment to the bottom of the component.
  537. * @see #getAlignmentY
  538. */
  539. public static final float BOTTOM_ALIGNMENT = 1.0f;
  540. /**
  541. * Ease-of-use constant for <code>getAlignmentX</code>.
  542. * Specifies an alignment to the left side of the component.
  543. * @see #getAlignmentX
  544. */
  545. public static final float LEFT_ALIGNMENT = 0.0f;
  546. /**
  547. * Ease-of-use constant for <code>getAlignmentX</code>.
  548. * Specifies an alignment to the right side of the component.
  549. * @see #getAlignmentX
  550. */
  551. public static final float RIGHT_ALIGNMENT = 1.0f;
  552. /*
  553. * JDK 1.1 serialVersionUID
  554. */
  555. private static final long serialVersionUID = -7644114512714619750L;
  556. /**
  557. * If any <code>PropertyChangeListeners</code> have been registered,
  558. * the <code>changeSupport</code> field describes them.
  559. *
  560. * @serial
  561. * @since 1.2
  562. * @see #addPropertyChangeListener
  563. * @see #removePropertyChangeListener
  564. * @see #firePropertyChange
  565. */
  566. private PropertyChangeSupport changeSupport;
  567. boolean isPacked = false;
  568. /**
  569. * This object is used as a key for internal hashtables.
  570. */
  571. transient private Object privateKey = new Object();
  572. /**
  573. * Pseudoparameter for direct Geometry API (setLocation, setBounds setSize
  574. * to signal setBounds what's changing. Should be used under TreeLock.
  575. * This is only needed due to the inability to change the cross-calling
  576. * order of public and deprecated methods.
  577. */
  578. private int boundsOp = ComponentPeer.DEFAULT_OPERATION;
  579. /**
  580. * Should only be used in subclass getBounds to check that part of bounds
  581. * is actualy changing
  582. */
  583. int getBoundsOp() {
  584. assert Thread.holdsLock(getTreeLock());
  585. return boundsOp;
  586. }
  587. void setBoundsOp(int op) {
  588. assert Thread.holdsLock(getTreeLock());
  589. if (op == ComponentPeer.RESET_OPERATION) {
  590. boundsOp = ComponentPeer.DEFAULT_OPERATION;
  591. } else
  592. if (boundsOp == ComponentPeer.DEFAULT_OPERATION) {
  593. boundsOp = op;
  594. }
  595. }
  596. /**
  597. * Constructs a new component. Class <code>Component</code> can be
  598. * extended directly to create a lightweight component that does not
  599. * utilize an opaque native window. A lightweight component must be
  600. * hosted by a native container somewhere higher up in the component
  601. * tree (for example, by a <code>Frame</code> object).
  602. */
  603. protected Component() {
  604. appContext = AppContext.getAppContext();
  605. }
  606. void initializeFocusTraversalKeys() {
  607. focusTraversalKeys = new Set[3];
  608. }
  609. /**
  610. * Constructs a name for this component. Called by <code>getName</code>
  611. * when the name is <code>null</code>.
  612. */
  613. String constructComponentName() {
  614. return null; // For strict compliance with prior platform versions, a Component
  615. // that doesn't set its name should return null from
  616. // getName()
  617. }
  618. /**
  619. * Gets the name of the component.
  620. * @return this component's name
  621. * @see #setName
  622. * @since JDK1.1
  623. */
  624. public String getName() {
  625. if (name == null && !nameExplicitlySet) {
  626. synchronized(this) {
  627. if (name == null && !nameExplicitlySet)
  628. name = constructComponentName();
  629. }
  630. }
  631. return name;
  632. }
  633. /**
  634. * Sets the name of the component to the specified string.
  635. * @param name the string that is to be this
  636. * component's name
  637. * @see #getName
  638. * @since JDK1.1
  639. */
  640. public void setName(String name) {
  641. String oldName;
  642. synchronized(this) {
  643. oldName = this.name;
  644. this.name = name;
  645. nameExplicitlySet = true;
  646. }
  647. firePropertyChange("name", oldName, name);
  648. }
  649. /**
  650. * Gets the parent of this component.
  651. * @return the parent container of this component
  652. * @since JDK1.0
  653. */
  654. public Container getParent() {
  655. return getParent_NoClientCode();
  656. }
  657. // NOTE: This method may be called by privileged threads.
  658. // This functionality is implemented in a package-private method
  659. // to insure that it cannot be overridden by client subclasses.
  660. // DO NOT INVOKE CLIENT CODE ON THIS THREAD!
  661. final Container getParent_NoClientCode() {
  662. return parent;
  663. }
  664. /**
  665. * @deprecated As of JDK version 1.1,
  666. * programs should not directly manipulate peers;
  667. * replaced by <code>boolean isDisplayable()</code>.
  668. */
  669. @Deprecated
  670. public ComponentPeer getPeer() {
  671. return peer;
  672. }
  673. /**
  674. * Associate a <code>DropTarget</code> with this component.
  675. * The <code>Component</code> will receive drops only if it
  676. * is enabled.
  677. *
  678. * @see #isEnabled
  679. * @param dt The DropTarget
  680. */
  681. public synchronized void setDropTarget(DropTarget dt) {
  682. if (dt == dropTarget || (dropTarget != null && dropTarget.equals(dt)))
  683. return;
  684. DropTarget old;
  685. if ((old = dropTarget) != null) {
  686. if (peer != null) dropTarget.removeNotify(peer);
  687. DropTarget t = dropTarget;
  688. dropTarget = null;
  689. try {
  690. t.setComponent(null);
  691. } catch (IllegalArgumentException iae) {
  692. // ignore it.
  693. }
  694. }
  695. // if we have a new one, and we have a peer, add it!
  696. if ((dropTarget = dt) != null) {
  697. try {
  698. dropTarget.setComponent(this);
  699. if (peer != null) dropTarget.addNotify(peer);
  700. } catch (IllegalArgumentException iae) {
  701. if (old != null) {
  702. try {
  703. old.setComponent(this);
  704. if (peer != null) dropTarget.addNotify(peer);
  705. } catch (IllegalArgumentException iae1) {
  706. // ignore it!
  707. }
  708. }
  709. }
  710. }
  711. }
  712. /**
  713. * Gets the <code>DropTarget</code> associated with this
  714. * <code>Component</code>.
  715. */
  716. public synchronized DropTarget getDropTarget() { return dropTarget; }
  717. /**
  718. * Gets the <code>GraphicsConfiguration</code> associated with this
  719. * <code>Component</code>.
  720. * If the <code>Component</code> has not been assigned a specific
  721. * <code>GraphicsConfiguration</code>,
  722. * the <code>GraphicsConfiguration</code> of the
  723. * <code>Component</code> object's top-level container is
  724. * returned.
  725. * If the <code>Component</code> has been created, but not yet added
  726. * to a <code>Container</code>, this method returns <code>null</code>.
  727. *
  728. * @return the <code>GraphicsConfiguration</code> used by this
  729. * <code>Component</code> or <code>null</code>
  730. * @since 1.3
  731. */
  732. public GraphicsConfiguration getGraphicsConfiguration() {
  733. synchronized(getTreeLock()) {
  734. if (graphicsConfig != null) {
  735. return graphicsConfig;
  736. } else if (getParent() != null) {
  737. return getParent().getGraphicsConfiguration();
  738. } else {
  739. return null;
  740. }
  741. }
  742. }
  743. /**
  744. * Resets this <code>Component</code>'s
  745. * <code>GraphicsConfiguration</code> back to a default
  746. * value. For most componenets, this is <code>null</code>.
  747. * Called from the Toolkit thread, so NO CLIENT CODE.
  748. */
  749. void resetGC() {
  750. synchronized(getTreeLock()) {
  751. graphicsConfig = null;
  752. }
  753. }
  754. /*
  755. * Not called on Component, but needed for Canvas and Window
  756. */
  757. void setGCFromPeer() {
  758. synchronized(getTreeLock()) {
  759. if (peer != null) { // can't imagine how this will be false,
  760. // but just in case
  761. graphicsConfig = peer.getGraphicsConfiguration();
  762. } else {
  763. graphicsConfig = null;
  764. }
  765. }
  766. }
  767. /**
  768. * Checks that this component's <code>GraphicsDevice</code>
  769. * <code>idString</code> matches the string argument.
  770. */
  771. void checkGD(String stringID) {
  772. if (graphicsConfig != null) {
  773. if (!graphicsConfig.getDevice().getIDstring().equals(stringID)) {
  774. throw new IllegalArgumentException(
  775. "adding a container to a container on a different GraphicsDevice");
  776. }
  777. }
  778. }
  779. /**
  780. * Gets this component's locking object (the object that owns the thread
  781. * sychronization monitor) for AWT component-tree and layout
  782. * operations.
  783. * @return this component's locking object
  784. */
  785. public final Object getTreeLock() {
  786. return LOCK;
  787. }
  788. /**
  789. * Gets the toolkit of this component. Note that
  790. * the frame that contains a component controls which
  791. * toolkit is used by that component. Therefore if the component
  792. * is moved from one frame to another, the toolkit it uses may change.
  793. * @return the toolkit of this component
  794. * @since JDK1.0
  795. */
  796. public Toolkit getToolkit() {
  797. return getToolkitImpl();
  798. }
  799. /*
  800. * This is called by the native code, so client code can't
  801. * be called on the toolkit thread.
  802. */
  803. final Toolkit getToolkitImpl() {
  804. ComponentPeer peer = this.peer;
  805. if ((peer != null) && ! (peer instanceof LightweightPeer)){
  806. return peer.getToolkit();
  807. }
  808. Container parent = this.parent;
  809. if (parent != null) {
  810. return parent.getToolkitImpl();
  811. }
  812. return Toolkit.getDefaultToolkit();
  813. }
  814. /**
  815. * Determines whether this component is valid. A component is valid
  816. * when it is correctly sized and positioned within its parent
  817. * container and all its children are also valid.
  818. * In order to account for peers' size requirements, components are invalidated
  819. * before they are first shown on the screen. By the time the parent container
  820. * is fully realized, all its components will be valid.
  821. * @return <code>true</code> if the component is valid, <code>false</code>
  822. * otherwise
  823. * @see #validate
  824. * @see #invalidate
  825. * @since JDK1.0
  826. */
  827. public boolean isValid() {
  828. return (peer != null) && valid;
  829. }
  830. /**
  831. * Determines whether this component is displayable. A component is
  832. * displayable when it is connected to a native screen resource.
  833. * <p>
  834. * A component is made displayable either when it is added to
  835. * a displayable containment hierarchy or when its containment
  836. * hierarchy is made displayable.
  837. * A containment hierarchy is made displayable when its ancestor
  838. * window is either packed or made visible.
  839. * <p>
  840. * A component is made undisplayable either when it is removed from
  841. * a displayable containment hierarchy or when its containment hierarchy
  842. * is made undisplayable. A containment hierarchy is made
  843. * undisplayable when its ancestor window is disposed.
  844. *
  845. * @return <code>true</code> if the component is displayable,
  846. * <code>false</code> otherwise
  847. * @see Container#add(Component)
  848. * @see Window#pack
  849. * @see Window#show
  850. * @see Container#remove(Component)
  851. * @see Window#dispose
  852. * @since 1.2
  853. */
  854. public boolean isDisplayable() {
  855. return getPeer() != null;
  856. }
  857. /**
  858. * Determines whether this component should be visible when its
  859. * parent is visible. Components are
  860. * initially visible, with the exception of top level components such
  861. * as <code>Frame</code> objects.
  862. * @return <code>true</code> if the component is visible,
  863. * <code>false</code> otherwise
  864. * @see #setVisible
  865. * @since JDK1.0
  866. */
  867. public boolean isVisible() {
  868. return visible;
  869. }
  870. /**
  871. * Determines whether this component will be displayed on the screen
  872. * if it's displayable.
  873. * @return <code>true</code> if the component and all of its ancestors
  874. * are visible, <code>false</code> otherwise
  875. */
  876. boolean isRecursivelyVisible() {
  877. return visible && (parent == null || parent.isRecursivelyVisible());
  878. }
  879. /**
  880. * Translates absolute coordinates into coordinates in the coordinate
  881. * space of this component.
  882. */
  883. Point pointRelativeToComponent(Point absolute) {
  884. Point compCoords = getLocationOnScreen();
  885. return new Point(absolute.x - compCoords.x,
  886. absolute.y - compCoords.y);
  887. }
  888. /**
  889. * Assuming that mouse location is stored in PointerInfo passed
  890. * to this method, it finds a Component that is in the same
  891. * Window as this Component and is located under the mouse pointer.
  892. * If no such Component exists, null is returned.
  893. * NOTE: this method should be called under the protection of
  894. * tree lock, as it is done in Component.getMousePosition() and
  895. * Container.getMousePosition(boolean).
  896. */
  897. Component findUnderMouseInWindow(PointerInfo pi) {
  898. if (!isShowing()) {
  899. return null;
  900. }
  901. Window win = getContainingWindow();
  902. if (!Toolkit.getDefaultToolkit().getMouseInfoPeer().isWindowUnderMouse(win)) {
  903. return null;
  904. }
  905. final boolean INCLUDE_DISABLED = true;
  906. Point relativeToWindow = win.pointRelativeToComponent(pi.getLocation());
  907. Component inTheSameWindow = win.findComponentAt(relativeToWindow.x,
  908. relativeToWindow.y,
  909. INCLUDE_DISABLED);
  910. return inTheSameWindow;
  911. }
  912. /**
  913. * Returns the position of the mouse pointer in this <code>Component</code>'s
  914. * coordinate space if the <code>Component</code> is directly under the mouse
  915. * pointer, otherwise returns <code>null</code>.
  916. * If the <code>Component</code> is not showing on the screen, this method
  917. * returns <code>null</code> even if the mouse pointer is above the area
  918. * where the <code>Component</code> would be displayed.
  919. * If the <code>Component</code> is partially or fully obscured by other
  920. * <code>Component</code>s or native windows, this method returns a non-null
  921. * value only if the mouse pointer is located above the unobscured part of the
  922. * <code>Component</code>.
  923. * <p>
  924. * For <code>Container</code>s it returns a non-null value if the mouse is
  925. * above the <code>Container</code> itself or above any of its descendants.
  926. * Use {@link Container#getMousePosition(boolean)} if you need to exclude children.
  927. * <p>
  928. * Sometimes the exact mouse coordinates are not important, and the only thing
  929. * that matters is whether a specific <code>Component</code> is under the mouse
  930. * pointer. If the return value of this method is <code>null</code>, mouse
  931. * pointer is not directly above the <code>Component</code>.
  932. *
  933. * @exception HeadlessException if GraphicsEnvironment.isHeadless() returns true
  934. * @see #isShowing
  935. * @see Container#getMousePosition
  936. * @return mouse coordinates relative to this <code>Component</code>, or null
  937. * @since 1.5
  938. */
  939. public Point getMousePosition() throws HeadlessException {
  940. if (GraphicsEnvironment.isHeadless()) {
  941. throw new HeadlessException();
  942. }
  943. PointerInfo pi = (PointerInfo)java.security.AccessController.doPrivileged(
  944. new java.security.PrivilegedAction() {
  945. public Object run() {
  946. return MouseInfo.getPointerInfo();
  947. }
  948. }
  949. );
  950. synchronized (getTreeLock()) {
  951. Component inTheSameWindow = findUnderMouseInWindow(pi);
  952. if (!isSameOrAncestorOf(inTheSameWindow, true)) {
  953. return null;
  954. }
  955. return pointRelativeToComponent(pi.getLocation());
  956. }
  957. }
  958. /**
  959. * Overridden in Container. Must be called under TreeLock.
  960. */
  961. boolean isSameOrAncestorOf(Component comp, boolean allowChildren) {
  962. return comp == this;
  963. }
  964. /**
  965. * Determines whether this component is showing on screen. This means
  966. * that the component must be visible, and it must be in a container
  967. * that is visible and showing.
  968. * @return <code>true</code> if the component is showing,
  969. * <code>false</code> otherwise
  970. * @see #setVisible
  971. * @since JDK1.0
  972. */
  973. public boolean isShowing() {
  974. if (visible && (peer != null)) {
  975. Container parent = this.parent;
  976. return (parent == null) || parent.isShowing();
  977. }
  978. return false;
  979. }
  980. /**
  981. * Determines whether this component is enabled. An enabled component
  982. * can respond to user input and generate events. Components are
  983. * enabled initially by default. A component may be enabled or disabled by
  984. * calling its <code>setEnabled</code> method.
  985. * @return <code>true</code> if the component is enabled,
  986. * <code>false</code> otherwise
  987. * @see #setEnabled
  988. * @since JDK1.0
  989. */
  990. public boolean isEnabled() {
  991. return isEnabledImpl();
  992. }
  993. /*
  994. * This is called by the native code, so client code can't
  995. * be called on the toolkit thread.
  996. */
  997. final boolean isEnabledImpl() {
  998. return enabled;
  999. }
  1000. /**
  1001. * Enables or disables this component, depending on the value of the
  1002. * parameter <code>b</code>. An enabled component can respond to user
  1003. * input and generate events. Components are enabled initially by default.
  1004. *
  1005. * <p>Note: Disabling a lightweight component does not prevent it from
  1006. * receiving MouseEvents.
  1007. *
  1008. * @param b If <code>true</code>, this component is
  1009. * enabled; otherwise this component is disabled
  1010. * @see #isEnabled
  1011. * @see #isLightweight
  1012. * @since JDK1.1
  1013. */
  1014. public void setEnabled(boolean b) {
  1015. enable(b);
  1016. }
  1017. /**
  1018. * @deprecated As of JDK version 1.1,
  1019. * replaced by <code>setEnabled(boolean)</code>.
  1020. */
  1021. @Deprecated
  1022. public void enable() {
  1023. if (!enabled) {
  1024. synchronized (getTreeLock()) {
  1025. enabled = true;
  1026. ComponentPeer peer = this.peer;
  1027. if (peer != null) {
  1028. peer.enable();
  1029. if (visible) {
  1030. updateCursorImmediately();
  1031. }
  1032. }
  1033. }
  1034. if (accessibleContext != null) {
  1035. accessibleContext.firePropertyChange(
  1036. AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
  1037. null, AccessibleState.ENABLED);
  1038. }
  1039. }
  1040. }
  1041. /**
  1042. * @deprecated As of JDK version 1.1,
  1043. * replaced by <code>setEnabled(boolean)</code>.
  1044. */
  1045. @Deprecated
  1046. public void enable(boolean b) {
  1047. if (b) {
  1048. enable();
  1049. } else {
  1050. disable();
  1051. }
  1052. }
  1053. /**
  1054. * @deprecated As of JDK version 1.1,
  1055. * replaced by <code>setEnabled(boolean)</code>.
  1056. */
  1057. @Deprecated
  1058. public void disable() {
  1059. if (enabled) {
  1060. KeyboardFocusManager.clearMostRecentFocusOwner(this);
  1061. synchronized (getTreeLock()) {
  1062. enabled = false;
  1063. if (isFocusOwner()) {
  1064. // Don't clear the global focus owner. If transferFocus
  1065. // fails, we want the focus to stay on the disabled
  1066. // Component so that keyboard traversal, et. al. still
  1067. // makes sense to the user.
  1068. autoTransferFocus(false);
  1069. }
  1070. ComponentPeer peer = this.peer;
  1071. if (peer != null) {
  1072. peer.disable();
  1073. if (visible) {
  1074. updateCursorImmediately();
  1075. }
  1076. }
  1077. }
  1078. if (accessibleContext != null) {
  1079. accessibleContext.firePropertyChange(
  1080. AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
  1081. null, AccessibleState.ENABLED);
  1082. }
  1083. }
  1084. }
  1085. /**
  1086. * Returns true if this component is painted to an offscreen image
  1087. * ("buffer") that's copied to the screen later. Component
  1088. * subclasses that support double buffering should override this
  1089. * method to return true if double buffering is enabled.
  1090. *
  1091. * @return false by default
  1092. */
  1093. public boolean isDoubleBuffered() {
  1094. return false;
  1095. }
  1096. /**
  1097. * Enables or disables input method support for this component. If input
  1098. * method support is enabled and the component also processes key events,
  1099. * incoming events are offered to
  1100. * the current input method and will only be processed by the component or
  1101. * dispatched to its listeners if the input method does not consume them.
  1102. * By default, input method support is enabled.
  1103. *
  1104. * @param enable true to enable, false to disable
  1105. * @see #processKeyEvent
  1106. * @since 1.2
  1107. */
  1108. public void enableInputMethods(boolean enable) {
  1109. if (enable) {
  1110. if ((eventMask & AWTEvent.INPUT_METHODS_ENABLED_MASK) != 0)
  1111. return;
  1112. // If this component already has focus, then activate the
  1113. // input method by dispatching a synthesized focus gained
  1114. // event.
  1115. if (isFocusOwner()) {
  1116. InputContext inputContext = getInputContext();
  1117. if (inputContext != null) {
  1118. FocusEvent focusGainedEvent =
  1119. new FocusEvent(this, FocusEvent.FOCUS_GAINED);
  1120. inputContext.dispatchEvent(focusGainedEvent);
  1121. }
  1122. }
  1123. eventMask |= AWTEvent.INPUT_METHODS_ENABLED_MASK;
  1124. } else {
  1125. if ((eventMask & AWTEvent.INPUT_METHODS_ENABLED_MASK) != 0) {
  1126. InputContext inputContext = getInputContext();
  1127. if (inputContext != null) {
  1128. inputContext.endComposition();
  1129. inputContext.removeNotify(this);
  1130. }
  1131. }
  1132. eventMask &= ~AWTEvent.INPUT_METHODS_ENABLED_MASK;
  1133. }
  1134. }
  1135. /**
  1136. * Shows or hides this component depending on the value of parameter
  1137. * <code>b</code>.
  1138. * @param b if <code>true</code>, shows this component;
  1139. * otherwise, hides this component
  1140. * @see #isVisible
  1141. * @since JDK1.1
  1142. */
  1143. public void setVisible(boolean b) {
  1144. show(b);
  1145. }
  1146. /**
  1147. * @deprecated As of JDK version 1.1,
  1148. * replaced by <code>setVisible(boolean)</code>.
  1149. */
  1150. @Deprecated
  1151. public void show() {
  1152. if (!visible) {
  1153. synchronized (getTreeLock()) {
  1154. visible = true;
  1155. ComponentPeer peer = this.peer;
  1156. if (peer != null) {
  1157. peer.show();
  1158. createHierarchyEvents(HierarchyEvent.HIERARCHY_CHANGED,
  1159. this, parent,
  1160. HierarchyEvent.SHOWING_CHANGED,
  1161. Toolkit.enabledOnToolkit(AWTEvent.HIERARCHY_EVENT_MASK));
  1162. if (peer instanceof LightweightPeer) {
  1163. repaint();
  1164. }
  1165. updateCursorImmediately();
  1166. }
  1167. if (componentListener != null ||
  1168. (eventMask & AWTEvent.COMPONENT_EVENT_MASK) != 0 ||
  1169. Toolkit.enabledOnToolkit(AWTEvent.COMPONENT_EVENT_MASK)) {
  1170. ComponentEvent e = new ComponentEvent(this,
  1171. ComponentEvent.COMPONENT_SHOWN);
  1172. Toolkit.getEventQueue().postEvent(e);
  1173. }
  1174. }
  1175. Container parent = this.parent;
  1176. if (parent != null) {
  1177. parent.invalidate();
  1178. }
  1179. }
  1180. }
  1181. /**
  1182. * @deprecated As of JDK version 1.1,
  1183. * replaced by <code>setVisible(boolean)</code>.
  1184. */
  1185. @Deprecated
  1186. public void show(boolean b) {
  1187. if (b) {
  1188. show();
  1189. } else {
  1190. hide();
  1191. }
  1192. }
  1193. boolean containsFocus() {
  1194. return isFocusOwner();
  1195. }
  1196. void clearMostRecentFocusOwnerOnHide() {
  1197. KeyboardFocusManager.clearMostRecentFocusOwner(this);
  1198. }
  1199. void clearCurrentFocusCycleRootOnHide() {
  1200. /* do nothing */
  1201. }
  1202. /**
  1203. * @deprecated As of JDK version 1.1,
  1204. * replaced by <code>setVisible(boolean)</code>.
  1205. */
  1206. @Deprecated
  1207. public void hide() {
  1208. isPacked = false;
  1209. if (visible) {
  1210. clearCurrentFocusCycleRootOnHide();
  1211. clearMostRecentFocusOwnerOnHide();
  1212. synchronized (getTreeLock()) {
  1213. visible = false;
  1214. if (containsFocus()) {
  1215. autoTransferFocus(true);
  1216. }
  1217. ComponentPeer peer = this.peer;
  1218. if (peer != null) {
  1219. peer.hide();
  1220. createHierarchyEvents(HierarchyEvent.HIERARCHY_CHANGED,
  1221. this, parent,
  1222. HierarchyEvent.SHOWING_CHANGED,
  1223. Toolkit.enabledOnToolkit(AWTEvent.HIERARCHY_EVENT_MASK));
  1224. if (peer instanceof LightweightPeer) {
  1225. repaint();
  1226. }
  1227. updateCursorImmediately();
  1228. }
  1229. if (componentListener != null ||
  1230. (eventMask & AWTEvent.COMPONENT_EVENT_MASK) != 0 ||
  1231. Toolkit.enabledOnToolkit(AWTEvent.COMPONENT_EVENT_MASK)) {
  1232. ComponentEvent e = new ComponentEvent(this,
  1233. ComponentEvent.COMPONENT_HIDDEN);
  1234. Toolkit.getEventQueue().postEvent(e);
  1235. }
  1236. }
  1237. Container parent = this.parent;
  1238. if (parent != null) {
  1239. parent.invalidate();
  1240. }
  1241. }
  1242. }
  1243. /**
  1244. * Gets the foreground color of this component.
  1245. * @return this component's foreground color; if this component does
  1246. * not have a foreground color, the foreground color of its parent
  1247. * is returned
  1248. * @see #setForeground
  1249. * @since JDK1.0
  1250. * @beaninfo
  1251. * bound: true
  1252. */
  1253. public Color getForeground() {
  1254. Color foreground = this.foreground;
  1255. if (foreground != null) {
  1256. return foreground;
  1257. }
  1258. Container parent = this.parent;
  1259. return (parent != null) ? parent.getForeground() : null;
  1260. }
  1261. /**
  1262. * Sets the foreground color of this component.
  1263. * @param c the color to become this component's
  1264. * foreground color; if this parameter is <code>null</code>
  1265. * then this component will inherit
  1266. * the foreground color of its parent
  1267. * @see #getForeground
  1268. * @since JDK1.0
  1269. */
  1270. public void setForeground(Color c) {
  1271. Color oldColor = foreground;
  1272. ComponentPeer peer = this.peer;
  1273. foreground = c;
  1274. if (peer != null) {
  1275. c = getForeground();
  1276. if (c != null) {
  1277. peer.setForeground(c);
  1278. }
  1279. }
  1280. // This is a bound property, so report the change to
  1281. // any registered listeners. (Cheap if there are none.)
  1282. firePropertyChange("foreground", oldColor, c);
  1283. }
  1284. /**
  1285. * Returns whether the foreground color has been explicitly set for this
  1286. * Component. If this method returns <code>false</code>, this Component is
  1287. * inheriting its foreground color from an ancestor.
  1288. *
  1289. * @return <code>true</code> if the foreground color has been explicitly
  1290. * set for this Component; <code>false</code> otherwise.
  1291. * @since 1.4
  1292. */
  1293. public boolean isForegroundSet() {
  1294. return (foreground != null);
  1295. }
  1296. /**
  1297. * Gets the background color of this component.
  1298. * @return this component's background color; if this component does
  1299. * not have a background color,
  1300. * the background color of its parent is returned
  1301. * @see #setBackground
  1302. * @since JDK1.0
  1303. */
  1304. public Color getBackground() {
  1305. Color background = this.background;
  1306. if (background != null) {
  1307. return background;
  1308. }
  1309. Container parent = this.parent;
  1310. return (parent != null) ? parent.getBackground() : null;
  1311. }
  1312. /**
  1313. * Sets the background color of this component.
  1314. * <p>
  1315. * The background color affects each component differently and the
  1316. * parts of the component that are affected by the background color
  1317. * may differ between operating systems.
  1318. *
  1319. * @param c the color to become this component's color;
  1320. * if this parameter is <code>null</code>, then this
  1321. * component will inherit the background color of its parent
  1322. * @see #getBackground
  1323. * @since JDK1.0
  1324. * @beaninfo
  1325. * bound: true
  1326. */
  1327. public void setBackground(Color c) {
  1328. Color oldColor = background;
  1329. ComponentPeer peer = this.peer;
  1330. background = c;
  1331. if (peer != null) {
  1332. c = getBackground();
  1333. if (c != null) {
  1334. peer.setBackground(c);
  1335. }
  1336. }
  1337. // This is a bound property, so report the change to
  1338. // any registered listeners. (Cheap if there are none.)
  1339. firePropertyChange("background", oldColor, c);
  1340. }
  1341. /**
  1342. * Returns whether the background color has been explicitly set for this
  1343. * Component. If this method returns <code>false</code>, this Component is
  1344. * inheriting its background color from an ancestor.
  1345. *
  1346. * @return <code>true</code> if the background color has been explicitly
  1347. * set for this Component; <code>false</code> otherwise.
  1348. * @since 1.4
  1349. */
  1350. public boolean isBackgroundSet() {
  1351. return (background != null);
  1352. }
  1353. /**
  1354. * Gets the font of this component.
  1355. * @return this component's font; if a font has not been set
  1356. * for this component, the font of its parent is returned
  1357. * @see #setFont
  1358. * @since JDK1.0
  1359. */
  1360. public Font getFont() {
  1361. return getFont_NoClientCode();
  1362. }
  1363. // NOTE: This method may be called by privileged threads.
  1364. // This functionality is implemented in a package-private method
  1365. // to insure that it cannot be overridden by client subclasses.
  1366. // DO NOT INVOKE CLIENT CODE ON THIS THREAD!
  1367. final Font getFont_NoClientCode() {
  1368. Font font = this.font;
  1369. if (font != null) {
  1370. return font;
  1371. }
  1372. Container parent = this.parent;
  1373. return (parent != null) ? parent.getFont_NoClientCode() : null;
  1374. }
  1375. /**
  1376. * Sets the font of this component.
  1377. * @param f the font to become this component's font;
  1378. * if this parameter is <code>null</code> then this
  1379. * component will inherit the font of its parent
  1380. * @see #getFont
  1381. * @since JDK1.0
  1382. * @beaninfo
  1383. * bound: true
  1384. */
  1385. public void setFont(Font f) {
  1386. Font oldFont, newFont;
  1387. synchronized(getTreeLock()) {
  1388. synchronized (this) {
  1389. oldFont = font;
  1390. newFont = font = f;
  1391. }
  1392. ComponentPeer peer = this.peer;
  1393. if (peer != null) {
  1394. f = getFont();
  1395. if (f != null) {
  1396. peer.setFont(f);
  1397. peerFont = f;
  1398. }
  1399. }
  1400. }
  1401. // This is a bound property, so report the change to
  1402. // any registered listeners. (Cheap if there are none.)
  1403. firePropertyChange("font", oldFont, newFont);
  1404. // This could change the preferred size of the Component.
  1405. if (valid) {
  1406. invalidate();
  1407. }
  1408. }
  1409. /**
  1410. * Returns whether the font has been explicitly set for this Component. If
  1411. * this method returns <code>false</code>, this Component is inheriting its
  1412. * font from an ancestor.
  1413. *
  1414. * @return <code>true</code> if the font has been explicitly set for this
  1415. * Component; <code>false</code> otherwise.
  1416. * @since 1.4
  1417. */
  1418. public boolean isFontSet() {
  1419. return (font != null);
  1420. }
  1421. /**
  1422. * Gets the locale of this component.
  1423. * @return this component's locale; if this component does not
  1424. * have a locale, the locale of its parent is returned
  1425. * @see #setLocale
  1426. * @exception IllegalComponentStateException if the <code>Component</code>
  1427. * does not have its own locale and has not yet been added to
  1428. * a containment hierarchy such that the locale can be determined
  1429. * from the containing parent
  1430. * @since JDK1.1
  1431. */
  1432. public Locale getLocale() {
  1433. Locale locale = this.locale;
  1434. if (locale != null) {
  1435. return locale;
  1436. }
  1437. Container parent = this.parent;
  1438. if (parent == null) {
  1439. throw new IllegalComponentStateException("This component must have a parent in order to determine its locale");
  1440. } else {
  1441. return parent.getLocale();
  1442. }
  1443. }
  1444. /**
  1445. * Sets the locale of this component. This is a bound property.
  1446. * @param l the locale to become this component's locale
  1447. * @see #getLocale
  1448. * @since JDK1.1
  1449. */
  1450. public void setLocale(Locale l) {
  1451. Locale oldValue = locale;
  1452. locale = l;
  1453. // This is a bound property, so report the change to
  1454. // any registered listeners. (Cheap if there are none.)
  1455. firePropertyChange("locale", oldValue, l);
  1456. // This could change the preferred size of the Component.
  1457. if (valid) {
  1458. invalidate();
  1459. }
  1460. }
  1461. /**
  1462. * Gets the instance of <code>ColorModel</code> used to display
  1463. * the component on the output device.
  1464. * @return the color model used by this component
  1465. * @see java.awt.image.ColorModel
  1466. * @see java.awt.peer.ComponentPeer#getColorModel()
  1467. * @see Toolkit#getColorModel()
  1468. * @since JDK1.0
  1469. */
  1470. public ColorModel getColorModel() {
  1471. ComponentPeer peer = this.peer;
  1472. if ((peer != null) && ! (peer instanceof LightweightPeer)) {
  1473. return peer.getColorModel();
  1474. } else if (GraphicsEnvironment.isHeadless()) {
  1475. return ColorModel.getRGBdefault();
  1476. } // else
  1477. return getToolkit().getColorModel();
  1478. }
  1479. /**
  1480. * Gets the location of this component in the form of a
  1481. * point specifying the component's top-left corner.
  1482. * The location will be relative to the parent's coordinate space.
  1483. * <p>
  1484. * Due to the asynchronous nature of native event handling, this
  1485. * method can return outdated values (for instance, after several calls
  1486. * of <code>setLocation()</code> in rapid succession). For this
  1487. * reason, the recommended method of obtaining a component's position is
  1488. * within <code>java.awt.event.ComponentListener.componentMoved()</code>,
  1489. * which is called after the operating system has finished moving the
  1490. * component.
  1491. * </p>
  1492. * @return an instance of <code>Point</code> representing
  1493. * the top-left corner of the component's bounds in
  1494. * the coordinate space of the component's parent
  1495. * @see #setLocation
  1496. * @see #getLocationOnScreen
  1497. * @since JDK1.1
  1498. */
  1499. public Point getLocation() {
  1500. return location();
  1501. }
  1502. /**
  1503. * Gets the location of this component in the form of a point
  1504. * specifying the component's top-left corner in the screen's
  1505. * coordinate space.
  1506. * @return an instance of <code>Point</code> representing
  1507. * the top-left corner of the component's bounds in the
  1508. * coordinate space of the screen
  1509. * @throws <code>IllegalComponentStateException</code> if the
  1510. * component is not showing on the screen
  1511. * @see #setLocation
  1512. * @see #getLocation
  1513. */
  1514. public Point getLocationOnScreen() {
  1515. synchronized (getTreeLock()) {
  1516. return getLocationOnScreen_NoTreeLock();
  1517. }
  1518. }
  1519. /*
  1520. * a package private version of getLocationOnScreen
  1521. * used by GlobalCursormanager to update cursor
  1522. */
  1523. final Point getLocationOnScreen_NoTreeLock() {
  1524. if (peer != null && isShowing()) {
  1525. if (peer instanceof LightweightPeer) {
  1526. // lightweight component location needs to be translated
  1527. // relative to a native component.
  1528. Container host = getNativeContainer();
  1529. Point pt = host.peer.getLocationOnScreen();
  1530. for(Component c = this; c != host; c = c.getParent()) {
  1531. pt.x += c.x;
  1532. pt.y += c.y;
  1533. }
  1534. return pt;
  1535. } else {
  1536. Point pt = peer.getLocationOnScreen();
  1537. return pt;
  1538. }
  1539. } else {
  1540. throw new IllegalComponentStateException("component must be showing on the screen to determine its location");
  1541. }
  1542. }
  1543. /**
  1544. * @deprecated As of JDK version 1.1,
  1545. * replaced by <code>getLocation()</code>.
  1546. */
  1547. @Deprecated
  1548. public Point location() {
  1549. return new Point(x, y);
  1550. }
  1551. /**
  1552. * Moves this component to a new location. The top-left corner of
  1553. * the new location is specified by the <code>x</code> and <code>y</code>
  1554. * parameters in the coordinate space of this component's parent.
  1555. * @param x the <i>x</i>-coordinate of the new location's
  1556. * top-left corner in the parent's coordinate space
  1557. * @param y the <i>y</i>-coordinate of the new location's
  1558. * top-left corner in the parent's coordinate space
  1559. * @see #getLocation
  1560. * @see #setBounds
  1561. * @since JDK1.1
  1562. */
  1563. public void setLocation(int x, int y) {
  1564. move(x, y);
  1565. }
  1566. /**
  1567. * @deprecated As of JDK version 1.1,
  1568. * replaced by <code>setLocation(int, int)</code>.
  1569. */
  1570. @Deprecated
  1571. public void move(int x, int y) {
  1572. synchronized(getTreeLock()) {
  1573. setBoundsOp(ComponentPeer.SET_LOCATION);
  1574. setBounds(x, y, width, height);
  1575. }
  1576. }
  1577. /**
  1578. * Moves this component to a new location. The top-left corner of
  1579. * the new location is specified by point <code>p</code>. Point
  1580. * <code>p</code> is given in the parent's coordinate space.
  1581. * @param p the point defining the top-left corner
  1582. * of the new location, given in the coordinate space of this
  1583. * component's parent
  1584. * @see #getLocation
  1585. * @see #setBounds
  1586. * @since JDK1.1
  1587. */
  1588. public void setLocation(Point p) {
  1589. setLocation(p.x, p.y);
  1590. }
  1591. /**
  1592. * Returns the size of this component in the form of a
  1593. * <code>Dimension</code> object. The <code>height</code>
  1594. * field of the <code>Dimension</code> object contains
  1595. * this component's height, and the <code>width</code>
  1596. * field of the <code>Dimension</code> object contains
  1597. * this component's width.
  1598. * @return a <code>Dimension</code> object that indicates the
  1599. * size of this component
  1600. * @see #setSize
  1601. * @since JDK1.1
  1602. */
  1603. public Dimension getSize() {
  1604. return size();
  1605. }
  1606. /**
  1607. * @deprecated As of JDK version 1.1,
  1608. * replaced by <code>getSize()</code>.
  1609. */
  1610. @Deprecated
  1611. public Dimension size() {
  1612. return new Dimension(width, height);
  1613. }
  1614. /**
  1615. * Resizes this component so that it has width <code>width</code>
  1616. * and height <code>height</code>.
  1617. * @param width the new width of this component in pixels
  1618. * @param height the new height of this component in pixels
  1619. * @see #getSize
  1620. * @see #setBounds
  1621. * @since JDK1.1
  1622. */
  1623. public void setSize(int width, int height) {
  1624. resize(width, height);
  1625. }
  1626. /**
  1627. * @deprecated As of JDK version 1.1,
  1628. * replaced by <code>setSize(int, int)</code>.
  1629. */
  1630. @Deprecated
  1631. public void resize(int width, int height) {
  1632. synchronized(getTreeLock()) {
  1633. setBoundsOp(ComponentPeer.SET_SIZE);
  1634. setBounds(x, y, width, height);
  1635. }
  1636. }
  1637. /**
  1638. * Resizes this component so that it has width <code>d.width</code>
  1639. * and height <code>d.height</code>.
  1640. * @param d the dimension specifying the new size
  1641. * of this component
  1642. * @see #setSize
  1643. * @see #setBounds
  1644. * @since JDK1.1
  1645. */
  1646. public void setSize(Dimension d) {
  1647. resize(d);
  1648. }
  1649. /**
  1650. * @deprecated As of JDK version 1.1,
  1651. * replaced by <code>setSize(Dimension)</code>.
  1652. */
  1653. @Deprecated
  1654. public void resize(Dimension d) {
  1655. setSize(d.width, d.height);
  1656. }
  1657. /**
  1658. * Gets the bounds of this component in the form of a
  1659. * <code>Rectangle</code> object. The bounds specify this
  1660. * component's width, height, and location relative to
  1661. * its parent.
  1662. * @return a rectangle indicating this component's bounds
  1663. * @see #setBounds
  1664. * @see #getLocation
  1665. * @see #getSize
  1666. */
  1667. public Rectangle getBounds() {
  1668. return bounds();
  1669. }
  1670. /**
  1671. * @deprecated As of JDK version 1.1,
  1672. * replaced by <code>getBounds()</code>.
  1673. */
  1674. @Deprecated
  1675. public Rectangle bounds() {
  1676. return new Rectangle(x, y, width, height);
  1677. }
  1678. /**
  1679. * Moves and resizes this component. The new location of the top-left
  1680. * corner is specified by <code>x</code> and <code>y</code>, and the
  1681. * new size is specified by <code>width</code> and <code>height</code>.
  1682. * @param x the new <i>x</i>-coordinate of this component
  1683. * @param y the new <i>y</i>-coordinate of this component
  1684. * @param width the new <code>width</code> of this component
  1685. * @param height the new <code>height</code> of this
  1686. * component
  1687. * @see #getBounds
  1688. * @see #setLocation(int, int)
  1689. * @see #setLocation(Point)
  1690. * @see #setSize(int, int)
  1691. * @see #setSize(Dimension)
  1692. * @since JDK1.1
  1693. */
  1694. public void setBounds(int x, int y, int width, int height) {
  1695. reshape(x, y, width, height);
  1696. }
  1697. /**
  1698. * @deprecated As of JDK version 1.1,
  1699. * replaced by <code>setBounds(int, int, int, int)</code>.
  1700. */
  1701. @Deprecated
  1702. public void reshape(int x, int y, int width, int height) {
  1703. synchronized (getTreeLock()) {
  1704. try {
  1705. setBoundsOp(ComponentPeer.SET_BOUNDS);
  1706. boolean resized = (this.width != width) || (this.height != height);
  1707. boolean moved = (this.x != x) || (this.y != y);
  1708. if (!resized && !moved) {
  1709. return;
  1710. }
  1711. int oldX = this.x;
  1712. int oldY = this.y;
  1713. int oldWidth = this.width;
  1714. int oldHeight = this.height;
  1715. this.x = x;
  1716. this.y = y;
  1717. this.width = width;
  1718. this.height = height;
  1719. if (resized) {
  1720. isPacked = false;
  1721. }
  1722. if (peer != null) {
  1723. // LightwightPeer is an empty stub so can skip peer.reshape
  1724. if (!(peer instanceof LightweightPeer)) {
  1725. reshapeNativePeer(x, y, width, height, getBoundsOp());
  1726. // Check peer actualy changed coordinates
  1727. resized = (oldWidth != this.width) || (oldHeight != this.height);
  1728. moved = (oldX != this.x) || (oldY != this.y);
  1729. }
  1730. if (resized) {
  1731. invalidate();
  1732. }
  1733. if (parent != null && parent.valid) {
  1734. parent.invalidate();
  1735. }
  1736. }
  1737. notifyNewBounds(resized, moved);
  1738. repaintParentIfNeeded(oldX, oldY, oldWidth, oldHeight);
  1739. } finally {
  1740. setBoundsOp(ComponentPeer.RESET_OPERATION);
  1741. }
  1742. }
  1743. }
  1744. private void repaintParentIfNeeded(int oldX, int oldY, int oldWidth,
  1745. int oldHeight)
  1746. {
  1747. if (parent != null && peer instanceof LightweightPeer && isShowing()) {
  1748. // Have the parent redraw the area this component occupied.
  1749. parent.repaint(oldX, oldY, oldWidth, oldHeight);
  1750. // Have the parent redraw the area this component *now* occupies.
  1751. repaint();
  1752. }
  1753. }
  1754. private void reshapeNativePeer(int x, int y, int width, int height, int op) {
  1755. // native peer might be offset by more than direct
  1756. // parent since parent might be lightweight.
  1757. int nativeX = x;
  1758. int nativeY = y;
  1759. for (Component c = parent;
  1760. (c != null) && (c.peer instanceof LightweightPeer);
  1761. c = c.parent)
  1762. {
  1763. nativeX += c.x;
  1764. nativeY += c.y;
  1765. }
  1766. peer.setBounds(nativeX, nativeY, width, height, op);
  1767. }
  1768. private void notifyNewBounds(boolean resized, boolean moved) {
  1769. if (componentListener != null
  1770. || (eventMask & AWTEvent.COMPONENT_EVENT_MASK) != 0
  1771. || Toolkit.enabledOnToolkit(AWTEvent.COMPONENT_EVENT_MASK))
  1772. {
  1773. if (resized) {
  1774. ComponentEvent e = new ComponentEvent(this,
  1775. ComponentEvent.COMPONENT_RESIZED);
  1776. Toolkit.getEventQueue().postEvent(e);
  1777. }
  1778. if (moved) {
  1779. ComponentEvent e = new ComponentEvent(this,
  1780. ComponentEvent.COMPONENT_MOVED);
  1781. Toolkit.getEventQueue().postEvent(e);
  1782. }
  1783. } else
  1784. // Swing optimization. JComponent extends Container
  1785. if (this instanceof Container && ((Container)this).ncomponents > 0) {
  1786. boolean enabledOnToolkit =
  1787. Toolkit.enabledOnToolkit(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK);
  1788. // Container.dispatchEventImpl will create
  1789. // HierarchyEvents
  1790. if (resized) {
  1791. ((Container)this).createChildHierarchyEvents(
  1792. HierarchyEvent.ANCESTOR_RESIZED, 0, enabledOnToolkit);
  1793. }
  1794. if (moved) {
  1795. ((Container)this).createChildHierarchyEvents(
  1796. HierarchyEvent.ANCESTOR_MOVED, 0, enabledOnToolkit);
  1797. }
  1798. }
  1799. }
  1800. /**
  1801. * Moves and resizes this component to conform to the new
  1802. * bounding rectangle <code>r</code>. This component's new
  1803. * position is specified by <code>r.x</code> and <code>r.y</code>,
  1804. * and its new size is specified by <code>r.width</code> and
  1805. * <code>r.height</code>
  1806. * @param r the new bounding rectangle for this component
  1807. * @see #getBounds
  1808. * @see #setLocation(int, int)
  1809. * @see #setLocation(Point)
  1810. * @see #setSize(int, int)
  1811. * @see #setSize(Dimension)
  1812. * @since JDK1.1
  1813. */
  1814. public void setBounds(Rectangle r) {
  1815. setBounds(r.x, r.y, r.width, r.height);
  1816. }
  1817. /**
  1818. * Returns the current x coordinate of the components origin.
  1819. * This method is preferable to writing
  1820. * <code>component.getBounds().x</code>,
  1821. * or <code>component.getLocation().x</code> because it doesn't
  1822. * cause any heap allocations.
  1823. *
  1824. * @return the current x coordinate of the components origin
  1825. * @since 1.2
  1826. */
  1827. public int getX() {
  1828. return x;
  1829. }
  1830. /**
  1831. * Returns the current y coordinate of the components origin.
  1832. * This method is preferable to writing
  1833. * <code>component.getBounds().y</code>,
  1834. * or <code>component.getLocation().y</code> because it
  1835. * doesn't cause any heap allocations.
  1836. *
  1837. * @return the current y coordinate of the components origin
  1838. * @since 1.2
  1839. */
  1840. public int getY() {
  1841. return y;
  1842. }
  1843. /**
  1844. * Returns the current width of this component.
  1845. * This method is preferable to writing
  1846. * <code>component.getBounds().width</code>,
  1847. * or <code>component.getSize().width</code> because it
  1848. * doesn't cause any heap allocations.
  1849. *
  1850. * @return the current width of this component
  1851. * @since 1.2
  1852. */
  1853. public int getWidth() {
  1854. return width;
  1855. }
  1856. /**
  1857. * Returns the current height of this component.
  1858. * This method is preferable to writing
  1859. * <code>component.getBounds().height</code.,
  1860. * or <code>component.getSize().height</code> because it
  1861. * doesn't cause any heap allocations.
  1862. *
  1863. * @return the current height of this component
  1864. * @since 1.2
  1865. */
  1866. public int getHeight() {
  1867. return height;
  1868. }
  1869. /**
  1870. * Stores the bounds of this component into "return value" <b>rv</b> and
  1871. * return <b>rv</b>. If rv is <code>null</code> a new
  1872. * <code>Rectangle</code> is allocated.
  1873. * This version of <code>getBounds</code> is useful if the caller
  1874. * wants to avoid allocating a new <code>Rectangle</code> object
  1875. * on the heap.
  1876. *
  1877. * @param rv the return value, modified to the components bounds
  1878. * @return rv
  1879. */
  1880. public Rectangle getBounds(Rectangle rv) {
  1881. if (rv == null) {
  1882. return new Rectangle(getX(), getY(), getWidth(), getHeight());
  1883. }
  1884. else {
  1885. rv.setBounds(getX(), getY(), getWidth(), getHeight());
  1886. return rv;
  1887. }
  1888. }
  1889. /**
  1890. * Stores the width/height of this component into "return value" <b>rv</b>
  1891. * and return <b>rv</b>. If rv is <code>null</code> a new
  1892. * <code>Dimension</code> object is allocated. This version of
  1893. * <code>getSize</code> is useful if the caller wants to avoid
  1894. * allocating a new <code>Dimension</code> object on the heap.
  1895. *
  1896. * @param rv the return value, modified to the components size
  1897. * @return rv
  1898. */
  1899. public Dimension getSize(Dimension rv) {
  1900. if (rv == null) {
  1901. return new Dimension(getWidth(), getHeight());
  1902. }
  1903. else {
  1904. rv.setSize(getWidth(), getHeight());
  1905. return rv;
  1906. }
  1907. }
  1908. /**
  1909. * Stores the x,y origin of this component into "return value" <b>rv</b>
  1910. * and return <b>rv</b>. If rv is <code>null</code> a new
  1911. * <code>Point</code> is allocated.
  1912. * This version of <code>getLocation</code> is useful if the
  1913. * caller wants to avoid allocating a new <code>Point</code>
  1914. * object on the heap.
  1915. *
  1916. * @param rv the return value, modified to the components location
  1917. * @return rv
  1918. */
  1919. public Point getLocation(Point rv) {
  1920. if (rv == null) {
  1921. return new Point(getX(), getY());
  1922. }
  1923. else {
  1924. rv.setLocation(getX(), getY());
  1925. return rv;
  1926. }
  1927. }
  1928. /**
  1929. * Returns true if this component is completely opaque, returns
  1930. * false by default.
  1931. * <p>
  1932. * An opaque component paints every pixel within its
  1933. * rectangular region. A non-opaque component paints only some of
  1934. * its pixels, allowing the pixels underneath it to "show through".
  1935. * A component that does not fully paint its pixels therefore
  1936. * provides a degree of transparency. Only lightweight
  1937. * components can be transparent.
  1938. * <p>
  1939. * Subclasses that guarantee to always completely paint their
  1940. * contents should override this method and return true. All
  1941. * of the "heavyweight" AWT components are opaque.
  1942. *
  1943. * @return true if this component is completely opaque
  1944. * @see #isLightweight
  1945. * @since 1.2
  1946. */
  1947. public boolean isOpaque() {
  1948. if (getPeer() == null) {
  1949. return false;
  1950. }
  1951. else {
  1952. return !isLightweight();
  1953. }
  1954. }
  1955. /**
  1956. * A lightweight component doesn't have a native toolkit peer.
  1957. * Subclasses of <code>Component</code> and <code>Container</code>,
  1958. * other than the ones defined in this package like <code>Button</code>
  1959. * or <code>Scrollbar</code>, are lightweight.
  1960. * All of the Swing components are lightweights.
  1961. * <p>
  1962. * This method will always return <code>false</code> if this component
  1963. * is not displayable because it is impossible to determine the
  1964. * weight of an undisplayable component.
  1965. *
  1966. * @return true if this component has a lightweight peer; false if
  1967. * it has a native peer or no peer
  1968. * @see #isDisplayable
  1969. * @since 1.2
  1970. */
  1971. public boolean isLightweight() {
  1972. return getPeer() instanceof LightweightPeer;
  1973. }
  1974. /**
  1975. * Sets the preferred size of this component to a constant
  1976. * value. Subsequent calls to <code>getPreferredSize</code> will always
  1977. * return this value. Setting the preferred size to <code>null</code>
  1978. * restores the default behavior.
  1979. *
  1980. * @param preferredSize The new preferred size, or null
  1981. * @see #getPreferredSize
  1982. * @see #isPreferredSizeSet
  1983. * @since 1.5
  1984. */
  1985. public void setPreferredSize(Dimension preferredSize) {
  1986. Dimension old;
  1987. // If the preferred size was set, use it as the old value, otherwise
  1988. // use null to indicate we didn't previously have a set preferred
  1989. // size.
  1990. if (prefSizeSet) {
  1991. old = this.prefSize;
  1992. }
  1993. else {
  1994. old = null;
  1995. }
  1996. this.prefSize = preferredSize;
  1997. prefSizeSet = (preferredSize != null);
  1998. firePropertyChange("preferredSize", old, preferredSize);
  1999. }
  2000. /**
  2001. * Returns true if the preferred size has been set to a
  2002. * non-<code>null</code> value otherwise returns false.
  2003. *
  2004. * @return true if <code>setPreferredSize</code> has been invoked
  2005. * with a non-null value.
  2006. * @since 1.5
  2007. */
  2008. public boolean isPreferredSizeSet() {
  2009. return prefSizeSet;
  2010. }
  2011. /**
  2012. * Gets the preferred size of this component.
  2013. * @return a dimension object indicating this component's preferred size
  2014. * @see #getMinimumSize
  2015. * @see LayoutManager
  2016. */
  2017. public Dimension getPreferredSize() {
  2018. return preferredSize();
  2019. }
  2020. /**
  2021. * @deprecated As of JDK version 1.1,
  2022. * replaced by <code>getPreferredSize()</code>.
  2023. */
  2024. @Deprecated
  2025. public Dimension preferredSize() {
  2026. /* Avoid grabbing the lock if a reasonable cached size value
  2027. * is available.
  2028. */
  2029. Dimension dim = prefSize;
  2030. if (dim == null || !(isPreferredSizeSet() || isValid())) {
  2031. synchronized (getTreeLock()) {
  2032. prefSize = (peer != null) ?
  2033. peer.preferredSize() :
  2034. getMinimumSize();
  2035. dim = prefSize;
  2036. }
  2037. }
  2038. return new Dimension(dim);
  2039. }
  2040. /**
  2041. * Sets the minimum size of this component to a constant
  2042. * value. Subsequent calls to <code>getMinimumSize</code> will always
  2043. * return this value. Setting the minimum size to <code>null</code>
  2044. * restores the default behavior.
  2045. *
  2046. * @param minimumSize the new minimum size of this component
  2047. * @see #getMinimumSize
  2048. * @see #isMinimumSizeSet
  2049. * @since 1.5
  2050. */
  2051. public void setMinimumSize(Dimension minimumSize) {
  2052. Dimension old;
  2053. // If the minimum size was set, use it as the old value, otherwise
  2054. // use null to indicate we didn't previously have a set minimum
  2055. // size.
  2056. if (minSizeSet) {
  2057. old = this.minSize;
  2058. }
  2059. else {
  2060. old = null;
  2061. }
  2062. this.minSize = minimumSize;
  2063. minSizeSet = (minimumSize != null);
  2064. firePropertyChange("minimumSize", old, minimumSize);
  2065. }
  2066. /**
  2067. * Returns whether or not <code>setMinimumSize</code> has been
  2068. * invoked with a non-null value.
  2069. *
  2070. * @return true if <code>setMinimumSize</code> has been invoked with a
  2071. * non-null value.
  2072. * @since 1.5
  2073. */
  2074. public boolean isMinimumSizeSet() {
  2075. return minSizeSet;
  2076. }
  2077. /**
  2078. * Gets the mininimum size of this component.
  2079. * @return a dimension object indicating this component's minimum size
  2080. * @see #getPreferredSize
  2081. * @see LayoutManager
  2082. */
  2083. public Dimension getMinimumSize() {
  2084. return minimumSize();
  2085. }
  2086. /**
  2087. * @deprecated As of JDK version 1.1,
  2088. * replaced by <code>getMinimumSize()</code>.
  2089. */
  2090. @Deprecated
  2091. public Dimension minimumSize() {
  2092. /* Avoid grabbing the lock if a reasonable cached size value
  2093. * is available.
  2094. */
  2095. Dimension dim = minSize;
  2096. if (dim == null || !(isMinimumSizeSet() || isValid())) {
  2097. synchronized (getTreeLock()) {
  2098. minSize = (peer != null) ?
  2099. peer.minimumSize() :
  2100. size();
  2101. dim = minSize;
  2102. }
  2103. }
  2104. return new Dimension(dim);
  2105. }
  2106. /**
  2107. * Sets the maximum size of this component to a constant
  2108. * value. Subsequent calls to <code>getMaximumSize</code> will always
  2109. * return this value. Setting the maximum size to <code>null</code>
  2110. * restores the default behavior.
  2111. *
  2112. * @param maximumSize a <code>Dimension</code> containing the
  2113. * desired maximum allowable size
  2114. * @see #getMaximumSize
  2115. * @see #isMaximumSizeSet
  2116. * @since 1.5
  2117. */
  2118. public void setMaximumSize(Dimension maximumSize) {
  2119. // If the maximum size was set, use it as the old value, otherwise
  2120. // use null to indicate we didn't previously have a set maximum
  2121. // size.
  2122. Dimension old;
  2123. if (maxSizeSet) {
  2124. old = this.maxSize;
  2125. }
  2126. else {
  2127. old = null;
  2128. }
  2129. this.maxSize = maximumSize;
  2130. maxSizeSet = (maximumSize != null);
  2131. firePropertyChange("maximumSize", old, maximumSize);
  2132. }
  2133. /**
  2134. * Returns true if the maximum size has been set to a non-<code>null</code>
  2135. * value otherwise returns false.
  2136. *
  2137. * @return true if <code>maximumSize</code> is non-<code>null</code>,
  2138. * false otherwise
  2139. * @since 1.5
  2140. */
  2141. public boolean isMaximumSizeSet() {
  2142. return maxSizeSet;
  2143. }
  2144. /**
  2145. * Gets the maximum size of this component.
  2146. * @return a dimension object indicating this component's maximum size
  2147. * @see #getMinimumSize
  2148. * @see #getPreferredSize
  2149. * @see LayoutManager
  2150. */
  2151. public Dimension getMaximumSize() {
  2152. if (isMaximumSizeSet()) {
  2153. return new Dimension(maxSize);
  2154. }
  2155. return new Dimension(Short.MAX_VALUE, Short.MAX_VALUE);
  2156. }
  2157. /**
  2158. * Returns the alignment along the x axis. This specifies how
  2159. * the component would like to be aligned relative to other
  2160. * components. The value should be a number between 0 and 1
  2161. * where 0 represents alignment along the origin, 1 is aligned
  2162. * the furthest away from the origin, 0.5 is centered, etc.
  2163. */
  2164. public float getAlignmentX() {
  2165. return CENTER_ALIGNMENT;
  2166. }
  2167. /**
  2168. * Returns the alignment along the y axis. This specifies how
  2169. * the component would like to be aligned relative to other
  2170. * components. The value should be a number between 0 and 1
  2171. * where 0 represents alignment along the origin, 1 is aligned
  2172. * the furthest away from the origin, 0.5 is centered, etc.
  2173. */
  2174. public float getAlignmentY() {
  2175. return CENTER_ALIGNMENT;
  2176. }
  2177. /**
  2178. * Prompts the layout manager to lay out this component. This is
  2179. * usually called when the component (more specifically, container)
  2180. * is validated.
  2181. * @see #validate
  2182. * @see LayoutManager
  2183. */
  2184. public void doLayout() {
  2185. layout();
  2186. }
  2187. /**
  2188. * @deprecated As of JDK version 1.1,
  2189. * replaced by <code>doLayout()</code>.
  2190. */
  2191. @Deprecated
  2192. public void layout() {
  2193. }
  2194. /**
  2195. * Ensures that this component has a valid layout. This method is
  2196. * primarily intended to operate on instances of <code>Container</code>.
  2197. * @see #invalidate
  2198. * @see #doLayout()
  2199. * @see LayoutManager
  2200. * @see Container#validate
  2201. * @since JDK1.0
  2202. */
  2203. public void validate() {
  2204. if (!valid) {
  2205. synchronized (getTreeLock()) {
  2206. ComponentPeer peer = this.peer;
  2207. if (!valid && peer != null) {
  2208. Font newfont = getFont();
  2209. Font oldfont = peerFont;
  2210. if (newfont != oldfont && (oldfont == null
  2211. || !oldfont.equals(newfont))) {
  2212. peer.setFont(newfont);
  2213. peerFont = newfont;
  2214. }
  2215. peer.layout();
  2216. }
  2217. }
  2218. valid = true;
  2219. }
  2220. }
  2221. /**
  2222. * Invalidates this component. This component and all parents
  2223. * above it are marked as needing to be laid out. This method can
  2224. * be called often, so it needs to execute quickly.
  2225. * @see #validate
  2226. * @see #doLayout
  2227. * @see LayoutManager
  2228. * @since JDK1.0
  2229. */
  2230. public void invalidate() {
  2231. synchronized (getTreeLock()) {
  2232. /* Nullify cached layout and size information.
  2233. * For efficiency, propagate invalidate() upwards only if
  2234. * some other component hasn't already done so first.
  2235. */
  2236. valid = false;
  2237. if (!isPreferredSizeSet()) {
  2238. prefSize = null;
  2239. }
  2240. if (!isMinimumSizeSet()) {
  2241. minSize = null;
  2242. }
  2243. if (!isMaximumSizeSet()) {
  2244. maxSize = null;
  2245. }
  2246. if (parent != null && parent.valid) {
  2247. parent.invalidate();
  2248. }
  2249. }
  2250. }
  2251. /**
  2252. * Creates a graphics context for this component. This method will
  2253. * return <code>null</code> if this component is currently not
  2254. * displayable.
  2255. * @return a graphics context for this component, or <code>null</code>
  2256. * if it has none
  2257. * @see #paint
  2258. * @since JDK1.0
  2259. */
  2260. public Graphics getGraphics() {
  2261. if (peer instanceof LightweightPeer) {
  2262. // This is for a lightweight component, need to
  2263. // translate coordinate spaces and clip relative
  2264. // to the parent.
  2265. if (parent == null) return null;
  2266. Graphics g = parent.getGraphics();
  2267. if (g == null) return null;
  2268. if (g instanceof ConstrainableGraphics) {
  2269. ((ConstrainableGraphics) g).constrain(x, y, width, height);
  2270. } else {
  2271. g.translate(x,y);
  2272. g.setClip(0, 0, width, height);
  2273. }
  2274. g.setFont(getFont());
  2275. return g;
  2276. } else {
  2277. ComponentPeer peer = this.peer;
  2278. return (peer != null) ? peer.getGraphics() : null;
  2279. }
  2280. }
  2281. /** saves an internal cache of FontMetrics for better performance **/
  2282. static java.util.Hashtable metrics = new java.util.Hashtable();
  2283. /**
  2284. * Gets the font metrics for the specified font.
  2285. * @param font the font for which font metrics is to be
  2286. * obtained
  2287. * @return the font metrics for <code>font</code>
  2288. * @see #getFont
  2289. * @see #getPeer
  2290. * @see java.awt.peer.ComponentPeer#getFontMetrics(Font)
  2291. * @see Toolkit#getFontMetrics(Font)
  2292. * @since JDK1.0
  2293. */
  2294. public FontMetrics getFontMetrics(Font font) {
  2295. FontMetrics result = (FontMetrics) metrics.get(font);
  2296. if (result != null) {
  2297. return result;
  2298. }
  2299. // REMIND: PlatformFont flag should be obsolete soon...
  2300. if (sun.font.FontManager.usePlatformFontMetrics()) {
  2301. if (peer != null &&
  2302. !(peer instanceof LightweightPeer)) {
  2303. result = peer.getFontMetrics(font);
  2304. metrics.put(font, result);
  2305. return result;
  2306. }
  2307. }
  2308. if (parent != null) {
  2309. // These are the lines that cost the big dollars. Calling
  2310. // parent.getGraphics triggers the construcion (at great
  2311. // expense) of a new Graphics object that is then quickly
  2312. // discarded. - Graham
  2313. Graphics g = parent.getGraphics();
  2314. if (g != null) {
  2315. try {
  2316. result = g.getFontMetrics(font);
  2317. metrics.put(font, result);
  2318. return result;
  2319. } finally {
  2320. g.dispose();
  2321. }
  2322. }
  2323. }
  2324. result = getToolkit().getFontMetrics(font);
  2325. metrics.put(font, result);
  2326. return result;
  2327. }
  2328. /**
  2329. * Sets the cursor image to the specified cursor. This cursor
  2330. * image is displayed when the <code>contains</code> method for
  2331. * this component returns true for the current cursor location, and
  2332. * this Component is visible, displayable, and enabled. Setting the
  2333. * cursor of a <code>Container</code> causes that cursor to be displayed
  2334. * within all of the container's subcomponents, except for those
  2335. * that have a non-<code>null</code> cursor.
  2336. *
  2337. * @param cursor One of the constants defined
  2338. * by the <code>Cursor</code> class;
  2339. * if this parameter is <code>null</code>
  2340. * then this component will inherit
  2341. * the cursor of its parent
  2342. * @see #isEnabled
  2343. * @see #isShowing
  2344. * @see #getCursor
  2345. * @see #contains
  2346. * @see Toolkit#createCustomCursor
  2347. * @see Cursor
  2348. * @since JDK1.1
  2349. */
  2350. public void setCursor(Cursor cursor) {
  2351. this.cursor = cursor;
  2352. updateCursorImmediately();
  2353. }
  2354. /**
  2355. * Updates the cursor. May not be invoked from the native
  2356. * message pump.
  2357. */
  2358. final void updateCursorImmediately() {
  2359. if (peer instanceof LightweightPeer) {
  2360. Container nativeContainer = getNativeContainer();
  2361. if (nativeContainer == null) return;
  2362. ComponentPeer cPeer = nativeContainer.getPeer();
  2363. if (cPeer != null) {
  2364. cPeer.updateCursorImmediately();
  2365. }
  2366. } else if (peer != null) {
  2367. peer.updateCursorImmediately();
  2368. }
  2369. }
  2370. /**
  2371. * Gets the cursor set in the component. If the component does
  2372. * not have a cursor set, the cursor of its parent is returned.
  2373. * If no cursor is set in the entire hierarchy,
  2374. * <code>Cursor.DEFAULT_CURSOR</code> is returned.
  2375. * @see #setCursor
  2376. * @since JDK1.1
  2377. */
  2378. public Cursor getCursor() {
  2379. Cursor cursor = this.cursor;
  2380. if (cursor != null) {
  2381. return cursor;
  2382. }
  2383. Container parent = this.parent;
  2384. if (parent != null) {
  2385. return parent.getCursor();
  2386. } else {
  2387. return Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR);
  2388. }
  2389. }
  2390. /**
  2391. * Returns whether the cursor has been explicitly set for this Component.
  2392. * If this method returns <code>false</code>, this Component is inheriting
  2393. * its cursor from an ancestor.
  2394. *
  2395. * @return <code>true</code> if the cursor has been explicitly set for this
  2396. * Component; <code>false</code> otherwise.
  2397. * @since 1.4
  2398. */
  2399. public boolean isCursorSet() {
  2400. return (cursor != null);
  2401. }
  2402. /**
  2403. * Paints this component.
  2404. * <p>
  2405. * This method is called when the contents of the component should
  2406. * be painted; such as when the component is first being shown or
  2407. * is damaged and in need of repair. The clip rectangle in the
  2408. * <code>Graphics</code> parameter is set to the area
  2409. * which needs to be painted.
  2410. * Subclasses of <code>Component</code> that override this
  2411. * method need not call <code>super.paint(g)</code>.
  2412. * <p>
  2413. * For performance reasons, <code>Component</code>s with zero width
  2414. * or height aren't considered to need painting when they are first shown,
  2415. * and also aren't considered to need repair.
  2416. * <p>
  2417. * <b>Note</b>: For more information on the paint mechanisms utilitized
  2418. * by AWT and Swing, including information on how to write the most
  2419. * efficient painting code, see
  2420. * <a href="http://java.sun.com/products/jfc/tsc/articles/painting/index.html">Painting in AWT and Swing</a>.
  2421. *
  2422. * @param g the graphics context to use for painting
  2423. * @see #update
  2424. * @since JDK1.0
  2425. */
  2426. public void paint(Graphics g) {
  2427. }
  2428. /**
  2429. * Updates this component.
  2430. * <p>
  2431. * If this component is not a lightweight component, the
  2432. * AWT calls the <code>update</code> method in response to
  2433. * a call to <code>repaint</code>. You can assume that
  2434. * the background is not cleared.
  2435. * <p>
  2436. * The <code>update</code> method of <code>Component</code>
  2437. * calls this component's <code>paint</code> method to redraw
  2438. * this component. This method is commonly overridden by subclasses
  2439. * which need to do additional work in response to a call to
  2440. * <code>repaint</code>.
  2441. * Subclasses of Component that override this method should either
  2442. * call <code>super.update(g)</code>, or call <code>paint(g)</code>
  2443. * directly from their <code>update</code> method.
  2444. * <p>
  2445. * The origin of the graphics context, its
  2446. * (<code>0</code>, <code>0</code>) coordinate point, is the
  2447. * top-left corner of this component. The clipping region of the
  2448. * graphics context is the bounding rectangle of this component.
  2449. *
  2450. * <p>
  2451. * <b>Note</b>: For more information on the paint mechanisms utilitized
  2452. * by AWT and Swing, including information on how to write the most
  2453. * efficient painting code, see
  2454. * <a href="http://java.sun.com/products/jfc/tsc/articles/painting/index.html">Painting in AWT and Swing</a>.
  2455. *
  2456. * @param g the specified context to use for updating
  2457. * @see #paint
  2458. * @see #repaint()
  2459. * @since JDK1.0
  2460. */
  2461. public void update(Graphics g) {
  2462. paint(g);
  2463. }
  2464. /**
  2465. * Paints this component and all of its subcomponents.
  2466. * <p>
  2467. * The origin of the graphics context, its
  2468. * (<code>0</code>, <code>0</code>) coordinate point, is the
  2469. * top-left corner of this component. The clipping region of the
  2470. * graphics context is the bounding rectangle of this component.
  2471. *
  2472. * @param g the graphics context to use for painting
  2473. * @see #paint
  2474. * @since JDK1.0
  2475. */
  2476. public void paintAll(Graphics g) {
  2477. if (isShowing()) {
  2478. GraphicsCallback.PeerPaintCallback.getInstance().
  2479. runOneComponent(this, new Rectangle(0, 0, width, height),
  2480. g, g.getClip(),
  2481. GraphicsCallback.LIGHTWEIGHTS |
  2482. GraphicsCallback.HEAVYWEIGHTS);
  2483. }
  2484. }
  2485. /**
  2486. * Simulates the peer callbacks into java.awt for painting of
  2487. * lightweight Components.
  2488. * @param g the graphics context to use for painting
  2489. * @see #paintAll
  2490. */
  2491. void lightweightPaint(Graphics g) {
  2492. paint(g);
  2493. }
  2494. /**
  2495. * Paints all the heavyweight subcomponents.
  2496. */
  2497. void paintHeavyweightComponents(Graphics g) {
  2498. }
  2499. /**
  2500. * Repaints this component.
  2501. * <p>
  2502. * If this component is a lightweight component, this method
  2503. * causes a call to this component's <code>paint</code>
  2504. * method as soon as possible. Otherwise, this method causes
  2505. * a call to this component's <code>update</code> method as soon
  2506. * as possible.
  2507. * <p>
  2508. * <b>Note</b>: For more information on the paint mechanisms utilitized
  2509. * by AWT and Swing, including information on how to write the most
  2510. * efficient painting code, see
  2511. * <a href="http://java.sun.com/products/jfc/tsc/articles/painting/index.html">Painting in AWT and Swing</a>.
  2512. *
  2513. * @see #update(Graphics)
  2514. * @since JDK1.0
  2515. */
  2516. public void repaint() {
  2517. repaint(0, 0, 0, width, height);
  2518. }
  2519. /**
  2520. * Repaints the component. If this component is a lightweight
  2521. * component, this results in a call to <code>paint</code>
  2522. * within <code>tm</code> milliseconds.
  2523. * <p>
  2524. * <b>Note</b>: For more information on the paint mechanisms utilitized
  2525. * by AWT and Swing, including information on how to write the most
  2526. * efficient painting code, see
  2527. * <a href="http://java.sun.com/products/jfc/tsc/articles/painting/index.html">Painting in AWT and Swing</a>.
  2528. *
  2529. * @param tm maximum time in milliseconds before update
  2530. * @see #paint
  2531. * @see #update(Graphics)
  2532. * @since JDK1.0
  2533. */
  2534. public void repaint(long tm) {
  2535. repaint(tm, 0, 0, width, height);
  2536. }
  2537. /**
  2538. * Repaints the specified rectangle of this component.
  2539. * <p>
  2540. * If this component is a lightweight component, this method
  2541. * causes a call to this component's <code>paint</code> method
  2542. * as soon as possible. Otherwise, this method causes a call to
  2543. * this component's <code>update</code> method as soon as possible.
  2544. * <p>
  2545. * <b>Note</b>: For more information on the paint mechanisms utilitized
  2546. * by AWT and Swing, including information on how to write the most
  2547. * efficient painting code, see
  2548. * <a href="http://java.sun.com/products/jfc/tsc/articles/painting/index.html">Painting in AWT and Swing</a>.
  2549. *
  2550. * @param x the <i>x</i> coordinate
  2551. * @param y the <i>y</i> coordinate
  2552. * @param width the width
  2553. * @param height the height
  2554. * @see #update(Graphics)
  2555. * @since JDK1.0
  2556. */
  2557. public void repaint(int x, int y, int width, int height) {
  2558. repaint(0, x, y, width, height);
  2559. }
  2560. /**
  2561. * Repaints the specified rectangle of this component within
  2562. * <code>tm</code> milliseconds.
  2563. * <p>
  2564. * If this component is a lightweight component, this method causes
  2565. * a call to this component's <code>paint</code> method.
  2566. * Otherwise, this method causes a call to this component's
  2567. * <code>update</code> method.
  2568. * <p>
  2569. * <b>Note</b>: For more information on the paint mechanisms utilitized
  2570. * by AWT and Swing, including information on how to write the most
  2571. * efficient painting code, see
  2572. * <a href="http://java.sun.com/products/jfc/tsc/articles/painting/index.html">Painting in AWT and Swing</a>.
  2573. *
  2574. * @param tm maximum time in milliseconds before update
  2575. * @param x the <i>x</i> coordinate
  2576. * @param y the <i>y</i> coordinate
  2577. * @param width the width
  2578. * @param height the height
  2579. * @see #update(Graphics)
  2580. * @since JDK1.0
  2581. */
  2582. public void repaint(long tm, int x, int y, int width, int height) {
  2583. if (this.peer instanceof LightweightPeer) {
  2584. // Needs to be translated to parent coordinates since
  2585. // a parent native container provides the actual repaint
  2586. // services. Additionally, the request is restricted to
  2587. // the bounds of the component.
  2588. if (parent != null) {
  2589. int px = this.x + ((x < 0) ? 0 : x);
  2590. int py = this.y + ((y < 0) ? 0 : y);
  2591. int pwidth = (width > this.width) ? this.width : width;
  2592. int pheight = (height > this.height) ? this.height : height;
  2593. parent.repaint(tm, px, py, pwidth, pheight);
  2594. }
  2595. } else {
  2596. if (isVisible() && (this.peer != null) &&
  2597. (width > 0) && (height > 0)) {
  2598. PaintEvent e = new PaintEvent(this, PaintEvent.UPDATE,
  2599. new Rectangle(x, y, width, height));
  2600. Toolkit.getEventQueue().postEvent(e);
  2601. }
  2602. }
  2603. }
  2604. /**
  2605. * Prints this component. Applications should override this method
  2606. * for components that must do special processing before being
  2607. * printed or should be printed differently than they are painted.
  2608. * <p>
  2609. * The default implementation of this method calls the
  2610. * <code>paint</code> method.
  2611. * <p>
  2612. * The origin of the graphics context, its
  2613. * (<code>0</code>, <code>0</code>) coordinate point, is the
  2614. * top-left corner of this component. The clipping region of the
  2615. * graphics context is the bounding rectangle of this component.
  2616. * @param g the graphics context to use for printing
  2617. * @see #paint(Graphics)
  2618. * @since JDK1.0
  2619. */
  2620. public void print(Graphics g) {
  2621. paint(g);
  2622. }
  2623. /**
  2624. * Prints this component and all of its subcomponents.
  2625. * <p>
  2626. * The origin of the graphics context, its
  2627. * (<code>0</code>, <code>0</code>) coordinate point, is the
  2628. * top-left corner of this component. The clipping region of the
  2629. * graphics context is the bounding rectangle of this component.
  2630. * @param g the graphics context to use for printing
  2631. * @see #print(Graphics)
  2632. * @since JDK1.0
  2633. */
  2634. public void printAll(Graphics g) {
  2635. if (isShowing()) {
  2636. GraphicsCallback.PeerPrintCallback.getInstance().
  2637. runOneComponent(this, new Rectangle(0, 0, width, height),
  2638. g, g.getClip(),
  2639. GraphicsCallback.LIGHTWEIGHTS |
  2640. GraphicsCallback.HEAVYWEIGHTS);
  2641. }
  2642. }
  2643. /**
  2644. * Simulates the peer callbacks into java.awt for printing of
  2645. * lightweight Components.
  2646. * @param g the graphics context to use for printing
  2647. * @see #printAll
  2648. */
  2649. void lightweightPrint(Graphics g) {
  2650. print(g);
  2651. }
  2652. /**
  2653. * Prints all the heavyweight subcomponents.
  2654. */
  2655. void printHeavyweightComponents(Graphics g) {
  2656. }
  2657. /**
  2658. * Repaints the component when the image has changed.
  2659. * This <code>imageUpdate</code> method of an <code>ImageObserver</code>
  2660. * is called when more information about an
  2661. * image which had been previously requested using an asynchronous
  2662. * routine such as the <code>drawImage</code> method of
  2663. * <code>Graphics</code> becomes available.
  2664. * See the definition of <code>imageUpdate</code> for
  2665. * more information on this method and its arguments.
  2666. * <p>
  2667. * The <code>imageUpdate</code> method of <code>Component</code>
  2668. * incrementally draws an image on the component as more of the bits
  2669. * of the image are available.
  2670. * <p>
  2671. * If the system property <code>awt.image.incrementaldraw</code>
  2672. * is missing or has the value <code>true</code>, the image is
  2673. * incrementally drawn. If the system property has any other value,
  2674. * then the image is not drawn until it has been completely loaded.
  2675. * <p>
  2676. * Also, if incremental drawing is in effect, the value of the
  2677. * system property <code>awt.image.redrawrate</code> is interpreted
  2678. * as an integer to give the maximum redraw rate, in milliseconds. If
  2679. * the system property is missing or cannot be interpreted as an
  2680. * integer, the redraw rate is once every 100ms.
  2681. * <p>
  2682. * The interpretation of the <code>x</code>, <code>y</code>,
  2683. * <code>width</code>, and <code>height</code> arguments depends on
  2684. * the value of the <code>infoflags</code> argument.
  2685. *
  2686. * @param img the image being observed
  2687. * @param infoflags see <code>imageUpdate</code> for more information
  2688. * @param x the <i>x</i> coordinate
  2689. * @param y the <i>y</i> coordinate
  2690. * @param w the width
  2691. * @param h the height
  2692. * @return <code>false</code> if the infoflags indicate that the
  2693. * image is completely loaded; <code>true</code> otherwise.
  2694. *
  2695. * @see java.awt.image.ImageObserver
  2696. * @see Graphics#drawImage(Image, int, int, Color, java.awt.image.ImageObserver)
  2697. * @see Graphics#drawImage(Image, int, int, java.awt.image.ImageObserver)
  2698. * @see Graphics#drawImage(Image, int, int, int, int, Color, java.awt.image.ImageObserver)
  2699. * @see Graphics#drawImage(Image, int, int, int, int, java.awt.image.ImageObserver)
  2700. * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int)
  2701. * @since JDK1.0
  2702. */
  2703. public boolean imageUpdate(Image img, int infoflags,
  2704. int x, int y, int w, int h) {
  2705. int rate = -1;
  2706. if ((infoflags & (FRAMEBITS|ALLBITS)) != 0) {
  2707. rate = 0;
  2708. } else if ((infoflags & SOMEBITS) != 0) {
  2709. if (isInc) {
  2710. rate = incRate;
  2711. if (rate < 0) {
  2712. rate = 0;
  2713. }
  2714. }
  2715. }
  2716. if (rate >= 0) {
  2717. repaint(rate, 0, 0, width, height);
  2718. }
  2719. return (infoflags & (ALLBITS|ABORT)) == 0;
  2720. }
  2721. /**
  2722. * Creates an image from the specified image producer.
  2723. * @param producer the image producer
  2724. * @return the image produced
  2725. * @since JDK1.0
  2726. */
  2727. public Image createImage(ImageProducer producer) {
  2728. ComponentPeer peer = this.peer;
  2729. if ((peer != null) && ! (peer instanceof LightweightPeer)) {
  2730. return peer.createImage(producer);
  2731. }
  2732. return getToolkit().createImage(producer);
  2733. }
  2734. /**
  2735. * Creates an off-screen drawable image
  2736. * to be used for double buffering.
  2737. * @param width the specified width
  2738. * @param height the specified height
  2739. * @return an off-screen drawable image, which can be used for double
  2740. * buffering. The return value may be <code>null</code> if the
  2741. * component is not displayable. This will always happen if
  2742. * <code>GraphicsEnvironment.isHeadless()</code> returns
  2743. * <code>true</code>.
  2744. * @see #isDisplayable
  2745. * @see GraphicsEnvironment#isHeadless
  2746. * @since JDK1.0
  2747. */
  2748. public Image createImage(int width, int height) {
  2749. ComponentPeer peer = this.peer;
  2750. if (peer instanceof LightweightPeer) {
  2751. if (parent != null) { return parent.createImage(width, height); }
  2752. else { return null;}
  2753. } else {
  2754. return (peer != null) ? peer.createImage(width, height) : null;
  2755. }
  2756. }
  2757. /**
  2758. * Creates a volatile off-screen drawable image
  2759. * to be used for double buffering.
  2760. * @param width the specified width.
  2761. * @param height the specified height.
  2762. * @return an off-screen drawable image, which can be used for double
  2763. * buffering. The return value may be <code>null</code> if the
  2764. * component is not displayable. This will always happen if
  2765. * <code>GraphicsEnvironment.isHeadless()</code> returns
  2766. * <code>true</code>.
  2767. * @see java.awt.image.VolatileImage
  2768. * @see #isDisplayable
  2769. * @see GraphicsEnvironment#isHeadless
  2770. * @since 1.4
  2771. */
  2772. public VolatileImage createVolatileImage(int width, int height) {
  2773. ComponentPeer peer = this.peer;
  2774. if (peer instanceof LightweightPeer) {
  2775. if (parent != null) {
  2776. return parent.createVolatileImage(width, height);
  2777. }
  2778. else { return null;}
  2779. } else {
  2780. return (peer != null) ?
  2781. peer.createVolatileImage(width, height) : null;
  2782. }
  2783. }
  2784. /**
  2785. * Creates a volatile off-screen drawable image, with the given capabilities.
  2786. * The contents of this image may be lost at any time due
  2787. * to operating system issues, so the image must be managed
  2788. * via the <code>VolatileImage</code> interface.
  2789. * @param width the specified width.
  2790. * @param height the specified height.
  2791. * @param caps the image capabilities
  2792. * @exception AWTException if an image with the specified capabilities cannot
  2793. * be created
  2794. * @return a VolatileImage object, which can be used
  2795. * to manage surface contents loss and capabilities.
  2796. * @see java.awt.image.VolatileImage
  2797. * @since 1.4
  2798. */
  2799. public VolatileImage createVolatileImage(int width, int height,
  2800. ImageCapabilities caps) throws AWTException {
  2801. // REMIND : check caps
  2802. return createVolatileImage(width, height);
  2803. }
  2804. /**
  2805. * Prepares an image for rendering on this component. The image
  2806. * data is downloaded asynchronously in another thread and the
  2807. * appropriate screen representation of the image is generated.
  2808. * @param image the <code>Image</code> for which to
  2809. * prepare a screen representation
  2810. * @param observer the <code>ImageObserver</code> object
  2811. * to be notified as the image is being prepared
  2812. * @return <code>true</code> if the image has already been fully
  2813. * prepared; <code>false</code> otherwise
  2814. * @since JDK1.0
  2815. */
  2816. public boolean prepareImage(Image image, ImageObserver observer) {
  2817. return prepareImage(image, -1, -1, observer);
  2818. }
  2819. /**
  2820. * Prepares an image for rendering on this component at the
  2821. * specified width and height.
  2822. * <p>
  2823. * The image data is downloaded asynchronously in another thread,
  2824. * and an appropriately scaled screen representation of the image is
  2825. * generated.
  2826. * @param image the instance of <code>Image</code>
  2827. * for which to prepare a screen representation
  2828. * @param width the width of the desired screen representation
  2829. * @param height the height of the desired screen representation
  2830. * @param observer the <code>ImageObserver</code> object
  2831. * to be notified as the image is being prepared
  2832. * @return <code>true</code> if the image has already been fully
  2833. * prepared; <code>false</code> otherwise
  2834. * @see java.awt.image.ImageObserver
  2835. * @since JDK1.0
  2836. */
  2837. public boolean prepareImage(Image image, int width, int height,
  2838. ImageObserver observer) {
  2839. ComponentPeer peer = this.peer;
  2840. if (peer instanceof LightweightPeer) {
  2841. return (parent != null)
  2842. ? parent.prepareImage(image, width, height, observer)
  2843. : getToolkit().prepareImage(image, width, height, observer);
  2844. } else {
  2845. return (peer != null)
  2846. ? peer.prepareImage(image, width, height, observer)
  2847. : getToolkit().prepareImage(image, width, height, observer);
  2848. }
  2849. }
  2850. /**
  2851. * Returns the status of the construction of a screen representation
  2852. * of the specified image.
  2853. * <p>
  2854. * This method does not cause the image to begin loading. An
  2855. * application must use the <code>prepareImage</code> method
  2856. * to force the loading of an image.
  2857. * <p>
  2858. * Information on the flags returned by this method can be found
  2859. * with the discussion of the <code>ImageObserver</code> interface.
  2860. * @param image the <code>Image</code> object whose status
  2861. * is being checked
  2862. * @param observer the <code>ImageObserver</code>
  2863. * object to be notified as the image is being prepared
  2864. * @return the bitwise inclusive <b>OR</b> of
  2865. * <code>ImageObserver</code> flags indicating what
  2866. * information about the image is currently available
  2867. * @see #prepareImage(Image, int, int, java.awt.image.ImageObserver)
  2868. * @see Toolkit#checkImage(Image, int, int, java.awt.image.ImageObserver)
  2869. * @see java.awt.image.ImageObserver
  2870. * @since JDK1.0
  2871. */
  2872. public int checkImage(Image image, ImageObserver observer) {
  2873. return checkImage(image, -1, -1, observer);
  2874. }
  2875. /**
  2876. * Returns the status of the construction of a screen representation
  2877. * of the specified image.
  2878. * <p>
  2879. * This method does not cause the image to begin loading. An
  2880. * application must use the <code>prepareImage</code> method
  2881. * to force the loading of an image.
  2882. * <p>
  2883. * The <code>checkImage</code> method of <code>Component</code>
  2884. * calls its peer's <code>checkImage</code> method to calculate
  2885. * the flags. If this component does not yet have a peer, the
  2886. * component's toolkit's <code>checkImage</code> method is called
  2887. * instead.
  2888. * <p>
  2889. * Information on the flags returned by this method can be found
  2890. * with the discussion of the <code>ImageObserver</code> interface.
  2891. * @param image the <code>Image</code> object whose status
  2892. * is being checked
  2893. * @param width the width of the scaled version
  2894. * whose status is to be checked
  2895. * @param height the height of the scaled version
  2896. * whose status is to be checked
  2897. * @param observer the <code>ImageObserver</code> object
  2898. * to be notified as the image is being prepared
  2899. * @return the bitwise inclusive <b>OR</b> of
  2900. * <code>ImageObserver</code> flags indicating what
  2901. * information about the image is currently available
  2902. * @see #prepareImage(Image, int, int, java.awt.image.ImageObserver)
  2903. * @see Toolkit#checkImage(Image, int, int, java.awt.image.ImageObserver)
  2904. * @see java.awt.image.ImageObserver
  2905. * @since JDK1.0
  2906. */
  2907. public int checkImage(Image image, int width, int height,
  2908. ImageObserver observer) {
  2909. ComponentPeer peer = this.peer;
  2910. if (peer instanceof LightweightPeer) {
  2911. return (parent != null)
  2912. ? parent.checkImage(image, width, height, observer)
  2913. : getToolkit().checkImage(image, width, height, observer);
  2914. } else {
  2915. return (peer != null)
  2916. ? peer.checkImage(image, width, height, observer)
  2917. : getToolkit().checkImage(image, width, height, observer);
  2918. }
  2919. }
  2920. /**
  2921. * Creates a new strategy for multi-buffering on this component.
  2922. * Multi-buffering is useful for rendering performance. This method
  2923. * attempts to create the best strategy available with the number of
  2924. * buffers supplied. It will always create a <code>BufferStrategy</code>
  2925. * with that number of buffers.
  2926. * A page-flipping strategy is attempted first, then a blitting strategy
  2927. * using accelerated buffers. Finally, an unaccelerated blitting
  2928. * strategy is used.
  2929. * <p>
  2930. * Each time this method is called,
  2931. * the existing buffer strategy for this component is discarded.
  2932. * @param numBuffers number of buffers to create, including the front buffer
  2933. * @exception IllegalArgumentException if numBuffers is less than 1.
  2934. * @exception IllegalStateException if the component is not displayable
  2935. * @see #isDisplayable
  2936. * @see #getBufferStrategy()
  2937. * @since 1.4
  2938. */
  2939. void createBufferStrategy(int numBuffers) {
  2940. BufferCapabilities bufferCaps;
  2941. if (numBuffers > 1) {
  2942. // Try to create a page-flipping strategy
  2943. bufferCaps = new BufferCapabilities(
  2944. new ImageCapabilities(true), new ImageCapabilities(true),
  2945. BufferCapabilities.FlipContents.UNDEFINED);
  2946. try {
  2947. createBufferStrategy(numBuffers, bufferCaps);
  2948. return; // Success
  2949. } catch (AWTException e) {
  2950. // Failed
  2951. }
  2952. }
  2953. // Try a blitting (but still accelerated) strategy
  2954. bufferCaps = new BufferCapabilities(
  2955. new ImageCapabilities(true), new ImageCapabilities(true), null);
  2956. try {
  2957. createBufferStrategy(numBuffers, bufferCaps);
  2958. return; // Success
  2959. } catch (AWTException e) {
  2960. // Failed
  2961. }
  2962. // Try an unaccelerated blitting strategy
  2963. bufferCaps = new BufferCapabilities(
  2964. new ImageCapabilities(false), new ImageCapabilities(false), null);
  2965. try {
  2966. createBufferStrategy(numBuffers, bufferCaps);
  2967. return; // Success
  2968. } catch (AWTException e) {
  2969. // Failed
  2970. }
  2971. // Code should never reach here (an unaccelerated blitting
  2972. // strategy should always work)
  2973. throw new InternalError("Could not create a buffer strategy");
  2974. }
  2975. /**
  2976. * Creates a new strategy for multi-buffering on this component with the
  2977. * required buffer capabilities. This is useful, for example, if only
  2978. * accelerated memory or page flipping is desired (as specified by the
  2979. * buffer capabilities).
  2980. * <p>
  2981. * Each time this method
  2982. * is called, the existing buffer strategy for this component is discarded.
  2983. * @param numBuffers number of buffers to create
  2984. * @param caps the required capabilities for creating the buffer strategy;
  2985. * cannot be <code>null</code>
  2986. * @exception AWTException if the capabilities supplied could not be
  2987. * supported or met; this may happen, for example, if there is not enough
  2988. * accelerated memory currently available, or if page flipping is specified
  2989. * but not possible.
  2990. * @exception IllegalArgumentException if numBuffers is less than 1, or if
  2991. * caps is <code>null</code>
  2992. * @see #getBufferStrategy()
  2993. * @since 1.4
  2994. */
  2995. void createBufferStrategy(int numBuffers,
  2996. BufferCapabilities caps) throws AWTException {
  2997. // Check arguments
  2998. if (numBuffers < 1) {
  2999. throw new IllegalArgumentException(
  3000. "Number of buffers must be at least 1");
  3001. }
  3002. if (caps == null) {
  3003. throw new IllegalArgumentException("No capabilities specified");
  3004. }
  3005. // Destroy old buffers
  3006. if (bufferStrategy instanceof FlipBufferStrategy) {
  3007. ((FlipBufferStrategy)bufferStrategy).destroyBuffers();
  3008. }
  3009. if (numBuffers == 1) {
  3010. bufferStrategy = new SingleBufferStrategy(caps);
  3011. } else {
  3012. // assert numBuffers > 1;
  3013. if (caps.isPageFlipping()) {
  3014. bufferStrategy = new FlipBufferStrategy(numBuffers, caps);
  3015. } else {
  3016. bufferStrategy = new BltBufferStrategy(numBuffers, caps);
  3017. }
  3018. }
  3019. }
  3020. /**
  3021. * @return the buffer strategy used by this component
  3022. * @see Window#createBufferStrategy
  3023. * @see Canvas#createBufferStrategy
  3024. * @since 1.4
  3025. */
  3026. BufferStrategy getBufferStrategy() {
  3027. if (bufferStrategy == null) {
  3028. createBufferStrategy(1);
  3029. }
  3030. return bufferStrategy;
  3031. }
  3032. /**
  3033. * @return the back buffer currently used by this component's
  3034. * BufferStrategy. If there is no BufferStrategy or no
  3035. * back buffer, this method returns null.
  3036. */
  3037. Image getBackBuffer() {
  3038. if (bufferStrategy != null) {
  3039. if (bufferStrategy instanceof BltBufferStrategy) {
  3040. BltBufferStrategy bltBS = (BltBufferStrategy)bufferStrategy;
  3041. return bltBS.getBackBuffer();
  3042. } else if (bufferStrategy instanceof FlipBufferStrategy) {
  3043. FlipBufferStrategy flipBS = (FlipBufferStrategy)bufferStrategy;
  3044. return flipBS.getBackBuffer();
  3045. }
  3046. }
  3047. return null;
  3048. }
  3049. /**
  3050. * Inner class for flipping buffers on a component. That component must
  3051. * be a <code>Canvas</code> or <code>Window</code>.
  3052. * @see Canvas
  3053. * @see Window
  3054. * @see java.awt.image.BufferStrategy
  3055. * @author Michael Martak
  3056. * @since 1.4
  3057. */
  3058. protected class FlipBufferStrategy extends BufferStrategy {
  3059. /**
  3060. * The number of buffers
  3061. */
  3062. protected int numBuffers; // = 0
  3063. /**
  3064. * The buffering capabilities
  3065. */
  3066. protected BufferCapabilities caps; // = null
  3067. /**
  3068. * The drawing buffer
  3069. */
  3070. protected Image drawBuffer; // = null
  3071. /**
  3072. * The drawing buffer as a volatile image
  3073. */
  3074. protected VolatileImage drawVBuffer; // = null
  3075. /**
  3076. * Whether or not the drawing buffer has been recently restored from
  3077. * a lost state.
  3078. */
  3079. protected boolean validatedContents; // = false
  3080. /**
  3081. * Creates a new flipping buffer strategy for this component.
  3082. * The component must be a <code>Canvas</code> or <code>Window</code>.
  3083. * @see Canvas
  3084. * @see Window
  3085. * @param numBuffers the number of buffers
  3086. * @param caps the capabilities of the buffers
  3087. * @exception AWTException if the capabilities supplied could not be
  3088. * supported or met
  3089. * @exception ClassCastException if the component is not a canvas or
  3090. * window.
  3091. */
  3092. protected FlipBufferStrategy(int numBuffers, BufferCapabilities caps)
  3093. throws AWTException {
  3094. if (!(Component.this instanceof Window) &&
  3095. !(Component.this instanceof Canvas)) {
  3096. throw new ClassCastException(
  3097. "Component must be a Canvas or Window");
  3098. }
  3099. this.numBuffers = numBuffers;
  3100. this.caps = caps;
  3101. createBuffers(numBuffers, caps);
  3102. }
  3103. /**
  3104. * Creates one or more complex, flipping buffers with the given
  3105. * capabilities.
  3106. * @param numBuffers number of buffers to create; must be greater than
  3107. * one
  3108. * @param caps the capabilities of the buffers.
  3109. * <code>BufferCapabilities.isPageFlipping</code> must be
  3110. * <code>true</code>.
  3111. * @exception AWTException if the capabilities supplied could not be
  3112. * supported or met
  3113. * @exception IllegalStateException if the component has no peer
  3114. * @exception IllegalArgumentException if numBuffers is less than two,
  3115. * or if <code>BufferCapabilities.isPageFlipping</code> is not
  3116. * <code>true</code>.
  3117. * @see java.awt.BufferCapabilities#isPageFlipping()
  3118. */
  3119. protected void createBuffers(int numBuffers, BufferCapabilities caps)
  3120. throws AWTException {
  3121. if (numBuffers < 2) {
  3122. throw new IllegalArgumentException(
  3123. "Number of buffers cannot be less than two");
  3124. } else if (peer == null) {
  3125. throw new IllegalStateException(
  3126. "Component must have a valid peer");
  3127. } else if (caps == null || !caps.isPageFlipping()) {
  3128. throw new IllegalArgumentException(
  3129. "Page flipping capabilities must be specified");
  3130. } else {
  3131. peer.createBuffers(numBuffers, caps);
  3132. }
  3133. }
  3134. /**
  3135. * @return direct access to the back buffer, as an image.
  3136. * @exception IllegalStateException if the buffers have not yet
  3137. * been created
  3138. */
  3139. protected Image getBackBuffer() {
  3140. if (peer != null) {
  3141. Image drawBuffer = peer.getBackBuffer();
  3142. if (drawBuffer instanceof VolatileImage) {
  3143. drawVBuffer = (VolatileImage)drawBuffer;
  3144. }
  3145. revalidate();
  3146. return drawBuffer;
  3147. } else {
  3148. throw new IllegalStateException(
  3149. "Component must have a valid peer");
  3150. }
  3151. }
  3152. /**
  3153. * Flipping moves the contents of the back buffer to the front buffer,
  3154. * either by copying or by moving the video pointer.
  3155. * @param flipAction an integer value describing the flipping action
  3156. * for the contents of the back buffer. This should be one of the
  3157. * values of the <code>BufferCapabilities.FlipContents</code>
  3158. * property.
  3159. * @exception IllegalStateException if the buffers have not yet
  3160. * been created
  3161. * @see java.awt.BufferCapabilities#getFlipContents()
  3162. */
  3163. protected void flip(BufferCapabilities.FlipContents flipAction) {
  3164. if (peer != null) {
  3165. peer.flip(flipAction);
  3166. } else {
  3167. throw new IllegalStateException(
  3168. "Component must have a valid peer");
  3169. }
  3170. }
  3171. /**
  3172. * Destroys the buffers created through this object
  3173. */
  3174. protected void destroyBuffers() {
  3175. if (peer != null) {
  3176. peer.destroyBuffers();
  3177. } else {
  3178. throw new IllegalStateException(
  3179. "Component must have a valid peer");
  3180. }
  3181. }
  3182. /**
  3183. * @return the buffering capabilities of this strategy
  3184. */
  3185. public BufferCapabilities getCapabilities() {
  3186. return caps;
  3187. }
  3188. /**
  3189. * @return the graphics on the drawing buffer. This method may not
  3190. * be synchronized for performance reasons; use of this method by multiple
  3191. * threads should be handled at the application level. Disposal of the
  3192. * graphics object must be handled by the application.
  3193. */
  3194. public Graphics getDrawGraphics() {
  3195. if (drawBuffer == null) {
  3196. // Set up drawing buffer
  3197. drawBuffer = getBackBuffer();
  3198. if (drawBuffer instanceof VolatileImage) {
  3199. drawVBuffer = (VolatileImage)drawBuffer;
  3200. }
  3201. }
  3202. revalidate();
  3203. return drawBuffer.getGraphics();
  3204. }
  3205. /**
  3206. * Restore the drawing buffer if it has been lost
  3207. */
  3208. protected void revalidate() {
  3209. // REMIND: this whole validation mechanism needs to be re-examined
  3210. // for correctness. Currently, the value of validatedContents
  3211. // may be changed and overwritten before the user has a chance to
  3212. // see that there was any restoration to the surface. Also, we
  3213. // need to handle the IMAGE_INCOMPATIBLE case.
  3214. if (drawVBuffer != null) {
  3215. validatedContents = (drawVBuffer.validate(
  3216. getGraphicsConfiguration()) == VolatileImage.IMAGE_RESTORED);
  3217. } else {
  3218. validatedContents = false;
  3219. }
  3220. }
  3221. /**
  3222. * @return whether the drawing buffer was lost since the last call to
  3223. * <code>getDrawGraphics</code>
  3224. */
  3225. public boolean contentsLost() {
  3226. if (drawVBuffer == null) {
  3227. return false;
  3228. }
  3229. return drawVBuffer.contentsLost();
  3230. }
  3231. /**
  3232. * @return whether the drawing buffer was recently restored from a lost
  3233. * state and reinitialized to the default background color (white)
  3234. */
  3235. public boolean contentsRestored() {
  3236. return validatedContents;
  3237. }
  3238. /**
  3239. * Makes the next available buffer visible by either blitting or
  3240. * flipping.
  3241. */
  3242. public void show() {
  3243. flip(caps.getFlipContents());
  3244. }
  3245. } // Inner class FlipBufferStrategy
  3246. /**
  3247. * Inner class for blitting offscreen surfaces to a component.
  3248. *
  3249. * @author Michael Martak
  3250. * @since 1.4
  3251. */
  3252. protected class BltBufferStrategy extends BufferStrategy {
  3253. /**
  3254. * The buffering capabilities
  3255. */
  3256. protected BufferCapabilities caps; // = null
  3257. /**
  3258. * The back buffers
  3259. */
  3260. protected VolatileImage[] backBuffers; // = null
  3261. /**
  3262. * Whether or not the drawing buffer has been recently restored from
  3263. * a lost state.
  3264. */
  3265. protected boolean validatedContents; // = false
  3266. /**
  3267. * Size of the back buffers
  3268. */
  3269. protected int width;
  3270. protected int height;
  3271. /**
  3272. * Creates a new blt buffer strategy around a component
  3273. * @param numBuffers the component to use as the front buffer
  3274. * @param caps the capabilities of the buffers
  3275. */
  3276. protected BltBufferStrategy(int numBuffers, BufferCapabilities caps) {
  3277. this.caps = caps;
  3278. createBackBuffers(numBuffers - 1);
  3279. }
  3280. /**
  3281. * Creates the back buffers
  3282. */
  3283. protected void createBackBuffers(int numBuffers) {
  3284. if (numBuffers == 0) {
  3285. backBuffers = null;
  3286. } else {
  3287. width = getWidth();
  3288. height = getHeight();
  3289. backBuffers = new VolatileImage[numBuffers];
  3290. for (int i = 0; i < numBuffers; i++) {
  3291. backBuffers[i] = createVolatileImage(width, height);
  3292. }
  3293. }
  3294. }
  3295. /**
  3296. * @return the buffering capabilities of this strategy
  3297. */
  3298. public BufferCapabilities getCapabilities() {
  3299. return caps;
  3300. }
  3301. /**
  3302. * @return the draw graphics
  3303. */
  3304. public Graphics getDrawGraphics() {
  3305. revalidate();
  3306. Image backBuffer = getBackBuffer();
  3307. if (backBuffer == null) {
  3308. return getGraphics();
  3309. }
  3310. return backBuffer.getGraphics();
  3311. }
  3312. /**
  3313. * @return direct access to the back buffer, as an image.
  3314. * If there is no back buffer, returns null.
  3315. */
  3316. Image getBackBuffer() {
  3317. if (backBuffers != null) {
  3318. return backBuffers[backBuffers.length - 1];
  3319. } else {
  3320. return null;
  3321. }
  3322. }
  3323. /**
  3324. * Makes the next available buffer visible.
  3325. */
  3326. public void show() {
  3327. if (backBuffers == null) {
  3328. return;
  3329. }
  3330. Graphics g = getGraphics();
  3331. try {
  3332. for (int i = 0; i < backBuffers.length; i++) {
  3333. g.drawImage(backBuffers[i], 0, 0, Component.this);
  3334. g.dispose();
  3335. g = null;
  3336. g = backBuffers[i].getGraphics();
  3337. }
  3338. } finally {
  3339. if (g != null) {
  3340. g.dispose();
  3341. }
  3342. }
  3343. }
  3344. /**
  3345. * Restore the drawing buffer if it has been lost
  3346. */
  3347. protected void revalidate() {
  3348. if (backBuffers == null) {
  3349. validatedContents = false;
  3350. } else if (getWidth() != width || getHeight() != height) {
  3351. createBackBuffers(backBuffers.length);
  3352. validatedContents = true;
  3353. } else {
  3354. validatedContents =
  3355. (backBuffers[backBuffers.length - 1].validate(
  3356. getGraphicsConfiguration())
  3357. == VolatileImage.IMAGE_RESTORED);
  3358. // REMIND : handle IMAGE_INCOMPATIBLE
  3359. }
  3360. }
  3361. /**
  3362. * @return whether the drawing buffer was lost since the last call to
  3363. * <code>getDrawGraphics</code>
  3364. */
  3365. public boolean contentsLost() {
  3366. if (width < getWidth() || height < getHeight()) {
  3367. return true;
  3368. } else {
  3369. return backBuffers[backBuffers.length - 1].contentsLost();
  3370. }
  3371. }
  3372. /**
  3373. * @return whether the drawing buffer was recently restored from a lost
  3374. * state and reinitialized to the default background color (white)
  3375. */
  3376. public boolean contentsRestored() {
  3377. return validatedContents;
  3378. }
  3379. } // Inner class BltBufferStrategy
  3380. /**
  3381. * Inner class for flipping buffers on a component. That component must
  3382. * be a <code>Canvas</code> or <code>Window</code>.
  3383. * @see Canvas
  3384. * @see Window
  3385. * @see java.awt.image.BufferStrategy
  3386. * @author Michael Martak
  3387. * @since 1.4
  3388. */
  3389. private class SingleBufferStrategy extends BufferStrategy {
  3390. private BufferCapabilities caps;
  3391. public SingleBufferStrategy(BufferCapabilities caps) {
  3392. this.caps = caps;
  3393. }
  3394. public BufferCapabilities getCapabilities() {
  3395. return caps;
  3396. }
  3397. public Graphics getDrawGraphics() {
  3398. return getGraphics();
  3399. }
  3400. public boolean contentsLost() {
  3401. // return peer.getSurfaceData().contentsLost();
  3402. return false;
  3403. }
  3404. public boolean contentsRestored() {
  3405. // return peer.getSurfaceData().validate();
  3406. return false;
  3407. }
  3408. public void show() {
  3409. // Do nothing; could repaint
  3410. }
  3411. } // Inner class SingleBufferStrategy
  3412. /**
  3413. * Sets whether or not paint messages received from the operating system
  3414. * should be ignored. This does not affect paint events generated in
  3415. * software by the AWT, unless they are an immediate response to an
  3416. * OS-level paint message.
  3417. * <p>
  3418. * This is useful, for example, if running under full-screen mode and
  3419. * better performance is desired, or if page-flipping is used as the
  3420. * buffer strategy.
  3421. *
  3422. * @since 1.4
  3423. * @see #getIgnoreRepaint
  3424. * @see Canvas#createBufferStrategy
  3425. * @see Window#createBufferStrategy
  3426. * @see java.awt.image.BufferStrategy
  3427. * @see GraphicsDevice#setFullScreenWindow
  3428. */
  3429. public void setIgnoreRepaint(boolean ignoreRepaint) {
  3430. this.ignoreRepaint = ignoreRepaint;
  3431. }
  3432. /**
  3433. * @return whether or not paint messages received from the operating system
  3434. * should be ignored.
  3435. *
  3436. * @since 1.4
  3437. * @see #setIgnoreRepaint
  3438. */
  3439. public boolean getIgnoreRepaint() {
  3440. return ignoreRepaint;
  3441. }
  3442. /**
  3443. * Checks whether this component "contains" the specified point,
  3444. * where <code>x</code> and <code>y</code> are defined to be
  3445. * relative to the coordinate system of this component.
  3446. * @param x the <i>x</i> coordinate of the point
  3447. * @param y the <i>y</i> coordinate of the point
  3448. * @see #getComponentAt(int, int)
  3449. * @since JDK1.1
  3450. */
  3451. public boolean contains(int x, int y) {
  3452. return inside(x, y);
  3453. }
  3454. /**
  3455. * @deprecated As of JDK version 1.1,
  3456. * replaced by contains(int, int).
  3457. */
  3458. @Deprecated
  3459. public boolean inside(int x, int y) {
  3460. return (x >= 0) && (x < width) && (y >= 0) && (y < height);
  3461. }
  3462. /**
  3463. * Checks whether this component "contains" the specified point,
  3464. * where the point's <i>x</i> and <i>y</i> coordinates are defined
  3465. * to be relative to the coordinate system of this component.
  3466. * @param p the point
  3467. * @see #getComponentAt(Point)
  3468. * @since JDK1.1
  3469. */
  3470. public boolean contains(Point p) {
  3471. return contains(p.x, p.y);
  3472. }
  3473. /**
  3474. * Determines if this component or one of its immediate
  3475. * subcomponents contains the (<i>x</i>, <i>y</i>) location,
  3476. * and if so, returns the containing component. This method only
  3477. * looks one level deep. If the point (<i>x</i>, <i>y</i>) is
  3478. * inside a subcomponent that itself has subcomponents, it does not
  3479. * go looking down the subcomponent tree.
  3480. * <p>
  3481. * The <code>locate</code> method of <code>Component</code> simply
  3482. * returns the component itself if the (<i>x</i>, <i>y</i>)
  3483. * coordinate location is inside its bounding box, and <code>null</code>
  3484. * otherwise.
  3485. * @param x the <i>x</i> coordinate
  3486. * @param y the <i>y</i> coordinate
  3487. * @return the component or subcomponent that contains the
  3488. * (<i>x</i>, <i>y</i>) location;
  3489. * <code>null</code> if the location
  3490. * is outside this component
  3491. * @see #contains(int, int)
  3492. * @since JDK1.0
  3493. */
  3494. public Component getComponentAt(int x, int y) {
  3495. return locate(x, y);
  3496. }
  3497. /**
  3498. * @deprecated As of JDK version 1.1,
  3499. * replaced by getComponentAt(int, int).
  3500. */
  3501. @Deprecated
  3502. public Component locate(int x, int y) {
  3503. return contains(x, y) ? this : null;
  3504. }
  3505. /**
  3506. * Returns the component or subcomponent that contains the
  3507. * specified point.
  3508. * @param p the point
  3509. * @see java.awt.Component#contains
  3510. * @since JDK1.1
  3511. */
  3512. public Component getComponentAt(Point p) {
  3513. return getComponentAt(p.x, p.y);
  3514. }
  3515. /**
  3516. * @deprecated As of JDK version 1.1,
  3517. * replaced by <code>dispatchEvent(AWTEvent e)</code>.
  3518. */
  3519. @Deprecated
  3520. public void deliverEvent(Event e) {
  3521. postEvent(e);
  3522. }
  3523. /**
  3524. * Dispatches an event to this component or one of its sub components.
  3525. * Calls <code>processEvent</code> before returning for 1.1-style
  3526. * events which have been enabled for the <code>Component</code>.
  3527. * @param e the event
  3528. */
  3529. public final void dispatchEvent(AWTEvent e) {
  3530. dispatchEventImpl(e);
  3531. }
  3532. void dispatchEventImpl(AWTEvent e) {
  3533. int id = e.getID();
  3534. // Check that this component belongs to this app-context
  3535. AppContext compContext = appContext;
  3536. if (compContext != null && !compContext.equals(AppContext.getAppContext())) {
  3537. log.fine("Event " + e + " is being dispatched on the wrong AppContext");
  3538. }
  3539. /*
  3540. * 0. Set timestamp and modifiers of current event.
  3541. */
  3542. EventQueue.setCurrentEventAndMostRecentTime(e);
  3543. /*
  3544. * 1. Pre-dispatchers. Do any necessary retargeting/reordering here
  3545. * before we notify AWTEventListeners.
  3546. */
  3547. if (e instanceof SunDropTargetEvent) {
  3548. ((SunDropTargetEvent)e).dispatch();
  3549. return;
  3550. }
  3551. if (!e.focusManagerIsDispatching) {
  3552. // Invoke the private focus retargeting method which provides
  3553. // lightweight Component support
  3554. if (e.isPosted) {
  3555. e = KeyboardFocusManager.retargetFocusEvent(e);
  3556. e.isPosted = true;
  3557. }
  3558. // Now, with the event properly targeted to a lightweight
  3559. // descendant if necessary, invoke the public focus retargeting
  3560. // and dispatching function
  3561. if (KeyboardFocusManager.getCurrentKeyboardFocusManager().
  3562. dispatchEvent(e))
  3563. {
  3564. return;
  3565. }
  3566. }
  3567. if (e instanceof FocusEvent && focusLog.isLoggable(Level.FINE)) {
  3568. focusLog.fine("" + e);
  3569. }
  3570. // MouseWheel may need to be retargeted here so that
  3571. // AWTEventListener sees the event go to the correct
  3572. // Component. If the MouseWheelEvent needs to go to an ancestor,
  3573. // the event is dispatched to the ancestor, and dispatching here
  3574. // stops.
  3575. if (id == MouseEvent.MOUSE_WHEEL &&
  3576. (!eventTypeEnabled(id)) &&
  3577. (peer != null && !peer.handlesWheelScrolling()) &&
  3578. (dispatchMouseWheelToAncestor((MouseWheelEvent)e)))
  3579. {
  3580. return;
  3581. }
  3582. /*
  3583. * 2. Allow the Toolkit to pass this to AWTEventListeners.
  3584. */
  3585. Toolkit toolkit = Toolkit.getDefaultToolkit();
  3586. toolkit.notifyAWTEventListeners(e);
  3587. /*
  3588. * 3. If no one has consumed a key event, allow the
  3589. * KeyboardFocusManager to process it.
  3590. */
  3591. if (!e.isConsumed()) {
  3592. if (e instanceof java.awt.event.KeyEvent) {
  3593. KeyboardFocusManager.getCurrentKeyboardFocusManager().
  3594. processKeyEvent(this, (KeyEvent)e);
  3595. if (e.isConsumed()) {
  3596. return;
  3597. }
  3598. }
  3599. }
  3600. /*
  3601. * 4. Allow input methods to process the event
  3602. */
  3603. if (areInputMethodsEnabled()
  3604. && (
  3605. // We need to pass on InputMethodEvents since some host
  3606. // input method adapters send them through the Java
  3607. // event queue instead of directly to the component,
  3608. // and the input context also handles the Java composition window
  3609. ((e instanceof InputMethodEvent) && !(this instanceof CompositionArea))
  3610. ||
  3611. // Otherwise, we only pass on input and focus events, because
  3612. // a) input methods shouldn't know about semantic or component-level events
  3613. // b) passing on the events takes time
  3614. // c) isConsumed() is always true for semantic events.
  3615. (e instanceof InputEvent) || (e instanceof FocusEvent))) {
  3616. InputContext inputContext = getInputContext();
  3617. if (inputContext != null) {
  3618. inputContext.dispatchEvent(e);
  3619. if (e.isConsumed()) {
  3620. if (e instanceof FocusEvent && focusLog.isLoggable(Level.FINER)) {
  3621. focusLog.finer("3579: Skipping " + e);
  3622. }
  3623. return;
  3624. }
  3625. }
  3626. }
  3627. /*
  3628. * 5. Pre-process any special events before delivery
  3629. */
  3630. switch(id) {
  3631. // Handling of the PAINT and UPDATE events is now done in the
  3632. // peer's handleEvent() method so the background can be cleared
  3633. // selectively for non-native components on Windows only.
  3634. // - Fred.Ecks@Eng.sun.com, 5-8-98
  3635. case KeyEvent.KEY_PRESSED:
  3636. case KeyEvent.KEY_RELEASED:
  3637. Container p = (Container)((this instanceof Container) ? this : parent);
  3638. if (p != null) {
  3639. p.preProcessKeyEvent((KeyEvent)e);
  3640. if (e.isConsumed()) {
  3641. return;
  3642. }
  3643. }
  3644. break;
  3645. case WindowEvent.WINDOW_CLOSING:
  3646. if (toolkit instanceof WindowClosingListener) {
  3647. windowClosingException = ((WindowClosingListener)
  3648. toolkit).windowClosingNotify((WindowEvent)e);
  3649. if (checkWindowClosingException()) {
  3650. return;
  3651. }
  3652. }
  3653. break;
  3654. default:
  3655. break;
  3656. }
  3657. /*
  3658. * 6. Deliver event for normal processing
  3659. */
  3660. if (newEventsOnly) {
  3661. // Filtering needs to really be moved to happen at a lower
  3662. // level in order to get maximum performance gain; it is
  3663. // here temporarily to ensure the API spec is honored.
  3664. //
  3665. if (eventEnabled(e)) {
  3666. processEvent(e);
  3667. }
  3668. } else if (id == MouseEvent.MOUSE_WHEEL) {
  3669. // newEventsOnly will be false for a listenerless ScrollPane, but
  3670. // MouseWheelEvents still need to be dispatched to it so scrolling
  3671. // can be done.
  3672. autoProcessMouseWheel((MouseWheelEvent)e);
  3673. } else if (!(e instanceof MouseEvent && !postsOldMouseEvents())) {
  3674. //
  3675. // backward compatibility
  3676. //
  3677. Event olde = e.convertToOld();
  3678. if (olde != null) {
  3679. int key = olde.key;
  3680. int modifiers = olde.modifiers;
  3681. postEvent(olde);
  3682. if (olde.isConsumed()) {
  3683. e.consume();
  3684. }
  3685. // if target changed key or modifier values, copy them
  3686. // back to original event
  3687. //
  3688. switch(olde.id) {
  3689. case Event.KEY_PRESS:
  3690. case Event.KEY_RELEASE:
  3691. case Event.KEY_ACTION:
  3692. case Event.KEY_ACTION_RELEASE:
  3693. if (olde.key != key) {
  3694. ((KeyEvent)e).setKeyChar(olde.getKeyEventChar());
  3695. }
  3696. if (olde.modifiers != modifiers) {
  3697. ((KeyEvent)e).setModifiers(olde.modifiers);
  3698. }
  3699. break;
  3700. default:
  3701. break;
  3702. }
  3703. }
  3704. }
  3705. /*
  3706. * 8. Special handling for 4061116 : Hook for browser to close modal
  3707. * dialogs.
  3708. */
  3709. if (id == WindowEvent.WINDOW_CLOSING && !e.isConsumed()) {
  3710. if (toolkit instanceof WindowClosingListener) {
  3711. windowClosingException =
  3712. ((WindowClosingListener)toolkit).
  3713. windowClosingDelivered((WindowEvent)e);
  3714. if (checkWindowClosingException()) {
  3715. return;
  3716. }
  3717. }
  3718. }
  3719. /*
  3720. * 9. Allow the peer to process the event.
  3721. * Except KeyEvents, they will be processed by peer after
  3722. * all KeyEventPostProcessors
  3723. * (see DefaultKeyboardFocusManager.dispatchKeyEvent())
  3724. */
  3725. if (!(e instanceof KeyEvent)) {
  3726. ComponentPeer tpeer = peer;
  3727. if (e instanceof FocusEvent && (tpeer == null || tpeer instanceof LightweightPeer)) {
  3728. // if focus owner is lightweight then its native container
  3729. // processes event
  3730. Component source = (Component)e.getSource();
  3731. if (source != null) {
  3732. Container target = source.getNativeContainer();
  3733. if (target != null) {
  3734. tpeer = target.getPeer();
  3735. }
  3736. }
  3737. }
  3738. if (tpeer != null) {
  3739. tpeer.handleEvent(e);
  3740. }
  3741. }
  3742. } // dispatchEventImpl()
  3743. /*
  3744. * If newEventsOnly is false, method is called so that ScrollPane can
  3745. * override it and handle common-case mouse wheel scrolling. NOP
  3746. * for Component.
  3747. */
  3748. void autoProcessMouseWheel(MouseWheelEvent e) {}
  3749. /*
  3750. * Dispatch given MouseWheelEvent to the first ancestor for which
  3751. * MouseWheelEvents are enabled.
  3752. *
  3753. * Returns whether or not event was dispatched to an ancestor
  3754. */
  3755. boolean dispatchMouseWheelToAncestor(MouseWheelEvent e) {
  3756. int newX, newY;
  3757. newX = e.getX() + getX(); // Coordinates take into account at least
  3758. newY = e.getY() + getY(); // the cursor's position relative to this
  3759. // Component (e.getX()), and this Component's
  3760. // position relative to its parent.
  3761. MouseWheelEvent newMWE;
  3762. if (dbg.on) {
  3763. dbg.println("Component.dispatchMouseWheelToAncestor");
  3764. dbg.println("orig event src is of " + e.getSource().getClass());
  3765. }
  3766. /* parent field for Window refers to the owning Window.
  3767. * MouseWheelEvents should NOT be propagated into owning Windows
  3768. */
  3769. synchronized (getTreeLock()) {
  3770. Container anc = getParent();
  3771. while (anc != null && !anc.eventEnabled(e)) {
  3772. // fix coordinates to be relative to new event source
  3773. newX += anc.getX();
  3774. newY += anc.getY();
  3775. if (!(anc instanceof Window)) {
  3776. anc = anc.getParent();
  3777. }
  3778. else {
  3779. break;
  3780. }
  3781. }
  3782. if (dbg.on) dbg.println("new event src is " + anc.getClass());
  3783. if (anc != null && anc.eventEnabled(e)) {
  3784. // Change event to be from new source, with new x,y
  3785. // For now, just create a new event - yucky
  3786. newMWE = new MouseWheelEvent(anc, // new source
  3787. e.getID(),
  3788. e.getWhen(),
  3789. e.getModifiers(),
  3790. newX, // x relative to new source
  3791. newY, // y relative to new source
  3792. e.getClickCount(),
  3793. e.isPopupTrigger(),
  3794. e.getScrollType(),
  3795. e.getScrollAmount(),
  3796. e.getWheelRotation());
  3797. ((AWTEvent)e).copyPrivateDataInto(newMWE);
  3798. anc.dispatchEventImpl(newMWE);
  3799. }
  3800. }
  3801. return true;
  3802. }
  3803. boolean checkWindowClosingException() {
  3804. if (windowClosingException != null) {
  3805. if (this instanceof Dialog) {
  3806. ((Dialog)this).interruptBlocking();
  3807. } else {
  3808. windowClosingException.fillInStackTrace();
  3809. windowClosingException.printStackTrace();
  3810. windowClosingException = null;
  3811. }
  3812. return true;
  3813. }
  3814. return false;
  3815. }
  3816. boolean areInputMethodsEnabled() {
  3817. // in 1.2, we assume input method support is required for all
  3818. // components that handle key events, but components can turn off
  3819. // input methods by calling enableInputMethods(false).
  3820. return ((eventMask & AWTEvent.INPUT_METHODS_ENABLED_MASK) != 0) &&
  3821. ((eventMask & AWTEvent.KEY_EVENT_MASK) != 0 || keyListener != null);
  3822. }
  3823. // REMIND: remove when filtering is handled at lower level
  3824. boolean eventEnabled(AWTEvent e) {
  3825. return eventTypeEnabled(e.id);
  3826. }
  3827. boolean eventTypeEnabled(int type) {
  3828. switch(type) {
  3829. case ComponentEvent.COMPONENT_MOVED:
  3830. case ComponentEvent.COMPONENT_RESIZED:
  3831. case ComponentEvent.COMPONENT_SHOWN:
  3832. case ComponentEvent.COMPONENT_HIDDEN:
  3833. if ((eventMask & AWTEvent.COMPONENT_EVENT_MASK) != 0 ||
  3834. componentListener != null) {
  3835. return true;
  3836. }
  3837. break;
  3838. case FocusEvent.FOCUS_GAINED:
  3839. case FocusEvent.FOCUS_LOST:
  3840. if ((eventMask & AWTEvent.FOCUS_EVENT_MASK) != 0 ||
  3841. focusListener != null) {
  3842. return true;
  3843. }
  3844. break;
  3845. case KeyEvent.KEY_PRESSED:
  3846. case KeyEvent.KEY_RELEASED:
  3847. case KeyEvent.KEY_TYPED:
  3848. if ((eventMask & AWTEvent.KEY_EVENT_MASK) != 0 ||
  3849. keyListener != null) {
  3850. return true;
  3851. }
  3852. break;
  3853. case MouseEvent.MOUSE_PRESSED:
  3854. case MouseEvent.MOUSE_RELEASED:
  3855. case MouseEvent.MOUSE_ENTERED:
  3856. case MouseEvent.MOUSE_EXITED:
  3857. case MouseEvent.MOUSE_CLICKED:
  3858. if ((eventMask & AWTEvent.MOUSE_EVENT_MASK) != 0 ||
  3859. mouseListener != null) {
  3860. return true;
  3861. }
  3862. break;
  3863. case MouseEvent.MOUSE_MOVED:
  3864. case MouseEvent.MOUSE_DRAGGED:
  3865. if ((eventMask & AWTEvent.MOUSE_MOTION_EVENT_MASK) != 0 ||
  3866. mouseMotionListener != null) {
  3867. return true;
  3868. }
  3869. break;
  3870. case MouseEvent.MOUSE_WHEEL:
  3871. if ((eventMask & AWTEvent.MOUSE_WHEEL_EVENT_MASK) != 0 ||
  3872. mouseWheelListener != null) {
  3873. return true;
  3874. }
  3875. break;
  3876. case InputMethodEvent.INPUT_METHOD_TEXT_CHANGED:
  3877. case InputMethodEvent.CARET_POSITION_CHANGED:
  3878. if ((eventMask & AWTEvent.INPUT_METHOD_EVENT_MASK) != 0 ||
  3879. inputMethodListener != null) {
  3880. return true;
  3881. }
  3882. break;
  3883. case HierarchyEvent.HIERARCHY_CHANGED:
  3884. if ((eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0 ||
  3885. hierarchyListener != null) {
  3886. return true;
  3887. }
  3888. break;
  3889. case HierarchyEvent.ANCESTOR_MOVED:
  3890. case HierarchyEvent.ANCESTOR_RESIZED:
  3891. if ((eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0 ||
  3892. hierarchyBoundsListener != null) {
  3893. return true;
  3894. }
  3895. break;
  3896. case ActionEvent.ACTION_PERFORMED:
  3897. if ((eventMask & AWTEvent.ACTION_EVENT_MASK) != 0) {
  3898. return true;
  3899. }
  3900. break;
  3901. case TextEvent.TEXT_VALUE_CHANGED:
  3902. if ((eventMask & AWTEvent.TEXT_EVENT_MASK) != 0) {
  3903. return true;
  3904. }
  3905. break;
  3906. case ItemEvent.ITEM_STATE_CHANGED:
  3907. if ((eventMask & AWTEvent.ITEM_EVENT_MASK) != 0) {
  3908. return true;
  3909. }
  3910. break;
  3911. case AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED:
  3912. if ((eventMask & AWTEvent.ADJUSTMENT_EVENT_MASK) != 0) {
  3913. return true;
  3914. }
  3915. break;
  3916. default:
  3917. break;
  3918. }
  3919. //
  3920. // Always pass on events defined by external programs.
  3921. //
  3922. if (type > AWTEvent.RESERVED_ID_MAX) {
  3923. return true;
  3924. }
  3925. return false;
  3926. }
  3927. /**
  3928. * @deprecated As of JDK version 1.1,
  3929. * replaced by dispatchEvent(AWTEvent).
  3930. */
  3931. @Deprecated
  3932. public boolean postEvent(Event e) {
  3933. ComponentPeer peer = this.peer;
  3934. if (handleEvent(e)) {
  3935. e.consume();
  3936. return true;
  3937. }
  3938. Component parent = this.parent;
  3939. int eventx = e.x;
  3940. int eventy = e.y;
  3941. if (parent != null) {
  3942. e.translate(x, y);
  3943. if (parent.postEvent(e)) {
  3944. e.consume();
  3945. return true;
  3946. }
  3947. // restore coords
  3948. e.x = eventx;
  3949. e.y = eventy;
  3950. }
  3951. return false;
  3952. }
  3953. // Event source interfaces
  3954. /**
  3955. * Adds the specified component listener to receive component events from
  3956. * this component.
  3957. * If listener <code>l</code> is <code>null</code>,
  3958. * no exception is thrown and no action is performed.
  3959. *
  3960. * @param l the component listener
  3961. * @see java.awt.event.ComponentEvent
  3962. * @see java.awt.event.ComponentListener
  3963. * @see #removeComponentListener
  3964. * @see #getComponentListeners
  3965. * @since JDK1.1
  3966. */
  3967. public synchronized void addComponentListener(ComponentListener l) {
  3968. if (l == null) {
  3969. return;
  3970. }
  3971. componentListener = AWTEventMulticaster.add(componentListener, l);
  3972. newEventsOnly = true;
  3973. }
  3974. /**
  3975. * Removes the specified component listener so that it no longer
  3976. * receives component events from this component. This method performs
  3977. * no function, nor does it throw an exception, if the listener
  3978. * specified by the argument was not previously added to this component.
  3979. * If listener <code>l</code> is <code>null</code>,
  3980. * no exception is thrown and no action is performed.
  3981. * @param l the component listener
  3982. * @see java.awt.event.ComponentEvent
  3983. * @see java.awt.event.ComponentListener
  3984. * @see #addComponentListener
  3985. * @see #getComponentListeners
  3986. * @since JDK1.1
  3987. */
  3988. public synchronized void removeComponentListener(ComponentListener l) {
  3989. if (l == null) {
  3990. return;
  3991. }
  3992. componentListener = AWTEventMulticaster.remove(componentListener, l);
  3993. }
  3994. /**
  3995. * Returns an array of all the component listeners
  3996. * registered on this component.
  3997. *
  3998. * @return all of this comonent's <code>ComponentListener</code>s
  3999. * or an empty array if no component
  4000. * listeners are currently registered
  4001. *
  4002. * @see #addComponentListener
  4003. * @see #removeComponentListener
  4004. * @since 1.4
  4005. */
  4006. public synchronized ComponentListener[] getComponentListeners() {
  4007. return (ComponentListener[]) (getListeners(ComponentListener.class));
  4008. }
  4009. /**
  4010. * Adds the specified focus listener to receive focus events from
  4011. * this component when this component gains input focus.
  4012. * If listener <code>l</code> is <code>null</code>,
  4013. * no exception is thrown and no action is performed.
  4014. *
  4015. * @param l the focus listener
  4016. * @see java.awt.event.FocusEvent
  4017. * @see java.awt.event.FocusListener
  4018. * @see #removeFocusListener
  4019. * @see #getFocusListeners
  4020. * @since JDK1.1
  4021. */
  4022. public synchronized void addFocusListener(FocusListener l) {
  4023. if (l == null) {
  4024. return;
  4025. }
  4026. focusListener = AWTEventMulticaster.add(focusListener, l);
  4027. newEventsOnly = true;
  4028. // if this is a lightweight component, enable focus events
  4029. // in the native container.
  4030. if (peer instanceof LightweightPeer) {
  4031. parent.proxyEnableEvents(AWTEvent.FOCUS_EVENT_MASK);
  4032. }
  4033. }
  4034. /**
  4035. * Removes the specified focus listener so that it no longer
  4036. * receives focus events from this component. This method performs
  4037. * no function, nor does it throw an exception, if the listener
  4038. * specified by the argument was not previously added to this component.
  4039. * If listener <code>l</code> is <code>null</code>,
  4040. * no exception is thrown and no action is performed.
  4041. *
  4042. * @param l the focus listener
  4043. * @see java.awt.event.FocusEvent
  4044. * @see java.awt.event.FocusListener
  4045. * @see #addFocusListener
  4046. * @see #getFocusListeners
  4047. * @since JDK1.1
  4048. */
  4049. public synchronized void removeFocusListener(FocusListener l) {
  4050. if (l == null) {
  4051. return;
  4052. }
  4053. focusListener = AWTEventMulticaster.remove(focusListener, l);
  4054. }
  4055. /**
  4056. * Returns an array of all the focus listeners
  4057. * registered on this component.
  4058. *
  4059. * @return all of this component's <code>FocusListener</code>s
  4060. * or an empty array if no component
  4061. * listeners are currently registered
  4062. *
  4063. * @see #addFocusListener
  4064. * @see #removeFocusListener
  4065. * @since 1.4
  4066. */
  4067. public synchronized FocusListener[] getFocusListeners() {
  4068. return (FocusListener[]) (getListeners(FocusListener.class));
  4069. }
  4070. /**
  4071. * Adds the specified hierarchy listener to receive hierarchy changed
  4072. * events from this component when the hierarchy to which this container
  4073. * belongs changes.
  4074. * If listener <code>l</code> is <code>null</code>,
  4075. * no exception is thrown and no action is performed.
  4076. *
  4077. * @param l the hierarchy listener
  4078. * @see java.awt.event.HierarchyEvent
  4079. * @see java.awt.event.HierarchyListener
  4080. * @see #removeHierarchyListener
  4081. * @see #getHierarchyListeners
  4082. * @since 1.3
  4083. */
  4084. public void addHierarchyListener(HierarchyListener l) {
  4085. if (l == null) {
  4086. return;
  4087. }
  4088. boolean notifyAncestors;
  4089. synchronized (this) {
  4090. notifyAncestors =
  4091. (hierarchyListener == null &&
  4092. (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) == 0);
  4093. hierarchyListener = AWTEventMulticaster.add(hierarchyListener, l);
  4094. notifyAncestors = (notifyAncestors && hierarchyListener != null);
  4095. newEventsOnly = true;
  4096. }
  4097. if (notifyAncestors) {
  4098. synchronized (getTreeLock()) {
  4099. adjustListeningChildrenOnParent(AWTEvent.HIERARCHY_EVENT_MASK,
  4100. 1);
  4101. }
  4102. }
  4103. }
  4104. /**
  4105. * Removes the specified hierarchy listener so that it no longer
  4106. * receives hierarchy changed events from this component. This method
  4107. * performs no function, nor does it throw an exception, if the listener
  4108. * specified by the argument was not previously added to this component.
  4109. * If listener <code>l</code> is <code>null</code>,
  4110. * no exception is thrown and no action is performed.
  4111. *
  4112. * @param l the hierarchy listener
  4113. * @see java.awt.event.HierarchyEvent
  4114. * @see java.awt.event.HierarchyListener
  4115. * @see #addHierarchyListener
  4116. * @see #getHierarchyListeners
  4117. * @since 1.3
  4118. */
  4119. public void removeHierarchyListener(HierarchyListener l) {
  4120. if (l == null) {
  4121. return;
  4122. }
  4123. boolean notifyAncestors;
  4124. synchronized (this) {
  4125. notifyAncestors =
  4126. (hierarchyListener != null &&
  4127. (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) == 0);
  4128. hierarchyListener =
  4129. AWTEventMulticaster.remove(hierarchyListener, l);
  4130. notifyAncestors = (notifyAncestors && hierarchyListener == null);
  4131. }
  4132. if (notifyAncestors) {
  4133. synchronized (getTreeLock()) {
  4134. adjustListeningChildrenOnParent(AWTEvent.HIERARCHY_EVENT_MASK,
  4135. -1);
  4136. }
  4137. }
  4138. }
  4139. /**
  4140. * Returns an array of all the hierarchy listeners
  4141. * registered on this component.
  4142. *
  4143. * @return all of this component's <code>HierarchyListener</code>s
  4144. * or an empty array if no hierarchy
  4145. * listeners are currently registered
  4146. *
  4147. * @see #addHierarchyListener
  4148. * @see #removeHierarchyListener
  4149. * @since 1.4
  4150. */
  4151. public synchronized HierarchyListener[] getHierarchyListeners() {
  4152. return (HierarchyListener[])(getListeners(HierarchyListener.class));
  4153. }
  4154. /**
  4155. * Adds the specified hierarchy bounds listener to receive hierarchy
  4156. * bounds events from this component when the hierarchy to which this
  4157. * container belongs changes.
  4158. * If listener <code>l</code> is <code>null</code>,
  4159. * no exception is thrown and no action is performed.
  4160. *
  4161. * @param l the hierarchy bounds listener
  4162. * @see java.awt.event.HierarchyEvent
  4163. * @see java.awt.event.HierarchyBoundsListener
  4164. * @see #removeHierarchyBoundsListener
  4165. * @see #getHierarchyBoundsListeners
  4166. * @since 1.3
  4167. */
  4168. public void addHierarchyBoundsListener(HierarchyBoundsListener l) {
  4169. if (l == null) {
  4170. return;
  4171. }
  4172. boolean notifyAncestors;
  4173. synchronized (this) {
  4174. notifyAncestors =
  4175. (hierarchyBoundsListener == null &&
  4176. (eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) == 0);
  4177. hierarchyBoundsListener =
  4178. AWTEventMulticaster.add(hierarchyBoundsListener, l);
  4179. notifyAncestors = (notifyAncestors &&
  4180. hierarchyBoundsListener != null);
  4181. newEventsOnly = true;
  4182. }
  4183. if (notifyAncestors) {
  4184. synchronized (getTreeLock()) {
  4185. adjustListeningChildrenOnParent(
  4186. AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK, 1);
  4187. }
  4188. }
  4189. }
  4190. /**
  4191. * Removes the specified hierarchy bounds listener so that it no longer
  4192. * receives hierarchy bounds events from this component. This method
  4193. * performs no function, nor does it throw an exception, if the listener
  4194. * specified by the argument was not previously added to this component.
  4195. * If listener <code>l</code> is <code>null</code>,
  4196. * no exception is thrown and no action is performed.
  4197. *
  4198. * @param l the hierarchy bounds listener
  4199. * @see java.awt.event.HierarchyEvent
  4200. * @see java.awt.event.HierarchyBoundsListener
  4201. * @see #addHierarchyBoundsListener
  4202. * @see #getHierarchyBoundsListeners
  4203. * @since 1.3
  4204. */
  4205. public void removeHierarchyBoundsListener(HierarchyBoundsListener l) {
  4206. if (l == null) {
  4207. return;
  4208. }
  4209. boolean notifyAncestors;
  4210. synchronized (this) {
  4211. notifyAncestors =
  4212. (hierarchyBoundsListener != null &&
  4213. (eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) == 0);
  4214. hierarchyBoundsListener =
  4215. AWTEventMulticaster.remove(hierarchyBoundsListener, l);
  4216. notifyAncestors = (notifyAncestors &&
  4217. hierarchyBoundsListener == null);
  4218. }
  4219. if (notifyAncestors) {
  4220. synchronized (getTreeLock()) {
  4221. adjustListeningChildrenOnParent(
  4222. AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK, -1);
  4223. }
  4224. }
  4225. }
  4226. // Should only be called while holding the tree lock
  4227. int numListening(long mask) {
  4228. if (dbg.on) {
  4229. // One mask or the other, but not neither or both.
  4230. dbg.assertion(mask == AWTEvent.HIERARCHY_EVENT_MASK ||
  4231. mask == AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK);
  4232. }
  4233. if ((mask == AWTEvent.HIERARCHY_EVENT_MASK &&
  4234. (hierarchyListener != null ||
  4235. (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0)) ||
  4236. (mask == AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK &&
  4237. (hierarchyBoundsListener != null ||
  4238. (eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0))) {
  4239. return 1;
  4240. } else {
  4241. return 0;
  4242. }
  4243. }
  4244. // Should only be called while holding tree lock
  4245. int countHierarchyMembers() {
  4246. return 1;
  4247. }
  4248. // Should only be called while holding the tree lock
  4249. int createHierarchyEvents(int id, Component changed,
  4250. Container changedParent, long changeFlags,
  4251. boolean enabledOnToolkit) {
  4252. switch (id) {
  4253. case HierarchyEvent.HIERARCHY_CHANGED:
  4254. if (hierarchyListener != null ||
  4255. (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0 ||
  4256. enabledOnToolkit) {
  4257. HierarchyEvent e = new HierarchyEvent(this, id, changed,
  4258. changedParent,
  4259. changeFlags);
  4260. dispatchEvent(e);
  4261. return 1;
  4262. }
  4263. break;
  4264. case HierarchyEvent.ANCESTOR_MOVED:
  4265. case HierarchyEvent.ANCESTOR_RESIZED:
  4266. if (dbg.on) {
  4267. dbg.assertion(changeFlags == 0);
  4268. }
  4269. if (hierarchyBoundsListener != null ||
  4270. (eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0 ||
  4271. enabledOnToolkit) {
  4272. HierarchyEvent e = new HierarchyEvent(this, id, changed,
  4273. changedParent);
  4274. dispatchEvent(e);
  4275. return 1;
  4276. }
  4277. break;
  4278. default:
  4279. if (dbg.on) {
  4280. dbg.assertion(false);
  4281. }
  4282. break;
  4283. }
  4284. return 0;
  4285. }
  4286. /**
  4287. * Returns an array of all the hierarchy bounds listeners
  4288. * registered on this component.
  4289. *
  4290. * @return all of this component's <code>HierarchyBoundsListener</code>s
  4291. * or an empty array if no hierarchy bounds
  4292. * listeners are currently registered
  4293. *
  4294. * @see #addHierarchyBoundsListener
  4295. * @see #removeHierarchyBoundsListener
  4296. * @since 1.4
  4297. */
  4298. public synchronized HierarchyBoundsListener[] getHierarchyBoundsListeners() {
  4299. return (HierarchyBoundsListener[])
  4300. (getListeners(HierarchyBoundsListener.class));
  4301. }
  4302. /*
  4303. * Should only be called while holding the tree lock.
  4304. * It's added only for overriding in java.awt.Window
  4305. * because parent in Window is owner.
  4306. */
  4307. void adjustListeningChildrenOnParent(long mask, int num) {
  4308. if (parent != null) {
  4309. parent.adjustListeningChildren(mask, num);
  4310. }
  4311. }
  4312. /**
  4313. * Adds the specified key listener to receive key events from
  4314. * this component.
  4315. * If l is null, no exception is thrown and no action is performed.
  4316. *
  4317. * @param l the key listener.
  4318. * @see java.awt.event.KeyEvent
  4319. * @see java.awt.event.KeyListener
  4320. * @see #removeKeyListener
  4321. * @see #getKeyListeners
  4322. * @since JDK1.1
  4323. */
  4324. public synchronized void addKeyListener(KeyListener l) {
  4325. if (l == null) {
  4326. return;
  4327. }
  4328. keyListener = AWTEventMulticaster.add(keyListener, l);
  4329. newEventsOnly = true;
  4330. // if this is a lightweight component, enable key events
  4331. // in the native container.
  4332. if (peer instanceof LightweightPeer) {
  4333. parent.proxyEnableEvents(AWTEvent.KEY_EVENT_MASK);
  4334. }
  4335. }
  4336. /**
  4337. * Removes the specified key listener so that it no longer
  4338. * receives key events from this component. This method performs
  4339. * no function, nor does it throw an exception, if the listener
  4340. * specified by the argument was not previously added to this component.
  4341. * If listener <code>l</code> is <code>null</code>,
  4342. * no exception is thrown and no action is performed.
  4343. *
  4344. * @param l the key listener
  4345. * @see java.awt.event.KeyEvent
  4346. * @see java.awt.event.KeyListener
  4347. * @see #addKeyListener
  4348. * @see #getKeyListeners
  4349. * @since JDK1.1
  4350. */
  4351. public synchronized void removeKeyListener(KeyListener l) {
  4352. if (l == null) {
  4353. return;
  4354. }
  4355. keyListener = AWTEventMulticaster.remove(keyListener, l);
  4356. }
  4357. /**
  4358. * Returns an array of all the key listeners
  4359. * registered on this component.
  4360. *
  4361. * @return all of this component's <code>KeyListener</code>s
  4362. * or an empty array if no key
  4363. * listeners are currently registered
  4364. *
  4365. * @see #addKeyListener
  4366. * @see #removeKeyListener
  4367. * @since 1.4
  4368. */
  4369. public synchronized KeyListener[] getKeyListeners() {
  4370. return (KeyListener[]) (getListeners(KeyListener.class));
  4371. }
  4372. /**
  4373. * Adds the specified mouse listener to receive mouse events from
  4374. * this component.
  4375. * If listener <code>l</code> is <code>null</code>,
  4376. * no exception is thrown and no action is performed.
  4377. *
  4378. * @param l the mouse listener
  4379. * @see java.awt.event.MouseEvent
  4380. * @see java.awt.event.MouseListener
  4381. * @see #removeMouseListener
  4382. * @see #getMouseListeners
  4383. * @since JDK1.1
  4384. */
  4385. public synchronized void addMouseListener(MouseListener l) {
  4386. if (l == null) {
  4387. return;
  4388. }
  4389. mouseListener = AWTEventMulticaster.add(mouseListener,l);
  4390. newEventsOnly = true;
  4391. // if this is a lightweight component, enable mouse events
  4392. // in the native container.
  4393. if (peer instanceof LightweightPeer) {
  4394. parent.proxyEnableEvents(AWTEvent.MOUSE_EVENT_MASK);
  4395. }
  4396. }
  4397. /**
  4398. * Removes the specified mouse listener so that it no longer
  4399. * receives mouse events from this component. This method performs
  4400. * no function, nor does it throw an exception, if the listener
  4401. * specified by the argument was not previously added to this component.
  4402. * If listener <code>l</code> is <code>null</code>,
  4403. * no exception is thrown and no action is performed.
  4404. *
  4405. * @param l the mouse listener
  4406. * @see java.awt.event.MouseEvent
  4407. * @see java.awt.event.MouseListener
  4408. * @see #addMouseListener
  4409. * @see #getMouseListeners
  4410. * @since JDK1.1
  4411. */
  4412. public synchronized void removeMouseListener(MouseListener l) {
  4413. if (l == null) {
  4414. return;
  4415. }
  4416. mouseListener = AWTEventMulticaster.remove(mouseListener, l);
  4417. }
  4418. /**
  4419. * Returns an array of all the mouse listeners
  4420. * registered on this component.
  4421. *
  4422. * @return all of this component's <code>MouseListener</code>s
  4423. * or an empty array if no mouse
  4424. * listeners are currently registered
  4425. *
  4426. * @see #addMouseListener
  4427. * @see #removeMouseListener
  4428. * @since 1.4
  4429. */
  4430. public synchronized MouseListener[] getMouseListeners() {
  4431. return (MouseListener[]) (getListeners(MouseListener.class));
  4432. }
  4433. /**
  4434. * Adds the specified mouse motion listener to receive mouse motion
  4435. * events from this component.
  4436. * If listener <code>l</code> is <code>null</code>,
  4437. * no exception is thrown and no action is performed.
  4438. *
  4439. * @param l the mouse motion listener
  4440. * @see java.awt.event.MouseEvent
  4441. * @see java.awt.event.MouseMotionListener
  4442. * @see #removeMouseMotionListener
  4443. * @see #getMouseMotionListeners
  4444. * @since JDK1.1
  4445. */
  4446. public synchronized void addMouseMotionListener(MouseMotionListener l) {
  4447. if (l == null) {
  4448. return;
  4449. }
  4450. mouseMotionListener = AWTEventMulticaster.add(mouseMotionListener,l);
  4451. newEventsOnly = true;
  4452. // if this is a lightweight component, enable mouse events
  4453. // in the native container.
  4454. if (peer instanceof LightweightPeer) {
  4455. parent.proxyEnableEvents(AWTEvent.MOUSE_MOTION_EVENT_MASK);
  4456. }
  4457. }
  4458. /**
  4459. * Removes the specified mouse motion listener so that it no longer
  4460. * receives mouse motion events from this component. This method performs
  4461. * no function, nor does it throw an exception, if the listener
  4462. * specified by the argument was not previously added to this component.
  4463. * If listener <code>l</code> is <code>null</code>,
  4464. * no exception is thrown and no action is performed.
  4465. *
  4466. * @param l the mouse motion listener
  4467. * @see java.awt.event.MouseEvent
  4468. * @see java.awt.event.MouseMotionListener
  4469. * @see #addMouseMotionListener
  4470. * @see #getMouseMotionListeners
  4471. * @since JDK1.1
  4472. */
  4473. public synchronized void removeMouseMotionListener(MouseMotionListener l) {
  4474. if (l == null) {
  4475. return;
  4476. }
  4477. mouseMotionListener = AWTEventMulticaster.remove(mouseMotionListener, l);
  4478. }
  4479. /**
  4480. * Returns an array of all the mouse motion listeners
  4481. * registered on this component.
  4482. *
  4483. * @return all of this component's <code>MouseMotionListener</code>s
  4484. * or an empty array if no mouse motion
  4485. * listeners are currently registered
  4486. *
  4487. * @see #addMouseMotionListener
  4488. * @see #removeMouseMotionListener
  4489. * @since 1.4
  4490. */
  4491. public synchronized MouseMotionListener[] getMouseMotionListeners() {
  4492. return (MouseMotionListener[]) (getListeners(MouseMotionListener.class));
  4493. }
  4494. /**
  4495. * Adds the specified mouse wheel listener to receive mouse wheel events
  4496. * from this component. Containers also receive mouse wheel events from
  4497. * sub-components.
  4498. * <p>
  4499. * For information on how mouse wheel events are dispatched, see
  4500. * the class description for {@link MouseWheelEvent}.
  4501. * <p>
  4502. * If l is <code>null</code>, no exception is thrown and no
  4503. * action is performed.
  4504. *
  4505. * @param l the mouse wheel listener
  4506. * @see java.awt.event.MouseWheelEvent
  4507. * @see java.awt.event.MouseWheelListener
  4508. * @see #removeMouseWheelListener
  4509. * @see #getMouseWheelListeners
  4510. * @since 1.4
  4511. */
  4512. public synchronized void addMouseWheelListener(MouseWheelListener l) {
  4513. if (l == null) {
  4514. return;
  4515. }
  4516. mouseWheelListener = AWTEventMulticaster.add(mouseWheelListener,l);
  4517. newEventsOnly = true;
  4518. dbg.println("Component.addMouseWheelListener(): newEventsOnly = " + newEventsOnly);
  4519. // if this is a lightweight component, enable mouse events
  4520. // in the native container.
  4521. if (peer instanceof LightweightPeer) {
  4522. parent.proxyEnableEvents(AWTEvent.MOUSE_WHEEL_EVENT_MASK);
  4523. }
  4524. }
  4525. /**
  4526. * Removes the specified mouse wheel listener so that it no longer
  4527. * receives mouse wheel events from this component. This method performs
  4528. * no function, nor does it throw an exception, if the listener
  4529. * specified by the argument was not previously added to this component.
  4530. * If l is null, no exception is thrown and no action is performed.
  4531. *
  4532. * @param l the mouse wheel listener.
  4533. * @see java.awt.event.MouseWheelEvent
  4534. * @see java.awt.event.MouseWheelListener
  4535. * @see #addMouseWheelListener
  4536. * @see #getMouseWheelListeners
  4537. * @since 1.4
  4538. */
  4539. public synchronized void removeMouseWheelListener(MouseWheelListener l) {
  4540. if (l == null) {
  4541. return;
  4542. }
  4543. mouseWheelListener = AWTEventMulticaster.remove(mouseWheelListener, l);
  4544. }
  4545. /**
  4546. * Returns an array of all the mouse wheel listeners
  4547. * registered on this component.
  4548. *
  4549. * @return all of this component's <code>MouseWheelListener</code>s
  4550. * or an empty array if no mouse wheel
  4551. * listeners are currently registered
  4552. *
  4553. * @see #addMouseWheelListener
  4554. * @see #removeMouseWheelListener
  4555. * @since 1.4
  4556. */
  4557. public synchronized MouseWheelListener[] getMouseWheelListeners() {
  4558. return (MouseWheelListener[]) (getListeners(MouseWheelListener.class));
  4559. }
  4560. /**
  4561. * Adds the specified input method listener to receive
  4562. * input method events from this component. A component will
  4563. * only receive input method events from input methods
  4564. * if it also overrides <code>getInputMethodRequests</code> to return an
  4565. * <code>InputMethodRequests</code> instance.
  4566. * If listener <code>l</code> is <code>null</code>,
  4567. * no exception is thrown and no action is performed.
  4568. *
  4569. * @param l the input method listener
  4570. * @see java.awt.event.InputMethodEvent
  4571. * @see java.awt.event.InputMethodListener
  4572. * @see #removeInputMethodListener
  4573. * @see #getInputMethodListeners
  4574. * @see #getInputMethodRequests
  4575. * @since 1.2
  4576. */
  4577. public synchronized void addInputMethodListener(InputMethodListener l) {
  4578. if (l == null) {
  4579. return;
  4580. }
  4581. inputMethodListener = AWTEventMulticaster.add(inputMethodListener, l);
  4582. newEventsOnly = true;
  4583. }
  4584. /**
  4585. * Removes the specified input method listener so that it no longer
  4586. * receives input method events from this component. This method performs
  4587. * no function, nor does it throw an exception, if the listener
  4588. * specified by the argument was not previously added to this component.
  4589. * If listener <code>l</code> is <code>null</code>,
  4590. * no exception is thrown and no action is performed.
  4591. *
  4592. * @param l the input method listener
  4593. * @see java.awt.event.InputMethodEvent
  4594. * @see java.awt.event.InputMethodListener
  4595. * @see #addInputMethodListener
  4596. * @see #getInputMethodListeners
  4597. * @since 1.2
  4598. */
  4599. public synchronized void removeInputMethodListener(InputMethodListener l) {
  4600. if (l == null) {
  4601. return;
  4602. }
  4603. inputMethodListener = AWTEventMulticaster.remove(inputMethodListener, l);
  4604. }
  4605. /**
  4606. * Returns an array of all the input method listeners
  4607. * registered on this component.
  4608. *
  4609. * @return all of this component's <code>InputMethodListener</code>s
  4610. * or an empty array if no input method
  4611. * listeners are currently registered
  4612. *
  4613. * @see #addInputMethodListener
  4614. * @see #removeInputMethodListener
  4615. * @since 1.4
  4616. */
  4617. public synchronized InputMethodListener[] getInputMethodListeners() {
  4618. return (InputMethodListener[]) (getListeners(InputMethodListener.class));
  4619. }
  4620. /**
  4621. * Returns an array of all the objects currently registered
  4622. * as <code><em>Foo</em>Listener</code>s
  4623. * upon this <code>Component</code>.
  4624. * <code><em>Foo</em>Listener</code>s are registered using the
  4625. * <code>add<em>Foo</em>Listener</code> method.
  4626. *
  4627. * <p>
  4628. * You can specify the <code>listenerType</code> argument
  4629. * with a class literal, such as
  4630. * <code><em>Foo</em>Listener.class</code>.
  4631. * For example, you can query a
  4632. * <code>Component</code> <code>c</code>
  4633. * for its mouse listeners with the following code:
  4634. *
  4635. * <pre>MouseListener[] mls = (MouseListener[])(c.getListeners(MouseListener.class));</pre>
  4636. *
  4637. * If no such listeners exist, this method returns an empty array.
  4638. *
  4639. * @param listenerType the type of listeners requested; this parameter
  4640. * should specify an interface that descends from
  4641. * <code>java.util.EventListener</code>
  4642. * @return an array of all objects registered as
  4643. * <code><em>Foo</em>Listener</code>s on this component,
  4644. * or an empty array if no such listeners have been added
  4645. * @exception ClassCastException if <code>listenerType</code>
  4646. * doesn't specify a class or interface that implements
  4647. * <code>java.util.EventListener</code>
  4648. *
  4649. * @see #getComponentListeners
  4650. * @see #getFocusListeners
  4651. * @see #getHierarchyListeners
  4652. * @see #getHierarchyBoundsListeners
  4653. * @see #getKeyListeners
  4654. * @see #getMouseListeners
  4655. * @see #getMouseMotionListeners
  4656. * @see #getMouseWheelListeners
  4657. * @see #getInputMethodListeners
  4658. * @see #getPropertyChangeListeners
  4659. *
  4660. * @since 1.3
  4661. */
  4662. public <T extends EventListener> T[] getListeners(Class<T> listenerType) {
  4663. EventListener l = null;
  4664. if (listenerType == ComponentListener.class) {
  4665. l = componentListener;
  4666. } else if (listenerType == FocusListener.class) {
  4667. l = focusListener;
  4668. } else if (listenerType == HierarchyListener.class) {
  4669. l = hierarchyListener;
  4670. } else if (listenerType == HierarchyBoundsListener.class) {
  4671. l = hierarchyBoundsListener;
  4672. } else if (listenerType == KeyListener.class) {
  4673. l = keyListener;
  4674. } else if (listenerType == MouseListener.class) {
  4675. l = mouseListener;
  4676. } else if (listenerType == MouseMotionListener.class) {
  4677. l = mouseMotionListener;
  4678. } else if (listenerType == MouseWheelListener.class) {
  4679. l = mouseWheelListener;
  4680. } else if (listenerType == InputMethodListener.class) {
  4681. l = inputMethodListener;
  4682. } else if (listenerType == PropertyChangeListener.class) {
  4683. return (T[])getPropertyChangeListeners();
  4684. }
  4685. return AWTEventMulticaster.getListeners(l, listenerType);
  4686. }
  4687. /**
  4688. * Gets the input method request handler which supports
  4689. * requests from input methods for this component. A component
  4690. * that supports on-the-spot text input must override this
  4691. * method to return an <code>InputMethodRequests</code> instance.
  4692. * At the same time, it also has to handle input method events.
  4693. *
  4694. * @return the input method request handler for this component,
  4695. * <code>null</code> by default
  4696. * @see #addInputMethodListener
  4697. * @since 1.2
  4698. */
  4699. public InputMethodRequests getInputMethodRequests() {
  4700. return null;
  4701. }
  4702. /**
  4703. * Gets the input context used by this component for handling
  4704. * the communication with input methods when text is entered
  4705. * in this component. By default, the input context used for
  4706. * the parent component is returned. Components may
  4707. * override this to return a private input context.
  4708. *
  4709. * @return the input context used by this component;
  4710. * <code>null</code> if no context can be determined
  4711. * @since 1.2
  4712. */
  4713. public InputContext getInputContext() {
  4714. Container parent = this.parent;
  4715. if (parent == null) {
  4716. return null;
  4717. } else {
  4718. return parent.getInputContext();
  4719. }
  4720. }
  4721. /**
  4722. * Enables the events defined by the specified event mask parameter
  4723. * to be delivered to this component.
  4724. * <p>
  4725. * Event types are automatically enabled when a listener for
  4726. * that event type is added to the component.
  4727. * <p>
  4728. * This method only needs to be invoked by subclasses of
  4729. * <code>Component</code> which desire to have the specified event
  4730. * types delivered to <code>processEvent</code> regardless of whether
  4731. * or not a listener is registered.
  4732. * @param eventsToEnable the event mask defining the event types
  4733. * @see #processEvent
  4734. * @see #disableEvents
  4735. * @see AWTEvent
  4736. * @since JDK1.1
  4737. */
  4738. protected final void enableEvents(long eventsToEnable) {
  4739. long notifyAncestors = 0;
  4740. synchronized (this) {
  4741. if ((eventsToEnable & AWTEvent.HIERARCHY_EVENT_MASK) != 0 &&
  4742. hierarchyListener == null &&
  4743. (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) == 0) {
  4744. notifyAncestors |= AWTEvent.HIERARCHY_EVENT_MASK;
  4745. }
  4746. if ((eventsToEnable & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0 &&
  4747. hierarchyBoundsListener == null &&
  4748. (eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) == 0) {
  4749. notifyAncestors |= AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK;
  4750. }
  4751. eventMask |= eventsToEnable;
  4752. newEventsOnly = true;
  4753. }
  4754. // if this is a lightweight component, enable mouse events
  4755. // in the native container.
  4756. if (peer instanceof LightweightPeer) {
  4757. parent.proxyEnableEvents(eventMask);
  4758. }
  4759. if (notifyAncestors != 0) {
  4760. synchronized (getTreeLock()) {
  4761. adjustListeningChildrenOnParent(notifyAncestors, 1);
  4762. }
  4763. }
  4764. }
  4765. /**
  4766. * Disables the events defined by the specified event mask parameter
  4767. * from being delivered to this component.
  4768. * @param eventsToDisable the event mask defining the event types
  4769. * @see #enableEvents
  4770. * @since JDK1.1
  4771. */
  4772. protected final void disableEvents(long eventsToDisable) {
  4773. long notifyAncestors = 0;
  4774. synchronized (this) {
  4775. if ((eventsToDisable & AWTEvent.HIERARCHY_EVENT_MASK) != 0 &&
  4776. hierarchyListener == null &&
  4777. (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0) {
  4778. notifyAncestors |= AWTEvent.HIERARCHY_EVENT_MASK;
  4779. }
  4780. if ((eventsToDisable & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK)!=0 &&
  4781. hierarchyBoundsListener == null &&
  4782. (eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0) {
  4783. notifyAncestors |= AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK;
  4784. }
  4785. eventMask &= ~eventsToDisable;
  4786. }
  4787. if (notifyAncestors != 0) {
  4788. synchronized (getTreeLock()) {
  4789. adjustListeningChildrenOnParent(notifyAncestors, -1);
  4790. }
  4791. }
  4792. }
  4793. /**
  4794. * Potentially coalesce an event being posted with an existing
  4795. * event. This method is called by <code>EventQueue.postEvent</code>
  4796. * if an event with the same ID as the event to be posted is found in
  4797. * the queue (both events must have this component as their source).
  4798. * This method either returns a coalesced event which replaces
  4799. * the existing event (and the new event is then discarded), or
  4800. * <code>null</code> to indicate that no combining should be done
  4801. * (add the second event to the end of the queue). Either event
  4802. * parameter may be modified and returned, as the other one is discarded
  4803. * unless <code>null</code> is returned.
  4804. * <p>
  4805. * This implementation of <code>coalesceEvents</code> coalesces
  4806. * two event types: mouse move (and drag) events,
  4807. * and paint (and update) events.
  4808. * For mouse move events the last event is always returned, causing
  4809. * intermediate moves to be discarded. For paint events, the new
  4810. * event is coalesced into a complex <code>RepaintArea</code> in the peer.
  4811. * The new <code>AWTEvent</code> is always returned.
  4812. *
  4813. * @param existingEvent the event already on the <code>EventQueue</code>
  4814. * @param newEvent the event being posted to the
  4815. * <code>EventQueue</code>
  4816. * @return a coalesced event, or <code>null</code> indicating that no
  4817. * coalescing was done
  4818. */
  4819. protected AWTEvent coalesceEvents(AWTEvent existingEvent,
  4820. AWTEvent newEvent) {
  4821. int id = existingEvent.getID();
  4822. if (dbg.on) {
  4823. dbg.assertion(id == newEvent.getID() &&
  4824. existingEvent.getSource().equals(newEvent.getSource()));
  4825. }
  4826. switch (id) {
  4827. case Event.MOUSE_MOVE:
  4828. case Event.MOUSE_DRAG: {
  4829. MouseEvent e = (MouseEvent)existingEvent;
  4830. if (e.getModifiers() == ((MouseEvent)newEvent).getModifiers()) {
  4831. // Just return the newEvent, causing the old to be
  4832. // discarded.
  4833. return newEvent;
  4834. }
  4835. break;
  4836. }
  4837. case PaintEvent.PAINT:
  4838. case PaintEvent.UPDATE: {
  4839. if(peer != null && !(peer instanceof LightweightPeer)) {
  4840. // EventQueue.postEvent should use peer.coalescePaintEvent
  4841. return newEvent;
  4842. }
  4843. // This approach to coalescing paint events seems to be
  4844. // better than any heuristic for unioning rectangles.
  4845. PaintEvent existingPaintEvent = (PaintEvent) existingEvent;
  4846. PaintEvent newPaintEvent = (PaintEvent) newEvent;
  4847. Rectangle existingRect = existingPaintEvent.getUpdateRect();
  4848. Rectangle newRect = newPaintEvent.getUpdateRect();
  4849. if (dbg.on) {
  4850. dbg.println("Component::coalesceEvents : newEvent : nullPeer : x = " +
  4851. newRect.x + " y = " + newRect.y + " width = " + newRect.width +
  4852. " height = " + newRect.height);
  4853. }
  4854. if (existingRect.contains(newRect)) {
  4855. return existingEvent;
  4856. }
  4857. if (newRect.contains(existingRect)) {
  4858. return newEvent;
  4859. }
  4860. break;
  4861. }
  4862. }
  4863. return null;
  4864. }
  4865. /**
  4866. * Processes events occurring on this component. By default this
  4867. * method calls the appropriate
  4868. * <code>process<event type>Event</code>
  4869. * method for the given class of event.
  4870. * <p>Note that if the event parameter is <code>null</code>
  4871. * the behavior is unspecified and may result in an
  4872. * exception.
  4873. *
  4874. * @param e the event
  4875. * @see #processComponentEvent
  4876. * @see #processFocusEvent
  4877. * @see #processKeyEvent
  4878. * @see #processMouseEvent
  4879. * @see #processMouseMotionEvent
  4880. * @see #processInputMethodEvent
  4881. * @see #processHierarchyEvent
  4882. * @see #processMouseWheelEvent
  4883. * @since JDK1.1
  4884. */
  4885. protected void processEvent(AWTEvent e) {
  4886. if (e instanceof FocusEvent) {
  4887. processFocusEvent((FocusEvent)e);
  4888. } else if (e instanceof MouseEvent) {
  4889. switch(e.getID()) {
  4890. case MouseEvent.MOUSE_PRESSED:
  4891. case MouseEvent.MOUSE_RELEASED:
  4892. case MouseEvent.MOUSE_CLICKED:
  4893. case MouseEvent.MOUSE_ENTERED:
  4894. case MouseEvent.MOUSE_EXITED:
  4895. processMouseEvent((MouseEvent)e);
  4896. break;
  4897. case MouseEvent.MOUSE_MOVED:
  4898. case MouseEvent.MOUSE_DRAGGED:
  4899. processMouseMotionEvent((MouseEvent)e);
  4900. break;
  4901. case MouseEvent.MOUSE_WHEEL:
  4902. processMouseWheelEvent((MouseWheelEvent)e);
  4903. break;
  4904. }
  4905. } else if (e instanceof KeyEvent) {
  4906. processKeyEvent((KeyEvent)e);
  4907. } else if (e instanceof ComponentEvent) {
  4908. processComponentEvent((ComponentEvent)e);
  4909. } else if (e instanceof InputMethodEvent) {
  4910. processInputMethodEvent((InputMethodEvent)e);
  4911. } else if (e instanceof HierarchyEvent) {
  4912. switch (e.getID()) {
  4913. case HierarchyEvent.HIERARCHY_CHANGED:
  4914. processHierarchyEvent((HierarchyEvent)e);
  4915. break;
  4916. case HierarchyEvent.ANCESTOR_MOVED:
  4917. case HierarchyEvent.ANCESTOR_RESIZED:
  4918. processHierarchyBoundsEvent((HierarchyEvent)e);
  4919. break;
  4920. }
  4921. }
  4922. }
  4923. /**
  4924. * Processes component events occurring on this component by
  4925. * dispatching them to any registered
  4926. * <code>ComponentListener</code> objects.
  4927. * <p>
  4928. * This method is not called unless component events are
  4929. * enabled for this component. Component events are enabled
  4930. * when one of the following occurs:
  4931. * <p><ul>
  4932. * <li>A <code>ComponentListener</code> object is registered
  4933. * via <code>addComponentListener</code>.
  4934. * <li>Component events are enabled via <code>enableEvents</code>.
  4935. * </ul>
  4936. * <p>Note that if the event parameter is <code>null</code>
  4937. * the behavior is unspecified and may result in an
  4938. * exception.
  4939. *
  4940. * @param e the component event
  4941. * @see java.awt.event.ComponentEvent
  4942. * @see java.awt.event.ComponentListener
  4943. * @see #addComponentListener
  4944. * @see #enableEvents
  4945. * @since JDK1.1
  4946. */
  4947. protected void processComponentEvent(ComponentEvent e) {
  4948. ComponentListener listener = componentListener;
  4949. if (listener != null) {
  4950. int id = e.getID();
  4951. switch(id) {
  4952. case ComponentEvent.COMPONENT_RESIZED:
  4953. listener.componentResized(e);
  4954. break;
  4955. case ComponentEvent.COMPONENT_MOVED:
  4956. listener.componentMoved(e);
  4957. break;
  4958. case ComponentEvent.COMPONENT_SHOWN:
  4959. listener.componentShown(e);
  4960. break;
  4961. case ComponentEvent.COMPONENT_HIDDEN:
  4962. listener.componentHidden(e);
  4963. break;
  4964. }
  4965. }
  4966. }
  4967. /**
  4968. * Processes focus events occurring on this component by
  4969. * dispatching them to any registered
  4970. * <code>FocusListener</code> objects.
  4971. * <p>
  4972. * This method is not called unless focus events are
  4973. * enabled for this component. Focus events are enabled
  4974. * when one of the following occurs:
  4975. * <p><ul>
  4976. * <li>A <code>FocusListener</code> object is registered
  4977. * via <code>addFocusListener</code>.
  4978. * <li>Focus events are enabled via <code>enableEvents</code>.
  4979. * </ul>
  4980. * <p>
  4981. * If focus events are enabled for a <code>Component</code>,
  4982. * the current <code>KeyboardFocusManager</code> determines
  4983. * whether or not a focus event should be dispatched to
  4984. * registered <code>FocusListener</code> objects. If the
  4985. * events are to be dispatched, the <code>KeyboardFocusManager</code>
  4986. * calls the <code>Component</code>'s <code>dispatchEvent</code>
  4987. * method, which results in a call to the <code>Component</code>'s
  4988. * <code>processFocusEvent</code> method.
  4989. * <p>
  4990. * If focus events are enabled for a <code>Component</code>, calling
  4991. * the <code>Component</code>'s <code>dispatchEvent</code> method
  4992. * with a <code>FocusEvent</code> as the argument will result in a
  4993. * call to the <code>Component</code>'s <code>processFocusEvent</code>
  4994. * method regardless of the current <code>KeyboardFocusManager</code>.
  4995. * <p>
  4996. * <p>Note that if the event parameter is <code>null</code>
  4997. * the behavior is unspecified and may result in an
  4998. * exception.
  4999. *
  5000. * @param e the focus event
  5001. * @see java.awt.event.FocusEvent
  5002. * @see java.awt.event.FocusListener
  5003. * @see java.awt.KeyboardFocusManager
  5004. * @see #addFocusListener
  5005. * @see #enableEvents
  5006. * @see #dispatchEvent
  5007. * @since JDK1.1
  5008. */
  5009. protected void processFocusEvent(FocusEvent e) {
  5010. FocusListener listener = focusListener;
  5011. if (listener != null) {
  5012. int id = e.getID();
  5013. switch(id) {
  5014. case FocusEvent.FOCUS_GAINED:
  5015. listener.focusGained(e);
  5016. break;
  5017. case FocusEvent.FOCUS_LOST:
  5018. listener.focusLost(e);
  5019. break;
  5020. }
  5021. }
  5022. }
  5023. /**
  5024. * Processes key events occurring on this component by
  5025. * dispatching them to any registered
  5026. * <code>KeyListener</code> objects.
  5027. * <p>
  5028. * This method is not called unless key events are
  5029. * enabled for this component. Key events are enabled
  5030. * when one of the following occurs:
  5031. * <p><ul>
  5032. * <li>A <code>KeyListener</code> object is registered
  5033. * via <code>addKeyListener</code>.
  5034. * <li>Key events are enabled via <code>enableEvents</code>.
  5035. * </ul>
  5036. *
  5037. * <p>
  5038. * If key events are enabled for a <code>Component</code>,
  5039. * the current <code>KeyboardFocusManager</code> determines
  5040. * whether or not a key event should be dispatched to
  5041. * registered <code>KeyListener</code> objects. The
  5042. * <code>DefaultKeyboardFocusManager</code> will not dispatch
  5043. * key events to a <code>Component</code> that is not the focus
  5044. * owner or is not showing.
  5045. * <p>
  5046. * As of J2SE 1.4, <code>KeyEvent</code>s are redirected to
  5047. * the focus owner. Please see the
  5048. * <a href="doc-files/FocusSpec.html">Focus Specification</a>
  5049. * for further information.
  5050. * <p>
  5051. * Calling a <code>Component</code>'s <code>dispatchEvent</code>
  5052. * method with a <code>KeyEvent</code> as the argument will
  5053. * result in a call to the <code>Component</code>'s
  5054. * <code>processKeyEvent</code> method regardless of the
  5055. * current <code>KeyboardFocusManager</code> as long as the
  5056. * component is showing, focused, and enabled, and key events
  5057. * are enabled on it.
  5058. * <p>If the event parameter is <code>null</code>
  5059. * the behavior is unspecified and may result in an
  5060. * exception.
  5061. *
  5062. * @param e the key event
  5063. * @see java.awt.event.KeyEvent
  5064. * @see java.awt.event.KeyListener
  5065. * @see java.awt.KeyboardFocusManager
  5066. * @see java.awt.DefaultKeyboardFocusManager
  5067. * @see #processEvent
  5068. * @see #dispatchEvent
  5069. * @see #addKeyListener
  5070. * @see #enableEvents
  5071. * @see #isShowing
  5072. * @since JDK1.1
  5073. */
  5074. protected void processKeyEvent(KeyEvent e) {
  5075. KeyListener listener = keyListener;
  5076. if (listener != null) {
  5077. int id = e.getID();
  5078. switch(id) {
  5079. case KeyEvent.KEY_TYPED:
  5080. listener.keyTyped(e);
  5081. break;
  5082. case KeyEvent.KEY_PRESSED:
  5083. listener.keyPressed(e);
  5084. break;
  5085. case KeyEvent.KEY_RELEASED:
  5086. listener.keyReleased(e);
  5087. break;
  5088. }
  5089. }
  5090. }
  5091. /**
  5092. * Processes mouse events occurring on this component by
  5093. * dispatching them to any registered
  5094. * <code>MouseListener</code> objects.
  5095. * <p>
  5096. * This method is not called unless mouse events are
  5097. * enabled for this component. Mouse events are enabled
  5098. * when one of the following occurs:
  5099. * <p><ul>
  5100. * <li>A <code>MouseListener</code> object is registered
  5101. * via <code>addMouseListener</code>.
  5102. * <li>Mouse events are enabled via <code>enableEvents</code>.
  5103. * </ul>
  5104. * <p>Note that if the event parameter is <code>null</code>
  5105. * the behavior is unspecified and may result in an
  5106. * exception.
  5107. *
  5108. * @param e the mouse event
  5109. * @see java.awt.event.MouseEvent
  5110. * @see java.awt.event.MouseListener
  5111. * @see #addMouseListener
  5112. * @see #enableEvents
  5113. * @since JDK1.1
  5114. */
  5115. protected void processMouseEvent(MouseEvent e) {
  5116. MouseListener listener = mouseListener;
  5117. if (listener != null) {
  5118. int id = e.getID();
  5119. switch(id) {
  5120. case MouseEvent.MOUSE_PRESSED:
  5121. listener.mousePressed(e);
  5122. break;
  5123. case MouseEvent.MOUSE_RELEASED:
  5124. listener.mouseReleased(e);
  5125. break;
  5126. case MouseEvent.MOUSE_CLICKED:
  5127. listener.mouseClicked(e);
  5128. break;
  5129. case MouseEvent.MOUSE_EXITED:
  5130. listener.mouseExited(e);
  5131. break;
  5132. case MouseEvent.MOUSE_ENTERED:
  5133. listener.mouseEntered(e);
  5134. break;
  5135. }
  5136. }
  5137. }
  5138. /**
  5139. * Processes mouse motion events occurring on this component by
  5140. * dispatching them to any registered
  5141. * <code>MouseMotionListener</code> objects.
  5142. * <p>
  5143. * This method is not called unless mouse motion events are
  5144. * enabled for this component. Mouse motion events are enabled
  5145. * when one of the following occurs:
  5146. * <p><ul>
  5147. * <li>A <code>MouseMotionListener</code> object is registered
  5148. * via <code>addMouseMotionListener</code>.
  5149. * <li>Mouse motion events are enabled via <code>enableEvents</code>.
  5150. * </ul>
  5151. * <p>Note that if the event parameter is <code>null</code>
  5152. * the behavior is unspecified and may result in an
  5153. * exception.
  5154. *
  5155. * @param e the mouse motion event
  5156. * @see java.awt.event.MouseEvent
  5157. * @see java.awt.event.MouseMotionListener
  5158. * @see #addMouseMotionListener
  5159. * @see #enableEvents
  5160. * @since JDK1.1
  5161. */
  5162. protected void processMouseMotionEvent(MouseEvent e) {
  5163. MouseMotionListener listener = mouseMotionListener;
  5164. if (listener != null) {
  5165. int id = e.getID();
  5166. switch(id) {
  5167. case MouseEvent.MOUSE_MOVED:
  5168. listener.mouseMoved(e);
  5169. break;
  5170. case MouseEvent.MOUSE_DRAGGED:
  5171. listener.mouseDragged(e);
  5172. break;
  5173. }
  5174. }
  5175. }
  5176. /**
  5177. * Processes mouse wheel events occurring on this component by
  5178. * dispatching them to any registered
  5179. * <code>MouseWheelListener</code> objects.
  5180. * <p>
  5181. * This method is not called unless mouse wheel events are
  5182. * enabled for this component. Mouse wheel events are enabled
  5183. * when one of the following occurs:
  5184. * <p><ul>
  5185. * <li>A <code>MouseWheelListener</code> object is registered
  5186. * via <code>addMouseWheelListener</code>.
  5187. * <li>Mouse wheel events are enabled via <code>enableEvents</code>.
  5188. * </ul>
  5189. * <p>
  5190. * For information on how mouse wheel events are dispatched, see
  5191. * the class description for {@link MouseWheelEvent}.
  5192. * <p>
  5193. * Note that if the event parameter is <code>null</code>
  5194. * the behavior is unspecified and may result in an
  5195. * exception.
  5196. *
  5197. * @param e the mouse wheel event
  5198. * @see java.awt.event.MouseWheelEvent
  5199. * @see java.awt.event.MouseWheelListener
  5200. * @see #addMouseWheelListener
  5201. * @see #enableEvents
  5202. * @since 1.4
  5203. */
  5204. protected void processMouseWheelEvent(MouseWheelEvent e) {
  5205. MouseWheelListener listener = mouseWheelListener;
  5206. if (listener != null) {
  5207. int id = e.getID();
  5208. switch(id) {
  5209. case MouseEvent.MOUSE_WHEEL:
  5210. listener.mouseWheelMoved(e);
  5211. break;
  5212. }
  5213. }
  5214. }
  5215. boolean postsOldMouseEvents() {
  5216. return false;
  5217. }
  5218. /**
  5219. * Processes input method events occurring on this component by
  5220. * dispatching them to any registered
  5221. * <code>InputMethodListener</code> objects.
  5222. * <p>
  5223. * This method is not called unless input method events
  5224. * are enabled for this component. Input method events are enabled
  5225. * when one of the following occurs:
  5226. * <p><ul>
  5227. * <li>An <code>InputMethodListener</code> object is registered
  5228. * via <code>addInputMethodListener</code>.
  5229. * <li>Input method events are enabled via <code>enableEvents</code>.
  5230. * </ul>
  5231. * <p>Note that if the event parameter is <code>null</code>
  5232. * the behavior is unspecified and may result in an
  5233. * exception.
  5234. *
  5235. * @param e the input method event
  5236. * @see java.awt.event.InputMethodEvent
  5237. * @see java.awt.event.InputMethodListener
  5238. * @see #addInputMethodListener
  5239. * @see #enableEvents
  5240. * @since 1.2
  5241. */
  5242. protected void processInputMethodEvent(InputMethodEvent e) {
  5243. InputMethodListener listener = inputMethodListener;
  5244. if (listener != null) {
  5245. int id = e.getID();
  5246. switch (id) {
  5247. case InputMethodEvent.INPUT_METHOD_TEXT_CHANGED:
  5248. listener.inputMethodTextChanged(e);
  5249. break;
  5250. case InputMethodEvent.CARET_POSITION_CHANGED:
  5251. listener.caretPositionChanged(e);
  5252. break;
  5253. }
  5254. }
  5255. }
  5256. /**
  5257. * Processes hierarchy events occurring on this component by
  5258. * dispatching them to any registered
  5259. * <code>HierarchyListener</code> objects.
  5260. * <p>
  5261. * This method is not called unless hierarchy events
  5262. * are enabled for this component. Hierarchy events are enabled
  5263. * when one of the following occurs:
  5264. * <p><ul>
  5265. * <li>An <code>HierarchyListener</code> object is registered
  5266. * via <code>addHierarchyListener</code>.
  5267. * <li>Hierarchy events are enabled via <code>enableEvents</code>.
  5268. * </ul>
  5269. * <p>Note that if the event parameter is <code>null</code>
  5270. * the behavior is unspecified and may result in an
  5271. * exception.
  5272. *
  5273. * @param e the hierarchy event
  5274. * @see java.awt.event.HierarchyEvent
  5275. * @see java.awt.event.HierarchyListener
  5276. * @see #addHierarchyListener
  5277. * @see #enableEvents
  5278. * @since 1.3
  5279. */
  5280. protected void processHierarchyEvent(HierarchyEvent e) {
  5281. HierarchyListener listener = hierarchyListener;
  5282. if (listener != null) {
  5283. int id = e.getID();
  5284. switch (id) {
  5285. case HierarchyEvent.HIERARCHY_CHANGED:
  5286. listener.hierarchyChanged(e);
  5287. break;
  5288. }
  5289. }
  5290. }
  5291. /**
  5292. * Processes hierarchy bounds events occurring on this component by
  5293. * dispatching them to any registered
  5294. * <code>HierarchyBoundsListener</code> objects.
  5295. * <p>
  5296. * This method is not called unless hierarchy bounds events
  5297. * are enabled for this component. Hierarchy bounds events are enabled
  5298. * when one of the following occurs:
  5299. * <p><ul>
  5300. * <li>An <code>HierarchyBoundsListener</code> object is registered
  5301. * via <code>addHierarchyBoundsListener</code>.
  5302. * <li>Hierarchy bounds events are enabled via <code>enableEvents</code>.
  5303. * </ul>
  5304. * <p>Note that if the event parameter is <code>null</code>
  5305. * the behavior is unspecified and may result in an
  5306. * exception.
  5307. *
  5308. * @param e the hierarchy event
  5309. * @see java.awt.event.HierarchyEvent
  5310. * @see java.awt.event.HierarchyBoundsListener
  5311. * @see #addHierarchyBoundsListener
  5312. * @see #enableEvents
  5313. * @since 1.3
  5314. */
  5315. protected void processHierarchyBoundsEvent(HierarchyEvent e) {
  5316. HierarchyBoundsListener listener = hierarchyBoundsListener;
  5317. if (listener != null) {
  5318. int id = e.getID();
  5319. switch (id) {
  5320. case HierarchyEvent.ANCESTOR_MOVED:
  5321. listener.ancestorMoved(e);
  5322. break;
  5323. case HierarchyEvent.ANCESTOR_RESIZED:
  5324. listener.ancestorResized(e);
  5325. break;
  5326. }
  5327. }
  5328. }
  5329. /**
  5330. * @deprecated As of JDK version 1.1
  5331. * replaced by processEvent(AWTEvent).
  5332. */
  5333. @Deprecated
  5334. public boolean handleEvent(Event evt) {
  5335. switch (evt.id) {
  5336. case Event.MOUSE_ENTER:
  5337. return mouseEnter(evt, evt.x, evt.y);
  5338. case Event.MOUSE_EXIT:
  5339. return mouseExit(evt, evt.x, evt.y);
  5340. case Event.MOUSE_MOVE:
  5341. return mouseMove(evt, evt.x, evt.y);
  5342. case Event.MOUSE_DOWN:
  5343. return mouseDown(evt, evt.x, evt.y);
  5344. case Event.MOUSE_DRAG:
  5345. return mouseDrag(evt, evt.x, evt.y);
  5346. case Event.MOUSE_UP:
  5347. return mouseUp(evt, evt.x, evt.y);
  5348. case Event.KEY_PRESS:
  5349. case Event.KEY_ACTION:
  5350. return keyDown(evt, evt.key);
  5351. case Event.KEY_RELEASE:
  5352. case Event.KEY_ACTION_RELEASE:
  5353. return keyUp(evt, evt.key);
  5354. case Event.ACTION_EVENT:
  5355. return action(evt, evt.arg);
  5356. case Event.GOT_FOCUS:
  5357. return gotFocus(evt, evt.arg);
  5358. case Event.LOST_FOCUS:
  5359. return lostFocus(evt, evt.arg);
  5360. }
  5361. return false;
  5362. }
  5363. /**
  5364. * @deprecated As of JDK version 1.1,
  5365. * replaced by processMouseEvent(MouseEvent).
  5366. */
  5367. @Deprecated
  5368. public boolean mouseDown(Event evt, int x, int y) {
  5369. return false;
  5370. }
  5371. /**
  5372. * @deprecated As of JDK version 1.1,
  5373. * replaced by processMouseMotionEvent(MouseEvent).
  5374. */
  5375. @Deprecated
  5376. public boolean mouseDrag(Event evt, int x, int y) {
  5377. return false;
  5378. }
  5379. /**
  5380. * @deprecated As of JDK version 1.1,
  5381. * replaced by processMouseEvent(MouseEvent).
  5382. */
  5383. @Deprecated
  5384. public boolean mouseUp(Event evt, int x, int y) {
  5385. return false;
  5386. }
  5387. /**
  5388. * @deprecated As of JDK version 1.1,
  5389. * replaced by processMouseMotionEvent(MouseEvent).
  5390. */
  5391. @Deprecated
  5392. public boolean mouseMove(Event evt, int x, int y) {
  5393. return false;
  5394. }
  5395. /**
  5396. * @deprecated As of JDK version 1.1,
  5397. * replaced by processMouseEvent(MouseEvent).
  5398. */
  5399. @Deprecated
  5400. public boolean mouseEnter(Event evt, int x, int y) {
  5401. return false;
  5402. }
  5403. /**
  5404. * @deprecated As of JDK version 1.1,
  5405. * replaced by processMouseEvent(MouseEvent).
  5406. */
  5407. @Deprecated
  5408. public boolean mouseExit(Event evt, int x, int y) {
  5409. return false;
  5410. }
  5411. /**
  5412. * @deprecated As of JDK version 1.1,
  5413. * replaced by processKeyEvent(KeyEvent).
  5414. */
  5415. @Deprecated
  5416. public boolean keyDown(Event evt, int key) {
  5417. return false;
  5418. }
  5419. /**
  5420. * @deprecated As of JDK version 1.1,
  5421. * replaced by processKeyEvent(KeyEvent).
  5422. */
  5423. @Deprecated
  5424. public boolean keyUp(Event evt, int key) {
  5425. return false;
  5426. }
  5427. /**
  5428. * @deprecated As of JDK version 1.1,
  5429. * should register this component as ActionListener on component
  5430. * which fires action events.
  5431. */
  5432. @Deprecated
  5433. public boolean action(Event evt, Object what) {
  5434. return false;
  5435. }
  5436. /**
  5437. * Makes this <code>Component</code> displayable by connecting it to a
  5438. * native screen resource.
  5439. * This method is called internally by the toolkit and should
  5440. * not be called directly by programs.
  5441. * @see #isDisplayable
  5442. * @see #removeNotify
  5443. * @since JDK1.0
  5444. */
  5445. public void addNotify() {
  5446. synchronized (getTreeLock()) {
  5447. ComponentPeer peer = this.peer;
  5448. if (peer == null || peer instanceof LightweightPeer){
  5449. if (peer == null) {
  5450. // Update both the Component's peer variable and the local
  5451. // variable we use for thread safety.
  5452. this.peer = peer = getToolkit().createComponent(this);
  5453. }
  5454. // This is a lightweight component which means it won't be
  5455. // able to get window-related events by itself. If any
  5456. // have been enabled, then the nearest native container must
  5457. // be enabled.
  5458. if (parent != null) {
  5459. long mask = 0;
  5460. if ((mouseListener != null) || ((eventMask & AWTEvent.MOUSE_EVENT_MASK) != 0)) {
  5461. mask |= AWTEvent.MOUSE_EVENT_MASK;
  5462. }
  5463. if ((mouseMotionListener != null) ||
  5464. ((eventMask & AWTEvent.MOUSE_MOTION_EVENT_MASK) != 0)) {
  5465. mask |= AWTEvent.MOUSE_MOTION_EVENT_MASK;
  5466. }
  5467. if ((mouseWheelListener != null ) ||
  5468. ((eventMask & AWTEvent.MOUSE_WHEEL_EVENT_MASK) != 0)) {
  5469. mask |= AWTEvent.MOUSE_WHEEL_EVENT_MASK;
  5470. }
  5471. if (focusListener != null || (eventMask & AWTEvent.FOCUS_EVENT_MASK) != 0) {
  5472. mask |= AWTEvent.FOCUS_EVENT_MASK;
  5473. }
  5474. if (keyListener != null || (eventMask & AWTEvent.KEY_EVENT_MASK) != 0) {
  5475. mask |= AWTEvent.KEY_EVENT_MASK;
  5476. }
  5477. if (mask != 0) {
  5478. parent.proxyEnableEvents(mask);
  5479. }
  5480. }
  5481. } else {
  5482. // It's native. If the parent is lightweight it
  5483. // will need some help.
  5484. Container parent = this.parent;
  5485. if (parent != null && parent.peer instanceof LightweightPeer) {
  5486. nativeInLightFixer = new NativeInLightFixer();
  5487. }
  5488. }
  5489. invalidate();
  5490. int npopups = (popups != null? popups.size() : 0);
  5491. for (int i = 0 ; i < npopups ; i++) {
  5492. PopupMenu popup = (PopupMenu)popups.elementAt(i);
  5493. popup.addNotify();
  5494. }
  5495. if (dropTarget != null) dropTarget.addNotify(peer);
  5496. peerFont = getFont();
  5497. // Update stacking order
  5498. if (parent != null && parent.peer != null) {
  5499. ContainerPeer parentContPeer = (ContainerPeer) parent.peer;
  5500. // if our parent is lightweight and we are not
  5501. // we should call restack on nearest heavyweight
  5502. // container.
  5503. if (parentContPeer instanceof LightweightPeer
  5504. && ! (peer instanceof LightweightPeer))
  5505. {
  5506. Container hwParent = getNativeContainer();
  5507. if (hwParent != null && hwParent.peer != null) {
  5508. parentContPeer = (ContainerPeer) hwParent.peer;
  5509. }
  5510. }
  5511. if (parentContPeer.isRestackSupported()) {
  5512. parentContPeer.restack();
  5513. }
  5514. }
  5515. if (hierarchyListener != null ||
  5516. (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0 ||
  5517. Toolkit.enabledOnToolkit(AWTEvent.HIERARCHY_EVENT_MASK)) {
  5518. HierarchyEvent e =
  5519. new HierarchyEvent(this, HierarchyEvent.HIERARCHY_CHANGED,
  5520. this, parent,
  5521. HierarchyEvent.DISPLAYABILITY_CHANGED |
  5522. ((isRecursivelyVisible())
  5523. ? HierarchyEvent.SHOWING_CHANGED
  5524. : 0));
  5525. dispatchEvent(e);
  5526. }
  5527. }
  5528. }
  5529. /**
  5530. * Makes this <code>Component</code> undisplayable by destroying it native
  5531. * screen resource.
  5532. * <p>
  5533. * This method is called by the toolkit internally and should
  5534. * not be called directly by programs. Code overriding
  5535. * this method should call <code>super.removeNotify</code> as
  5536. * the first line of the overriding method.
  5537. *
  5538. * @see #isDisplayable
  5539. * @see #addNotify
  5540. * @since JDK1.0
  5541. */
  5542. public void removeNotify() {
  5543. KeyboardFocusManager.clearMostRecentFocusOwner(this);
  5544. if (KeyboardFocusManager.getCurrentKeyboardFocusManager().
  5545. getPermanentFocusOwner() == this)
  5546. {
  5547. KeyboardFocusManager.getCurrentKeyboardFocusManager().
  5548. setGlobalPermanentFocusOwner(null);
  5549. }
  5550. synchronized (getTreeLock()) {
  5551. if (isFocusOwner() && !nextFocusHelper()) {
  5552. KeyboardFocusManager.getCurrentKeyboardFocusManager().
  5553. clearGlobalFocusOwner();
  5554. }
  5555. int npopups = (popups != null? popups.size() : 0);
  5556. for (int i = 0 ; i < npopups ; i++) {
  5557. PopupMenu popup = (PopupMenu)popups.elementAt(i);
  5558. popup.removeNotify();
  5559. }
  5560. // If there is any input context for this component, notify
  5561. // that this component is being removed. (This has to be done
  5562. // before hiding peer.)
  5563. if ((eventMask & AWTEvent.INPUT_METHODS_ENABLED_MASK) != 0) {
  5564. InputContext inputContext = getInputContext();
  5565. if (inputContext != null) {
  5566. inputContext.removeNotify(this);
  5567. }
  5568. }
  5569. ComponentPeer p = peer;
  5570. if (p != null) {
  5571. if (bufferStrategy instanceof FlipBufferStrategy) {
  5572. ((FlipBufferStrategy)bufferStrategy).destroyBuffers();
  5573. }
  5574. if (dropTarget != null) dropTarget.removeNotify(peer);
  5575. // Hide peer first to stop system events such as cursor moves.
  5576. if (visible) {
  5577. p.hide();
  5578. }
  5579. peer = null; // Stop peer updates.
  5580. peerFont = null;
  5581. Toolkit.getEventQueue().removeSourceEvents(this, false);
  5582. KeyboardFocusManager.getCurrentKeyboardFocusManager().
  5583. discardKeyEvents(this);
  5584. p.dispose();
  5585. }
  5586. if (hierarchyListener != null ||
  5587. (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0 ||
  5588. Toolkit.enabledOnToolkit(AWTEvent.HIERARCHY_EVENT_MASK)) {
  5589. HierarchyEvent e =
  5590. new HierarchyEvent(this, HierarchyEvent.HIERARCHY_CHANGED,
  5591. this, parent,
  5592. HierarchyEvent.DISPLAYABILITY_CHANGED |
  5593. ((isRecursivelyVisible())
  5594. ? HierarchyEvent.SHOWING_CHANGED
  5595. : 0));
  5596. dispatchEvent(e);
  5597. }
  5598. }
  5599. }
  5600. /**
  5601. * @deprecated As of JDK version 1.1,
  5602. * replaced by processFocusEvent(FocusEvent).
  5603. */
  5604. @Deprecated
  5605. public boolean gotFocus(Event evt, Object what) {
  5606. return false;
  5607. }
  5608. /**
  5609. * @deprecated As of JDK version 1.1,
  5610. * replaced by processFocusEvent(FocusEvent).
  5611. */
  5612. @Deprecated
  5613. public boolean lostFocus(Event evt, Object what) {
  5614. return false;
  5615. }
  5616. /**
  5617. * Returns whether this <code>Component</code> can become the focus
  5618. * owner.
  5619. *
  5620. * @return <code>true</code> if this <code>Component</code> is
  5621. * focusable; <code>false</code> otherwise
  5622. * @see #setFocusable
  5623. * @since JDK1.1
  5624. * @deprecated As of 1.4, replaced by <code>isFocusable()</code>.
  5625. */
  5626. @Deprecated
  5627. public boolean isFocusTraversable() {
  5628. if (isFocusTraversableOverridden == FOCUS_TRAVERSABLE_UNKNOWN) {
  5629. isFocusTraversableOverridden = FOCUS_TRAVERSABLE_DEFAULT;
  5630. }
  5631. return focusable;
  5632. }
  5633. /**
  5634. * Returns whether this Component can be focused.
  5635. *
  5636. * @return <code>true</code> if this Component is focusable;
  5637. * <code>false</code> otherwise.
  5638. * @see #setFocusable
  5639. * @since 1.4
  5640. */
  5641. public boolean isFocusable() {
  5642. return isFocusTraversable();
  5643. }
  5644. /**
  5645. * Sets the focusable state of this Component to the specified value. This
  5646. * value overrides the Component's default focusability.
  5647. *
  5648. * @param focusable indicates whether this Component is focusable
  5649. * @see #isFocusable
  5650. * @since 1.4
  5651. * @beaninfo
  5652. * bound: true
  5653. */
  5654. public void setFocusable(boolean focusable) {
  5655. boolean oldFocusable;
  5656. synchronized (this) {
  5657. oldFocusable = this.focusable;
  5658. this.focusable = focusable;
  5659. }
  5660. isFocusTraversableOverridden = FOCUS_TRAVERSABLE_SET;
  5661. firePropertyChange("focusable", oldFocusable, focusable);
  5662. if (oldFocusable && !focusable) {
  5663. if (isFocusOwner()) {
  5664. autoTransferFocus(true);
  5665. }
  5666. KeyboardFocusManager.clearMostRecentFocusOwner(this);
  5667. }
  5668. }
  5669. final boolean isFocusTraversableOverridden() {
  5670. return (isFocusTraversableOverridden != FOCUS_TRAVERSABLE_DEFAULT);
  5671. }
  5672. /**
  5673. * Sets the focus traversal keys for a given traversal operation for this
  5674. * Component.
  5675. * <p>
  5676. * The default values for a Component's focus traversal keys are
  5677. * implementation-dependent. Sun recommends that all implementations for a
  5678. * particular native platform use the same default values. The
  5679. * recommendations for Windows and Unix are listed below. These
  5680. * recommendations are used in the Sun AWT implementations.
  5681. *
  5682. * <table border=1 summary="Recommended default values for a Component's focus traversal keys">
  5683. * <tr>
  5684. * <th>Identifier</th>
  5685. * <th>Meaning</th>
  5686. * <th>Default</th>
  5687. * </tr>
  5688. * <tr>
  5689. * <td>KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS</td>
  5690. * <td>Normal forward keyboard traversal</td>
  5691. * <td>TAB on KEY_PRESSED, CTRL-TAB on KEY_PRESSED</td>
  5692. * </tr>
  5693. * <tr>
  5694. * <td>KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS</td>
  5695. * <td>Normal reverse keyboard traversal</td>
  5696. * <td>SHIFT-TAB on KEY_PRESSED, CTRL-SHIFT-TAB on KEY_PRESSED</td>
  5697. * </tr>
  5698. * <tr>
  5699. * <td>KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS</td>
  5700. * <td>Go up one focus traversal cycle</td>
  5701. * <td>none</td>
  5702. * </tr>
  5703. * </table>
  5704. *
  5705. * To disable a traversal key, use an empty Set; Collections.EMPTY_SET is
  5706. * recommended.
  5707. * <p>
  5708. * Using the AWTKeyStroke API, client code can specify on which of two
  5709. * specific KeyEvents, KEY_PRESSED or KEY_RELEASED, the focus traversal
  5710. * operation will occur. Regardless of which KeyEvent is specified,
  5711. * however, all KeyEvents related to the focus traversal key, including the
  5712. * associated KEY_TYPED event, will be consumed, and will not be dispatched
  5713. * to any Component. It is a runtime error to specify a KEY_TYPED event as
  5714. * mapping to a focus traversal operation, or to map the same event to
  5715. * multiple default focus traversal operations.
  5716. * <p>
  5717. * If a value of null is specified for the Set, this Component inherits the
  5718. * Set from its parent. If all ancestors of this Component have null
  5719. * specified for the Set, then the current KeyboardFocusManager's default
  5720. * Set is used.
  5721. *
  5722. * @param id one of KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
  5723. * KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, or
  5724. * KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS
  5725. * @param keystrokes the Set of AWTKeyStroke for the specified operation
  5726. * @see #getFocusTraversalKeys
  5727. * @see KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS
  5728. * @see KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS
  5729. * @see KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS
  5730. * @throws IllegalArgumentException if id is not one of
  5731. * KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
  5732. * KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, or
  5733. * KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, or if keystrokes
  5734. * contains null, or if any Object in keystrokes is not an
  5735. * AWTKeyStroke, or if any keystroke represents a KEY_TYPED event,
  5736. * or if any keystroke already maps to another focus traversal
  5737. * operation for this Component
  5738. * @since 1.4
  5739. * @beaninfo
  5740. * bound: true
  5741. */
  5742. public void setFocusTraversalKeys(int id,
  5743. Set<? extends AWTKeyStroke> keystrokes)
  5744. {
  5745. if (id < 0 || id >= KeyboardFocusManager.TRAVERSAL_KEY_LENGTH - 1) {
  5746. throw new IllegalArgumentException("invalid focus traversal key identifier");
  5747. }
  5748. setFocusTraversalKeys_NoIDCheck(id, keystrokes);
  5749. }
  5750. /**
  5751. * Returns the Set of focus traversal keys for a given traversal operation
  5752. * for this Component. (See
  5753. * <code>setFocusTraversalKeys</code> for a full description of each key.)
  5754. * <p>
  5755. * If a Set of traversal keys has not been explicitly defined for this
  5756. * Component, then this Component's parent's Set is returned. If no Set
  5757. * has been explicitly defined for any of this Component's ancestors, then
  5758. * the current KeyboardFocusManager's default Set is returned.
  5759. *
  5760. * @param id one of KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
  5761. * KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, or
  5762. * KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS
  5763. * @return the Set of AWTKeyStrokes for the specified operation. The Set
  5764. * will be unmodifiable, and may be empty. null will never be
  5765. * returned.
  5766. * @see #setFocusTraversalKeys
  5767. * @see KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS
  5768. * @see KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS
  5769. * @see KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS
  5770. * @throws IllegalArgumentException if id is not one of
  5771. * KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
  5772. * KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, or
  5773. * KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS
  5774. * @since 1.4
  5775. */
  5776. public Set<AWTKeyStroke> getFocusTraversalKeys(int id) {
  5777. if (id < 0 || id >= KeyboardFocusManager.TRAVERSAL_KEY_LENGTH - 1) {
  5778. throw new IllegalArgumentException("invalid focus traversal key identifier");
  5779. }
  5780. return getFocusTraversalKeys_NoIDCheck(id);
  5781. }
  5782. // We define these methods so that Container does not need to repeat this
  5783. // code. Container cannot call super.<method> because Container allows
  5784. // DOWN_CYCLE_TRAVERSAL_KEY while Component does not. The Component method
  5785. // would erroneously generate an IllegalArgumentException for
  5786. // DOWN_CYCLE_TRAVERSAL_KEY.
  5787. final void setFocusTraversalKeys_NoIDCheck(int id, Set keystrokes) {
  5788. Set oldKeys;
  5789. synchronized (this) {
  5790. if (focusTraversalKeys == null) {
  5791. initializeFocusTraversalKeys();
  5792. }
  5793. if (keystrokes != null) {
  5794. for (Iterator iter = keystrokes.iterator(); iter.hasNext(); ) {
  5795. Object obj = iter.next();
  5796. if (obj == null) {
  5797. throw new IllegalArgumentException("cannot set null focus traversal key");
  5798. }
  5799. // Generates a ClassCastException if the element is not an
  5800. // AWTKeyStroke. This is desirable.
  5801. AWTKeyStroke keystroke = (AWTKeyStroke)obj;
  5802. if (keystroke.getKeyChar() != KeyEvent.CHAR_UNDEFINED) {
  5803. throw new IllegalArgumentException("focus traversal keys cannot map to KEY_TYPED events");
  5804. }
  5805. for (int i = 0; i < focusTraversalKeys.length; i++) {
  5806. if (i == id) {
  5807. continue;
  5808. }
  5809. if (getFocusTraversalKeys_NoIDCheck(i).contains(keystroke))
  5810. {
  5811. throw new IllegalArgumentException("focus traversal keys must be unique for a Component");
  5812. }
  5813. }
  5814. }
  5815. }
  5816. oldKeys = focusTraversalKeys[id];
  5817. focusTraversalKeys[id] = (keystrokes != null)
  5818. ? Collections.unmodifiableSet(new HashSet(keystrokes))
  5819. : null;
  5820. }
  5821. firePropertyChange(focusTraversalKeyPropertyNames[id], oldKeys,
  5822. keystrokes);
  5823. }
  5824. final Set getFocusTraversalKeys_NoIDCheck(int id) {
  5825. // Okay to return Set directly because it is an unmodifiable view
  5826. Set keystrokes = (focusTraversalKeys != null)
  5827. ? focusTraversalKeys[id]
  5828. : null;
  5829. if (keystrokes != null) {
  5830. return keystrokes;
  5831. } else {
  5832. Container parent = this.parent;
  5833. if (parent != null) {
  5834. return parent.getFocusTraversalKeys(id);
  5835. } else {
  5836. return KeyboardFocusManager.getCurrentKeyboardFocusManager().
  5837. getDefaultFocusTraversalKeys(id);
  5838. }
  5839. }
  5840. }
  5841. /**
  5842. * Returns whether the Set of focus traversal keys for the given focus
  5843. * traversal operation has been explicitly defined for this Component. If
  5844. * this method returns <code>false</code>, this Component is inheriting the
  5845. * Set from an ancestor, or from the current KeyboardFocusManager.
  5846. *
  5847. * @param id one of KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
  5848. * KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, or
  5849. * KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS
  5850. * @return <code>true</code> if the the Set of focus traversal keys for the
  5851. * given focus traversal operation has been explicitly defined for
  5852. * this Component; <code>false</code> otherwise.
  5853. * @throws IllegalArgumentException if id is not one of
  5854. * KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
  5855. * KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, or
  5856. * KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS
  5857. * @since 1.4
  5858. */
  5859. public boolean areFocusTraversalKeysSet(int id) {
  5860. if (id < 0 || id >= KeyboardFocusManager.TRAVERSAL_KEY_LENGTH - 1) {
  5861. throw new IllegalArgumentException("invalid focus traversal key identifier");
  5862. }
  5863. return (focusTraversalKeys != null && focusTraversalKeys[id] != null);
  5864. }
  5865. /**
  5866. * Sets whether focus traversal keys are enabled for this Component.
  5867. * Components for which focus traversal keys are disabled receive key
  5868. * events for focus traversal keys. Components for which focus traversal
  5869. * keys are enabled do not see these events; instead, the events are
  5870. * automatically converted to traversal operations.
  5871. *
  5872. * @param focusTraversalKeysEnabled whether focus traversal keys are
  5873. * enabled for this Component
  5874. * @see #getFocusTraversalKeysEnabled
  5875. * @see #setFocusTraversalKeys
  5876. * @see #getFocusTraversalKeys
  5877. * @since 1.4
  5878. * @beaninfo
  5879. * bound: true
  5880. */
  5881. public void setFocusTraversalKeysEnabled(boolean
  5882. focusTraversalKeysEnabled) {
  5883. boolean oldFocusTraversalKeysEnabled;
  5884. synchronized (this) {
  5885. oldFocusTraversalKeysEnabled = this.focusTraversalKeysEnabled;
  5886. this.focusTraversalKeysEnabled = focusTraversalKeysEnabled;
  5887. }
  5888. firePropertyChange("focusTraversalKeysEnabled",
  5889. oldFocusTraversalKeysEnabled,
  5890. focusTraversalKeysEnabled);
  5891. }
  5892. /**
  5893. * Returns whether focus traversal keys are enabled for this Component.
  5894. * Components for which focus traversal keys are disabled receive key
  5895. * events for focus traversal keys. Components for which focus traversal
  5896. * keys are enabled do not see these events; instead, the events are
  5897. * automatically converted to traversal operations.
  5898. *
  5899. * @return whether focus traversal keys are enabled for this Component
  5900. * @see #setFocusTraversalKeysEnabled
  5901. * @see #setFocusTraversalKeys
  5902. * @see #getFocusTraversalKeys
  5903. * @since 1.4
  5904. */
  5905. public boolean getFocusTraversalKeysEnabled() {
  5906. return focusTraversalKeysEnabled;
  5907. }
  5908. /**
  5909. * Requests that this Component get the input focus, and that this
  5910. * Component's top-level ancestor become the focused Window. This component
  5911. * must be displayable, visible, and focusable for the request to be
  5912. * granted. Every effort will be made to honor the request; however, in
  5913. * some cases it may be impossible to do so. Developers must never assume
  5914. * that this Component is the focus owner until this Component receives a
  5915. * FOCUS_GAINED event. If this request is denied because this Component's
  5916. * top-level Window cannot become the focused Window, the request will be
  5917. * remembered and will be granted when the Window is later focused by the
  5918. * user.
  5919. * <p>
  5920. * This method cannot be used to set the focus owner to no Component at
  5921. * all. Use <code>KeyboardFocusManager.clearGlobalFocusOwner()</code>
  5922. * instead.
  5923. * <p>
  5924. * Because the focus behavior of this method is platform-dependent,
  5925. * developers are strongly encouraged to use
  5926. * <code>requestFocusInWindow</code> when possible.
  5927. *
  5928. * @see #requestFocusInWindow
  5929. * @see java.awt.event.FocusEvent
  5930. * @see #addFocusListener
  5931. * @see #isFocusable
  5932. * @see #isDisplayable
  5933. * @see KeyboardFocusManager#clearGlobalFocusOwner
  5934. * @since JDK1.0
  5935. */
  5936. public void requestFocus() {
  5937. requestFocusHelper(false, true);
  5938. }
  5939. /**
  5940. * Requests that this <code>Component</code> get the input focus,
  5941. * and that this <code>Component</code>'s top-level ancestor
  5942. * become the focused <code>Window</code>. This component
  5943. * must be displayable, visible, and focusable for the request to be
  5944. * granted. Every effort will be made to honor the request; however, in
  5945. * some cases it may be impossible to do so. Developers must never assume
  5946. * that this component is the focus owner until this component receives a
  5947. * FOCUS_GAINED event. If this request is denied because this component's
  5948. * top-level window cannot become the focused window, the request will be
  5949. * remembered and will be granted when the window is later focused by the
  5950. * user.
  5951. * <p>
  5952. * This method returns a boolean value. If <code>false</code> is returned,
  5953. * the request is <b>guaranteed to fail</b>. If <code>true</code> is
  5954. * returned, the request will succeed <b>unless</b> it is vetoed, or an
  5955. * extraordinary event, such as disposal of the component's peer, occurs
  5956. * before the request can be granted by the native windowing system. Again,
  5957. * while a return value of <code>true</code> indicates that the request is
  5958. * likely to succeed, developers must never assume that this component is
  5959. * the focus owner until this component receives a FOCUS_GAINED event.
  5960. * <p>
  5961. * This method cannot be used to set the focus owner to no component at
  5962. * all. Use <code>KeyboardFocusManager.clearGlobalFocusOwner</code>
  5963. * instead.
  5964. * <p>
  5965. * Because the focus behavior of this method is platform-dependent,
  5966. * developers are strongly encouraged to use
  5967. * <code>requestFocusInWindow</code> when possible.
  5968. * <p>
  5969. * Every effort will be made to ensure that <code>FocusEvent</code>s
  5970. * generated as a
  5971. * result of this request will have the specified temporary value. However,
  5972. * because specifying an arbitrary temporary state may not be implementable
  5973. * on all native windowing systems, correct behavior for this method can be
  5974. * guaranteed only for lightweight <code>Component</code>s.
  5975. * This method is not intended
  5976. * for general use, but exists instead as a hook for lightweight component
  5977. * libraries, such as Swing.
  5978. *
  5979. * @param temporary true if the focus change is temporary,
  5980. * such as when the window loses the focus; for
  5981. * more information on temporary focus changes see the
  5982. *<a href="../../java/awt/doc-files/FocusSpec.html">Focus Specification</a>
  5983. * @return <code>false</code> if the focus change request is guaranteed to
  5984. * fail; <code>true</code> if it is likely to succeed
  5985. * @see java.awt.event.FocusEvent
  5986. * @see #addFocusListener
  5987. * @see #isFocusable
  5988. * @see #isDisplayable
  5989. * @see KeyboardFocusManager#clearGlobalFocusOwner
  5990. * @since 1.4
  5991. */
  5992. protected boolean requestFocus(boolean temporary) {
  5993. return requestFocusHelper(temporary, true);
  5994. }
  5995. /**
  5996. * Requests that this Component get the input focus, if this Component's
  5997. * top-level ancestor is already the focused Window. This component must be
  5998. * displayable, visible, and focusable for the request to be granted. Every
  5999. * effort will be made to honor the request; however, in some cases it may
  6000. * be impossible to do so. Developers must never assume that this Component
  6001. * is the focus owner until this Component receives a FOCUS_GAINED event.
  6002. * <p>
  6003. * This method returns a boolean value. If <code>false</code> is returned,
  6004. * the request is <b>guaranteed to fail</b>. If <code>true</code> is
  6005. * returned, the request will succeed <b>unless</b> it is vetoed, or an
  6006. * extraordinary event, such as disposal of the Component's peer, occurs
  6007. * before the request can be granted by the native windowing system. Again,
  6008. * while a return value of <code>true</code> indicates that the request is
  6009. * likely to succeed, developers must never assume that this Component is
  6010. * the focus owner until this Component receives a FOCUS_GAINED event.
  6011. * <p>
  6012. * This method cannot be used to set the focus owner to no Component at
  6013. * all. Use <code>KeyboardFocusManager.clearGlobalFocusOwner()</code>
  6014. * instead.
  6015. * <p>
  6016. * The focus behavior of this method can be implemented uniformly across
  6017. * platforms, and thus developers are strongly encouraged to use this
  6018. * method over <code>requestFocus</code> when possible. Code which relies
  6019. * on <code>requestFocus</code> may exhibit different focus behavior on
  6020. * different platforms.
  6021. *
  6022. * @return <code>false</code> if the focus change request is guaranteed to
  6023. * fail; <code>true</code> if it is likely to succeed
  6024. * @see #requestFocus
  6025. * @see java.awt.event.FocusEvent
  6026. * @see #addFocusListener
  6027. * @see #isFocusable
  6028. * @see #isDisplayable
  6029. * @see KeyboardFocusManager#clearGlobalFocusOwner
  6030. * @since 1.4
  6031. */
  6032. public boolean requestFocusInWindow() {
  6033. return requestFocusHelper(false, false);
  6034. }
  6035. /**
  6036. * Requests that this <code>Component</code> get the input focus,
  6037. * if this <code>Component</code>'s
  6038. * top-level ancestor is already the focused <code>Window</code>.
  6039. * This component must be
  6040. * displayable, visible, and focusable for the request to be granted. Every
  6041. * effort will be made to honor the request; however, in some cases it may
  6042. * be impossible to do so. Developers must never assume that this component
  6043. * is the focus owner until this component receives a FOCUS_GAINED event.
  6044. * <p>
  6045. * This method returns a boolean value. If <code>false</code> is returned,
  6046. * the request is <b>guaranteed to fail</b>. If <code>true</code> is
  6047. * returned, the request will succeed <b>unless</b> it is vetoed, or an
  6048. * extraordinary event, such as disposal of the component's peer, occurs
  6049. * before the request can be granted by the native windowing system. Again,
  6050. * while a return value of <code>true</code> indicates that the request is
  6051. * likely to succeed, developers must never assume that this component is
  6052. * the focus owner until this component receives a FOCUS_GAINED event.
  6053. * <p>
  6054. * This method cannot be used to set the focus owner to no component at
  6055. * all. Use <code>KeyboardFocusManager.clearGlobalFocusOwner</code>
  6056. * instead.
  6057. * <p>
  6058. * The focus behavior of this method can be implemented uniformly across
  6059. * platforms, and thus developers are strongly encouraged to use this
  6060. * method over <code>requestFocus</code> when possible. Code which relies
  6061. * on <code>requestFocus</code> may exhibit different focus behavior on
  6062. * different platforms.
  6063. * <p>
  6064. * Every effort will be made to ensure that <code>FocusEvent</code>s
  6065. * generated as a
  6066. * result of this request will have the specified temporary value. However,
  6067. * because specifying an arbitrary temporary state may not be implementable
  6068. * on all native windowing systems, correct behavior for this method can be
  6069. * guaranteed only for lightweight components. This method is not intended
  6070. * for general use, but exists instead as a hook for lightweight component
  6071. * libraries, such as Swing.
  6072. *
  6073. * @param temporary true if the focus change is temporary,
  6074. * such as when the window loses the focus; for
  6075. * more information on temporary focus changes see the
  6076. *<a href="../../java/awt/doc-files/FocusSpec.html">Focus Specification</a>
  6077. * @return <code>false</code> if the focus change request is guaranteed to
  6078. * fail; <code>true</code> if it is likely to succeed
  6079. * @see #requestFocus
  6080. * @see java.awt.event.FocusEvent
  6081. * @see #addFocusListener
  6082. * @see #isFocusable
  6083. * @see #isDisplayable
  6084. * @see KeyboardFocusManager#clearGlobalFocusOwner
  6085. * @since 1.4
  6086. */
  6087. protected boolean requestFocusInWindow(boolean temporary) {
  6088. return requestFocusHelper(temporary, false);
  6089. }
  6090. final boolean requestFocusHelper(boolean temporary,
  6091. boolean focusedWindowChangeAllowed) {
  6092. if (isFocusable() && isVisible()) {
  6093. ComponentPeer peer = this.peer;
  6094. if (peer != null) {
  6095. boolean recursivelyInvisible = false;
  6096. Component window = this;
  6097. while (!(window instanceof Window)) {
  6098. if (!window.isVisible()) {
  6099. recursivelyInvisible = true;
  6100. }
  6101. window = window.parent;
  6102. }
  6103. if (window == null || !((Window)window).isFocusableWindow()) {
  6104. focusLog.finest("FAIL 1");
  6105. return false;
  6106. }
  6107. // Update most-recent map
  6108. KeyboardFocusManager.setMostRecentFocusOwner(this);
  6109. if (recursivelyInvisible) {
  6110. focusLog.finest("FAIL 1.5");
  6111. return false;
  6112. }
  6113. Component heavyweight = (peer instanceof LightweightPeer)
  6114. ? getNativeContainer() : this;
  6115. if (heavyweight == null || !heavyweight.isVisible()) {
  6116. focusLog.finest("FAIL 2");
  6117. return false;
  6118. }
  6119. peer = heavyweight.peer;
  6120. if (peer == null) {
  6121. focusLog.finest("FAIL 3");
  6122. return false;
  6123. }
  6124. // Focus this Component
  6125. long time = EventQueue.getMostRecentEventTime();
  6126. boolean success = peer.requestFocus
  6127. (this, temporary, focusedWindowChangeAllowed, time);
  6128. if (!success) {
  6129. KeyboardFocusManager.getCurrentKeyboardFocusManager
  6130. (appContext).dequeueKeyEvents(time, this);
  6131. focusLog.finest("FAIL 4");
  6132. } else {
  6133. if (focusLog.isLoggable(Level.FINEST)) focusLog.finest("Pass for " + this);
  6134. }
  6135. return success;
  6136. }
  6137. }
  6138. focusLog.finest("FAIL 5");
  6139. return false;
  6140. }
  6141. final void autoTransferFocus(boolean clearOnFailure) {
  6142. Component toTest = KeyboardFocusManager.
  6143. getCurrentKeyboardFocusManager().getFocusOwner();
  6144. if (toTest != this) {
  6145. if (toTest != null) {
  6146. toTest.autoTransferFocus(clearOnFailure);
  6147. }
  6148. return;
  6149. }
  6150. // the following code will execute only if this Component is the focus
  6151. // owner
  6152. if (!(isDisplayable() && isVisible() && isEnabled() && isFocusable())) {
  6153. doAutoTransfer(clearOnFailure);
  6154. return;
  6155. }
  6156. toTest = getParent();
  6157. while (toTest != null && !(toTest instanceof Window)) {
  6158. if (!(toTest.isDisplayable() && toTest.isVisible() &&
  6159. (toTest.isEnabled() || toTest.isLightweight()))) {
  6160. doAutoTransfer(clearOnFailure);
  6161. return;
  6162. }
  6163. toTest = toTest.getParent();
  6164. }
  6165. }
  6166. private void doAutoTransfer(boolean clearOnFailure) {
  6167. if (clearOnFailure) {
  6168. if (!nextFocusHelper()) {
  6169. KeyboardFocusManager.getCurrentKeyboardFocusManager().
  6170. clearGlobalFocusOwner();
  6171. }
  6172. } else {
  6173. transferFocus();
  6174. }
  6175. }
  6176. /**
  6177. * Transfers the focus to the next component, as though this Component were
  6178. * the focus owner.
  6179. * @see #requestFocus()
  6180. * @since JDK1.1
  6181. */
  6182. public void transferFocus() {
  6183. nextFocus();
  6184. }
  6185. /**
  6186. * Returns the Container which is the focus cycle root of this Component's
  6187. * focus traversal cycle. Each focus traversal cycle has only a single
  6188. * focus cycle root and each Component which is not a Container belongs to
  6189. * only a single focus traversal cycle. Containers which are focus cycle
  6190. * roots belong to two cycles: one rooted at the Container itself, and one
  6191. * rooted at the Container's nearest focus-cycle-root ancestor. For such
  6192. * Containers, this method will return the Container's nearest focus-cycle-
  6193. * root ancestor.
  6194. *
  6195. * @return this Component's nearest focus-cycle-root ancestor
  6196. * @see Container#isFocusCycleRoot()
  6197. * @since 1.4
  6198. */
  6199. public Container getFocusCycleRootAncestor() {
  6200. Container rootAncestor = this.parent;
  6201. while (rootAncestor != null && !rootAncestor.isFocusCycleRoot()) {
  6202. rootAncestor = rootAncestor.parent;
  6203. }
  6204. return rootAncestor;
  6205. }
  6206. /**
  6207. * Returns whether the specified Container is the focus cycle root of this
  6208. * Component's focus traversal cycle. Each focus traversal cycle has only
  6209. * a single focus cycle root and each Component which is not a Container
  6210. * belongs to only a single focus traversal cycle.
  6211. *
  6212. * @param container the Container to be tested
  6213. * @return <code>true</code> if the specified Container is a focus-cycle-
  6214. * root of this Component; <code>false</code> otherwise
  6215. * @see Container#isFocusCycleRoot()
  6216. * @since 1.4
  6217. */
  6218. public boolean isFocusCycleRoot(Container container) {
  6219. Container rootAncestor = getFocusCycleRootAncestor();
  6220. return (rootAncestor == container);
  6221. }
  6222. /**
  6223. * @deprecated As of JDK version 1.1,
  6224. * replaced by transferFocus().
  6225. */
  6226. @Deprecated
  6227. public void nextFocus() {
  6228. nextFocusHelper();
  6229. }
  6230. boolean nextFocusHelper() {
  6231. Container rootAncestor = getFocusCycleRootAncestor();
  6232. Component comp = this;
  6233. while (rootAncestor != null &&
  6234. !(rootAncestor.isShowing() &&
  6235. rootAncestor.isFocusable() &&
  6236. rootAncestor.isEnabled()))
  6237. {
  6238. comp = rootAncestor;
  6239. rootAncestor = comp.getFocusCycleRootAncestor();
  6240. }
  6241. if (rootAncestor != null) {
  6242. FocusTraversalPolicy policy =
  6243. rootAncestor.getFocusTraversalPolicy();
  6244. Component toFocus = policy.getComponentAfter(rootAncestor, comp);
  6245. if (toFocus == null) {
  6246. toFocus = policy.getDefaultComponent(rootAncestor);
  6247. }
  6248. if (toFocus != null) {
  6249. if (focusLog.isLoggable(Level.FINER)) focusLog.finer("Next component " + toFocus);
  6250. boolean res = toFocus.requestFocus(false);
  6251. if (focusLog.isLoggable(Level.FINER)) focusLog.finer("Request focus returned " + res);
  6252. return res;
  6253. }
  6254. }
  6255. return false;
  6256. }
  6257. /**
  6258. * Transfers the focus to the previous component, as though this Component
  6259. * were the focus owner.
  6260. * @see #requestFocus()
  6261. * @since 1.4
  6262. */
  6263. public void transferFocusBackward() {
  6264. Container rootAncestor = getFocusCycleRootAncestor();
  6265. Component comp = this;
  6266. while (rootAncestor != null &&
  6267. !(rootAncestor.isShowing() &&
  6268. rootAncestor.isFocusable() &&
  6269. rootAncestor.isEnabled()))
  6270. {
  6271. comp = rootAncestor;
  6272. rootAncestor = comp.getFocusCycleRootAncestor();
  6273. }
  6274. if (rootAncestor != null) {
  6275. FocusTraversalPolicy policy =
  6276. rootAncestor.getFocusTraversalPolicy();
  6277. Component toFocus = policy.getComponentBefore(rootAncestor, comp);
  6278. if (toFocus == null) {
  6279. toFocus = policy.getDefaultComponent(rootAncestor);
  6280. }
  6281. if (toFocus != null) {
  6282. toFocus.requestFocus();
  6283. }
  6284. }
  6285. }
  6286. /**
  6287. * Transfers the focus up one focus traversal cycle. Typically, the focus
  6288. * owner is set to this Component's focus cycle root, and the current focus
  6289. * cycle root is set to the new focus owner's focus cycle root. If,
  6290. * however, this Component's focus cycle root is a Window, then the focus
  6291. * owner is set to the focus cycle root's default Component to focus, and
  6292. * the current focus cycle root is unchanged.
  6293. *
  6294. * @see #requestFocus()
  6295. * @see Container#isFocusCycleRoot()
  6296. * @see Container#setFocusCycleRoot(boolean)
  6297. * @since 1.4
  6298. */
  6299. public void transferFocusUpCycle() {
  6300. Container rootAncestor;
  6301. for (rootAncestor = getFocusCycleRootAncestor();
  6302. rootAncestor != null && !(rootAncestor.isShowing() &&
  6303. rootAncestor.isFocusable() &&
  6304. rootAncestor.isEnabled());
  6305. rootAncestor = rootAncestor.getFocusCycleRootAncestor()) {
  6306. }
  6307. if (rootAncestor != null) {
  6308. Container rootAncestorRootAncestor =
  6309. rootAncestor.getFocusCycleRootAncestor();
  6310. KeyboardFocusManager.getCurrentKeyboardFocusManager().
  6311. setGlobalCurrentFocusCycleRoot(
  6312. (rootAncestorRootAncestor != null)
  6313. ? rootAncestorRootAncestor
  6314. : rootAncestor);
  6315. rootAncestor.requestFocus();
  6316. } else {
  6317. Container window =
  6318. (this instanceof Container) ? ((Container)this) : getParent();
  6319. while (window != null && !(window instanceof Window)) {
  6320. window = window.getParent();
  6321. }
  6322. if (window != null) {
  6323. Component toFocus = window.getFocusTraversalPolicy().
  6324. getDefaultComponent(window);
  6325. if (toFocus != null) {
  6326. KeyboardFocusManager.getCurrentKeyboardFocusManager().
  6327. setGlobalCurrentFocusCycleRoot(window);
  6328. toFocus.requestFocus();
  6329. }
  6330. }
  6331. }
  6332. }
  6333. /**
  6334. * Returns <code>true</code> if this <code>Component</code> is the
  6335. * focus owner. This method is obsolete, and has been replaced by
  6336. * <code>isFocusOwner()</code>.
  6337. *
  6338. * @return <code>true</code> if this <code>Component</code> is the
  6339. * focus owner; <code>false</code> otherwise
  6340. * @since 1.2
  6341. */
  6342. public boolean hasFocus() {
  6343. return (KeyboardFocusManager.getCurrentKeyboardFocusManager().
  6344. getFocusOwner() == this);
  6345. }
  6346. /**
  6347. * Returns <code>true</code> if this <code>Component</code> is the
  6348. * focus owner.
  6349. *
  6350. * @return <code>true</code> if this <code>Component</code> is the
  6351. * focus owner; <code>false</code> otherwise
  6352. * @since 1.4
  6353. */
  6354. public boolean isFocusOwner() {
  6355. return hasFocus();
  6356. }
  6357. /**
  6358. * Adds the specified popup menu to the component.
  6359. * @param popup the popup menu to be added to the component.
  6360. * @see #remove(MenuComponent)
  6361. * @since JDK1.1
  6362. */
  6363. public synchronized void add(PopupMenu popup) {
  6364. if (popup.parent != null) {
  6365. popup.parent.remove(popup);
  6366. }
  6367. if (popups == null) {
  6368. popups = new Vector();
  6369. }
  6370. popups.addElement(popup);
  6371. popup.parent = this;
  6372. if (peer != null) {
  6373. if (popup.peer == null) {
  6374. popup.addNotify();
  6375. }
  6376. }
  6377. }
  6378. /**
  6379. * Removes the specified popup menu from the component.
  6380. * @param popup the popup menu to be removed
  6381. * @see #add(PopupMenu)
  6382. * @since JDK1.1
  6383. */
  6384. public synchronized void remove(MenuComponent popup) {
  6385. if (popups != null) {
  6386. int index = popups.indexOf(popup);
  6387. if (index >= 0) {
  6388. PopupMenu pmenu = (PopupMenu)popup;
  6389. if (pmenu.peer != null) {
  6390. pmenu.removeNotify();
  6391. }
  6392. pmenu.parent = null;
  6393. popups.removeElementAt(index);
  6394. if (popups.size() == 0) {
  6395. popups = null;
  6396. }
  6397. }
  6398. }
  6399. }
  6400. /**
  6401. * Returns a string representing the state of this component. This
  6402. * method is intended to be used only for debugging purposes, and the
  6403. * content and format of the returned string may vary between
  6404. * implementations. The returned string may be empty but may not be
  6405. * <code>null</code>.
  6406. *
  6407. * @return a string representation of this component's state
  6408. * @since JDK1.0
  6409. */
  6410. protected String paramString() {
  6411. String thisName = getName();
  6412. String str = (thisName != null? thisName : "") + "," + x + "," + y + "," + width + "x" + height;
  6413. if (!valid) {
  6414. str += ",invalid";
  6415. }
  6416. if (!visible) {
  6417. str += ",hidden";
  6418. }
  6419. if (!enabled) {
  6420. str += ",disabled";
  6421. }
  6422. return str;
  6423. }
  6424. /**
  6425. * Returns a string representation of this component and its values.
  6426. * @return a string representation of this component
  6427. * @since JDK1.0
  6428. */
  6429. public String toString() {
  6430. return getClass().getName() + "[" + paramString() + "]";
  6431. }
  6432. /**
  6433. * Prints a listing of this component to the standard system output
  6434. * stream <code>System.out</code>.
  6435. * @see java.lang.System#out
  6436. * @since JDK1.0
  6437. */
  6438. public void list() {
  6439. list(System.out, 0);
  6440. }
  6441. /**
  6442. * Prints a listing of this component to the specified output
  6443. * stream.
  6444. * @param out a print stream
  6445. * @since JDK1.0
  6446. */
  6447. public void list(PrintStream out) {
  6448. list(out, 0);
  6449. }
  6450. /**
  6451. * Prints out a list, starting at the specified indentation, to the
  6452. * specified print stream.
  6453. * @param out a print stream
  6454. * @param indent number of spaces to indent
  6455. * @see java.io.PrintStream#println(java.lang.Object)
  6456. * @since JDK1.0
  6457. */
  6458. public void list(PrintStream out, int indent) {
  6459. for (int i = 0 ; i < indent ; i++) {
  6460. out.print(" ");
  6461. }
  6462. out.println(this);
  6463. }
  6464. /**
  6465. * Prints a listing to the specified print writer.
  6466. * @param out the print writer to print to
  6467. * @since JDK1.1
  6468. */
  6469. public void list(PrintWriter out) {
  6470. list(out, 0);
  6471. }
  6472. /**
  6473. * Prints out a list, starting at the specified indentation, to
  6474. * the specified print writer.
  6475. * @param out the print writer to print to
  6476. * @param indent the number of spaces to indent
  6477. * @see java.io.PrintStream#println(java.lang.Object)
  6478. * @since JDK1.1
  6479. */
  6480. public void list(PrintWriter out, int indent) {
  6481. for (int i = 0 ; i < indent ; i++) {
  6482. out.print(" ");
  6483. }
  6484. out.println(this);
  6485. }
  6486. /*
  6487. * Fetches the native container somewhere higher up in the component
  6488. * tree that contains this component.
  6489. */
  6490. Container getNativeContainer() {
  6491. Container p = parent;
  6492. while (p != null && p.peer instanceof LightweightPeer) {
  6493. p = p.getParent();
  6494. }
  6495. return p;
  6496. }
  6497. /**
  6498. * Adds a PropertyChangeListener to the listener list. The listener is
  6499. * registered for all bound properties of this class, including the
  6500. * following:
  6501. * <ul>
  6502. * <li>this Component's font ("font")</li>
  6503. * <li>this Component's background color ("background")</li>
  6504. * <li>this Component's foreground color ("foreground")</li>
  6505. * <li>this Component's focusability ("focusable")</li>
  6506. * <li>this Component's focus traversal keys enabled state
  6507. * ("focusTraversalKeysEnabled")</li>
  6508. * <li>this Component's Set of FORWARD_TRAVERSAL_KEYS
  6509. * ("forwardFocusTraversalKeys")</li>
  6510. * <li>this Component's Set of BACKWARD_TRAVERSAL_KEYS
  6511. * ("backwardFocusTraversalKeys")</li>
  6512. * <li>this Component's Set of UP_CYCLE_TRAVERSAL_KEYS
  6513. * ("upCycleFocusTraversalKeys")</li>
  6514. * <li>this Component's preferred size ("preferredSize")</li>
  6515. * <li>this Component's minimum size ("minimumSize")</li>
  6516. * <li>this Component's maximum size ("maximumSize")</li>
  6517. * <li>this Component's name ("name")</li>
  6518. * </ul>
  6519. * Note that if this <code>Component</code> is inheriting a bound property, then no
  6520. * event will be fired in response to a change in the inherited property.
  6521. * <p>
  6522. * If <code>listener</code> is <code>null</code>,
  6523. * no exception is thrown and no action is performed.
  6524. *
  6525. * @param listener the property change listener to be added
  6526. *
  6527. * @see #removePropertyChangeListener
  6528. * @see #getPropertyChangeListeners
  6529. * @see #addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)
  6530. */
  6531. public synchronized void addPropertyChangeListener(
  6532. PropertyChangeListener listener) {
  6533. if (listener == null) {
  6534. return;
  6535. }
  6536. if (changeSupport == null) {
  6537. changeSupport = new PropertyChangeSupport(this);
  6538. }
  6539. changeSupport.addPropertyChangeListener(listener);
  6540. }
  6541. /**
  6542. * Removes a PropertyChangeListener from the listener list. This method
  6543. * should be used to remove PropertyChangeListeners that were registered
  6544. * for all bound properties of this class.
  6545. * <p>
  6546. * If listener is null, no exception is thrown and no action is performed.
  6547. *
  6548. * @param listener the PropertyChangeListener to be removed
  6549. *
  6550. * @see #addPropertyChangeListener
  6551. * @see #getPropertyChangeListeners
  6552. * @see #removePropertyChangeListener(java.lang.String,java.beans.PropertyChangeListener)
  6553. */
  6554. public synchronized void removePropertyChangeListener(
  6555. PropertyChangeListener listener) {
  6556. if (listener == null || changeSupport == null) {
  6557. return;
  6558. }
  6559. changeSupport.removePropertyChangeListener(listener);
  6560. }
  6561. /**
  6562. * Returns an array of all the property change listeners
  6563. * registered on this component.
  6564. *
  6565. * @return all of this component's <code>PropertyChangeListener</code>s
  6566. * or an empty array if no property change
  6567. * listeners are currently registered
  6568. *
  6569. * @see #addPropertyChangeListener
  6570. * @see #removePropertyChangeListener
  6571. * @see #getPropertyChangeListeners(java.lang.String)
  6572. * @see java.beans.PropertyChangeSupport#getPropertyChangeListeners
  6573. * @since 1.4
  6574. */
  6575. public synchronized PropertyChangeListener[] getPropertyChangeListeners() {
  6576. if (changeSupport == null) {
  6577. return new PropertyChangeListener[0];
  6578. }
  6579. return changeSupport.getPropertyChangeListeners();
  6580. }
  6581. /**
  6582. * Adds a PropertyChangeListener to the listener list for a specific
  6583. * property. The specified property may be user-defined, or one of the
  6584. * following:
  6585. * <ul>
  6586. * <li>this Component's font ("font")</li>
  6587. * <li>this Component's background color ("background")</li>
  6588. * <li>this Component's foreground color ("foreground")</li>
  6589. * <li>this Component's focusability ("focusable")</li>
  6590. * <li>this Component's focus traversal keys enabled state
  6591. * ("focusTraversalKeysEnabled")</li>
  6592. * <li>this Component's Set of FORWARD_TRAVERSAL_KEYS
  6593. * ("forwardFocusTraversalKeys")</li>
  6594. * <li>this Component's Set of BACKWARD_TRAVERSAL_KEYS
  6595. * ("backwardFocusTraversalKeys")</li>
  6596. * <li>this Component's Set of UP_CYCLE_TRAVERSAL_KEYS
  6597. * ("upCycleFocusTraversalKeys")</li>
  6598. * </ul>
  6599. * Note that if this <code>Component</code> is inheriting a bound property, then no
  6600. * event will be fired in response to a change in the inherited property.
  6601. * <p>
  6602. * If <code>propertyName</code> or <code>listener</code> is <code>null</code>,
  6603. * no exception is thrown and no action is taken.
  6604. *
  6605. * @param propertyName one of the property names listed above
  6606. * @param listener the property change listener to be added
  6607. *
  6608. * @see #removePropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)
  6609. * @see #getPropertyChangeListeners(java.lang.String)
  6610. * @see #addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)
  6611. */
  6612. public synchronized void addPropertyChangeListener(
  6613. String propertyName,
  6614. PropertyChangeListener listener) {
  6615. if (listener == null) {
  6616. return;
  6617. }
  6618. if (changeSupport == null) {
  6619. changeSupport = new PropertyChangeSupport(this);
  6620. }
  6621. changeSupport.addPropertyChangeListener(propertyName, listener);
  6622. }
  6623. /**
  6624. * Removes a <code>PropertyChangeListener</code> from the listener
  6625. * list for a specific property. This method should be used to remove
  6626. * <code>PropertyChangeListener</code>s
  6627. * that were registered for a specific bound property.
  6628. * <p>
  6629. * If <code>propertyName</code> or <code>listener</code> is <code>null</code>,
  6630. * no exception is thrown and no action is taken.
  6631. *
  6632. * @param propertyName a valid property name
  6633. * @param listener the PropertyChangeListener to be removed
  6634. *
  6635. * @see #addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)
  6636. * @see #getPropertyChangeListeners(java.lang.String)
  6637. * @see #removePropertyChangeListener(java.beans.PropertyChangeListener)
  6638. */
  6639. public synchronized void removePropertyChangeListener(
  6640. String propertyName,
  6641. PropertyChangeListener listener) {
  6642. if (listener == null || changeSupport == null) {
  6643. return;
  6644. }
  6645. changeSupport.removePropertyChangeListener(propertyName, listener);
  6646. }
  6647. /**
  6648. * Returns an array of all the listeners which have been associated
  6649. * with the named property.
  6650. *
  6651. * @return all of the <code>PropertyChangeListener</code>s associated with
  6652. * the named property; if no such listeners have been added or
  6653. * if <code>propertyName</code> is <code>null</code>, an empty
  6654. * array is returned
  6655. *
  6656. * @see #addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)
  6657. * @see #removePropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)
  6658. * @see #getPropertyChangeListeners
  6659. * @since 1.4
  6660. */
  6661. public synchronized PropertyChangeListener[] getPropertyChangeListeners(
  6662. String propertyName) {
  6663. if (changeSupport == null) {
  6664. return new PropertyChangeListener[0];
  6665. }
  6666. return changeSupport.getPropertyChangeListeners(propertyName);
  6667. }
  6668. /**
  6669. * Support for reporting bound property changes for Object properties.
  6670. * This method can be called when a bound property has changed and it will
  6671. * send the appropriate PropertyChangeEvent to any registered
  6672. * PropertyChangeListeners.
  6673. *
  6674. * @param propertyName the property whose value has changed
  6675. * @param oldValue the property's previous value
  6676. * @param newValue the property's new value
  6677. */
  6678. protected void firePropertyChange(String propertyName,
  6679. Object oldValue, Object newValue) {
  6680. PropertyChangeSupport changeSupport = this.changeSupport;
  6681. if (changeSupport == null ||
  6682. (oldValue != null && newValue != null && oldValue.equals(newValue))) {
  6683. return;
  6684. }
  6685. changeSupport.firePropertyChange(propertyName, oldValue, newValue);
  6686. }
  6687. /**
  6688. * Support for reporting bound property changes for boolean properties.
  6689. * This method can be called when a bound property has changed and it will
  6690. * send the appropriate PropertyChangeEvent to any registered
  6691. * PropertyChangeListeners.
  6692. *
  6693. * @param propertyName the property whose value has changed
  6694. * @param oldValue the property's previous value
  6695. * @param newValue the property's new value
  6696. */
  6697. protected void firePropertyChange(String propertyName,
  6698. boolean oldValue, boolean newValue) {
  6699. PropertyChangeSupport changeSupport = this.changeSupport;
  6700. if (changeSupport == null || oldValue == newValue) {
  6701. return;
  6702. }
  6703. changeSupport.firePropertyChange(propertyName, oldValue, newValue);
  6704. }
  6705. /**
  6706. * Support for reporting bound property changes for integer properties.
  6707. * This method can be called when a bound property has changed and it will
  6708. * send the appropriate PropertyChangeEvent to any registered
  6709. * PropertyChangeListeners.
  6710. *
  6711. * @param propertyName the property whose value has changed
  6712. * @param oldValue the property's previous value
  6713. * @param newValue the property's new value
  6714. */
  6715. protected void firePropertyChange(String propertyName,
  6716. int oldValue, int newValue) {
  6717. PropertyChangeSupport changeSupport = this.changeSupport;
  6718. if (changeSupport == null || oldValue == newValue) {
  6719. return;
  6720. }
  6721. changeSupport.firePropertyChange(propertyName, oldValue, newValue);
  6722. }
  6723. /**
  6724. * Reports a bound property change.
  6725. *
  6726. * @param propertyName the programmatic name of the property
  6727. * that was changed
  6728. * @param oldValue the old value of the property (as a byte)
  6729. * @param newValue the new value of the property (as a byte)
  6730. * @see #firePropertyChange(java.lang.String, java.lang.Object,
  6731. * java.lang.Object)
  6732. * @since 1.5
  6733. */
  6734. public void firePropertyChange(String propertyName, byte oldValue, byte newValue) {
  6735. if (changeSupport == null || oldValue == newValue) {
  6736. return;
  6737. }
  6738. firePropertyChange(propertyName, new Byte(oldValue), new Byte(newValue));
  6739. }
  6740. /**
  6741. * Reports a bound property change.
  6742. *
  6743. * @param propertyName the programmatic name of the property
  6744. * that was changed
  6745. * @param oldValue the old value of the property (as a char)
  6746. * @param newValue the new value of the property (as a char)
  6747. * @see #firePropertyChange(java.lang.String, java.lang.Object,
  6748. * java.lang.Object)
  6749. * @since 1.5
  6750. */
  6751. public void firePropertyChange(String propertyName, char oldValue, char newValue) {
  6752. if (changeSupport == null || oldValue == newValue) {
  6753. return;
  6754. }
  6755. firePropertyChange(propertyName, new Character(oldValue), new Character(newValue));
  6756. }
  6757. /**
  6758. * Reports a bound property change.
  6759. *
  6760. * @param propertyName the programmatic name of the property
  6761. * that was changed
  6762. * @param oldValue the old value of the property (as a short)
  6763. * @param newValue the old value of the property (as a short)
  6764. * @see #firePropertyChange(java.lang.String, java.lang.Object,
  6765. * java.lang.Object)
  6766. * @since 1.5
  6767. */
  6768. public void firePropertyChange(String propertyName, short oldValue, short newValue) {
  6769. if (changeSupport == null || oldValue == newValue) {
  6770. return;
  6771. }
  6772. firePropertyChange(propertyName, new Short(oldValue), new Short(newValue));
  6773. }
  6774. /**
  6775. * Reports a bound property change.
  6776. *
  6777. * @param propertyName the programmatic name of the property
  6778. * that was changed
  6779. * @param oldValue the old value of the property (as a long)
  6780. * @param newValue the new value of the property (as a long)
  6781. * @see #firePropertyChange(java.lang.String, java.lang.Object,
  6782. * java.lang.Object)
  6783. * @since 1.5
  6784. */
  6785. public void firePropertyChange(String propertyName, long oldValue, long newValue) {
  6786. if (changeSupport == null || oldValue == newValue) {
  6787. return;
  6788. }
  6789. firePropertyChange(propertyName, new Long(oldValue), new Long(newValue));
  6790. }
  6791. /**
  6792. * Reports a bound property change.
  6793. *
  6794. * @param propertyName the programmatic name of the property
  6795. * that was changed
  6796. * @param oldValue the old value of the property (as a float)
  6797. * @param newValue the new value of the property (as a float)
  6798. * @see #firePropertyChange(java.lang.String, java.lang.Object,
  6799. * java.lang.Object)
  6800. * @since 1.5
  6801. */
  6802. public void firePropertyChange(String propertyName, float oldValue, float newValue) {
  6803. if (changeSupport == null || oldValue == newValue) {
  6804. return;
  6805. }
  6806. firePropertyChange(propertyName, new Float(oldValue), new Float(newValue));
  6807. }
  6808. /**
  6809. * Reports a bound property change.
  6810. *
  6811. * @param propertyName the programmatic name of the property
  6812. * that was changed
  6813. * @param oldValue the old value of the property (as a double)
  6814. * @param newValue the new value of the property (as a double)
  6815. * @see #firePropertyChange(java.lang.String, java.lang.Object,
  6816. * java.lang.Object)
  6817. * @since 1.5
  6818. */
  6819. public void firePropertyChange(String propertyName, double oldValue, double newValue) {
  6820. if (changeSupport == null || oldValue == newValue) {
  6821. return;
  6822. }
  6823. firePropertyChange(propertyName, new Double(oldValue), new Double(newValue));
  6824. }
  6825. // Serialization support.
  6826. /**
  6827. * Component Serialized Data Version.
  6828. *
  6829. * @serial
  6830. */
  6831. private int componentSerializedDataVersion = 4;
  6832. /**
  6833. * This hack is for Swing serialization. It will invoke
  6834. * the Swing package private method <code>compWriteObjectNotify</code>.
  6835. */
  6836. private void doSwingSerialization() {
  6837. Package swingPackage = Package.getPackage("javax.swing");
  6838. // Find the first Swing class. Swing classes MUST be loaded by
  6839. // the bootstrap class loader, otherwise we don't consider them.
  6840. Class klass = Component.this.getClass();
  6841. while (klass != null && klass.getPackage() != swingPackage &&
  6842. klass.getClassLoader() == null) {
  6843. klass = klass.getSuperclass();
  6844. }
  6845. while (klass != null && klass.getClassLoader() == null) {
  6846. if (klass.getPackage() == swingPackage) {
  6847. final Class swingClass = klass;
  6848. // Find the first override of the compWriteObjectNotify method
  6849. Method[] methods = (Method[])AccessController.doPrivileged(
  6850. new PrivilegedAction() {
  6851. public Object run() {
  6852. return swingClass.getDeclaredMethods();
  6853. }
  6854. });
  6855. for (int counter = methods.length - 1; counter >= 0;
  6856. counter--) {
  6857. final Method method = methods[counter];
  6858. if (method.getName().equals("compWriteObjectNotify")){
  6859. // We found it, use doPrivileged to make it accessible
  6860. // to use.
  6861. AccessController.doPrivileged(new PrivilegedAction() {
  6862. public Object run() {
  6863. method.setAccessible(true);
  6864. return null;
  6865. }
  6866. });
  6867. // Invoke the method
  6868. try {
  6869. method.invoke(this, null);
  6870. } catch (IllegalAccessException iae) {
  6871. } catch (InvocationTargetException ite) {
  6872. }
  6873. // We're done, bail.
  6874. return;
  6875. }
  6876. }
  6877. }
  6878. klass = klass.getSuperclass();
  6879. }
  6880. }
  6881. /**
  6882. * Writes default serializable fields to stream. Writes
  6883. * a variety of serializable listeners as optional data.
  6884. * The non-serializable listeners are detected and
  6885. * no attempt is made to serialize them.
  6886. *
  6887. * @param s the <code>ObjectOutputStream</code> to write
  6888. * @serialData <code>null</code> terminated sequence of
  6889. * 0 or more pairs; the pair consists of a <code>String</code>
  6890. * and an <code>Object</code> the <code>String</code> indicates
  6891. * the type of object and is one of the following (as of 1.4):
  6892. * <code>componentListenerK</code> indicating an
  6893. * <code>ComponentListener</code> object;
  6894. * <code>focusListenerK</code> indicating an
  6895. * <code>FocusListener</code> object;
  6896. * <code>keyListenerK</code> indicating an
  6897. * <code>KeyListener</code> object;
  6898. * <code>mouseListenerK</code> indicating an
  6899. * <code>MouseListener</code> object;
  6900. * <code>mouseMotionListenerK</code> indicating an
  6901. * <code>MouseMotionListener</code> object;
  6902. * <code>inputListenerK</code> indicating an
  6903. * <code>InputListener</code> object;
  6904. * <code>hierarchyListenerK</code> indicating an
  6905. * <code>HierarchyListener</code> object;
  6906. * <code>hierarchyBoundsListenerK</code> indicating an
  6907. * <code>HierarchyBoundsListener</code> object;
  6908. * <code>mouseWheelListenerK</code> indicating an
  6909. * <code>MouseWheelListener</code> object
  6910. * @serialData an optional <code>ComponentOrientation</code>
  6911. * (after <code>inputMethodListener</code>, as of 1.2)
  6912. *
  6913. * @see AWTEventMulticaster#save(java.io.ObjectOutputStream, java.lang.String, java.util.EventListener)
  6914. * @see #componentListenerK
  6915. * @see #focusListenerK
  6916. * @see #keyListenerK
  6917. * @see #mouseListenerK
  6918. * @see #mouseMotionListenerK
  6919. * @see #inputListenerK
  6920. * @see #hierarchyListenerK
  6921. * @see #hierarchyBoundsListenerK
  6922. * @see #mouseWheelListenerK
  6923. * @see #readObject(ObjectInputStream)
  6924. */
  6925. private void writeObject(ObjectOutputStream s)
  6926. throws IOException
  6927. {
  6928. doSwingSerialization();
  6929. s.defaultWriteObject();
  6930. AWTEventMulticaster.save(s, componentListenerK, componentListener);
  6931. AWTEventMulticaster.save(s, focusListenerK, focusListener);
  6932. AWTEventMulticaster.save(s, keyListenerK, keyListener);
  6933. AWTEventMulticaster.save(s, mouseListenerK, mouseListener);
  6934. AWTEventMulticaster.save(s, mouseMotionListenerK, mouseMotionListener);
  6935. AWTEventMulticaster.save(s, inputMethodListenerK, inputMethodListener);
  6936. s.writeObject(null);
  6937. s.writeObject(componentOrientation);
  6938. AWTEventMulticaster.save(s, hierarchyListenerK, hierarchyListener);
  6939. AWTEventMulticaster.save(s, hierarchyBoundsListenerK,
  6940. hierarchyBoundsListener);
  6941. s.writeObject(null);
  6942. AWTEventMulticaster.save(s, mouseWheelListenerK, mouseWheelListener);
  6943. s.writeObject(null);
  6944. }
  6945. /**
  6946. * Reads the <code>ObjectInputStream</code> and if it isn't
  6947. * <code>null</code> adds a listener to receive a variety
  6948. * of events fired by the component.
  6949. * Unrecognized keys or values will be ignored.
  6950. *
  6951. * @param s the <code>ObjectInputStream</code> to read
  6952. * @see #writeObject(ObjectOutputStream)
  6953. */
  6954. private void readObject(ObjectInputStream s)
  6955. throws ClassNotFoundException, IOException
  6956. {
  6957. s.defaultReadObject();
  6958. privateKey = new Object();
  6959. appContext = AppContext.getAppContext();
  6960. if (componentSerializedDataVersion < 4) {
  6961. // These fields are non-transient and rely on default
  6962. // serialization. However, the default values are insufficient,
  6963. // so we need to set them explicitly for object data streams prior
  6964. // to 1.4.
  6965. focusable = true;
  6966. isFocusTraversableOverridden = FOCUS_TRAVERSABLE_UNKNOWN;
  6967. initializeFocusTraversalKeys();
  6968. focusTraversalKeysEnabled = true;
  6969. }
  6970. Object keyOrNull;
  6971. while(null != (keyOrNull = s.readObject())) {
  6972. String key = ((String)keyOrNull).intern();
  6973. if (componentListenerK == key)
  6974. addComponentListener((ComponentListener)(s.readObject()));
  6975. else if (focusListenerK == key)
  6976. addFocusListener((FocusListener)(s.readObject()));
  6977. else if (keyListenerK == key)
  6978. addKeyListener((KeyListener)(s.readObject()));
  6979. else if (mouseListenerK == key)
  6980. addMouseListener((MouseListener)(s.readObject()));
  6981. else if (mouseMotionListenerK == key)
  6982. addMouseMotionListener((MouseMotionListener)(s.readObject()));
  6983. else if (inputMethodListenerK == key)
  6984. addInputMethodListener((InputMethodListener)(s.readObject()));
  6985. else // skip value for unrecognized key
  6986. s.readObject();
  6987. }
  6988. // Read the component's orientation if it's present
  6989. Object orient = null;
  6990. try {
  6991. orient = s.readObject();
  6992. } catch (java.io.OptionalDataException e) {
  6993. // JDK 1.1 instances will not have this optional data.
  6994. // e.eof will be true to indicate that there is no more
  6995. // data available for this object.
  6996. // If e.eof is not true, throw the exception as it
  6997. // might have been caused by reasons unrelated to
  6998. // componentOrientation.
  6999. if (!e.eof) {
  7000. throw (e);
  7001. }
  7002. }
  7003. if (orient != null) {
  7004. componentOrientation = (ComponentOrientation)orient;
  7005. } else {
  7006. componentOrientation = ComponentOrientation.UNKNOWN;
  7007. }
  7008. try {
  7009. while(null != (keyOrNull = s.readObject())) {
  7010. String key = ((String)keyOrNull).intern();
  7011. if (hierarchyListenerK == key) {
  7012. addHierarchyListener((HierarchyListener)(s.readObject()));
  7013. }
  7014. else if (hierarchyBoundsListenerK == key) {
  7015. addHierarchyBoundsListener((HierarchyBoundsListener)
  7016. (s.readObject()));
  7017. }
  7018. else {
  7019. // skip value for unrecognized key
  7020. s.readObject();
  7021. }
  7022. }
  7023. } catch (java.io.OptionalDataException e) {
  7024. // JDK 1.1/1.2 instances will not have this optional data.
  7025. // e.eof will be true to indicate that there is no more
  7026. // data available for this object.
  7027. // If e.eof is not true, throw the exception as it
  7028. // might have been caused by reasons unrelated to
  7029. // hierarchy and hierarchyBounds listeners.
  7030. if (!e.eof) {
  7031. throw (e);
  7032. }
  7033. }
  7034. try {
  7035. while (null != (keyOrNull = s.readObject())) {
  7036. String key = ((String)keyOrNull).intern();
  7037. if (mouseWheelListenerK == key) {
  7038. addMouseWheelListener((MouseWheelListener)(s.readObject()));
  7039. }
  7040. else {
  7041. // skip value for unrecognized key
  7042. s.readObject();
  7043. }
  7044. }
  7045. } catch (java.io.OptionalDataException e) {
  7046. // pre-1.3 instances will not have this optional data.
  7047. // e.eof will be true to indicate that there is no more
  7048. // data available for this object.
  7049. // If e.eof is not true, throw the exception as it
  7050. // might have been caused by reasons unrelated to
  7051. // mouse wheel listeners
  7052. if (!e.eof) {
  7053. throw (e);
  7054. }
  7055. }
  7056. if (popups != null) {
  7057. int npopups = popups.size();
  7058. for (int i = 0 ; i < npopups ; i++) {
  7059. PopupMenu popup = (PopupMenu)popups.elementAt(i);
  7060. popup.parent = this;
  7061. }
  7062. }
  7063. }
  7064. /**
  7065. * Sets the language-sensitive orientation that is to be used to order
  7066. * the elements or text within this component. Language-sensitive
  7067. * <code>LayoutManager</code> and <code>Component</code>
  7068. * subclasses will use this property to
  7069. * determine how to lay out and draw components.
  7070. * <p>
  7071. * At construction time, a component's orientation is set to
  7072. * <code>ComponentOrientation.UNKNOWN</code>,
  7073. * indicating that it has not been specified
  7074. * explicitly. The UNKNOWN orientation behaves the same as
  7075. * <code>ComponentOrientation.LEFT_TO_RIGHT</code>.
  7076. * <p>
  7077. * To set the orientation of a single component, use this method.
  7078. * To set the orientation of an entire component
  7079. * hierarchy, use
  7080. * {@link #applyComponentOrientation applyComponentOrientation}.
  7081. *
  7082. * @see ComponentOrientation
  7083. *
  7084. * @author Laura Werner, IBM
  7085. * @beaninfo
  7086. * bound: true
  7087. */
  7088. public void setComponentOrientation(ComponentOrientation o) {
  7089. ComponentOrientation oldValue = componentOrientation;
  7090. componentOrientation = o;
  7091. // This is a bound property, so report the change to
  7092. // any registered listeners. (Cheap if there are none.)
  7093. firePropertyChange("componentOrientation", oldValue, o);
  7094. // This could change the preferred size of the Component.
  7095. if (valid) {
  7096. invalidate();
  7097. }
  7098. }
  7099. /**
  7100. * Retrieves the language-sensitive orientation that is to be used to order
  7101. * the elements or text within this component. <code>LayoutManager</code>
  7102. * and <code>Component</code>
  7103. * subclasses that wish to respect orientation should call this method to
  7104. * get the component's orientation before performing layout or drawing.
  7105. *
  7106. * @see ComponentOrientation
  7107. *
  7108. * @author Laura Werner, IBM
  7109. */
  7110. public ComponentOrientation getComponentOrientation() {
  7111. return componentOrientation;
  7112. }
  7113. /**
  7114. * Sets the <code>ComponentOrientation</code> property of this component
  7115. * and all components contained within it.
  7116. *
  7117. * @param orientation the new component orientation of this component and
  7118. * the components contained within it.
  7119. * @exception NullPointerException if <code>orientation</code> is null.
  7120. * @see #setComponentOrientation
  7121. * @see #getComponentOrientation
  7122. * @since 1.4
  7123. */
  7124. public void applyComponentOrientation(ComponentOrientation orientation) {
  7125. if (orientation == null) {
  7126. throw new NullPointerException();
  7127. }
  7128. setComponentOrientation(orientation);
  7129. }
  7130. transient NativeInLightFixer nativeInLightFixer;
  7131. /**
  7132. * Checks that this component meets the prerequesites to be focus owner:
  7133. * - it is enabled, visible, focusable
  7134. * - it's parents are all enabled and showing
  7135. * - top-level window is focusable
  7136. * - if focus cycle root has DefaultFocusTraversalPolicy then it also checks that this policy accepts
  7137. * this component as focus owner
  7138. * @since 1.5
  7139. */
  7140. final boolean canBeFocusOwner() {
  7141. // - it is enabled, visible, focusable
  7142. if (!(isEnabled() && isDisplayable() && isVisible() && isFocusable())) {
  7143. return false;
  7144. }
  7145. // - it's parents are all enabled and showing
  7146. synchronized(getTreeLock()) {
  7147. if (parent != null) {
  7148. return parent.canContainFocusOwner(this);
  7149. }
  7150. }
  7151. return true;
  7152. }
  7153. /**
  7154. * This odd class is to help out a native component that has been
  7155. * embedded in a lightweight component. Moving lightweight
  7156. * components around and changing their visibility is not seen
  7157. * by the native window system. This is a feature for lightweights,
  7158. * but a problem for native components that depend upon the
  7159. * lightweights. An instance of this class listens to the lightweight
  7160. * parents of an associated native component (the outer class).
  7161. *
  7162. * @author Timothy Prinzing
  7163. */
  7164. final class NativeInLightFixer implements ComponentListener, ContainerListener {
  7165. NativeInLightFixer() {
  7166. lightParents = new Vector();
  7167. install(parent);
  7168. }
  7169. void install(Container parent) {
  7170. lightParents.clear();
  7171. Container p = parent;
  7172. boolean isLwParentsVisible = true;
  7173. // stash a reference to the components that are being observed so that
  7174. // we can reliably remove ourself as a listener later.
  7175. for (; p.peer instanceof LightweightPeer; p = p.parent) {
  7176. // register listeners and stash a reference
  7177. p.addComponentListener(this);
  7178. p.addContainerListener(this);
  7179. lightParents.addElement(p);
  7180. isLwParentsVisible &= p.isVisible();
  7181. }
  7182. // register with the native host (native parent of associated native)
  7183. // to get notified if the top-level lightweight is removed.
  7184. nativeHost = p;
  7185. p.addContainerListener(this);
  7186. // kick start the fixup. Since the event isn't looked at
  7187. // we can simulate movement notification.
  7188. componentMoved(null);
  7189. if (!isLwParentsVisible) {
  7190. synchronized (getTreeLock()) {
  7191. if (peer != null) {
  7192. peer.hide();
  7193. }
  7194. }
  7195. }
  7196. }
  7197. // --- ComponentListener -------------------------------------------
  7198. /**
  7199. * Invoked when one of the lightweight parents has been resized.
  7200. * This doesn't change the position of the native child so it
  7201. * is ignored.
  7202. */
  7203. public void componentResized(ComponentEvent e) {
  7204. }
  7205. /**
  7206. * Invoked when one of the lightweight parents has been moved.
  7207. * The native peer must be told of the new position which is
  7208. * relative to the native container that is hosting the
  7209. * lightweight components.
  7210. */
  7211. public void componentMoved(ComponentEvent e) {
  7212. synchronized (getTreeLock()) {
  7213. int nativeX = x;
  7214. int nativeY = y;
  7215. for(Component c = parent; (c != null) &&
  7216. (c.peer instanceof LightweightPeer);
  7217. c = c.parent) {
  7218. nativeX += c.x;
  7219. nativeY += c.y;
  7220. }
  7221. if (peer != null) {
  7222. peer.setBounds(nativeX, nativeY, width, height,
  7223. ComponentPeer.SET_LOCATION);
  7224. }
  7225. }
  7226. }
  7227. /**
  7228. * Invoked when a lightweight parent component has been
  7229. * shown. The associated native component must also be
  7230. * shown if it hasn't had an overriding hide done on it.
  7231. */
  7232. public void componentShown(ComponentEvent e) {
  7233. if (isShowing()) {
  7234. synchronized (getTreeLock()) {
  7235. if (peer != null) {
  7236. peer.show();
  7237. }
  7238. }
  7239. }
  7240. }
  7241. /**
  7242. * Invoked when component has been hidden.
  7243. */
  7244. public void componentHidden(ComponentEvent e) {
  7245. if (visible) {
  7246. synchronized (getTreeLock()) {
  7247. if (peer != null) {
  7248. peer.hide();
  7249. }
  7250. }
  7251. }
  7252. }
  7253. // --- ContainerListener ------------------------------------
  7254. /**
  7255. * Invoked when a component has been added to a lightweight
  7256. * parent. This doesn't effect the native component.
  7257. */
  7258. public void componentAdded(ContainerEvent e) {
  7259. }
  7260. /**
  7261. * Invoked when a lightweight parent has been removed.
  7262. * This means the services of this listener are no longer
  7263. * required and it should remove all references (ie
  7264. * registered listeners).
  7265. */
  7266. public void componentRemoved(ContainerEvent e) {
  7267. Component c = e.getChild();
  7268. if (c == Component.this) {
  7269. removeReferences();
  7270. } else {
  7271. int n = lightParents.size();
  7272. for (int i = 0; i < n; i++) {
  7273. Container p = (Container) lightParents.elementAt(i);
  7274. if (p == c) {
  7275. removeReferences();
  7276. break;
  7277. }
  7278. }
  7279. }
  7280. }
  7281. /**
  7282. * Removes references to this object so it can be
  7283. * garbage collected.
  7284. */
  7285. void removeReferences() {
  7286. int n = lightParents.size();
  7287. for (int i = 0; i < n; i++) {
  7288. Container c = (Container) lightParents.elementAt(i);
  7289. c.removeComponentListener(this);
  7290. c.removeContainerListener(this);
  7291. }
  7292. nativeHost.removeContainerListener(this);
  7293. lightParents.clear();
  7294. nativeHost = null;
  7295. }
  7296. Vector lightParents;
  7297. Container nativeHost;
  7298. }
  7299. /**
  7300. * Returns the <code>Window</code> ancestor of the component.
  7301. * @return Window ancestor of the component or component by itself if it is Window;
  7302. * null, if component is not a part of window hierarchy
  7303. */
  7304. Window getContainingWindow() {
  7305. return getContainingWindow(this);
  7306. }
  7307. /**
  7308. * Returns the <code>Window</code> ancestor of the component <code>comp</comp>.
  7309. * @return Window ancestor of the component or component by itself if it is Window;
  7310. * null, if component is not a part of window hierarchy
  7311. */
  7312. static Window getContainingWindow(Component comp) {
  7313. while (comp != null && !(comp instanceof Window)) {
  7314. comp = comp.getParent();
  7315. }
  7316. return (Window)comp;
  7317. }
  7318. /**
  7319. * Initialize JNI field and method IDs
  7320. */
  7321. private static native void initIDs();
  7322. /*
  7323. * --- Accessibility Support ---
  7324. *
  7325. * Component will contain all of the methods in interface Accessible,
  7326. * though it won't actually implement the interface - that will be up
  7327. * to the individual objects which extend Component.
  7328. */
  7329. AccessibleContext accessibleContext = null;
  7330. /**
  7331. * Gets the <code>AccessibleContext</code> associated
  7332. * with this <code>Component</code>.
  7333. * The method implemented by this base
  7334. * class returns null. Classes that extend <code>Component</code>
  7335. * should implement this method to return the
  7336. * <code>AccessibleContext</code> associated with the subclass.
  7337. *
  7338. *
  7339. * @return the <code>AccessibleContext</code> of this
  7340. * <code>Component</code>
  7341. */
  7342. public AccessibleContext getAccessibleContext() {
  7343. return accessibleContext;
  7344. }
  7345. /**
  7346. * Inner class of Component used to provide default support for
  7347. * accessibility. This class is not meant to be used directly by
  7348. * application developers, but is instead meant only to be
  7349. * subclassed by component developers.
  7350. * <p>
  7351. * The class used to obtain the accessible role for this object.
  7352. */
  7353. protected abstract class AccessibleAWTComponent extends AccessibleContext
  7354. implements Serializable, AccessibleComponent {
  7355. private static final long serialVersionUID = 642321655757800191L;
  7356. /**
  7357. * Though the class is abstract, this should be called by
  7358. * all sub-classes.
  7359. */
  7360. protected AccessibleAWTComponent() {
  7361. }
  7362. protected ComponentListener accessibleAWTComponentHandler = null;
  7363. protected FocusListener accessibleAWTFocusHandler = null;
  7364. /**
  7365. * Fire PropertyChange listener, if one is registered,
  7366. * when shown/hidden..
  7367. */
  7368. protected class AccessibleAWTComponentHandler implements ComponentListener {
  7369. public void componentHidden(ComponentEvent e) {
  7370. if (accessibleContext != null) {
  7371. accessibleContext.firePropertyChange(
  7372. AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
  7373. AccessibleState.VISIBLE, null);
  7374. }
  7375. }
  7376. public void componentShown(ComponentEvent e) {
  7377. if (accessibleContext != null) {
  7378. accessibleContext.firePropertyChange(
  7379. AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
  7380. null, AccessibleState.VISIBLE);
  7381. }
  7382. }
  7383. public void componentMoved(ComponentEvent e) {
  7384. }
  7385. public void componentResized(ComponentEvent e) {
  7386. }
  7387. } // inner class AccessibleAWTComponentHandler
  7388. /**
  7389. * Fire PropertyChange listener, if one is registered,
  7390. * when focus events happen
  7391. */
  7392. protected class AccessibleAWTFocusHandler implements FocusListener {
  7393. public void focusGained(FocusEvent event) {
  7394. if (accessibleContext != null) {
  7395. accessibleContext.firePropertyChange(
  7396. AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
  7397. null, AccessibleState.FOCUSED);
  7398. }
  7399. }
  7400. public void focusLost(FocusEvent event) {
  7401. if (accessibleContext != null) {
  7402. accessibleContext.firePropertyChange(
  7403. AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
  7404. AccessibleState.FOCUSED, null);
  7405. }
  7406. }
  7407. } // inner class AccessibleAWTFocusHandler
  7408. /**
  7409. * Adds a <code>PropertyChangeListener</code> to the listener list.
  7410. *
  7411. * @param listener the property change listener to be added
  7412. */
  7413. public void addPropertyChangeListener(PropertyChangeListener listener) {
  7414. if (accessibleAWTComponentHandler == null) {
  7415. accessibleAWTComponentHandler = new AccessibleAWTComponentHandler();
  7416. Component.this.addComponentListener(accessibleAWTComponentHandler);
  7417. }
  7418. if (accessibleAWTFocusHandler == null) {
  7419. accessibleAWTFocusHandler = new AccessibleAWTFocusHandler();
  7420. Component.this.addFocusListener(accessibleAWTFocusHandler);
  7421. }
  7422. super.addPropertyChangeListener(listener);
  7423. }
  7424. /**
  7425. * Remove a PropertyChangeListener from the listener list.
  7426. * This removes a PropertyChangeListener that was registered
  7427. * for all properties.
  7428. *
  7429. * @param listener The PropertyChangeListener to be removed
  7430. */
  7431. public void removePropertyChangeListener(PropertyChangeListener listener) {
  7432. if (accessibleAWTComponentHandler != null) {
  7433. Component.this.removeComponentListener(accessibleAWTComponentHandler);
  7434. accessibleAWTComponentHandler = null;
  7435. }
  7436. if (accessibleAWTFocusHandler != null) {
  7437. Component.this.removeFocusListener(accessibleAWTFocusHandler);
  7438. accessibleAWTFocusHandler = null;
  7439. }
  7440. super.removePropertyChangeListener(listener);
  7441. }
  7442. // AccessibleContext methods
  7443. //
  7444. /**
  7445. * Gets the accessible name of this object. This should almost never
  7446. * return <code>java.awt.Component.getName()</code>,
  7447. * as that generally isn't a localized name,
  7448. * and doesn't have meaning for the user. If the
  7449. * object is fundamentally a text object (e.g. a menu item), the
  7450. * accessible name should be the text of the object (e.g. "save").
  7451. * If the object has a tooltip, the tooltip text may also be an
  7452. * appropriate String to return.
  7453. *
  7454. * @return the localized name of the object -- can be
  7455. * <code>null</code> if this
  7456. * object does not have a name
  7457. * @see javax.accessibility.AccessibleContext#setAccessibleName
  7458. */
  7459. public String getAccessibleName() {
  7460. return accessibleName;
  7461. }
  7462. /**
  7463. * Gets the accessible description of this object. This should be
  7464. * a concise, localized description of what this object is - what
  7465. * is its meaning to the user. If the object has a tooltip, the
  7466. * tooltip text may be an appropriate string to return, assuming
  7467. * it contains a concise description of the object (instead of just
  7468. * the name of the object - e.g. a "Save" icon on a toolbar that
  7469. * had "save" as the tooltip text shouldn't return the tooltip
  7470. * text as the description, but something like "Saves the current
  7471. * text document" instead).
  7472. *
  7473. * @return the localized description of the object -- can be
  7474. * <code>null</code> if this object does not have a description
  7475. * @see javax.accessibility.AccessibleContext#setAccessibleDescription
  7476. */
  7477. public String getAccessibleDescription() {
  7478. return accessibleDescription;
  7479. }
  7480. /**
  7481. * Gets the role of this object.
  7482. *
  7483. * @return an instance of <code>AccessibleRole</code>
  7484. * describing the role of the object
  7485. * @see javax.accessibility.AccessibleRole
  7486. */
  7487. public AccessibleRole getAccessibleRole() {
  7488. return AccessibleRole.AWT_COMPONENT;
  7489. }
  7490. /**
  7491. * Gets the state of this object.
  7492. *
  7493. * @return an instance of <code>AccessibleStateSet</code>
  7494. * containing the current state set of the object
  7495. * @see javax.accessibility.AccessibleState
  7496. */
  7497. public AccessibleStateSet getAccessibleStateSet() {
  7498. return Component.this.getAccessibleStateSet();
  7499. }
  7500. /**
  7501. * Gets the <code>Accessible</code> parent of this object.
  7502. * If the parent of this object implements <code>Accessible</code>,
  7503. * this method should simply return <code>getParent</code>.
  7504. *
  7505. * @return the <code>Accessible</code> parent of this
  7506. * object -- can be <code>null</code> if this
  7507. * object does not have an <code>Accessible</code> parent
  7508. */
  7509. public Accessible getAccessibleParent() {
  7510. if (accessibleParent != null) {
  7511. return accessibleParent;
  7512. } else {
  7513. Container parent = getParent();
  7514. if (parent instanceof Accessible) {
  7515. return (Accessible) parent;
  7516. }
  7517. }
  7518. return null;
  7519. }
  7520. /**
  7521. * Gets the index of this object in its accessible parent.
  7522. *
  7523. * @return the index of this object in its parent; or -1 if this
  7524. * object does not have an accessible parent
  7525. * @see #getAccessibleParent
  7526. */
  7527. public int getAccessibleIndexInParent() {
  7528. return Component.this.getAccessibleIndexInParent();
  7529. }
  7530. /**
  7531. * Returns the number of accessible children in the object. If all
  7532. * of the children of this object implement <code>Accessible</code>,
  7533. * then this method should return the number of children of this object.
  7534. *
  7535. * @return the number of accessible children in the object
  7536. */
  7537. public int getAccessibleChildrenCount() {
  7538. return 0; // Components don't have children
  7539. }
  7540. /**
  7541. * Returns the nth <code>Accessible</code> child of the object.
  7542. *
  7543. * @param i zero-based index of child
  7544. * @return the nth <code>Accessible</code> child of the object
  7545. */
  7546. public Accessible getAccessibleChild(int i) {
  7547. return null; // Components don't have children
  7548. }
  7549. /**
  7550. * Returns the locale of this object.
  7551. *
  7552. * @return the locale of this object
  7553. */
  7554. public Locale getLocale() {
  7555. return Component.this.getLocale();
  7556. }
  7557. /**
  7558. * Gets the <code>AccessibleComponent</code> associated
  7559. * with this object if one exists.
  7560. * Otherwise return <code>null</code>.
  7561. *
  7562. * @return the component
  7563. */
  7564. public AccessibleComponent getAccessibleComponent() {
  7565. return this;
  7566. }
  7567. // AccessibleComponent methods
  7568. //
  7569. /**
  7570. * Gets the background color of this object.
  7571. *
  7572. * @return the background color, if supported, of the object;
  7573. * otherwise, <code>null</code>
  7574. */
  7575. public Color getBackground() {
  7576. return Component.this.getBackground();
  7577. }
  7578. /**
  7579. * Sets the background color of this object.
  7580. * (For transparency, see <code>isOpaque</code>.)
  7581. *
  7582. * @param c the new <code>Color</code> for the background
  7583. * @see Component#isOpaque
  7584. */
  7585. public void setBackground(Color c) {
  7586. Component.this.setBackground(c);
  7587. }
  7588. /**
  7589. * Gets the foreground color of this object.
  7590. *
  7591. * @return the foreground color, if supported, of the object;
  7592. * otherwise, <code>null</code>
  7593. */
  7594. public Color getForeground() {
  7595. return Component.this.getForeground();
  7596. }
  7597. /**
  7598. * Sets the foreground color of this object.
  7599. *
  7600. * @param c the new <code>Color</code> for the foreground
  7601. */
  7602. public void setForeground(Color c) {
  7603. Component.this.setForeground(c);
  7604. }
  7605. /**
  7606. * Gets the <code>Cursor</code> of this object.
  7607. *
  7608. * @return the <code>Cursor</code>, if supported,
  7609. * of the object; otherwise, <code>null</code>
  7610. */
  7611. public Cursor getCursor() {
  7612. return Component.this.getCursor();
  7613. }
  7614. /**
  7615. * Sets the <code>Cursor</code> of this object.
  7616. *
  7617. * @param cursor the new <code>Cursor</code> for the object
  7618. */
  7619. public void setCursor(Cursor cursor) {
  7620. Component.this.setCursor(cursor);
  7621. }
  7622. /**
  7623. * Gets the <code>Font</code> of this object.
  7624. *
  7625. * @return the <code>Font</code>, if supported,
  7626. * for the object; otherwise, <code>null</code>
  7627. */
  7628. public Font getFont() {
  7629. return Component.this.getFont();
  7630. }
  7631. /**
  7632. * Sets the <code>Font</code> of this object.
  7633. *
  7634. * @param f the new <code>Font</code> for the object
  7635. */
  7636. public void setFont(Font f) {
  7637. Component.this.setFont(f);
  7638. }
  7639. /**
  7640. * Gets the <code>FontMetrics</code> of this object.
  7641. *
  7642. * @param f the <code>Font</code>
  7643. * @return the <code>FontMetrics</code>, if supported,
  7644. * the object; otherwise, <code>null</code>
  7645. * @see #getFont
  7646. */
  7647. public FontMetrics getFontMetrics(Font f) {
  7648. if (f == null) {
  7649. return null;
  7650. } else {
  7651. return Component.this.getFontMetrics(f);
  7652. }
  7653. }
  7654. /**
  7655. * Determines if the object is enabled.
  7656. *
  7657. * @return true if object is enabled; otherwise, false
  7658. */
  7659. public boolean isEnabled() {
  7660. return Component.this.isEnabled();
  7661. }
  7662. /**
  7663. * Sets the enabled state of the object.
  7664. *
  7665. * @param b if true, enables this object; otherwise, disables it
  7666. */
  7667. public void setEnabled(boolean b) {
  7668. boolean old = Component.this.isEnabled();
  7669. Component.this.setEnabled(b);
  7670. if (b != old) {
  7671. if (accessibleContext != null) {
  7672. if (b) {
  7673. accessibleContext.firePropertyChange(
  7674. AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
  7675. null, AccessibleState.ENABLED);
  7676. } else {
  7677. accessibleContext.firePropertyChange(
  7678. AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
  7679. AccessibleState.ENABLED, null);
  7680. }
  7681. }
  7682. }
  7683. }
  7684. /**
  7685. * Determines if the object is visible. Note: this means that the
  7686. * object intends to be visible; however, it may not in fact be
  7687. * showing on the screen because one of the objects that this object
  7688. * is contained by is not visible. To determine if an object is
  7689. * showing on the screen, use <code>isShowing</code>.
  7690. *
  7691. * @return true if object is visible; otherwise, false
  7692. */
  7693. public boolean isVisible() {
  7694. return Component.this.isVisible();
  7695. }
  7696. /**
  7697. * Sets the visible state of the object.
  7698. *
  7699. * @param b if true, shows this object; otherwise, hides it
  7700. */
  7701. public void setVisible(boolean b) {
  7702. boolean old = Component.this.isVisible();
  7703. Component.this.setVisible(b);
  7704. if (b != old) {
  7705. if (accessibleContext != null) {
  7706. if (b) {
  7707. accessibleContext.firePropertyChange(
  7708. AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
  7709. null, AccessibleState.VISIBLE);
  7710. } else {
  7711. accessibleContext.firePropertyChange(
  7712. AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
  7713. AccessibleState.VISIBLE, null);
  7714. }
  7715. }
  7716. }
  7717. }
  7718. /**
  7719. * Determines if the object is showing. This is determined by checking
  7720. * the visibility of the object and ancestors of the object. Note:
  7721. * this will return true even if the object is obscured by another
  7722. * (for example, it happens to be underneath a menu that was pulled
  7723. * down).
  7724. *
  7725. * @return true if object is showing; otherwise, false
  7726. */
  7727. public boolean isShowing() {
  7728. return Component.this.isShowing();
  7729. }
  7730. /**
  7731. * Checks whether the specified point is within this object's bounds,
  7732. * where the point's x and y coordinates are defined to be relative to
  7733. * the coordinate system of the object.
  7734. *
  7735. * @param p the <code>Point</code> relative to the
  7736. * coordinate system of the object
  7737. * @return true if object contains <code>Point</code> otherwise false
  7738. */
  7739. public boolean contains(Point p) {
  7740. return Component.this.contains(p);
  7741. }
  7742. /**
  7743. * Returns the location of the object on the screen.
  7744. *
  7745. * @return location of object on screen -- can be
  7746. * <code>null</code> if this object is not on the screen
  7747. */
  7748. public Point getLocationOnScreen() {
  7749. synchronized (Component.this.getTreeLock()) {
  7750. if (Component.this.isShowing()) {
  7751. return Component.this.getLocationOnScreen();
  7752. } else {
  7753. return null;
  7754. }
  7755. }
  7756. }
  7757. /**
  7758. * Gets the location of the object relative to the parent in the form
  7759. * of a point specifying the object's top-left corner in the screen's
  7760. * coordinate space.
  7761. *
  7762. * @return an instance of Point representing the top-left corner of
  7763. * the object's bounds in the coordinate space of the screen;
  7764. * <code>null</code> if this object or its parent are not on the screen
  7765. */
  7766. public Point getLocation() {
  7767. return Component.this.getLocation();
  7768. }
  7769. /**
  7770. * Sets the location of the object relative to the parent.
  7771. * @param p the coordinates of the object
  7772. */
  7773. public void setLocation(Point p) {
  7774. Component.this.setLocation(p);
  7775. }
  7776. /**
  7777. * Gets the bounds of this object in the form of a Rectangle object.
  7778. * The bounds specify this object's width, height, and location
  7779. * relative to its parent.
  7780. *
  7781. * @return a rectangle indicating this component's bounds;
  7782. * <code>null</code> if this object is not on the screen
  7783. */
  7784. public Rectangle getBounds() {
  7785. return Component.this.getBounds();
  7786. }
  7787. /**
  7788. * Sets the bounds of this object in the form of a
  7789. * <code>Rectangle</code> object.
  7790. * The bounds specify this object's width, height, and location
  7791. * relative to its parent.
  7792. *
  7793. * @param r a rectangle indicating this component's bounds
  7794. */
  7795. public void setBounds(Rectangle r) {
  7796. Component.this.setBounds(r);
  7797. }
  7798. /**
  7799. * Returns the size of this object in the form of a
  7800. * <code>Dimension</code> object. The height field of the
  7801. * <code>Dimension</code> object contains this objects's
  7802. * height, and the width field of the <code>Dimension</code>
  7803. * object contains this object's width.
  7804. *
  7805. * @return a <code>Dimension</code> object that indicates
  7806. * the size of this component; <code>null</code> if
  7807. * this object is not on the screen
  7808. */
  7809. public Dimension getSize() {
  7810. return Component.this.getSize();
  7811. }
  7812. /**
  7813. * Resizes this object so that it has width width and height.
  7814. *
  7815. * @param d - the dimension specifying the new size of the object
  7816. */
  7817. public void setSize(Dimension d) {
  7818. Component.this.setSize(d);
  7819. }
  7820. /**
  7821. * Returns the <code>Accessible</code> child,
  7822. * if one exists, contained at the local
  7823. * coordinate <code>Point</code>. Otherwise returns
  7824. * <code>null</code>.
  7825. *
  7826. * @param p the point defining the top-left corner of
  7827. * the <code>Accessible</code>, given in the
  7828. * coordinate space of the object's parent
  7829. * @return the <code>Accessible</code>, if it exists,
  7830. * at the specified location; else <code>null</code>
  7831. */
  7832. public Accessible getAccessibleAt(Point p) {
  7833. return null; // Components don't have children
  7834. }
  7835. /**
  7836. * Returns whether this object can accept focus or not.
  7837. *
  7838. * @return true if object can accept focus; otherwise false
  7839. */
  7840. public boolean isFocusTraversable() {
  7841. return Component.this.isFocusTraversable();
  7842. }
  7843. /**
  7844. * Requests focus for this object.
  7845. */
  7846. public void requestFocus() {
  7847. Component.this.requestFocus();
  7848. }
  7849. /**
  7850. * Adds the specified focus listener to receive focus events from this
  7851. * component.
  7852. *
  7853. * @param l the focus listener
  7854. */
  7855. public void addFocusListener(FocusListener l) {
  7856. Component.this.addFocusListener(l);
  7857. }
  7858. /**
  7859. * Removes the specified focus listener so it no longer receives focus
  7860. * events from this component.
  7861. *
  7862. * @param l the focus listener
  7863. */
  7864. public void removeFocusListener(FocusListener l) {
  7865. Component.this.removeFocusListener(l);
  7866. }
  7867. } // inner class AccessibleAWTComponent
  7868. /**
  7869. * Gets the index of this object in its accessible parent.
  7870. * If this object does not have an accessible parent, returns
  7871. * -1.
  7872. *
  7873. * @return the index of this object in its accessible parent
  7874. */
  7875. int getAccessibleIndexInParent() {
  7876. synchronized (getTreeLock()) {
  7877. int index = -1;
  7878. Container parent = this.getParent();
  7879. if (parent != null && parent instanceof Accessible) {
  7880. Component ca[] = parent.getComponents();
  7881. for (int i = 0; i < ca.length; i++) {
  7882. if (ca[i] instanceof Accessible) {
  7883. index++;
  7884. }
  7885. if (this.equals(ca[i])) {
  7886. return index;
  7887. }
  7888. }
  7889. }
  7890. return -1;
  7891. }
  7892. }
  7893. /**
  7894. * Gets the current state set of this object.
  7895. *
  7896. * @return an instance of <code>AccessibleStateSet</code>
  7897. * containing the current state set of the object
  7898. * @see AccessibleState
  7899. */
  7900. AccessibleStateSet getAccessibleStateSet() {
  7901. synchronized (getTreeLock()) {
  7902. AccessibleStateSet states = new AccessibleStateSet();
  7903. if (this.isEnabled()) {
  7904. states.add(AccessibleState.ENABLED);
  7905. }
  7906. if (this.isFocusTraversable()) {
  7907. states.add(AccessibleState.FOCUSABLE);
  7908. }
  7909. if (this.isVisible()) {
  7910. states.add(AccessibleState.VISIBLE);
  7911. }
  7912. if (this.isShowing()) {
  7913. states.add(AccessibleState.SHOWING);
  7914. }
  7915. if (this.isFocusOwner()) {
  7916. states.add(AccessibleState.FOCUSED);
  7917. }
  7918. if (this instanceof Accessible) {
  7919. AccessibleContext ac = ((Accessible) this).getAccessibleContext();
  7920. if (ac != null) {
  7921. Accessible ap = ac.getAccessibleParent();
  7922. if (ap != null) {
  7923. AccessibleContext pac = ap.getAccessibleContext();
  7924. if (pac != null) {
  7925. AccessibleSelection as = pac.getAccessibleSelection();
  7926. if (as != null) {
  7927. states.add(AccessibleState.SELECTABLE);
  7928. int i = ac.getAccessibleIndexInParent();
  7929. if (i >= 0) {
  7930. if (as.isAccessibleChildSelected(i)) {
  7931. states.add(AccessibleState.SELECTED);
  7932. }
  7933. }
  7934. }
  7935. }
  7936. }
  7937. }
  7938. }
  7939. if (this instanceof javax.swing.JComponent) {
  7940. if (((javax.swing.JComponent) this).isOpaque()) {
  7941. states.add(AccessibleState.OPAQUE);
  7942. }
  7943. }
  7944. return states;
  7945. }
  7946. }
  7947. }