Reykez

cośtamćos

Dec 29th, 2018
211
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 211.13 KB | None | 0 0
  1. /*
  2. * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
  3. * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  4. *
  5. *
  6. *
  7. *
  8. *
  9. *
  10. *
  11. *
  12. *
  13. *
  14. *
  15. *
  16. *
  17. *
  18. *
  19. *
  20. *
  21. *
  22. *
  23. *
  24. */
  25. package javax.swing;
  26.  
  27.  
  28. import java.util.HashSet;
  29. import java.util.Hashtable;
  30. import java.util.Dictionary;
  31. import java.util.Enumeration;
  32. import java.util.Locale;
  33. import java.util.Vector;
  34. import java.util.EventListener;
  35. import java.util.Set;
  36. import java.util.Map;
  37. import java.util.HashMap;
  38.  
  39. import java.awt.*;
  40. import java.awt.event.*;
  41. import java.awt.image.VolatileImage;
  42. import java.awt.Graphics2D;
  43. import java.awt.peer.LightweightPeer;
  44. import java.awt.dnd.DropTarget;
  45. import java.awt.font.FontRenderContext;
  46. import java.beans.PropertyChangeListener;
  47. import java.beans.VetoableChangeListener;
  48. import java.beans.VetoableChangeSupport;
  49. import java.beans.Transient;
  50.  
  51. import java.applet.Applet;
  52.  
  53. import java.io.Serializable;
  54. import java.io.ObjectOutputStream;
  55. import java.io.ObjectInputStream;
  56. import java.io.IOException;
  57. import java.io.ObjectInputValidation;
  58. import java.io.InvalidObjectException;
  59. import java.util.concurrent.atomic.AtomicBoolean;
  60.  
  61. import javax.swing.border.*;
  62. import javax.swing.event.*;
  63. import javax.swing.plaf.*;
  64. import static javax.swing.ClientPropertyKey.*;
  65. import javax.accessibility.*;
  66.  
  67. import sun.awt.SunToolkit;
  68. import sun.swing.SwingUtilities2;
  69. import sun.swing.UIClientPropertyKey;
  70.  
  71. /**
  72. * The base class for all Swing components except top-level containers.
  73. * To use a component that inherits from <code>JComponent</code>,
  74. * you must place the component in a containment hierarchy
  75. * whose root is a top-level Swing container.
  76. * Top-level Swing containers --
  77. * such as <code>JFrame</code>, <code>JDialog</code>,
  78. * and <code>JApplet</code> --
  79. * are specialized components
  80. * that provide a place for other Swing components to paint themselves.
  81. * For an explanation of containment hierarchies, see
  82. * <a
  83. href="https://docs.oracle.com/javase/tutorial/uiswing/components/toplevel.html">Swing Components and the Containment Hierarchy</a>,
  84. * a section in <em>The Java Tutorial</em>.
  85. *
  86. * <p>
  87. * The <code>JComponent</code> class provides:
  88. * <ul>
  89. * <li>The base class for both standard and custom components
  90. * that use the Swing architecture.
  91. * <li>A "pluggable look and feel" (L&amp;F) that can be specified by the
  92. * programmer or (optionally) selected by the user at runtime.
  93. * The look and feel for each component is provided by a
  94. * <em>UI delegate</em> -- an object that descends from
  95. * {@link javax.swing.plaf.ComponentUI}.
  96. * See <a
  97. * href="https://docs.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html">How
  98. * to Set the Look and Feel</a>
  99. * in <em>The Java Tutorial</em>
  100. * for more information.
  101. * <li>Comprehensive keystroke handling.
  102. * See the document <a
  103. * href="https://docs.oracle.com/javase/tutorial/uiswing/misc/keybinding.html">How to Use Key Bindings</a>,
  104. * an article in <em>The Java Tutorial</em>,
  105. * for more information.
  106. * <li>Support for tool tips --
  107. * short descriptions that pop up when the cursor lingers
  108. * over a component.
  109. * See <a
  110. * href="https://docs.oracle.com/javase/tutorial/uiswing/components/tooltip.html">How
  111. * to Use Tool Tips</a>
  112. * in <em>The Java Tutorial</em>
  113. * for more information.
  114. * <li>Support for accessibility.
  115. * <code>JComponent</code> contains all of the methods in the
  116. * <code>Accessible</code> interface,
  117. * but it doesn't actually implement the interface. That is the
  118. * responsibility of the individual classes
  119. * that extend <code>JComponent</code>.
  120. * <li>Support for component-specific properties.
  121. * With the {@link #putClientProperty}
  122. * and {@link #getClientProperty} methods,
  123. * you can associate name-object pairs
  124. * with any object that descends from <code>JComponent</code>.
  125. * <li>An infrastructure for painting
  126. * that includes double buffering and support for borders.
  127. * For more information see <a
  128. * href="http://www.oracle.com/technetwork/java/painting-140037.html#swing">Painting</a> and
  129. * <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/border.htmll">How
  130. * to Use Borders</a>,
  131. * both of which are sections in <em>The Java Tutorial</em>.
  132. * </ul>
  133. * For more information on these subjects, see the
  134. * <a href="package-summary.html#package_description">Swing package description</a>
  135. * and <em>The Java Tutorial</em> section
  136. * <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/jcomponent.html">The JComponent Class</a>.
  137. * <p>
  138. * <code>JComponent</code> and its subclasses document default values
  139. * for certain properties. For example, <code>JTable</code> documents the
  140. * default row height as 16. Each <code>JComponent</code> subclass
  141. * that has a <code>ComponentUI</code> will create the
  142. * <code>ComponentUI</code> as part of its constructor. In order
  143. * to provide a particular look and feel each
  144. * <code>ComponentUI</code> may set properties back on the
  145. * <code>JComponent</code> that created it. For example, a custom
  146. * look and feel may require <code>JTable</code>s to have a row
  147. * height of 24. The documented defaults are the value of a property
  148. * BEFORE the <code>ComponentUI</code> has been installed. If you
  149. * need a specific value for a particular property you should
  150. * explicitly set it.
  151. * <p>
  152. * In release 1.4, the focus subsystem was rearchitected.
  153. * For more information, see
  154. * <a href="https://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
  155. * How to Use the Focus Subsystem</a>,
  156. * a section in <em>The Java Tutorial</em>.
  157. * <p>
  158. * <strong>Warning:</strong> Swing is not thread safe. For more
  159. * information see <a
  160. * href="package-summary.html#threading">Swing's Threading
  161. * Policy</a>.
  162. * <p>
  163. * <strong>Warning:</strong>
  164. * Serialized objects of this class will not be compatible with
  165. * future Swing releases. The current serialization support is
  166. * appropriate for short term storage or RMI between applications running
  167. * the same version of Swing. As of 1.4, support for long term storage
  168. * of all JavaBeans&trade;
  169. * has been added to the <code>java.beans</code> package.
  170. * Please see {@link java.beans.XMLEncoder}.
  171. *
  172. * @see KeyStroke
  173. * @see Action
  174. * @see #setBorder
  175. * @see #registerKeyboardAction
  176. * @see JOptionPane
  177. * @see #setDebugGraphicsOptions
  178. * @see #setToolTipText
  179. * @see #setAutoscrolls
  180. *
  181. * @author Hans Muller
  182. * @author Arnaud Weber
  183. */
  184. public abstract class JComponent extends Container implements Serializable,
  185. TransferHandler.HasGetTransferHandler
  186. {
  187. /**
  188. * @see #getUIClassID
  189. * @see #writeObject
  190. */
  191. private static final String uiClassID = "ComponentUI";
  192.  
  193. /**
  194. * @see #readObject
  195. */
  196. private static final Hashtable<ObjectInputStream, ReadObjectCallback> readObjectCallbacks =
  197. new Hashtable<ObjectInputStream, ReadObjectCallback>(1);
  198.  
  199. /**
  200. * Keys to use for forward focus traversal when the JComponent is
  201. * managing focus.
  202. */
  203. private static Set<KeyStroke> managingFocusForwardTraversalKeys;
  204.  
  205. /**
  206. * Keys to use for backward focus traversal when the JComponent is
  207. * managing focus.
  208. */
  209. private static Set<KeyStroke> managingFocusBackwardTraversalKeys;
  210.  
  211. // Following are the possible return values from getObscuredState.
  212. private static final int NOT_OBSCURED = 0;
  213. private static final int PARTIALLY_OBSCURED = 1;
  214. private static final int COMPLETELY_OBSCURED = 2;
  215.  
  216. /**
  217. * Set to true when DebugGraphics has been loaded.
  218. */
  219. static boolean DEBUG_GRAPHICS_LOADED;
  220.  
  221. /**
  222. * Key used to look up a value from the AppContext to determine the
  223. * JComponent the InputVerifier is running for. That is, if
  224. * AppContext.get(INPUT_VERIFIER_SOURCE_KEY) returns non-null, it
  225. * indicates the EDT is calling into the InputVerifier from the
  226. * returned component.
  227. */
  228. private static final Object INPUT_VERIFIER_SOURCE_KEY =
  229. new StringBuilder("InputVerifierSourceKey");
  230.  
  231. /* The following fields support set methods for the corresponding
  232. * java.awt.Component properties.
  233. */
  234. private boolean isAlignmentXSet;
  235. private float alignmentX;
  236. private boolean isAlignmentYSet;
  237. private float alignmentY;
  238.  
  239. /**
  240. * Backing store for JComponent properties and listeners
  241. */
  242.  
  243. /** The look and feel delegate for this component. */
  244. protected transient ComponentUI ui;
  245. /** A list of event listeners for this component. */
  246. protected EventListenerList listenerList = new EventListenerList();
  247.  
  248. private transient ArrayTable clientProperties;
  249. private VetoableChangeSupport vetoableChangeSupport;
  250. /**
  251. * Whether or not autoscroll has been enabled.
  252. */
  253. private boolean autoscrolls;
  254. private Border border;
  255. private int flags;
  256.  
  257. /* Input verifier for this component */
  258. private InputVerifier inputVerifier = null;
  259.  
  260. private boolean verifyInputWhenFocusTarget = true;
  261.  
  262. /**
  263. * Set in <code>_paintImmediately</code>.
  264. * Will indicate the child that initiated the painting operation.
  265. * If <code>paintingChild</code> is opaque, no need to paint
  266. * any child components after <code>paintingChild</code>.
  267. * Test used in <code>paintChildren</code>.
  268. */
  269. transient Component paintingChild;
  270.  
  271. /**
  272. * Constant used for <code>registerKeyboardAction</code> that
  273. * means that the command should be invoked when
  274. * the component has the focus.
  275. */
  276. public static final int WHEN_FOCUSED = 0;
  277.  
  278. /**
  279. * Constant used for <code>registerKeyboardAction</code> that
  280. * means that the command should be invoked when the receiving
  281. * component is an ancestor of the focused component or is
  282. * itself the focused component.
  283. */
  284. public static final int WHEN_ANCESTOR_OF_FOCUSED_COMPONENT = 1;
  285.  
  286. /**
  287. * Constant used for <code>registerKeyboardAction</code> that
  288. * means that the command should be invoked when
  289. * the receiving component is in the window that has the focus
  290. * or is itself the focused component.
  291. */
  292. public static final int WHEN_IN_FOCUSED_WINDOW = 2;
  293.  
  294. /**
  295. * Constant used by some of the APIs to mean that no condition is defined.
  296. */
  297. public static final int UNDEFINED_CONDITION = -1;
  298.  
  299. /**
  300. * The key used by <code>JComponent</code> to access keyboard bindings.
  301. */
  302. private static final String KEYBOARD_BINDINGS_KEY = "_KeyboardBindings";
  303.  
  304. /**
  305. * An array of <code>KeyStroke</code>s used for
  306. * <code>WHEN_IN_FOCUSED_WINDOW</code> are stashed
  307. * in the client properties under this string.
  308. */
  309. private static final String WHEN_IN_FOCUSED_WINDOW_BINDINGS = "_WhenInFocusedWindow";
  310.  
  311. /**
  312. * The comment to display when the cursor is over the component,
  313. * also known as a "value tip", "flyover help", or "flyover label".
  314. */
  315. public static final String TOOL_TIP_TEXT_KEY = "ToolTipText";
  316.  
  317. private static final String NEXT_FOCUS = "nextFocus";
  318.  
  319. /**
  320. * <code>JPopupMenu</code> assigned to this component
  321. * and all of its children
  322. */
  323. private JPopupMenu popupMenu;
  324.  
  325. /** Private flags **/
  326. private static final int IS_DOUBLE_BUFFERED = 0;
  327. private static final int ANCESTOR_USING_BUFFER = 1;
  328. private static final int IS_PAINTING_TILE = 2;
  329. private static final int IS_OPAQUE = 3;
  330. private static final int KEY_EVENTS_ENABLED = 4;
  331. private static final int FOCUS_INPUTMAP_CREATED = 5;
  332. private static final int ANCESTOR_INPUTMAP_CREATED = 6;
  333. private static final int WIF_INPUTMAP_CREATED = 7;
  334. private static final int ACTIONMAP_CREATED = 8;
  335. private static final int CREATED_DOUBLE_BUFFER = 9;
  336. // bit 10 is free
  337. private static final int IS_PRINTING = 11;
  338. private static final int IS_PRINTING_ALL = 12;
  339. private static final int IS_REPAINTING = 13;
  340. /** Bits 14-21 are used to handle nested writeObject calls. **/
  341. private static final int WRITE_OBJ_COUNTER_FIRST = 14;
  342. private static final int RESERVED_1 = 15;
  343. private static final int RESERVED_2 = 16;
  344. private static final int RESERVED_3 = 17;
  345. private static final int RESERVED_4 = 18;
  346. private static final int RESERVED_5 = 19;
  347. private static final int RESERVED_6 = 20;
  348. private static final int WRITE_OBJ_COUNTER_LAST = 21;
  349.  
  350. private static final int REQUEST_FOCUS_DISABLED = 22;
  351. private static final int INHERITS_POPUP_MENU = 23;
  352. private static final int OPAQUE_SET = 24;
  353. private static final int AUTOSCROLLS_SET = 25;
  354. private static final int FOCUS_TRAVERSAL_KEYS_FORWARD_SET = 26;
  355. private static final int FOCUS_TRAVERSAL_KEYS_BACKWARD_SET = 27;
  356.  
  357. private transient AtomicBoolean revalidateRunnableScheduled = new AtomicBoolean(false);
  358.  
  359. /**
  360. * Temporary rectangles.
  361. */
  362. private static java.util.List<Rectangle> tempRectangles = new java.util.ArrayList<Rectangle>(11);
  363.  
  364. /** Used for <code>WHEN_FOCUSED</code> bindings. */
  365. private InputMap focusInputMap;
  366. /** Used for <code>WHEN_ANCESTOR_OF_FOCUSED_COMPONENT</code> bindings. */
  367. private InputMap ancestorInputMap;
  368. /** Used for <code>WHEN_IN_FOCUSED_KEY</code> bindings. */
  369. private ComponentInputMap windowInputMap;
  370.  
  371. /** ActionMap. */
  372. private ActionMap actionMap;
  373.  
  374. /** Key used to store the default locale in an AppContext **/
  375. private static final String defaultLocale = "JComponent.defaultLocale";
  376.  
  377. private static Component componentObtainingGraphicsFrom;
  378. private static Object componentObtainingGraphicsFromLock = new
  379. StringBuilder("componentObtainingGraphicsFrom");
  380.  
  381. /**
  382. * AA text hints.
  383. */
  384. transient private Object aaTextInfo;
  385.  
  386. static Graphics safelyGetGraphics(Component c) {
  387. return safelyGetGraphics(c, SwingUtilities.getRoot(c));
  388. }
  389.  
  390. static Graphics safelyGetGraphics(Component c, Component root) {
  391. synchronized(componentObtainingGraphicsFromLock) {
  392. componentObtainingGraphicsFrom = root;
  393. Graphics g = c.getGraphics();
  394. componentObtainingGraphicsFrom = null;
  395. return g;
  396. }
  397. }
  398.  
  399. static void getGraphicsInvoked(Component root) {
  400. if (!JComponent.isComponentObtainingGraphicsFrom(root)) {
  401. JRootPane rootPane = ((RootPaneContainer)root).getRootPane();
  402. if (rootPane != null) {
  403. rootPane.disableTrueDoubleBuffering();
  404. }
  405. }
  406. }
  407.  
  408.  
  409. /**
  410. * Returns true if {@code c} is the component the graphics is being
  411. * requested of. This is intended for use when getGraphics is invoked.
  412. */
  413. private static boolean isComponentObtainingGraphicsFrom(Component c) {
  414. synchronized(componentObtainingGraphicsFromLock) {
  415. return (componentObtainingGraphicsFrom == c);
  416. }
  417. }
  418.  
  419. /**
  420. * Returns the Set of <code>KeyStroke</code>s to use if the component
  421. * is managing focus for forward focus traversal.
  422. */
  423. static Set<KeyStroke> getManagingFocusForwardTraversalKeys() {
  424. synchronized(JComponent.class) {
  425. if (managingFocusForwardTraversalKeys == null) {
  426. managingFocusForwardTraversalKeys = new HashSet<KeyStroke>(1);
  427. managingFocusForwardTraversalKeys.add(
  428. KeyStroke.getKeyStroke(KeyEvent.VK_TAB,
  429. InputEvent.CTRL_MASK));
  430. }
  431. }
  432. return managingFocusForwardTraversalKeys;
  433. }
  434.  
  435. /**
  436. * Returns the Set of <code>KeyStroke</code>s to use if the component
  437. * is managing focus for backward focus traversal.
  438. */
  439. static Set<KeyStroke> getManagingFocusBackwardTraversalKeys() {
  440. synchronized(JComponent.class) {
  441. if (managingFocusBackwardTraversalKeys == null) {
  442. managingFocusBackwardTraversalKeys = new HashSet<KeyStroke>(1);
  443. managingFocusBackwardTraversalKeys.add(
  444. KeyStroke.getKeyStroke(KeyEvent.VK_TAB,
  445. InputEvent.SHIFT_MASK |
  446. InputEvent.CTRL_MASK));
  447. }
  448. }
  449. return managingFocusBackwardTraversalKeys;
  450. }
  451.  
  452. private static Rectangle fetchRectangle() {
  453. synchronized(tempRectangles) {
  454. Rectangle rect;
  455. int size = tempRectangles.size();
  456. if (size > 0) {
  457. rect = tempRectangles.remove(size - 1);
  458. }
  459. else {
  460. rect = new Rectangle(0, 0, 0, 0);
  461. }
  462. return rect;
  463. }
  464. }
  465.  
  466. private static void recycleRectangle(Rectangle rect) {
  467. synchronized(tempRectangles) {
  468. tempRectangles.add(rect);
  469. }
  470. }
  471.  
  472. /**
  473. * Sets whether or not <code>getComponentPopupMenu</code> should delegate
  474. * to the parent if this component does not have a <code>JPopupMenu</code>
  475. * assigned to it.
  476. * <p>
  477. * The default value for this is false, but some <code>JComponent</code>
  478. * subclasses that are implemented as a number of <code>JComponent</code>s
  479. * may set this to true.
  480. * <p>
  481. * This is a bound property.
  482. *
  483. * @param value whether or not the JPopupMenu is inherited
  484. * @see #setComponentPopupMenu
  485. * @beaninfo
  486. * bound: true
  487. * description: Whether or not the JPopupMenu is inherited
  488. * @since 1.5
  489. */
  490. public void setInheritsPopupMenu(boolean value) {
  491. boolean oldValue = getFlag(INHERITS_POPUP_MENU);
  492. setFlag(INHERITS_POPUP_MENU, value);
  493. firePropertyChange("inheritsPopupMenu", oldValue, value);
  494. }
  495.  
  496. /**
  497. * Returns true if the JPopupMenu should be inherited from the parent.
  498. *
  499. * @see #setComponentPopupMenu
  500. * @since 1.5
  501. */
  502. public boolean getInheritsPopupMenu() {
  503. return getFlag(INHERITS_POPUP_MENU);
  504. }
  505.  
  506. /**
  507. * Sets the <code>JPopupMenu</code> for this <code>JComponent</code>.
  508. * The UI is responsible for registering bindings and adding the necessary
  509. * listeners such that the <code>JPopupMenu</code> will be shown at
  510. * the appropriate time. When the <code>JPopupMenu</code> is shown
  511. * depends upon the look and feel: some may show it on a mouse event,
  512. * some may enable a key binding.
  513. * <p>
  514. * If <code>popup</code> is null, and <code>getInheritsPopupMenu</code>
  515. * returns true, then <code>getComponentPopupMenu</code> will be delegated
  516. * to the parent. This provides for a way to make all child components
  517. * inherit the popupmenu of the parent.
  518. * <p>
  519. * This is a bound property.
  520. *
  521. * @param popup - the popup that will be assigned to this component
  522. * may be null
  523. * @see #getComponentPopupMenu
  524. * @beaninfo
  525. * bound: true
  526. * preferred: true
  527. * description: Popup to show
  528. * @since 1.5
  529. */
  530. public void setComponentPopupMenu(JPopupMenu popup) {
  531. if(popup != null) {
  532. enableEvents(AWTEvent.MOUSE_EVENT_MASK);
  533. }
  534. JPopupMenu oldPopup = this.popupMenu;
  535. this.popupMenu = popup;
  536. firePropertyChange("componentPopupMenu", oldPopup, popup);
  537. }
  538.  
  539. /**
  540. * Returns <code>JPopupMenu</code> that assigned for this component.
  541. * If this component does not have a <code>JPopupMenu</code> assigned
  542. * to it and <code>getInheritsPopupMenu</code> is true, this
  543. * will return <code>getParent().getComponentPopupMenu()</code> (assuming
  544. * the parent is valid.)
  545. *
  546. * @return <code>JPopupMenu</code> assigned for this component
  547. * or <code>null</code> if no popup assigned
  548. * @see #setComponentPopupMenu
  549. * @since 1.5
  550. */
  551. public JPopupMenu getComponentPopupMenu() {
  552.  
  553. if(!getInheritsPopupMenu()) {
  554. return popupMenu;
  555. }
  556.  
  557. if(popupMenu == null) {
  558. // Search parents for its popup
  559. Container parent = getParent();
  560. while (parent != null) {
  561. if(parent instanceof JComponent) {
  562. return ((JComponent)parent).getComponentPopupMenu();
  563. }
  564. if(parent instanceof Window ||
  565. parent instanceof Applet) {
  566. // Reached toplevel, break and return null
  567. break;
  568. }
  569. parent = parent.getParent();
  570. }
  571. return null;
  572. }
  573.  
  574. return popupMenu;
  575. }
  576.  
  577. /**
  578. * Default <code>JComponent</code> constructor. This constructor does
  579. * very little initialization beyond calling the <code>Container</code>
  580. * constructor. For example, the initial layout manager is
  581. * <code>null</code>. It does, however, set the component's locale
  582. * property to the value returned by
  583. * <code>JComponent.getDefaultLocale</code>.
  584. *
  585. * @see #getDefaultLocale
  586. */
  587. public JComponent() {
  588. super();
  589. // We enable key events on all JComponents so that accessibility
  590. // bindings will work everywhere. This is a partial fix to BugID
  591. // 4282211.
  592. enableEvents(AWTEvent.KEY_EVENT_MASK);
  593. if (isManagingFocus()) {
  594. LookAndFeel.installProperty(this,
  595. "focusTraversalKeysForward",
  596. getManagingFocusForwardTraversalKeys());
  597. LookAndFeel.installProperty(this,
  598. "focusTraversalKeysBackward",
  599. getManagingFocusBackwardTraversalKeys());
  600. }
  601.  
  602. super.setLocale( JComponent.getDefaultLocale() );
  603. }
  604.  
  605.  
  606. /**
  607. * Resets the UI property to a value from the current look and feel.
  608. * <code>JComponent</code> subclasses must override this method
  609. * like this:
  610. * <pre>
  611. * public void updateUI() {
  612. * setUI((SliderUI)UIManager.getUI(this);
  613. * }
  614. * </pre>
  615. *
  616. * @see #setUI
  617. * @see UIManager#getLookAndFeel
  618. * @see UIManager#getUI
  619. */
  620. public void updateUI() {}
  621.  
  622.  
  623. /**
  624. * Sets the look and feel delegate for this component.
  625. * <code>JComponent</code> subclasses generally override this method
  626. * to narrow the argument type. For example, in <code>JSlider</code>:
  627. * <pre>
  628. * public void setUI(SliderUI newUI) {
  629. * super.setUI(newUI);
  630. * }
  631. * </pre>
  632. * <p>
  633. * Additionally <code>JComponent</code> subclasses must provide a
  634. * <code>getUI</code> method that returns the correct type. For example:
  635. * <pre>
  636. * public SliderUI getUI() {
  637. * return (SliderUI)ui;
  638. * }
  639. * </pre>
  640. *
  641. * @param newUI the new UI delegate
  642. * @see #updateUI
  643. * @see UIManager#getLookAndFeel
  644. * @see UIManager#getUI
  645. * @beaninfo
  646. * bound: true
  647. * hidden: true
  648. * attribute: visualUpdate true
  649. * description: The component's look and feel delegate.
  650. */
  651. protected void setUI(ComponentUI newUI) {
  652. /* We do not check that the UI instance is different
  653. * before allowing the switch in order to enable the
  654. * same UI instance *with different default settings*
  655. * to be installed.
  656. */
  657.  
  658. uninstallUIAndProperties();
  659.  
  660. // aaText shouldn't persist between look and feels, reset it.
  661. aaTextInfo =
  662. UIManager.getDefaults().get(SwingUtilities2.AA_TEXT_PROPERTY_KEY);
  663. ComponentUI oldUI = ui;
  664. ui = newUI;
  665. if (ui != null) {
  666. ui.installUI(this);
  667. }
  668.  
  669. firePropertyChange("UI", oldUI, newUI);
  670. revalidate();
  671. repaint();
  672. }
  673.  
  674. /**
  675. * Uninstalls the UI, if any, and any client properties designated
  676. * as being specific to the installed UI - instances of
  677. * {@code UIClientPropertyKey}.
  678. */
  679. private void uninstallUIAndProperties() {
  680. if (ui != null) {
  681. ui.uninstallUI(this);
  682. //clean UIClientPropertyKeys from client properties
  683. if (clientProperties != null) {
  684. synchronized(clientProperties) {
  685. Object[] clientPropertyKeys =
  686. clientProperties.getKeys(null);
  687. if (clientPropertyKeys != null) {
  688. for (Object key : clientPropertyKeys) {
  689. if (key instanceof UIClientPropertyKey) {
  690. putClientProperty(key, null);
  691. }
  692. }
  693. }
  694. }
  695. }
  696. }
  697. }
  698.  
  699. /**
  700. * Returns the <code>UIDefaults</code> key used to
  701. * look up the name of the <code>swing.plaf.ComponentUI</code>
  702. * class that defines the look and feel
  703. * for this component. Most applications will never need to
  704. * call this method. Subclasses of <code>JComponent</code> that support
  705. * pluggable look and feel should override this method to
  706. * return a <code>UIDefaults</code> key that maps to the
  707. * <code>ComponentUI</code> subclass that defines their look and feel.
  708. *
  709. * @return the <code>UIDefaults</code> key for a
  710. * <code>ComponentUI</code> subclass
  711. * @see UIDefaults#getUI
  712. * @beaninfo
  713. * expert: true
  714. * description: UIClassID
  715. */
  716. public String getUIClassID() {
  717. return uiClassID;
  718. }
  719.  
  720.  
  721. /**
  722. * Returns the graphics object used to paint this component.
  723. * If <code>DebugGraphics</code> is turned on we create a new
  724. * <code>DebugGraphics</code> object if necessary.
  725. * Otherwise we just configure the
  726. * specified graphics object's foreground and font.
  727. *
  728. * @param g the original <code>Graphics</code> object
  729. * @return a <code>Graphics</code> object configured for this component
  730. */
  731. protected Graphics getComponentGraphics(Graphics g) {
  732. Graphics componentGraphics = g;
  733. if (ui != null && DEBUG_GRAPHICS_LOADED) {
  734. if ((DebugGraphics.debugComponentCount() != 0) &&
  735. (shouldDebugGraphics() != 0) &&
  736. !(g instanceof DebugGraphics)) {
  737. componentGraphics = new DebugGraphics(g,this);
  738. }
  739. }
  740. componentGraphics.setColor(getForeground());
  741. componentGraphics.setFont(getFont());
  742.  
  743. return componentGraphics;
  744. }
  745.  
  746.  
  747. /**
  748. * Calls the UI delegate's paint method, if the UI delegate
  749. * is non-<code>null</code>. We pass the delegate a copy of the
  750. * <code>Graphics</code> object to protect the rest of the
  751. * paint code from irrevocable changes
  752. * (for example, <code>Graphics.translate</code>).
  753. * <p>
  754. * If you override this in a subclass you should not make permanent
  755. * changes to the passed in <code>Graphics</code>. For example, you
  756. * should not alter the clip <code>Rectangle</code> or modify the
  757. * transform. If you need to do these operations you may find it
  758. * easier to create a new <code>Graphics</code> from the passed in
  759. * <code>Graphics</code> and manipulate it. Further, if you do not
  760. * invoker super's implementation you must honor the opaque property,
  761. * that is
  762. * if this component is opaque, you must completely fill in the background
  763. * in a non-opaque color. If you do not honor the opaque property you
  764. * will likely see visual artifacts.
  765. * <p>
  766. * The passed in <code>Graphics</code> object might
  767. * have a transform other than the identify transform
  768. * installed on it. In this case, you might get
  769. * unexpected results if you cumulatively apply
  770. * another transform.
  771. *
  772. * @param g the <code>Graphics</code> object to protect
  773. * @see #paint
  774. * @see ComponentUI
  775. */
  776. protected void paintComponent(Graphics g) {
  777. if (ui != null) {
  778. Graphics scratchGraphics = (g == null) ? null : g.create();
  779. try {
  780. ui.update(scratchGraphics, this);
  781. }
  782. finally {
  783. scratchGraphics.dispose();
  784. }
  785. }
  786. }
  787.  
  788. /**
  789. * Paints this component's children.
  790. * If <code>shouldUseBuffer</code> is true,
  791. * no component ancestor has a buffer and
  792. * the component children can use a buffer if they have one.
  793. * Otherwise, one ancestor has a buffer currently in use and children
  794. * should not use a buffer to paint.
  795. * @param g the <code>Graphics</code> context in which to paint
  796. * @see #paint
  797. * @see java.awt.Container#paint
  798. */
  799. protected void paintChildren(Graphics g) {
  800. Graphics sg = g;
  801.  
  802. synchronized(getTreeLock()) {
  803. int i = getComponentCount() - 1;
  804. if (i < 0) {
  805. return;
  806. }
  807. // If we are only to paint to a specific child, determine
  808. // its index.
  809. if (paintingChild != null &&
  810. (paintingChild instanceof JComponent) &&
  811. paintingChild.isOpaque()) {
  812. for (; i >= 0; i--) {
  813. if (getComponent(i) == paintingChild){
  814. break;
  815. }
  816. }
  817. }
  818. Rectangle tmpRect = fetchRectangle();
  819. boolean checkSiblings = (!isOptimizedDrawingEnabled() &&
  820. checkIfChildObscuredBySibling());
  821. Rectangle clipBounds = null;
  822. if (checkSiblings) {
  823. clipBounds = sg.getClipBounds();
  824. if (clipBounds == null) {
  825. clipBounds = new Rectangle(0, 0, getWidth(),
  826. getHeight());
  827. }
  828. }
  829. boolean printing = getFlag(IS_PRINTING);
  830. final Window window = SwingUtilities.getWindowAncestor(this);
  831. final boolean isWindowOpaque = window == null || window.isOpaque();
  832. for (; i >= 0 ; i--) {
  833. Component comp = getComponent(i);
  834. if (comp == null) {
  835. continue;
  836. }
  837.  
  838. final boolean isJComponent = comp instanceof JComponent;
  839.  
  840. // Enable painting of heavyweights in non-opaque windows.
  841. // See 6884960
  842. if ((!isWindowOpaque || isJComponent ||
  843. isLightweightComponent(comp)) && comp.isVisible())
  844. {
  845. Rectangle cr;
  846.  
  847. cr = comp.getBounds(tmpRect);
  848.  
  849. boolean hitClip = g.hitClip(cr.x, cr.y, cr.width,
  850. cr.height);
  851.  
  852. if (hitClip) {
  853. if (checkSiblings && i > 0) {
  854. int x = cr.x;
  855. int y = cr.y;
  856. int width = cr.width;
  857. int height = cr.height;
  858. SwingUtilities.computeIntersection
  859. (clipBounds.x, clipBounds.y,
  860. clipBounds.width, clipBounds.height, cr);
  861.  
  862. if(getObscuredState(i, cr.x, cr.y, cr.width,
  863. cr.height) == COMPLETELY_OBSCURED) {
  864. continue;
  865. }
  866. cr.x = x;
  867. cr.y = y;
  868. cr.width = width;
  869. cr.height = height;
  870. }
  871. Graphics cg = sg.create(cr.x, cr.y, cr.width,
  872. cr.height);
  873. cg.setColor(comp.getForeground());
  874. cg.setFont(comp.getFont());
  875. boolean shouldSetFlagBack = false;
  876. try {
  877. if(isJComponent) {
  878. if(getFlag(ANCESTOR_USING_BUFFER)) {
  879. ((JComponent)comp).setFlag(
  880. ANCESTOR_USING_BUFFER,true);
  881. shouldSetFlagBack = true;
  882. }
  883. if(getFlag(IS_PAINTING_TILE)) {
  884. ((JComponent)comp).setFlag(
  885. IS_PAINTING_TILE,true);
  886. shouldSetFlagBack = true;
  887. }
  888. if(!printing) {
  889. comp.paint(cg);
  890. }
  891. else {
  892. if (!getFlag(IS_PRINTING_ALL)) {
  893. comp.print(cg);
  894. }
  895. else {
  896. comp.printAll(cg);
  897. }
  898. }
  899. } else {
  900. // The component is either lightweight, or
  901. // heavyweight in a non-opaque window
  902. if (!printing) {
  903. comp.paint(cg);
  904. }
  905. else {
  906. if (!getFlag(IS_PRINTING_ALL)) {
  907. comp.print(cg);
  908. }
  909. else {
  910. comp.printAll(cg);
  911. }
  912. }
  913. }
  914. } finally {
  915. cg.dispose();
  916. if(shouldSetFlagBack) {
  917. ((JComponent)comp).setFlag(
  918. ANCESTOR_USING_BUFFER,false);
  919. ((JComponent)comp).setFlag(
  920. IS_PAINTING_TILE,false);
  921. }
  922. }
  923. }
  924. }
  925.  
  926. }
  927. recycleRectangle(tmpRect);
  928. }
  929. }
  930.  
  931. /**
  932. * Paints the component's border.
  933. * <p>
  934. * If you override this in a subclass you should not make permanent
  935. * changes to the passed in <code>Graphics</code>. For example, you
  936. * should not alter the clip <code>Rectangle</code> or modify the
  937. * transform. If you need to do these operations you may find it
  938. * easier to create a new <code>Graphics</code> from the passed in
  939. * <code>Graphics</code> and manipulate it.
  940. *
  941. * @param g the <code>Graphics</code> context in which to paint
  942. *
  943. * @see #paint
  944. * @see #setBorder
  945. */
  946. protected void paintBorder(Graphics g) {
  947. Border border = getBorder();
  948. if (border != null) {
  949. border.paintBorder(this, g, 0, 0, getWidth(), getHeight());
  950. }
  951. }
  952.  
  953.  
  954. /**
  955. * Calls <code>paint</code>. Doesn't clear the background but see
  956. * <code>ComponentUI.update</code>, which is called by
  957. * <code>paintComponent</code>.
  958. *
  959. * @param g the <code>Graphics</code> context in which to paint
  960. * @see #paint
  961. * @see #paintComponent
  962. * @see javax.swing.plaf.ComponentUI
  963. */
  964. public void update(Graphics g) {
  965. paint(g);
  966. }
  967.  
  968.  
  969. /**
  970. * Invoked by Swing to draw components.
  971. * Applications should not invoke <code>paint</code> directly,
  972. * but should instead use the <code>repaint</code> method to
  973. * schedule the component for redrawing.
  974. * <p>
  975. * This method actually delegates the work of painting to three
  976. * protected methods: <code>paintComponent</code>,
  977. * <code>paintBorder</code>,
  978. * and <code>paintChildren</code>. They're called in the order
  979. * listed to ensure that children appear on top of component itself.
  980. * Generally speaking, the component and its children should not
  981. * paint in the insets area allocated to the border. Subclasses can
  982. * just override this method, as always. A subclass that just
  983. * wants to specialize the UI (look and feel) delegate's
  984. * <code>paint</code> method should just override
  985. * <code>paintComponent</code>.
  986. *
  987. * @param g the <code>Graphics</code> context in which to paint
  988. * @see #paintComponent
  989. * @see #paintBorder
  990. * @see #paintChildren
  991. * @see #getComponentGraphics
  992. * @see #repaint
  993. */
  994. public void paint(Graphics g) {
  995. boolean shouldClearPaintFlags = false;
  996.  
  997. if ((getWidth() <= 0) || (getHeight() <= 0)) {
  998. return;
  999. }
  1000.  
  1001. Graphics componentGraphics = getComponentGraphics(g);
  1002. Graphics co = componentGraphics.create();
  1003. try {
  1004. RepaintManager repaintManager = RepaintManager.currentManager(this);
  1005. Rectangle clipRect = co.getClipBounds();
  1006. int clipX;
  1007. int clipY;
  1008. int clipW;
  1009. int clipH;
  1010. if (clipRect == null) {
  1011. clipX = clipY = 0;
  1012. clipW = getWidth();
  1013. clipH = getHeight();
  1014. }
  1015. else {
  1016. clipX = clipRect.x;
  1017. clipY = clipRect.y;
  1018. clipW = clipRect.width;
  1019. clipH = clipRect.height;
  1020. }
  1021.  
  1022. if(clipW > getWidth()) {
  1023. clipW = getWidth();
  1024. }
  1025. if(clipH > getHeight()) {
  1026. clipH = getHeight();
  1027. }
  1028.  
  1029. if(getParent() != null && !(getParent() instanceof JComponent)) {
  1030. adjustPaintFlags();
  1031. shouldClearPaintFlags = true;
  1032. }
  1033.  
  1034. int bw,bh;
  1035. boolean printing = getFlag(IS_PRINTING);
  1036. if (!printing && repaintManager.isDoubleBufferingEnabled() &&
  1037. !getFlag(ANCESTOR_USING_BUFFER) && isDoubleBuffered() &&
  1038. (getFlag(IS_REPAINTING) || repaintManager.isPainting()))
  1039. {
  1040. repaintManager.beginPaint();
  1041. try {
  1042. repaintManager.paint(this, this, co, clipX, clipY, clipW,
  1043. clipH);
  1044. } finally {
  1045. repaintManager.endPaint();
  1046. }
  1047. }
  1048. else {
  1049. // Will ocassionaly happen in 1.2, especially when printing.
  1050. if (clipRect == null) {
  1051. co.setClip(clipX, clipY, clipW, clipH);
  1052. }
  1053.  
  1054. if (!rectangleIsObscured(clipX,clipY,clipW,clipH)) {
  1055. if (!printing) {
  1056. paintComponent(co);
  1057. paintBorder(co);
  1058. }
  1059. else {
  1060. printComponent(co);
  1061. printBorder(co);
  1062. }
  1063. }
  1064. if (!printing) {
  1065. paintChildren(co);
  1066. }
  1067. else {
  1068. printChildren(co);
  1069. }
  1070. }
  1071. } finally {
  1072. co.dispose();
  1073. if(shouldClearPaintFlags) {
  1074. setFlag(ANCESTOR_USING_BUFFER,false);
  1075. setFlag(IS_PAINTING_TILE,false);
  1076. setFlag(IS_PRINTING,false);
  1077. setFlag(IS_PRINTING_ALL,false);
  1078. }
  1079. }
  1080. }
  1081.  
  1082. // paint forcing use of the double buffer. This is used for historical
  1083. // reasons: JViewport, when scrolling, previously directly invoked paint
  1084. // while turning off double buffering at the RepaintManager level, this
  1085. // codes simulates that.
  1086. void paintForceDoubleBuffered(Graphics g) {
  1087. RepaintManager rm = RepaintManager.currentManager(this);
  1088. Rectangle clip = g.getClipBounds();
  1089. rm.beginPaint();
  1090. setFlag(IS_REPAINTING, true);
  1091. try {
  1092. rm.paint(this, this, g, clip.x, clip.y, clip.width, clip.height);
  1093. } finally {
  1094. rm.endPaint();
  1095. setFlag(IS_REPAINTING, false);
  1096. }
  1097. }
  1098.  
  1099. /**
  1100. * Returns true if this component, or any of its ancestors, are in
  1101. * the processing of painting.
  1102. */
  1103. boolean isPainting() {
  1104. Container component = this;
  1105. while (component != null) {
  1106. if (component instanceof JComponent &&
  1107. ((JComponent)component).getFlag(ANCESTOR_USING_BUFFER)) {
  1108. return true;
  1109. }
  1110. component = component.getParent();
  1111. }
  1112. return false;
  1113. }
  1114.  
  1115. private void adjustPaintFlags() {
  1116. JComponent jparent;
  1117. Container parent;
  1118. for(parent = getParent() ; parent != null ; parent =
  1119. parent.getParent()) {
  1120. if(parent instanceof JComponent) {
  1121. jparent = (JComponent) parent;
  1122. if(jparent.getFlag(ANCESTOR_USING_BUFFER))
  1123. setFlag(ANCESTOR_USING_BUFFER, true);
  1124. if(jparent.getFlag(IS_PAINTING_TILE))
  1125. setFlag(IS_PAINTING_TILE, true);
  1126. if(jparent.getFlag(IS_PRINTING))
  1127. setFlag(IS_PRINTING, true);
  1128. if(jparent.getFlag(IS_PRINTING_ALL))
  1129. setFlag(IS_PRINTING_ALL, true);
  1130. break;
  1131. }
  1132. }
  1133. }
  1134.  
  1135. /**
  1136. * Invoke this method to print the component. This method invokes
  1137. * <code>print</code> on the component.
  1138. *
  1139. * @param g the <code>Graphics</code> context in which to paint
  1140. * @see #print
  1141. * @see #printComponent
  1142. * @see #printBorder
  1143. * @see #printChildren
  1144. */
  1145. public void printAll(Graphics g) {
  1146. setFlag(IS_PRINTING_ALL, true);
  1147. try {
  1148. print(g);
  1149. }
  1150. finally {
  1151. setFlag(IS_PRINTING_ALL, false);
  1152. }
  1153. }
  1154.  
  1155. /**
  1156. * Invoke this method to print the component to the specified
  1157. * <code>Graphics</code>. This method will result in invocations
  1158. * of <code>printComponent</code>, <code>printBorder</code> and
  1159. * <code>printChildren</code>. It is recommended that you override
  1160. * one of the previously mentioned methods rather than this one if
  1161. * your intention is to customize the way printing looks. However,
  1162. * it can be useful to override this method should you want to prepare
  1163. * state before invoking the superclass behavior. As an example,
  1164. * if you wanted to change the component's background color before
  1165. * printing, you could do the following:
  1166. * <pre>
  1167. * public void print(Graphics g) {
  1168. * Color orig = getBackground();
  1169. * setBackground(Color.WHITE);
  1170. *
  1171. * // wrap in try/finally so that we always restore the state
  1172. * try {
  1173. * super.print(g);
  1174. * } finally {
  1175. * setBackground(orig);
  1176. * }
  1177. * }
  1178. * </pre>
  1179. * <p>
  1180. * Alternatively, or for components that delegate painting to other objects,
  1181. * you can query during painting whether or not the component is in the
  1182. * midst of a print operation. The <code>isPaintingForPrint</code> method provides
  1183. * this ability and its return value will be changed by this method: to
  1184. * <code>true</code> immediately before rendering and to <code>false</code>
  1185. * immediately after. With each change a property change event is fired on
  1186. * this component with the name <code>"paintingForPrint"</code>.
  1187. * <p>
  1188. * This method sets the component's state such that the double buffer
  1189. * will not be used: painting will be done directly on the passed in
  1190. * <code>Graphics</code>.
  1191. *
  1192. * @param g the <code>Graphics</code> context in which to paint
  1193. * @see #printComponent
  1194. * @see #printBorder
  1195. * @see #printChildren
  1196. * @see #isPaintingForPrint
  1197. */
  1198. public void print(Graphics g) {
  1199. setFlag(IS_PRINTING, true);
  1200. firePropertyChange("paintingForPrint", false, true);
  1201. try {
  1202. paint(g);
  1203. }
  1204. finally {
  1205. setFlag(IS_PRINTING, false);
  1206. firePropertyChange("paintingForPrint", true, false);
  1207. }
  1208. }
  1209.  
  1210. /**
  1211. * This is invoked during a printing operation. This is implemented to
  1212. * invoke <code>paintComponent</code> on the component. Override this
  1213. * if you wish to add special painting behavior when printing.
  1214. *
  1215. * @param g the <code>Graphics</code> context in which to paint
  1216. * @see #print
  1217. * @since 1.3
  1218. */
  1219. protected void printComponent(Graphics g) {
  1220. paintComponent(g);
  1221. }
  1222.  
  1223. /**
  1224. * Prints this component's children. This is implemented to invoke
  1225. * <code>paintChildren</code> on the component. Override this if you
  1226. * wish to print the children differently than painting.
  1227. *
  1228. * @param g the <code>Graphics</code> context in which to paint
  1229. * @see #print
  1230. * @since 1.3
  1231. */
  1232. protected void printChildren(Graphics g) {
  1233. paintChildren(g);
  1234. }
  1235.  
  1236. /**
  1237. * Prints the component's border. This is implemented to invoke
  1238. * <code>paintBorder</code> on the component. Override this if you
  1239. * wish to print the border differently that it is painted.
  1240. *
  1241. * @param g the <code>Graphics</code> context in which to paint
  1242. * @see #print
  1243. * @since 1.3
  1244. */
  1245. protected void printBorder(Graphics g) {
  1246. paintBorder(g);
  1247. }
  1248.  
  1249. /**
  1250. * Returns true if the component is currently painting a tile.
  1251. * If this method returns true, paint will be called again for another
  1252. * tile. This method returns false if you are not painting a tile or
  1253. * if the last tile is painted.
  1254. * Use this method to keep some state you might need between tiles.
  1255. *
  1256. * @return true if the component is currently painting a tile,
  1257. * false otherwise
  1258. */
  1259. public boolean isPaintingTile() {
  1260. return getFlag(IS_PAINTING_TILE);
  1261. }
  1262.  
  1263. /**
  1264. * Returns <code>true</code> if the current painting operation on this
  1265. * component is part of a <code>print</code> operation. This method is
  1266. * useful when you want to customize what you print versus what you show
  1267. * on the screen.
  1268. * <p>
  1269. * You can detect changes in the value of this property by listening for
  1270. * property change events on this component with name
  1271. * <code>"paintingForPrint"</code>.
  1272. * <p>
  1273. * Note: This method provides complimentary functionality to that provided
  1274. * by other high level Swing printing APIs. However, it deals strictly with
  1275. * painting and should not be confused as providing information on higher
  1276. * level print processes. For example, a {@link javax.swing.JTable#print()}
  1277. * operation doesn't necessarily result in a continuous rendering of the
  1278. * full component, and the return value of this method can change multiple
  1279. * times during that operation. It is even possible for the component to be
  1280. * painted to the screen while the printing process is ongoing. In such a
  1281. * case, the return value of this method is <code>true</code> when, and only
  1282. * when, the table is being painted as part of the printing process.
  1283. *
  1284. * @return true if the current painting operation on this component
  1285. * is part of a print operation
  1286. * @see #print
  1287. * @since 1.6
  1288. */
  1289. public final boolean isPaintingForPrint() {
  1290. return getFlag(IS_PRINTING);
  1291. }
  1292.  
  1293. /**
  1294. * In release 1.4, the focus subsystem was rearchitected.
  1295. * For more information, see
  1296. * <a href="https://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
  1297. * How to Use the Focus Subsystem</a>,
  1298. * a section in <em>The Java Tutorial</em>.
  1299. * <p>
  1300. * Changes this <code>JComponent</code>'s focus traversal keys to
  1301. * CTRL+TAB and CTRL+SHIFT+TAB. Also prevents
  1302. * <code>SortingFocusTraversalPolicy</code> from considering descendants
  1303. * of this JComponent when computing a focus traversal cycle.
  1304. *
  1305. * @see java.awt.Component#setFocusTraversalKeys
  1306. * @see SortingFocusTraversalPolicy
  1307. * @deprecated As of 1.4, replaced by
  1308. * <code>Component.setFocusTraversalKeys(int, Set)</code> and
  1309. * <code>Container.setFocusCycleRoot(boolean)</code>.
  1310. */
  1311. @Deprecated
  1312. public boolean isManagingFocus() {
  1313. return false;
  1314. }
  1315.  
  1316. private void registerNextFocusableComponent() {
  1317. registerNextFocusableComponent(getNextFocusableComponent());
  1318. }
  1319.  
  1320. private void registerNextFocusableComponent(Component
  1321. nextFocusableComponent) {
  1322. if (nextFocusableComponent == null) {
  1323. return;
  1324. }
  1325.  
  1326. Container nearestRoot =
  1327. (isFocusCycleRoot()) ? this : getFocusCycleRootAncestor();
  1328. FocusTraversalPolicy policy = nearestRoot.getFocusTraversalPolicy();
  1329. if (!(policy instanceof LegacyGlueFocusTraversalPolicy)) {
  1330. policy = new LegacyGlueFocusTraversalPolicy(policy);
  1331. nearestRoot.setFocusTraversalPolicy(policy);
  1332. }
  1333. ((LegacyGlueFocusTraversalPolicy)policy).
  1334. setNextFocusableComponent(this, nextFocusableComponent);
  1335. }
  1336.  
  1337. private void deregisterNextFocusableComponent() {
  1338. Component nextFocusableComponent = getNextFocusableComponent();
  1339. if (nextFocusableComponent == null) {
  1340. return;
  1341. }
  1342.  
  1343. Container nearestRoot =
  1344. (isFocusCycleRoot()) ? this : getFocusCycleRootAncestor();
  1345. if (nearestRoot == null) {
  1346. return;
  1347. }
  1348. FocusTraversalPolicy policy = nearestRoot.getFocusTraversalPolicy();
  1349. if (policy instanceof LegacyGlueFocusTraversalPolicy) {
  1350. ((LegacyGlueFocusTraversalPolicy)policy).
  1351. unsetNextFocusableComponent(this, nextFocusableComponent);
  1352. }
  1353. }
  1354.  
  1355. /**
  1356. * In release 1.4, the focus subsystem was rearchitected.
  1357. * For more information, see
  1358. * <a href="https://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
  1359. * How to Use the Focus Subsystem</a>,
  1360. * a section in <em>The Java Tutorial</em>.
  1361. * <p>
  1362. * Overrides the default <code>FocusTraversalPolicy</code> for this
  1363. * <code>JComponent</code>'s focus traversal cycle by unconditionally
  1364. * setting the specified <code>Component</code> as the next
  1365. * <code>Component</code> in the cycle, and this <code>JComponent</code>
  1366. * as the specified <code>Component</code>'s previous
  1367. * <code>Component</code> in the cycle.
  1368. *
  1369. * @param aComponent the <code>Component</code> that should follow this
  1370. * <code>JComponent</code> in the focus traversal cycle
  1371. *
  1372. * @see #getNextFocusableComponent
  1373. * @see java.awt.FocusTraversalPolicy
  1374. * @deprecated As of 1.4, replaced by <code>FocusTraversalPolicy</code>
  1375. */
  1376. @Deprecated
  1377. public void setNextFocusableComponent(Component aComponent) {
  1378. boolean displayable = isDisplayable();
  1379. if (displayable) {
  1380. deregisterNextFocusableComponent();
  1381. }
  1382. putClientProperty(NEXT_FOCUS, aComponent);
  1383. if (displayable) {
  1384. registerNextFocusableComponent(aComponent);
  1385. }
  1386. }
  1387.  
  1388. /**
  1389. * In release 1.4, the focus subsystem was rearchitected.
  1390. * For more information, see
  1391. * <a href="https://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
  1392. * How to Use the Focus Subsystem</a>,
  1393. * a section in <em>The Java Tutorial</em>.
  1394. * <p>
  1395. * Returns the <code>Component</code> set by a prior call to
  1396. * <code>setNextFocusableComponent(Component)</code> on this
  1397. * <code>JComponent</code>.
  1398. *
  1399. * @return the <code>Component</code> that will follow this
  1400. * <code>JComponent</code> in the focus traversal cycle, or
  1401. * <code>null</code> if none has been explicitly specified
  1402. *
  1403. * @see #setNextFocusableComponent
  1404. * @deprecated As of 1.4, replaced by <code>FocusTraversalPolicy</code>.
  1405. */
  1406. @Deprecated
  1407. public Component getNextFocusableComponent() {
  1408. return (Component)getClientProperty(NEXT_FOCUS);
  1409. }
  1410.  
  1411. /**
  1412. * Provides a hint as to whether or not this <code>JComponent</code>
  1413. * should get focus. This is only a hint, and it is up to consumers that
  1414. * are requesting focus to honor this property. This is typically honored
  1415. * for mouse operations, but not keyboard operations. For example, look
  1416. * and feels could verify this property is true before requesting focus
  1417. * during a mouse operation. This would often times be used if you did
  1418. * not want a mouse press on a <code>JComponent</code> to steal focus,
  1419. * but did want the <code>JComponent</code> to be traversable via the
  1420. * keyboard. If you do not want this <code>JComponent</code> focusable at
  1421. * all, use the <code>setFocusable</code> method instead.
  1422. * <p>
  1423. * Please see
  1424. * <a href="https://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
  1425. * How to Use the Focus Subsystem</a>,
  1426. * a section in <em>The Java Tutorial</em>,
  1427. * for more information.
  1428. *
  1429. * @param requestFocusEnabled indicates whether you want this
  1430. * <code>JComponent</code> to be focusable or not
  1431. * @see <a href="../../java/awt/doc-files/FocusSpec.html">Focus Specification</a>
  1432. * @see java.awt.Component#setFocusable
  1433. */
  1434. public void setRequestFocusEnabled(boolean requestFocusEnabled) {
  1435. setFlag(REQUEST_FOCUS_DISABLED, !requestFocusEnabled);
  1436. }
  1437.  
  1438. /**
  1439. * Returns <code>true</code> if this <code>JComponent</code> should
  1440. * get focus; otherwise returns <code>false</code>.
  1441. * <p>
  1442. * Please see
  1443. * <a href="https://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
  1444. * How to Use the Focus Subsystem</a>,
  1445. * a section in <em>The Java Tutorial</em>,
  1446. * for more information.
  1447. *
  1448. * @return <code>true</code> if this component should get focus,
  1449. * otherwise returns <code>false</code>
  1450. * @see #setRequestFocusEnabled
  1451. * @see <a href="../../java/awt/doc-files/FocusSpec.html">Focus
  1452. * Specification</a>
  1453. * @see java.awt.Component#isFocusable
  1454. */
  1455. public boolean isRequestFocusEnabled() {
  1456. return !getFlag(REQUEST_FOCUS_DISABLED);
  1457. }
  1458.  
  1459. /**
  1460. * Requests that this <code>Component</code> gets the input focus.
  1461. * Refer to {@link java.awt.Component#requestFocus()
  1462. * Component.requestFocus()} for a complete description of
  1463. * this method.
  1464. * <p>
  1465. * Note that the use of this method is discouraged because
  1466. * its behavior is platform dependent. Instead we recommend the
  1467. * use of {@link #requestFocusInWindow() requestFocusInWindow()}.
  1468. * If you would like more information on focus, see
  1469. * <a href="https://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
  1470. * How to Use the Focus Subsystem</a>,
  1471. * a section in <em>The Java Tutorial</em>.
  1472. *
  1473. * @see java.awt.Component#requestFocusInWindow()
  1474. * @see java.awt.Component#requestFocusInWindow(boolean)
  1475. * @since 1.4
  1476. */
  1477. public void requestFocus() {
  1478. super.requestFocus();
  1479. }
  1480.  
  1481. /**
  1482. * Requests that this <code>Component</code> gets the input focus.
  1483. * Refer to {@link java.awt.Component#requestFocus(boolean)
  1484. * Component.requestFocus(boolean)} for a complete description of
  1485. * this method.
  1486. * <p>
  1487. * Note that the use of this method is discouraged because
  1488. * its behavior is platform dependent. Instead we recommend the
  1489. * use of {@link #requestFocusInWindow(boolean)
  1490. * requestFocusInWindow(boolean)}.
  1491. * If you would like more information on focus, see
  1492. * <a href="https://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
  1493. * How to Use the Focus Subsystem</a>,
  1494. * a section in <em>The Java Tutorial</em>.
  1495. *
  1496. * @param temporary boolean indicating if the focus change is temporary
  1497. * @return <code>false</code> if the focus change request is guaranteed to
  1498. * fail; <code>true</code> if it is likely to succeed
  1499. * @see java.awt.Component#requestFocusInWindow()
  1500. * @see java.awt.Component#requestFocusInWindow(boolean)
  1501. * @since 1.4
  1502. */
  1503. public boolean requestFocus(boolean temporary) {
  1504. return super.requestFocus(temporary);
  1505. }
  1506.  
  1507. /**
  1508. * Requests that this <code>Component</code> gets the input focus.
  1509. * Refer to {@link java.awt.Component#requestFocusInWindow()
  1510. * Component.requestFocusInWindow()} for a complete description of
  1511. * this method.
  1512. * <p>
  1513. * If you would like more information on focus, see
  1514. * <a href="https://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
  1515. * How to Use the Focus Subsystem</a>,
  1516. * a section in <em>The Java Tutorial</em>.
  1517. *
  1518. * @return <code>false</code> if the focus change request is guaranteed to
  1519. * fail; <code>true</code> if it is likely to succeed
  1520. * @see java.awt.Component#requestFocusInWindow()
  1521. * @see java.awt.Component#requestFocusInWindow(boolean)
  1522. * @since 1.4
  1523. */
  1524. public boolean requestFocusInWindow() {
  1525. return super.requestFocusInWindow();
  1526. }
  1527.  
  1528. /**
  1529. * Requests that this <code>Component</code> gets the input focus.
  1530. * Refer to {@link java.awt.Component#requestFocusInWindow(boolean)
  1531. * Component.requestFocusInWindow(boolean)} for a complete description of
  1532. * this method.
  1533. * <p>
  1534. * If you would like more information on focus, see
  1535. * <a href="https://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
  1536. * How to Use the Focus Subsystem</a>,
  1537. * a section in <em>The Java Tutorial</em>.
  1538. *
  1539. * @param temporary boolean indicating if the focus change is temporary
  1540. * @return <code>false</code> if the focus change request is guaranteed to
  1541. * fail; <code>true</code> if it is likely to succeed
  1542. * @see java.awt.Component#requestFocusInWindow()
  1543. * @see java.awt.Component#requestFocusInWindow(boolean)
  1544. * @since 1.4
  1545. */
  1546. protected boolean requestFocusInWindow(boolean temporary) {
  1547. return super.requestFocusInWindow(temporary);
  1548. }
  1549.  
  1550. /**
  1551. * Requests that this Component get the input focus, and that this
  1552. * Component's top-level ancestor become the focused Window. This component
  1553. * must be displayable, visible, and focusable for the request to be
  1554. * granted.
  1555. * <p>
  1556. * This method is intended for use by focus implementations. Client code
  1557. * should not use this method; instead, it should use
  1558. * <code>requestFocusInWindow()</code>.
  1559. *
  1560. * @see #requestFocusInWindow()
  1561. */
  1562. public void grabFocus() {
  1563. requestFocus();
  1564. }
  1565.  
  1566. /**
  1567. * Sets the value to indicate whether input verifier for the
  1568. * current focus owner will be called before this component requests
  1569. * focus. The default is true. Set to false on components such as a
  1570. * Cancel button or a scrollbar, which should activate even if the
  1571. * input in the current focus owner is not "passed" by the input
  1572. * verifier for that component.
  1573. *
  1574. * @param verifyInputWhenFocusTarget value for the
  1575. * <code>verifyInputWhenFocusTarget</code> property
  1576. * @see InputVerifier
  1577. * @see #setInputVerifier
  1578. * @see #getInputVerifier
  1579. * @see #getVerifyInputWhenFocusTarget
  1580. *
  1581. * @since 1.3
  1582. * @beaninfo
  1583. * bound: true
  1584. * description: Whether the Component verifies input before accepting
  1585. * focus.
  1586. */
  1587. public void setVerifyInputWhenFocusTarget(boolean
  1588. verifyInputWhenFocusTarget) {
  1589. boolean oldVerifyInputWhenFocusTarget =
  1590. this.verifyInputWhenFocusTarget;
  1591. this.verifyInputWhenFocusTarget = verifyInputWhenFocusTarget;
  1592. firePropertyChange("verifyInputWhenFocusTarget",
  1593. oldVerifyInputWhenFocusTarget,
  1594. verifyInputWhenFocusTarget);
  1595. }
  1596.  
  1597. /**
  1598. * Returns the value that indicates whether the input verifier for the
  1599. * current focus owner will be called before this component requests
  1600. * focus.
  1601. *
  1602. * @return value of the <code>verifyInputWhenFocusTarget</code> property
  1603. *
  1604. * @see InputVerifier
  1605. * @see #setInputVerifier
  1606. * @see #getInputVerifier
  1607. * @see #setVerifyInputWhenFocusTarget
  1608. *
  1609. * @since 1.3
  1610. */
  1611. public boolean getVerifyInputWhenFocusTarget() {
  1612. return verifyInputWhenFocusTarget;
  1613. }
  1614.  
  1615.  
  1616. /**
  1617. * Gets the <code>FontMetrics</code> for the specified <code>Font</code>.
  1618. *
  1619. * @param font the font for which font metrics is to be
  1620. * obtained
  1621. * @return the font metrics for <code>font</code>
  1622. * @throws NullPointerException if <code>font</code> is null
  1623. * @since 1.5
  1624. */
  1625. public FontMetrics getFontMetrics(Font font) {
  1626. return SwingUtilities2.getFontMetrics(this, font);
  1627. }
  1628.  
  1629.  
  1630. /**
  1631. * Sets the preferred size of this component.
  1632. * If <code>preferredSize</code> is <code>null</code>, the UI will
  1633. * be asked for the preferred size.
  1634. * @beaninfo
  1635. * preferred: true
  1636. * bound: true
  1637. * description: The preferred size of the component.
  1638. */
  1639. public void setPreferredSize(Dimension preferredSize) {
  1640. super.setPreferredSize(preferredSize);
  1641. }
  1642.  
  1643.  
  1644. /**
  1645. * If the <code>preferredSize</code> has been set to a
  1646. * non-<code>null</code> value just returns it.
  1647. * If the UI delegate's <code>getPreferredSize</code>
  1648. * method returns a non <code>null</code> value then return that;
  1649. * otherwise defer to the component's layout manager.
  1650. *
  1651. * @return the value of the <code>preferredSize</code> property
  1652. * @see #setPreferredSize
  1653. * @see ComponentUI
  1654. */
  1655. @Transient
  1656. public Dimension getPreferredSize() {
  1657. if (isPreferredSizeSet()) {
  1658. return super.getPreferredSize();
  1659. }
  1660. Dimension size = null;
  1661. if (ui != null) {
  1662. size = ui.getPreferredSize(this);
  1663. }
  1664. return (size != null) ? size : super.getPreferredSize();
  1665. }
  1666.  
  1667.  
  1668. /**
  1669. * Sets the maximum size of this component to a constant
  1670. * value. Subsequent calls to <code>getMaximumSize</code> will always
  1671. * return this value; the component's UI will not be asked
  1672. * to compute it. Setting the maximum size to <code>null</code>
  1673. * restores the default behavior.
  1674. *
  1675. * @param maximumSize a <code>Dimension</code> containing the
  1676. * desired maximum allowable size
  1677. * @see #getMaximumSize
  1678. * @beaninfo
  1679. * bound: true
  1680. * description: The maximum size of the component.
  1681. */
  1682. public void setMaximumSize(Dimension maximumSize) {
  1683. super.setMaximumSize(maximumSize);
  1684. }
  1685.  
  1686.  
  1687. /**
  1688. * If the maximum size has been set to a non-<code>null</code> value
  1689. * just returns it. If the UI delegate's <code>getMaximumSize</code>
  1690. * method returns a non-<code>null</code> value then return that;
  1691. * otherwise defer to the component's layout manager.
  1692. *
  1693. * @return the value of the <code>maximumSize</code> property
  1694. * @see #setMaximumSize
  1695. * @see ComponentUI
  1696. */
  1697. @Transient
  1698. public Dimension getMaximumSize() {
  1699. if (isMaximumSizeSet()) {
  1700. return super.getMaximumSize();
  1701. }
  1702. Dimension size = null;
  1703. if (ui != null) {
  1704. size = ui.getMaximumSize(this);
  1705. }
  1706. return (size != null) ? size : super.getMaximumSize();
  1707. }
  1708.  
  1709.  
  1710. /**
  1711. * Sets the minimum size of this component to a constant
  1712. * value. Subsequent calls to <code>getMinimumSize</code> will always
  1713. * return this value; the component's UI will not be asked
  1714. * to compute it. Setting the minimum size to <code>null</code>
  1715. * restores the default behavior.
  1716. *
  1717. * @param minimumSize the new minimum size of this component
  1718. * @see #getMinimumSize
  1719. * @beaninfo
  1720. * bound: true
  1721. * description: The minimum size of the component.
  1722. */
  1723. public void setMinimumSize(Dimension minimumSize) {
  1724. super.setMinimumSize(minimumSize);
  1725. }
  1726.  
  1727. /**
  1728. * If the minimum size has been set to a non-<code>null</code> value
  1729. * just returns it. If the UI delegate's <code>getMinimumSize</code>
  1730. * method returns a non-<code>null</code> value then return that; otherwise
  1731. * defer to the component's layout manager.
  1732. *
  1733. * @return the value of the <code>minimumSize</code> property
  1734. * @see #setMinimumSize
  1735. * @see ComponentUI
  1736. */
  1737. @Transient
  1738. public Dimension getMinimumSize() {
  1739. if (isMinimumSizeSet()) {
  1740. return super.getMinimumSize();
  1741. }
  1742. Dimension size = null;
  1743. if (ui != null) {
  1744. size = ui.getMinimumSize(this);
  1745. }
  1746. return (size != null) ? size : super.getMinimumSize();
  1747. }
  1748.  
  1749. /**
  1750. * Gives the UI delegate an opportunity to define the precise
  1751. * shape of this component for the sake of mouse processing.
  1752. *
  1753. * @return true if this component logically contains x,y
  1754. * @see java.awt.Component#contains(int, int)
  1755. * @see ComponentUI
  1756. */
  1757. public boolean contains(int x, int y) {
  1758. return (ui != null) ? ui.contains(this, x, y) : super.contains(x, y);
  1759. }
  1760.  
  1761. /**
  1762. * Sets the border of this component. The <code>Border</code> object is
  1763. * responsible for defining the insets for the component
  1764. * (overriding any insets set directly on the component) and
  1765. * for optionally rendering any border decorations within the
  1766. * bounds of those insets. Borders should be used (rather
  1767. * than insets) for creating both decorative and non-decorative
  1768. * (such as margins and padding) regions for a swing component.
  1769. * Compound borders can be used to nest multiple borders within a
  1770. * single component.
  1771. * <p>
  1772. * Although technically you can set the border on any object
  1773. * that inherits from <code>JComponent</code>, the look and
  1774. * feel implementation of many standard Swing components
  1775. * doesn't work well with user-set borders. In general,
  1776. * when you want to set a border on a standard Swing
  1777. * component other than <code>JPanel</code> or <code>JLabel</code>,
  1778. * we recommend that you put the component in a <code>JPanel</code>
  1779. * and set the border on the <code>JPanel</code>.
  1780. * <p>
  1781. * This is a bound property.
  1782. *
  1783. * @param border the border to be rendered for this component
  1784. * @see Border
  1785. * @see CompoundBorder
  1786. * @beaninfo
  1787. * bound: true
  1788. * preferred: true
  1789. * attribute: visualUpdate true
  1790. * description: The component's border.
  1791. */
  1792. public void setBorder(Border border) {
  1793. Border oldBorder = this.border;
  1794.  
  1795. this.border = border;
  1796. firePropertyChange("border", oldBorder, border);
  1797. if (border != oldBorder) {
  1798. if (border == null || oldBorder == null ||
  1799. !(border.getBorderInsets(this).equals(oldBorder.getBorderInsets(this)))) {
  1800. revalidate();
  1801. }
  1802. repaint();
  1803. }
  1804. }
  1805.  
  1806. /**
  1807. * Returns the border of this component or <code>null</code> if no
  1808. * border is currently set.
  1809. *
  1810. * @return the border object for this component
  1811. * @see #setBorder
  1812. */
  1813. public Border getBorder() {
  1814. return border;
  1815. }
  1816.  
  1817. /**
  1818. * If a border has been set on this component, returns the
  1819. * border's insets; otherwise calls <code>super.getInsets</code>.
  1820. *
  1821. * @return the value of the insets property
  1822. * @see #setBorder
  1823. */
  1824. public Insets getInsets() {
  1825. if (border != null) {
  1826. return border.getBorderInsets(this);
  1827. }
  1828. return super.getInsets();
  1829. }
  1830.  
  1831. /**
  1832. * Returns an <code>Insets</code> object containing this component's inset
  1833. * values. The passed-in <code>Insets</code> object will be reused
  1834. * if possible.
  1835. * Calling methods cannot assume that the same object will be returned,
  1836. * however. All existing values within this object are overwritten.
  1837. * If <code>insets</code> is null, this will allocate a new one.
  1838. *
  1839. * @param insets the <code>Insets</code> object, which can be reused
  1840. * @return the <code>Insets</code> object
  1841. * @see #getInsets
  1842. * @beaninfo
  1843. * expert: true
  1844. */
  1845. public Insets getInsets(Insets insets) {
  1846. if (insets == null) {
  1847. insets = new Insets(0, 0, 0, 0);
  1848. }
  1849. if (border != null) {
  1850. if (border instanceof AbstractBorder) {
  1851. return ((AbstractBorder)border).getBorderInsets(this, insets);
  1852. } else {
  1853. // Can't reuse border insets because the Border interface
  1854. // can't be enhanced.
  1855. return border.getBorderInsets(this);
  1856. }
  1857. } else {
  1858. // super.getInsets() always returns an Insets object with
  1859. // all of its value zeroed. No need for a new object here.
  1860. insets.left = insets.top = insets.right = insets.bottom = 0;
  1861. return insets;
  1862. }
  1863. }
  1864.  
  1865. /**
  1866. * Overrides <code>Container.getAlignmentY</code> to return
  1867. * the horizontal alignment.
  1868. *
  1869. * @return the value of the <code>alignmentY</code> property
  1870. * @see #setAlignmentY
  1871. * @see java.awt.Component#getAlignmentY
  1872. */
  1873. public float getAlignmentY() {
  1874. if (isAlignmentYSet) {
  1875. return alignmentY;
  1876. }
  1877. return super.getAlignmentY();
  1878. }
  1879.  
  1880. /**
  1881. * Sets the the horizontal alignment.
  1882. *
  1883. * @param alignmentY the new horizontal alignment
  1884. * @see #getAlignmentY
  1885. * @beaninfo
  1886. * description: The preferred vertical alignment of the component.
  1887. */
  1888. public void setAlignmentY(float alignmentY) {
  1889. this.alignmentY = alignmentY > 1.0f ? 1.0f : alignmentY < 0.0f ? 0.0f : alignmentY;
  1890. isAlignmentYSet = true;
  1891. }
  1892.  
  1893.  
  1894. /**
  1895. * Overrides <code>Container.getAlignmentX</code> to return
  1896. * the vertical alignment.
  1897. *
  1898. * @return the value of the <code>alignmentX</code> property
  1899. * @see #setAlignmentX
  1900. * @see java.awt.Component#getAlignmentX
  1901. */
  1902. public float getAlignmentX() {
  1903. if (isAlignmentXSet) {
  1904. return alignmentX;
  1905. }
  1906. return super.getAlignmentX();
  1907. }
  1908.  
  1909. /**
  1910. * Sets the the vertical alignment.
  1911. *
  1912. * @param alignmentX the new vertical alignment
  1913. * @see #getAlignmentX
  1914. * @beaninfo
  1915. * description: The preferred horizontal alignment of the component.
  1916. */
  1917. public void setAlignmentX(float alignmentX) {
  1918. this.alignmentX = alignmentX > 1.0f ? 1.0f : alignmentX < 0.0f ? 0.0f : alignmentX;
  1919. isAlignmentXSet = true;
  1920. }
  1921.  
  1922. /**
  1923. * Sets the input verifier for this component.
  1924. *
  1925. * @param inputVerifier the new input verifier
  1926. * @since 1.3
  1927. * @see InputVerifier
  1928. * @beaninfo
  1929. * bound: true
  1930. * description: The component's input verifier.
  1931. */
  1932. public void setInputVerifier(InputVerifier inputVerifier) {
  1933. InputVerifier oldInputVerifier = (InputVerifier)getClientProperty(
  1934. JComponent_INPUT_VERIFIER);
  1935. putClientProperty(JComponent_INPUT_VERIFIER, inputVerifier);
  1936. firePropertyChange("inputVerifier", oldInputVerifier, inputVerifier);
  1937. }
  1938.  
  1939. /**
  1940. * Returns the input verifier for this component.
  1941. *
  1942. * @return the <code>inputVerifier</code> property
  1943. * @since 1.3
  1944. * @see InputVerifier
  1945. */
  1946. public InputVerifier getInputVerifier() {
  1947. return (InputVerifier)getClientProperty(JComponent_INPUT_VERIFIER);
  1948. }
  1949.  
  1950. /**
  1951. * Returns this component's graphics context, which lets you draw
  1952. * on a component. Use this method to get a <code>Graphics</code> object and
  1953. * then invoke operations on that object to draw on the component.
  1954. * @return this components graphics context
  1955. */
  1956. public Graphics getGraphics() {
  1957. if (DEBUG_GRAPHICS_LOADED && shouldDebugGraphics() != 0) {
  1958. DebugGraphics graphics = new DebugGraphics(super.getGraphics(),
  1959. this);
  1960. return graphics;
  1961. }
  1962. return super.getGraphics();
  1963. }
  1964.  
  1965.  
  1966. /** Enables or disables diagnostic information about every graphics
  1967. * operation performed within the component or one of its children.
  1968. *
  1969. * @param debugOptions determines how the component should display
  1970. * the information; one of the following options:
  1971. * <ul>
  1972. * <li>DebugGraphics.LOG_OPTION - causes a text message to be printed.
  1973. * <li>DebugGraphics.FLASH_OPTION - causes the drawing to flash several
  1974. * times.
  1975. * <li>DebugGraphics.BUFFERED_OPTION - creates an
  1976. * <code>ExternalWindow</code> that displays the operations
  1977. * performed on the View's offscreen buffer.
  1978. * <li>DebugGraphics.NONE_OPTION disables debugging.
  1979. * <li>A value of 0 causes no changes to the debugging options.
  1980. * </ul>
  1981. * <code>debugOptions</code> is bitwise OR'd into the current value
  1982. *
  1983. * @beaninfo
  1984. * preferred: true
  1985. * enum: NONE_OPTION DebugGraphics.NONE_OPTION
  1986. * LOG_OPTION DebugGraphics.LOG_OPTION
  1987. * FLASH_OPTION DebugGraphics.FLASH_OPTION
  1988. * BUFFERED_OPTION DebugGraphics.BUFFERED_OPTION
  1989. * description: Diagnostic options for graphics operations.
  1990. */
  1991. public void setDebugGraphicsOptions(int debugOptions) {
  1992. DebugGraphics.setDebugOptions(this, debugOptions);
  1993. }
  1994.  
  1995. /** Returns the state of graphics debugging.
  1996. *
  1997. * @return a bitwise OR'd flag of zero or more of the following options:
  1998. * <ul>
  1999. * <li>DebugGraphics.LOG_OPTION - causes a text message to be printed.
  2000. * <li>DebugGraphics.FLASH_OPTION - causes the drawing to flash several
  2001. * times.
  2002. * <li>DebugGraphics.BUFFERED_OPTION - creates an
  2003. * <code>ExternalWindow</code> that displays the operations
  2004. * performed on the View's offscreen buffer.
  2005. * <li>DebugGraphics.NONE_OPTION disables debugging.
  2006. * <li>A value of 0 causes no changes to the debugging options.
  2007. * </ul>
  2008. * @see #setDebugGraphicsOptions
  2009. */
  2010. public int getDebugGraphicsOptions() {
  2011. return DebugGraphics.getDebugOptions(this);
  2012. }
  2013.  
  2014.  
  2015. /**
  2016. * Returns true if debug information is enabled for this
  2017. * <code>JComponent</code> or one of its parents.
  2018. */
  2019. int shouldDebugGraphics() {
  2020. return DebugGraphics.shouldComponentDebug(this);
  2021. }
  2022.  
  2023. /**
  2024. * This method is now obsolete, please use a combination of
  2025. * <code>getActionMap()</code> and <code>getInputMap()</code> for
  2026. * similar behavior. For example, to bind the <code>KeyStroke</code>
  2027. * <code>aKeyStroke</code> to the <code>Action</code> <code>anAction</code>
  2028. * now use:
  2029. * <pre>
  2030. * component.getInputMap().put(aKeyStroke, aCommand);
  2031. * component.getActionMap().put(aCommmand, anAction);
  2032. * </pre>
  2033. * The above assumes you want the binding to be applicable for
  2034. * <code>WHEN_FOCUSED</code>. To register bindings for other focus
  2035. * states use the <code>getInputMap</code> method that takes an integer.
  2036. * <p>
  2037. * Register a new keyboard action.
  2038. * <code>anAction</code> will be invoked if a key event matching
  2039. * <code>aKeyStroke</code> occurs and <code>aCondition</code> is verified.
  2040. * The <code>KeyStroke</code> object defines a
  2041. * particular combination of a keyboard key and one or more modifiers
  2042. * (alt, shift, ctrl, meta).
  2043. * <p>
  2044. * The <code>aCommand</code> will be set in the delivered event if
  2045. * specified.
  2046. * <p>
  2047. * The <code>aCondition</code> can be one of:
  2048. * <blockquote>
  2049. * <DL>
  2050. * <DT>WHEN_FOCUSED
  2051. * <DD>The action will be invoked only when the keystroke occurs
  2052. * while the component has the focus.
  2053. * <DT>WHEN_IN_FOCUSED_WINDOW
  2054. * <DD>The action will be invoked when the keystroke occurs while
  2055. * the component has the focus or if the component is in the
  2056. * window that has the focus. Note that the component need not
  2057. * be an immediate descendent of the window -- it can be
  2058. * anywhere in the window's containment hierarchy. In other
  2059. * words, whenever <em>any</em> component in the window has the focus,
  2060. * the action registered with this component is invoked.
  2061. * <DT>WHEN_ANCESTOR_OF_FOCUSED_COMPONENT
  2062. * <DD>The action will be invoked when the keystroke occurs while the
  2063. * component has the focus or if the component is an ancestor of
  2064. * the component that has the focus.
  2065. * </DL>
  2066. * </blockquote>
  2067. * <p>
  2068. * The combination of keystrokes and conditions lets you define high
  2069. * level (semantic) action events for a specified keystroke+modifier
  2070. * combination (using the KeyStroke class) and direct to a parent or
  2071. * child of a component that has the focus, or to the component itself.
  2072. * In other words, in any hierarchical structure of components, an
  2073. * arbitrary key-combination can be immediately directed to the
  2074. * appropriate component in the hierarchy, and cause a specific method
  2075. * to be invoked (usually by way of adapter objects).
  2076. * <p>
  2077. * If an action has already been registered for the receiving
  2078. * container, with the same charCode and the same modifiers,
  2079. * <code>anAction</code> will replace the action.
  2080. *
  2081. * @param anAction the <code>Action</code> to be registered
  2082. * @param aCommand the command to be set in the delivered event
  2083. * @param aKeyStroke the <code>KeyStroke</code> to bind to the action
  2084. * @param aCondition the condition that needs to be met, see above
  2085. * @see KeyStroke
  2086. */
  2087. public void registerKeyboardAction(ActionListener anAction,String aCommand,KeyStroke aKeyStroke,int aCondition) {
  2088.  
  2089. InputMap inputMap = getInputMap(aCondition, true);
  2090.  
  2091. if (inputMap != null) {
  2092. ActionMap actionMap = getActionMap(true);
  2093. ActionStandin action = new ActionStandin(anAction, aCommand);
  2094. inputMap.put(aKeyStroke, action);
  2095. if (actionMap != null) {
  2096. actionMap.put(action, action);
  2097. }
  2098. }
  2099. }
  2100.  
  2101. /**
  2102. * Registers any bound <code>WHEN_IN_FOCUSED_WINDOW</code> actions with
  2103. * the <code>KeyboardManager</code>. If <code>onlyIfNew</code>
  2104. * is true only actions that haven't been registered are pushed
  2105. * to the <code>KeyboardManager</code>;
  2106. * otherwise all actions are pushed to the <code>KeyboardManager</code>.
  2107. *
  2108. * @param onlyIfNew if true, only actions that haven't been registered
  2109. * are pushed to the <code>KeyboardManager</code>
  2110. */
  2111. private void registerWithKeyboardManager(boolean onlyIfNew) {
  2112. InputMap inputMap = getInputMap(WHEN_IN_FOCUSED_WINDOW, false);
  2113. KeyStroke[] strokes;
  2114. Hashtable<KeyStroke, KeyStroke> registered =
  2115. (Hashtable<KeyStroke, KeyStroke>)getClientProperty
  2116. (WHEN_IN_FOCUSED_WINDOW_BINDINGS);
  2117.  
  2118. if (inputMap != null) {
  2119. // Push any new KeyStrokes to the KeyboardManager.
  2120. strokes = inputMap.allKeys();
  2121. if (strokes != null) {
  2122. for (int counter = strokes.length - 1; counter >= 0;
  2123. counter--) {
  2124. if (!onlyIfNew || registered == null ||
  2125. registered.get(strokes[counter]) == null) {
  2126. registerWithKeyboardManager(strokes[counter]);
  2127. }
  2128. if (registered != null) {
  2129. registered.remove(strokes[counter]);
  2130. }
  2131. }
  2132. }
  2133. }
  2134. else {
  2135. strokes = null;
  2136. }
  2137. // Remove any old ones.
  2138. if (registered != null && registered.size() > 0) {
  2139. Enumeration<KeyStroke> keys = registered.keys();
  2140.  
  2141. while (keys.hasMoreElements()) {
  2142. KeyStroke ks = keys.nextElement();
  2143. unregisterWithKeyboardManager(ks);
  2144. }
  2145. registered.clear();
  2146. }
  2147. // Updated the registered Hashtable.
  2148. if (strokes != null && strokes.length > 0) {
  2149. if (registered == null) {
  2150. registered = new Hashtable<KeyStroke, KeyStroke>(strokes.length);
  2151. putClientProperty(WHEN_IN_FOCUSED_WINDOW_BINDINGS, registered);
  2152. }
  2153. for (int counter = strokes.length - 1; counter >= 0; counter--) {
  2154. registered.put(strokes[counter], strokes[counter]);
  2155. }
  2156. }
  2157. else {
  2158. putClientProperty(WHEN_IN_FOCUSED_WINDOW_BINDINGS, null);
  2159. }
  2160. }
  2161.  
  2162. /**
  2163. * Unregisters all the previously registered
  2164. * <code>WHEN_IN_FOCUSED_WINDOW</code> <code>KeyStroke</code> bindings.
  2165. */
  2166. private void unregisterWithKeyboardManager() {
  2167. Hashtable<KeyStroke, KeyStroke> registered =
  2168. (Hashtable<KeyStroke, KeyStroke>)getClientProperty
  2169. (WHEN_IN_FOCUSED_WINDOW_BINDINGS);
  2170.  
  2171. if (registered != null && registered.size() > 0) {
  2172. Enumeration<KeyStroke> keys = registered.keys();
  2173.  
  2174. while (keys.hasMoreElements()) {
  2175. KeyStroke ks = keys.nextElement();
  2176. unregisterWithKeyboardManager(ks);
  2177. }
  2178. }
  2179. putClientProperty(WHEN_IN_FOCUSED_WINDOW_BINDINGS, null);
  2180. }
  2181.  
  2182. /**
  2183. * Invoked from <code>ComponentInputMap</code> when its bindings change.
  2184. * If <code>inputMap</code> is the current <code>windowInputMap</code>
  2185. * (or a parent of the window <code>InputMap</code>)
  2186. * the <code>KeyboardManager</code> is notified of the new bindings.
  2187. *
  2188. * @param inputMap the map containing the new bindings
  2189. */
  2190. void componentInputMapChanged(ComponentInputMap inputMap) {
  2191. InputMap km = getInputMap(WHEN_IN_FOCUSED_WINDOW, false);
  2192.  
  2193. while (km != inputMap && km != null) {
  2194. km = km.getParent();
  2195. }
  2196. if (km != null) {
  2197. registerWithKeyboardManager(false);
  2198. }
  2199. }
  2200.  
  2201. private void registerWithKeyboardManager(KeyStroke aKeyStroke) {
  2202. KeyboardManager.getCurrentManager().registerKeyStroke(aKeyStroke,this);
  2203. }
  2204.  
  2205. private void unregisterWithKeyboardManager(KeyStroke aKeyStroke) {
  2206. KeyboardManager.getCurrentManager().unregisterKeyStroke(aKeyStroke,
  2207. this);
  2208. }
  2209.  
  2210. /**
  2211. * This method is now obsolete, please use a combination of
  2212. * <code>getActionMap()</code> and <code>getInputMap()</code> for
  2213. * similar behavior.
  2214. */
  2215. public void registerKeyboardAction(ActionListener anAction,KeyStroke aKeyStroke,int aCondition) {
  2216. registerKeyboardAction(anAction,null,aKeyStroke,aCondition);
  2217. }
  2218.  
  2219. /**
  2220. * This method is now obsolete. To unregister an existing binding
  2221. * you can either remove the binding from the
  2222. * <code>ActionMap/InputMap</code>, or place a dummy binding the
  2223. * <code>InputMap</code>. Removing the binding from the
  2224. * <code>InputMap</code> allows bindings in parent <code>InputMap</code>s
  2225. * to be active, whereas putting a dummy binding in the
  2226. * <code>InputMap</code> effectively disables
  2227. * the binding from ever happening.
  2228. * <p>
  2229. * Unregisters a keyboard action.
  2230. * This will remove the binding from the <code>ActionMap</code>
  2231. * (if it exists) as well as the <code>InputMap</code>s.
  2232. */
  2233. public void unregisterKeyboardAction(KeyStroke aKeyStroke) {
  2234. ActionMap am = getActionMap(false);
  2235. for (int counter = 0; counter < 3; counter++) {
  2236. InputMap km = getInputMap(counter, false);
  2237. if (km != null) {
  2238. Object actionID = km.get(aKeyStroke);
  2239.  
  2240. if (am != null && actionID != null) {
  2241. am.remove(actionID);
  2242. }
  2243. km.remove(aKeyStroke);
  2244. }
  2245. }
  2246. }
  2247.  
  2248. /**
  2249. * Returns the <code>KeyStrokes</code> that will initiate
  2250. * registered actions.
  2251. *
  2252. * @return an array of <code>KeyStroke</code> objects
  2253. * @see #registerKeyboardAction
  2254. */
  2255. public KeyStroke[] getRegisteredKeyStrokes() {
  2256. int[] counts = new int[3];
  2257. KeyStroke[][] strokes = new KeyStroke[3][];
  2258.  
  2259. for (int counter = 0; counter < 3; counter++) {
  2260. InputMap km = getInputMap(counter, false);
  2261. strokes[counter] = (km != null) ? km.allKeys() : null;
  2262. counts[counter] = (strokes[counter] != null) ?
  2263. strokes[counter].length : 0;
  2264. }
  2265. KeyStroke[] retValue = new KeyStroke[counts[0] + counts[1] +
  2266. counts[2]];
  2267. for (int counter = 0, last = 0; counter < 3; counter++) {
  2268. if (counts[counter] > 0) {
  2269. System.arraycopy(strokes[counter], 0, retValue, last,
  2270. counts[counter]);
  2271. last += counts[counter];
  2272. }
  2273. }
  2274. return retValue;
  2275. }
  2276.  
  2277. /**
  2278. * Returns the condition that determines whether a registered action
  2279. * occurs in response to the specified keystroke.
  2280. * <p>
  2281. * For Java 2 platform v1.3, a <code>KeyStroke</code> can be associated
  2282. * with more than one condition.
  2283. * For example, 'a' could be bound for the two
  2284. * conditions <code>WHEN_FOCUSED</code> and
  2285. * <code>WHEN_IN_FOCUSED_WINDOW</code> condition.
  2286. *
  2287. * @return the action-keystroke condition
  2288. */
  2289. public int getConditionForKeyStroke(KeyStroke aKeyStroke) {
  2290. for (int counter = 0; counter < 3; counter++) {
  2291. InputMap inputMap = getInputMap(counter, false);
  2292. if (inputMap != null && inputMap.get(aKeyStroke) != null) {
  2293. return counter;
  2294. }
  2295. }
  2296. return UNDEFINED_CONDITION;
  2297. }
  2298.  
  2299. /**
  2300. * Returns the object that will perform the action registered for a
  2301. * given keystroke.
  2302. *
  2303. * @return the <code>ActionListener</code>
  2304. * object invoked when the keystroke occurs
  2305. */
  2306. public ActionListener getActionForKeyStroke(KeyStroke aKeyStroke) {
  2307. ActionMap am = getActionMap(false);
  2308.  
  2309. if (am == null) {
  2310. return null;
  2311. }
  2312. for (int counter = 0; counter < 3; counter++) {
  2313. InputMap inputMap = getInputMap(counter, false);
  2314. if (inputMap != null) {
  2315. Object actionBinding = inputMap.get(aKeyStroke);
  2316.  
  2317. if (actionBinding != null) {
  2318. Action action = am.get(actionBinding);
  2319. if (action instanceof ActionStandin) {
  2320. return ((ActionStandin)action).actionListener;
  2321. }
  2322. return action;
  2323. }
  2324. }
  2325. }
  2326. return null;
  2327. }
  2328.  
  2329. /**
  2330. * Unregisters all the bindings in the first tier <code>InputMaps</code>
  2331. * and <code>ActionMap</code>. This has the effect of removing any
  2332. * local bindings, and allowing the bindings defined in parent
  2333. * <code>InputMap/ActionMaps</code>
  2334. * (the UI is usually defined in the second tier) to persist.
  2335. */
  2336. public void resetKeyboardActions() {
  2337. // Keys
  2338. for (int counter = 0; counter < 3; counter++) {
  2339. InputMap inputMap = getInputMap(counter, false);
  2340.  
  2341. if (inputMap != null) {
  2342. inputMap.clear();
  2343. }
  2344. }
  2345.  
  2346. // Actions
  2347. ActionMap am = getActionMap(false);
  2348.  
  2349. if (am != null) {
  2350. am.clear();
  2351. }
  2352. }
  2353.  
  2354. /**
  2355. * Sets the <code>InputMap</code> to use under the condition
  2356. * <code>condition</code> to
  2357. * <code>map</code>. A <code>null</code> value implies you
  2358. * do not want any bindings to be used, even from the UI. This will
  2359. * not reinstall the UI <code>InputMap</code> (if there was one).
  2360. * <code>condition</code> has one of the following values:
  2361. * <ul>
  2362. * <li><code>WHEN_IN_FOCUSED_WINDOW</code>
  2363. * <li><code>WHEN_FOCUSED</code>
  2364. * <li><code>WHEN_ANCESTOR_OF_FOCUSED_COMPONENT</code>
  2365. * </ul>
  2366. * If <code>condition</code> is <code>WHEN_IN_FOCUSED_WINDOW</code>
  2367. * and <code>map</code> is not a <code>ComponentInputMap</code>, an
  2368. * <code>IllegalArgumentException</code> will be thrown.
  2369. * Similarly, if <code>condition</code> is not one of the values
  2370. * listed, an <code>IllegalArgumentException</code> will be thrown.
  2371. *
  2372. * @param condition one of the values listed above
  2373. * @param map the <code>InputMap</code> to use for the given condition
  2374. * @exception IllegalArgumentException if <code>condition</code> is
  2375. * <code>WHEN_IN_FOCUSED_WINDOW</code> and <code>map</code>
  2376. * is not an instance of <code>ComponentInputMap</code>; or
  2377. * if <code>condition</code> is not one of the legal values
  2378. * specified above
  2379. * @since 1.3
  2380. */
  2381. public final void setInputMap(int condition, InputMap map) {
  2382. switch (condition) {
  2383. case WHEN_IN_FOCUSED_WINDOW:
  2384. if (map != null && !(map instanceof ComponentInputMap)) {
  2385. throw new IllegalArgumentException("WHEN_IN_FOCUSED_WINDOW InputMaps must be of type ComponentInputMap");
  2386. }
  2387. windowInputMap = (ComponentInputMap)map;
  2388. setFlag(WIF_INPUTMAP_CREATED, true);
  2389. registerWithKeyboardManager(false);
  2390. break;
  2391. case WHEN_ANCESTOR_OF_FOCUSED_COMPONENT:
  2392. ancestorInputMap = map;
  2393. setFlag(ANCESTOR_INPUTMAP_CREATED, true);
  2394. break;
  2395. case WHEN_FOCUSED:
  2396. focusInputMap = map;
  2397. setFlag(FOCUS_INPUTMAP_CREATED, true);
  2398. break;
  2399. default:
  2400. throw new IllegalArgumentException("condition must be one of JComponent.WHEN_IN_FOCUSED_WINDOW, JComponent.WHEN_FOCUSED or JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT");
  2401. }
  2402. }
  2403.  
  2404. /**
  2405. * Returns the <code>InputMap</code> that is used during
  2406. * <code>condition</code>.
  2407. *
  2408. * @param condition one of WHEN_IN_FOCUSED_WINDOW, WHEN_FOCUSED,
  2409. * WHEN_ANCESTOR_OF_FOCUSED_COMPONENT
  2410. * @return the <code>InputMap</code> for the specified
  2411. * <code>condition</code>
  2412. * @since 1.3
  2413. */
  2414. public final InputMap getInputMap(int condition) {
  2415. return getInputMap(condition, true);
  2416. }
  2417.  
  2418. /**
  2419. * Returns the <code>InputMap</code> that is used when the
  2420. * component has focus.
  2421. * This is convenience method for <code>getInputMap(WHEN_FOCUSED)</code>.
  2422. *
  2423. * @return the <code>InputMap</code> used when the component has focus
  2424. * @since 1.3
  2425. */
  2426. public final InputMap getInputMap() {
  2427. return getInputMap(WHEN_FOCUSED, true);
  2428. }
  2429.  
  2430. /**
  2431. * Sets the <code>ActionMap</code> to <code>am</code>. This does not set
  2432. * the parent of the <code>am</code> to be the <code>ActionMap</code>
  2433. * from the UI (if there was one), it is up to the caller to have done this.
  2434. *
  2435. * @param am the new <code>ActionMap</code>
  2436. * @since 1.3
  2437. */
  2438. public final void setActionMap(ActionMap am) {
  2439. actionMap = am;
  2440. setFlag(ACTIONMAP_CREATED, true);
  2441. }
  2442.  
  2443. /**
  2444. * Returns the <code>ActionMap</code> used to determine what
  2445. * <code>Action</code> to fire for particular <code>KeyStroke</code>
  2446. * binding. The returned <code>ActionMap</code>, unless otherwise
  2447. * set, will have the <code>ActionMap</code> from the UI set as the parent.
  2448. *
  2449. * @return the <code>ActionMap</code> containing the key/action bindings
  2450. * @since 1.3
  2451. */
  2452. public final ActionMap getActionMap() {
  2453. return getActionMap(true);
  2454. }
  2455.  
  2456. /**
  2457. * Returns the <code>InputMap</code> to use for condition
  2458. * <code>condition</code>. If the <code>InputMap</code> hasn't
  2459. * been created, and <code>create</code> is
  2460. * true, it will be created.
  2461. *
  2462. * @param condition one of the following values:
  2463. * <ul>
  2464. * <li>JComponent.FOCUS_INPUTMAP_CREATED
  2465. * <li>JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT
  2466. * <li>JComponent.WHEN_IN_FOCUSED_WINDOW
  2467. * </ul>
  2468. * @param create if true, create the <code>InputMap</code> if it
  2469. * is not already created
  2470. * @return the <code>InputMap</code> for the given <code>condition</code>;
  2471. * if <code>create</code> is false and the <code>InputMap</code>
  2472. * hasn't been created, returns <code>null</code>
  2473. * @exception IllegalArgumentException if <code>condition</code>
  2474. * is not one of the legal values listed above
  2475. */
  2476. final InputMap getInputMap(int condition, boolean create) {
  2477. switch (condition) {
  2478. case WHEN_FOCUSED:
  2479. if (getFlag(FOCUS_INPUTMAP_CREATED)) {
  2480. return focusInputMap;
  2481. }
  2482. // Hasn't been created yet.
  2483. if (create) {
  2484. InputMap km = new InputMap();
  2485. setInputMap(condition, km);
  2486. return km;
  2487. }
  2488. break;
  2489. case WHEN_ANCESTOR_OF_FOCUSED_COMPONENT:
  2490. if (getFlag(ANCESTOR_INPUTMAP_CREATED)) {
  2491. return ancestorInputMap;
  2492. }
  2493. // Hasn't been created yet.
  2494. if (create) {
  2495. InputMap km = new InputMap();
  2496. setInputMap(condition, km);
  2497. return km;
  2498. }
  2499. break;
  2500. case WHEN_IN_FOCUSED_WINDOW:
  2501. if (getFlag(WIF_INPUTMAP_CREATED)) {
  2502. return windowInputMap;
  2503. }
  2504. // Hasn't been created yet.
  2505. if (create) {
  2506. ComponentInputMap km = new ComponentInputMap(this);
  2507. setInputMap(condition, km);
  2508. return km;
  2509. }
  2510. break;
  2511. default:
  2512. throw new IllegalArgumentException("condition must be one of JComponent.WHEN_IN_FOCUSED_WINDOW, JComponent.WHEN_FOCUSED or JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT");
  2513. }
  2514. return null;
  2515. }
  2516.  
  2517. /**
  2518. * Finds and returns the appropriate <code>ActionMap</code>.
  2519. *
  2520. * @param create if true, create the <code>ActionMap</code> if it
  2521. * is not already created
  2522. * @return the <code>ActionMap</code> for this component; if the
  2523. * <code>create</code> flag is false and there is no
  2524. * current <code>ActionMap</code>, returns <code>null</code>
  2525. */
  2526. final ActionMap getActionMap(boolean create) {
  2527. if (getFlag(ACTIONMAP_CREATED)) {
  2528. return actionMap;
  2529. }
  2530. // Hasn't been created.
  2531. if (create) {
  2532. ActionMap am = new ActionMap();
  2533. setActionMap(am);
  2534. return am;
  2535. }
  2536. return null;
  2537. }
  2538.  
  2539. /**
  2540. * Returns the baseline. The baseline is measured from the top of
  2541. * the component. This method is primarily meant for
  2542. * <code>LayoutManager</code>s to align components along their
  2543. * baseline. A return value less than 0 indicates this component
  2544. * does not have a reasonable baseline and that
  2545. * <code>LayoutManager</code>s should not align this component on
  2546. * its baseline.
  2547. * <p>
  2548. * This method calls into the <code>ComponentUI</code> method of the
  2549. * same name. If this component does not have a <code>ComponentUI</code>
  2550. * -1 will be returned. If a value &gt;= 0 is
  2551. * returned, then the component has a valid baseline for any
  2552. * size &gt;= the minimum size and <code>getBaselineResizeBehavior</code>
  2553. * can be used to determine how the baseline changes with size.
  2554. *
  2555. * @throws IllegalArgumentException {@inheritDoc}
  2556. * @see #getBaselineResizeBehavior
  2557. * @see java.awt.FontMetrics
  2558. * @since 1.6
  2559. */
  2560. public int getBaseline(int width, int height) {
  2561. // check size.
  2562. super.getBaseline(width, height);
  2563. if (ui != null) {
  2564. return ui.getBaseline(this, width, height);
  2565. }
  2566. return -1;
  2567. }
  2568.  
  2569. /**
  2570. * Returns an enum indicating how the baseline of the component
  2571. * changes as the size changes. This method is primarily meant for
  2572. * layout managers and GUI builders.
  2573. * <p>
  2574. * This method calls into the <code>ComponentUI</code> method of
  2575. * the same name. If this component does not have a
  2576. * <code>ComponentUI</code>
  2577. * <code>BaselineResizeBehavior.OTHER</code> will be
  2578. * returned. Subclasses should
  2579. * never return <code>null</code>; if the baseline can not be
  2580. * calculated return <code>BaselineResizeBehavior.OTHER</code>. Callers
  2581. * should first ask for the baseline using
  2582. * <code>getBaseline</code> and if a value &gt;= 0 is returned use
  2583. * this method. It is acceptable for this method to return a
  2584. * value other than <code>BaselineResizeBehavior.OTHER</code> even if
  2585. * <code>getBaseline</code> returns a value less than 0.
  2586. *
  2587. * @see #getBaseline(int, int)
  2588. * @since 1.6
  2589. */
  2590. public BaselineResizeBehavior getBaselineResizeBehavior() {
  2591. if (ui != null) {
  2592. return ui.getBaselineResizeBehavior(this);
  2593. }
  2594. return BaselineResizeBehavior.OTHER;
  2595. }
  2596.  
  2597. /**
  2598. * In release 1.4, the focus subsystem was rearchitected.
  2599. * For more information, see
  2600. * <a href="https://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html">
  2601. * How to Use the Focus Subsystem</a>,
  2602. * a section in <em>The Java Tutorial</em>.
  2603. * <p>
  2604. * Requests focus on this <code>JComponent</code>'s
  2605. * <code>FocusTraversalPolicy</code>'s default <code>Component</code>.
  2606. * If this <code>JComponent</code> is a focus cycle root, then its
  2607. * <code>FocusTraversalPolicy</code> is used. Otherwise, the
  2608. * <code>FocusTraversalPolicy</code> of this <code>JComponent</code>'s
  2609. * focus-cycle-root ancestor is used.
  2610. *
  2611. * @see java.awt.FocusTraversalPolicy#getDefaultComponent
  2612. * @deprecated As of 1.4, replaced by
  2613. * <code>FocusTraversalPolicy.getDefaultComponent(Container).requestFocus()</code>
  2614. */
  2615. @Deprecated
  2616. public boolean requestDefaultFocus() {
  2617. Container nearestRoot =
  2618. (isFocusCycleRoot()) ? this : getFocusCycleRootAncestor();
  2619. if (nearestRoot == null) {
  2620. return false;
  2621. }
  2622. Component comp = nearestRoot.getFocusTraversalPolicy().
  2623. getDefaultComponent(nearestRoot);
  2624. if (comp != null) {
  2625. comp.requestFocus();
  2626. return true;
  2627. } else {
  2628. return false;
  2629. }
  2630. }
  2631.  
  2632. /**
  2633. * Makes the component visible or invisible.
  2634. * Overrides <code>Component.setVisible</code>.
  2635. *
  2636. * @param aFlag true to make the component visible; false to
  2637. * make it invisible
  2638. *
  2639. * @beaninfo
  2640. * attribute: visualUpdate true
  2641. */
  2642. public void setVisible(boolean aFlag) {
  2643. if (aFlag != isVisible()) {
  2644. super.setVisible(aFlag);
  2645. if (aFlag) {
  2646. Container parent = getParent();
  2647. if (parent != null) {
  2648. Rectangle r = getBounds();
  2649. parent.repaint(r.x, r.y, r.width, r.height);
  2650. }
  2651. revalidate();
  2652. }
  2653. }
  2654. }
  2655.  
  2656. /**
  2657. * Sets whether or not this component is enabled.
  2658. * A component that is enabled may respond to user input,
  2659. * while a component that is not enabled cannot respond to
  2660. * user input. Some components may alter their visual
  2661. * representation when they are disabled in order to
  2662. * provide feedback to the user that they cannot take input.
  2663. * <p>Note: Disabling a component does not disable its children.
  2664. *
  2665. * <p>Note: Disabling a lightweight component does not prevent it from
  2666. * receiving MouseEvents.
  2667. *
  2668. * @param enabled true if this component should be enabled, false otherwise
  2669. * @see java.awt.Component#isEnabled
  2670. * @see java.awt.Component#isLightweight
  2671. *
  2672. * @beaninfo
  2673. * preferred: true
  2674. * bound: true
  2675. * attribute: visualUpdate true
  2676. * description: The enabled state of the component.
  2677. */
  2678. public void setEnabled(boolean enabled) {
  2679. boolean oldEnabled = isEnabled();
  2680. super.setEnabled(enabled);
  2681. firePropertyChange("enabled", oldEnabled, enabled);
  2682. if (enabled != oldEnabled) {
  2683. repaint();
  2684. }
  2685. }
  2686.  
  2687. /**
  2688. * Sets the foreground color of this component. It is up to the
  2689. * look and feel to honor this property, some may choose to ignore
  2690. * it.
  2691. *
  2692. * @param fg the desired foreground <code>Color</code>
  2693. * @see java.awt.Component#getForeground
  2694. *
  2695. * @beaninfo
  2696. * preferred: true
  2697. * bound: true
  2698. * attribute: visualUpdate true
  2699. * description: The foreground color of the component.
  2700. */
  2701. public void setForeground(Color fg) {
  2702. Color oldFg = getForeground();
  2703. super.setForeground(fg);
  2704. if ((oldFg != null) ? !oldFg.equals(fg) : ((fg != null) && !fg.equals(oldFg))) {
  2705. // foreground already bound in AWT1.2
  2706. repaint();
  2707. }
  2708. }
  2709.  
  2710. /**
  2711. * Sets the background color of this component. The background
  2712. * color is used only if the component is opaque, and only
  2713. * by subclasses of <code>JComponent</code> or
  2714. * <code>ComponentUI</code> implementations. Direct subclasses of
  2715. * <code>JComponent</code> must override
  2716. * <code>paintComponent</code> to honor this property.
  2717. * <p>
  2718. * It is up to the look and feel to honor this property, some may
  2719. * choose to ignore it.
  2720. *
  2721. * @param bg the desired background <code>Color</code>
  2722. * @see java.awt.Component#getBackground
  2723. * @see #setOpaque
  2724. *
  2725. * @beaninfo
  2726. * preferred: true
  2727. * bound: true
  2728. * attribute: visualUpdate true
  2729. * description: The background color of the component.
  2730. */
  2731. public void setBackground(Color bg) {
  2732. Color oldBg = getBackground();
  2733. super.setBackground(bg);
  2734. if ((oldBg != null) ? !oldBg.equals(bg) : ((bg != null) && !bg.equals(oldBg))) {
  2735. // background already bound in AWT1.2
  2736. repaint();
  2737. }
  2738. }
  2739.  
  2740. /**
  2741. * Sets the font for this component.
  2742. *
  2743. * @param font the desired <code>Font</code> for this component
  2744. * @see java.awt.Component#getFont
  2745. *
  2746. * @beaninfo
  2747. * preferred: true
  2748. * bound: true
  2749. * attribute: visualUpdate true
  2750. * description: The font for the component.
  2751. */
  2752. public void setFont(Font font) {
  2753. Font oldFont = getFont();
  2754. super.setFont(font);
  2755. // font already bound in AWT1.2
  2756. if (font != oldFont) {
  2757. revalidate();
  2758. repaint();
  2759. }
  2760. }
  2761.  
  2762. /**
  2763. * Returns the default locale used to initialize each JComponent's
  2764. * locale property upon creation.
  2765. *
  2766. * The default locale has "AppContext" scope so that applets (and
  2767. * potentially multiple lightweight applications running in a single VM)
  2768. * can have their own setting. An applet can safely alter its default
  2769. * locale because it will have no affect on other applets (or the browser).
  2770. *
  2771. * @return the default <code>Locale</code>.
  2772. * @see #setDefaultLocale
  2773. * @see java.awt.Component#getLocale
  2774. * @see #setLocale
  2775. * @since 1.4
  2776. */
  2777. static public Locale getDefaultLocale() {
  2778. Locale l = (Locale) SwingUtilities.appContextGet(defaultLocale);
  2779. if( l == null ) {
  2780. //REMIND(bcb) choosing the default value is more complicated
  2781. //than this.
  2782. l = Locale.getDefault();
  2783. JComponent.setDefaultLocale( l );
  2784. }
  2785. return l;
  2786. }
  2787.  
  2788.  
  2789. /**
  2790. * Sets the default locale used to initialize each JComponent's locale
  2791. * property upon creation. The initial value is the VM's default locale.
  2792. *
  2793. * The default locale has "AppContext" scope so that applets (and
  2794. * potentially multiple lightweight applications running in a single VM)
  2795. * can have their own setting. An applet can safely alter its default
  2796. * locale because it will have no affect on other applets (or the browser).
  2797. *
  2798. * @param l the desired default <code>Locale</code> for new components.
  2799. * @see #getDefaultLocale
  2800. * @see java.awt.Component#getLocale
  2801. * @see #setLocale
  2802. * @since 1.4
  2803. */
  2804. static public void setDefaultLocale( Locale l ) {
  2805. SwingUtilities.appContextPut(defaultLocale, l);
  2806. }
  2807.  
  2808.  
  2809. /**
  2810. * Processes any key events that the component itself
  2811. * recognizes. This is called after the focus
  2812. * manager and any interested listeners have been
  2813. * given a chance to steal away the event. This
  2814. * method is called only if the event has not
  2815. * yet been consumed. This method is called prior
  2816. * to the keyboard UI logic.
  2817. * <p>
  2818. * This method is implemented to do nothing. Subclasses would
  2819. * normally override this method if they process some
  2820. * key events themselves. If the event is processed,
  2821. * it should be consumed.
  2822. */
  2823. protected void processComponentKeyEvent(KeyEvent e) {
  2824. }
  2825.  
  2826. /** Overrides <code>processKeyEvent</code> to process events. **/
  2827. protected void processKeyEvent(KeyEvent e) {
  2828. boolean result;
  2829. boolean shouldProcessKey;
  2830.  
  2831. // This gives the key event listeners a crack at the event
  2832. super.processKeyEvent(e);
  2833.  
  2834. // give the component itself a crack at the event
  2835. if (! e.isConsumed()) {
  2836. processComponentKeyEvent(e);
  2837. }
  2838.  
  2839. shouldProcessKey = KeyboardState.shouldProcess(e);
  2840.  
  2841. if(e.isConsumed()) {
  2842. return;
  2843. }
  2844.  
  2845. if (shouldProcessKey && processKeyBindings(e, e.getID() ==
  2846. KeyEvent.KEY_PRESSED)) {
  2847. e.consume();
  2848. }
  2849. }
  2850.  
  2851. /**
  2852. * Invoked to process the key bindings for <code>ks</code> as the result
  2853. * of the <code>KeyEvent</code> <code>e</code>. This obtains
  2854. * the appropriate <code>InputMap</code>,
  2855. * gets the binding, gets the action from the <code>ActionMap</code>,
  2856. * and then (if the action is found and the component
  2857. * is enabled) invokes <code>notifyAction</code> to notify the action.
  2858. *
  2859. * @param ks the <code>KeyStroke</code> queried
  2860. * @param e the <code>KeyEvent</code>
  2861. * @param condition one of the following values:
  2862. * <ul>
  2863. * <li>JComponent.WHEN_FOCUSED
  2864. * <li>JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT
  2865. * <li>JComponent.WHEN_IN_FOCUSED_WINDOW
  2866. * </ul>
  2867. * @param pressed true if the key is pressed
  2868. * @return true if there was a binding to an action, and the action
  2869. * was enabled
  2870. *
  2871. * @since 1.3
  2872. */
  2873. protected boolean processKeyBinding(KeyStroke ks, KeyEvent e,
  2874. int condition, boolean pressed) {
  2875. InputMap map = getInputMap(condition, false);
  2876. ActionMap am = getActionMap(false);
  2877.  
  2878. if(map != null && am != null && isEnabled()) {
  2879. Object binding = map.get(ks);
  2880. Action action = (binding == null) ? null : am.get(binding);
  2881. if (action != null) {
  2882. return SwingUtilities.notifyAction(action, ks, e, this,
  2883. e.getModifiers());
  2884. }
  2885. }
  2886. return false;
  2887. }
  2888.  
  2889. /**
  2890. * This is invoked as the result of a <code>KeyEvent</code>
  2891. * that was not consumed by the <code>FocusManager</code>,
  2892. * <code>KeyListeners</code>, or the component. It will first try
  2893. * <code>WHEN_FOCUSED</code> bindings,
  2894. * then <code>WHEN_ANCESTOR_OF_FOCUSED_COMPONENT</code> bindings,
  2895. * and finally <code>WHEN_IN_FOCUSED_WINDOW</code> bindings.
  2896. *
  2897. * @param e the unconsumed <code>KeyEvent</code>
  2898. * @param pressed true if the key is pressed
  2899. * @return true if there is a key binding for <code>e</code>
  2900. */
  2901. boolean processKeyBindings(KeyEvent e, boolean pressed) {
  2902. if (!SwingUtilities.isValidKeyEventForKeyBindings(e)) {
  2903. return false;
  2904. }
  2905. // Get the KeyStroke
  2906. // There may be two keystrokes associated with a low-level key event;
  2907. // in this case a keystroke made of an extended key code has a priority.
  2908. KeyStroke ks;
  2909. KeyStroke ksE = null;
  2910.  
  2911. if (e.getID() == KeyEvent.KEY_TYPED) {
  2912. ks = KeyStroke.getKeyStroke(e.getKeyChar());
  2913. }
  2914. else {
  2915. ks = KeyStroke.getKeyStroke(e.getKeyCode(),e.getModifiers(),
  2916. (pressed ? false:true));
  2917. if (e.getKeyCode() != e.getExtendedKeyCode()) {
  2918. ksE = KeyStroke.getKeyStroke(e.getExtendedKeyCode(),e.getModifiers(),
  2919. (pressed ? false:true));
  2920. }
  2921. }
  2922.  
  2923. // Do we have a key binding for e?
  2924. // If we have a binding by an extended code, use it.
  2925. // If not, check for regular code binding.
  2926. if(ksE != null && processKeyBinding(ksE, e, WHEN_FOCUSED, pressed)) {
  2927. return true;
  2928. }
  2929. if(processKeyBinding(ks, e, WHEN_FOCUSED, pressed))
  2930. return true;
  2931.  
  2932. /* We have no key binding. Let's try the path from our parent to the
  2933. * window excluded. We store the path components so we can avoid
  2934. * asking the same component twice.
  2935. */
  2936. Container parent = this;
  2937. while (parent != null && !(parent instanceof Window) &&
  2938. !(parent instanceof Applet)) {
  2939. if(parent instanceof JComponent) {
  2940. if(ksE != null && ((JComponent)parent).processKeyBinding(ksE, e,
  2941. WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, pressed))
  2942. return true;
  2943. if(((JComponent)parent).processKeyBinding(ks, e,
  2944. WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, pressed))
  2945. return true;
  2946. }
  2947. // This is done so that the children of a JInternalFrame are
  2948. // given precedence for WHEN_IN_FOCUSED_WINDOW bindings before
  2949. // other components WHEN_IN_FOCUSED_WINDOW bindings. This also gives
  2950. // more precedence to the WHEN_IN_FOCUSED_WINDOW bindings of the
  2951. // JInternalFrame's children vs the
  2952. // WHEN_ANCESTOR_OF_FOCUSED_COMPONENT bindings of the parents.
  2953. // maybe generalize from JInternalFrame (like isFocusCycleRoot).
  2954. if ((parent instanceof JInternalFrame) &&
  2955. JComponent.processKeyBindingsForAllComponents(e,parent,pressed)){
  2956. return true;
  2957. }
  2958. parent = parent.getParent();
  2959. }
  2960.  
  2961. /* No components between the focused component and the window is
  2962. * actually interested by the key event. Let's try the other
  2963. * JComponent in this window.
  2964. */
  2965. if(parent != null) {
  2966. return JComponent.processKeyBindingsForAllComponents(e,parent,pressed);
  2967. }
  2968. return false;
  2969. }
  2970.  
  2971. static boolean processKeyBindingsForAllComponents(KeyEvent e,
  2972. Container container, boolean pressed) {
  2973. while (true) {
  2974. if (KeyboardManager.getCurrentManager().fireKeyboardAction(
  2975. e, pressed, container)) {
  2976. return true;
  2977. }
  2978. if (container instanceof Popup.HeavyWeightWindow) {
  2979. container = ((Window)container).getOwner();
  2980. }
  2981. else {
  2982. return false;
  2983. }
  2984. }
  2985. }
  2986.  
  2987. /**
  2988. * Registers the text to display in a tool tip.
  2989. * The text displays when the cursor lingers over the component.
  2990. * <p>
  2991. * See <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/tooltip.html">How to Use Tool Tips</a>
  2992. * in <em>The Java Tutorial</em>
  2993. * for further documentation.
  2994. *
  2995. * @param text the string to display; if the text is <code>null</code>,
  2996. * the tool tip is turned off for this component
  2997. * @see #TOOL_TIP_TEXT_KEY
  2998. * @beaninfo
  2999. * preferred: true
  3000. * description: The text to display in a tool tip.
  3001. */
  3002. public void setToolTipText(String text) {
  3003. String oldText = getToolTipText();
  3004. putClientProperty(TOOL_TIP_TEXT_KEY, text);
  3005. ToolTipManager toolTipManager = ToolTipManager.sharedInstance();
  3006. if (text != null) {
  3007. if (oldText == null) {
  3008. toolTipManager.registerComponent(this);
  3009. }
  3010. } else {
  3011. toolTipManager.unregisterComponent(this);
  3012. }
  3013. }
  3014.  
  3015. /**
  3016. * Returns the tooltip string that has been set with
  3017. * <code>setToolTipText</code>.
  3018. *
  3019. * @return the text of the tool tip
  3020. * @see #TOOL_TIP_TEXT_KEY
  3021. */
  3022. public String getToolTipText() {
  3023. return (String)getClientProperty(TOOL_TIP_TEXT_KEY);
  3024. }
  3025.  
  3026.  
  3027. /**
  3028. * Returns the string to be used as the tooltip for <i>event</i>.
  3029. * By default this returns any string set using
  3030. * <code>setToolTipText</code>. If a component provides
  3031. * more extensive API to support differing tooltips at different locations,
  3032. * this method should be overridden.
  3033. */
  3034. public String getToolTipText(MouseEvent event) {
  3035. return getToolTipText();
  3036. }
  3037.  
  3038. /**
  3039. * Returns the tooltip location in this component's coordinate system.
  3040. * If <code>null</code> is returned, Swing will choose a location.
  3041. * The default implementation returns <code>null</code>.
  3042. *
  3043. * @param event the <code>MouseEvent</code> that caused the
  3044. * <code>ToolTipManager</code> to show the tooltip
  3045. * @return always returns <code>null</code>
  3046. */
  3047. public Point getToolTipLocation(MouseEvent event) {
  3048. return null;
  3049. }
  3050.  
  3051. /**
  3052. * Returns the preferred location to display the popup menu in this
  3053. * component's coordinate system. It is up to the look and feel to
  3054. * honor this property, some may choose to ignore it.
  3055. * If {@code null}, the look and feel will choose a suitable location.
  3056. *
  3057. * @param event the {@code MouseEvent} that triggered the popup to be
  3058. * shown, or {@code null} if the popup is not being shown as the
  3059. * result of a mouse event
  3060. * @return location to display the {@code JPopupMenu}, or {@code null}
  3061. * @since 1.5
  3062. */
  3063. public Point getPopupLocation(MouseEvent event) {
  3064. return null;
  3065. }
  3066.  
  3067.  
  3068. /**
  3069. * Returns the instance of <code>JToolTip</code> that should be used
  3070. * to display the tooltip.
  3071. * Components typically would not override this method,
  3072. * but it can be used to
  3073. * cause different tooltips to be displayed differently.
  3074. *
  3075. * @return the <code>JToolTip</code> used to display this toolTip
  3076. */
  3077. public JToolTip createToolTip() {
  3078. JToolTip tip = new JToolTip();
  3079. tip.setComponent(this);
  3080. return tip;
  3081. }
  3082.  
  3083. /**
  3084. * Forwards the <code>scrollRectToVisible()</code> message to the
  3085. * <code>JComponent</code>'s parent. Components that can service
  3086. * the request, such as <code>JViewport</code>,
  3087. * override this method and perform the scrolling.
  3088. *
  3089. * @param aRect the visible <code>Rectangle</code>
  3090. * @see JViewport
  3091. */
  3092. public void scrollRectToVisible(Rectangle aRect) {
  3093. Container parent;
  3094. int dx = getX(), dy = getY();
  3095.  
  3096. for (parent = getParent();
  3097. !(parent == null) &&
  3098. !(parent instanceof JComponent) &&
  3099. !(parent instanceof CellRendererPane);
  3100. parent = parent.getParent()) {
  3101. Rectangle bounds = parent.getBounds();
  3102.  
  3103. dx += bounds.x;
  3104. dy += bounds.y;
  3105. }
  3106.  
  3107. if (!(parent == null) && !(parent instanceof CellRendererPane)) {
  3108. aRect.x += dx;
  3109. aRect.y += dy;
  3110.  
  3111. ((JComponent)parent).scrollRectToVisible(aRect);
  3112. aRect.x -= dx;
  3113. aRect.y -= dy;
  3114. }
  3115. }
  3116.  
  3117. /**
  3118. * Sets the <code>autoscrolls</code> property.
  3119. * If <code>true</code> mouse dragged events will be
  3120. * synthetically generated when the mouse is dragged
  3121. * outside of the component's bounds and mouse motion
  3122. * has paused (while the button continues to be held
  3123. * down). The synthetic events make it appear that the
  3124. * drag gesture has resumed in the direction established when
  3125. * the component's boundary was crossed. Components that
  3126. * support autoscrolling must handle <code>mouseDragged</code>
  3127. * events by calling <code>scrollRectToVisible</code> with a
  3128. * rectangle that contains the mouse event's location. All of
  3129. * the Swing components that support item selection and are
  3130. * typically displayed in a <code>JScrollPane</code>
  3131. * (<code>JTable</code>, <code>JList</code>, <code>JTree</code>,
  3132. * <code>JTextArea</code>, and <code>JEditorPane</code>)
  3133. * already handle mouse dragged events in this way. To enable
  3134. * autoscrolling in any other component, add a mouse motion
  3135. * listener that calls <code>scrollRectToVisible</code>.
  3136. * For example, given a <code>JPanel</code>, <code>myPanel</code>:
  3137. * <pre>
  3138. * MouseMotionListener doScrollRectToVisible = new MouseMotionAdapter() {
  3139. * public void mouseDragged(MouseEvent e) {
  3140. * Rectangle r = new Rectangle(e.getX(), e.getY(), 1, 1);
  3141. * ((JPanel)e.getSource()).scrollRectToVisible(r);
  3142. * }
  3143. * };
  3144. * myPanel.addMouseMotionListener(doScrollRectToVisible);
  3145. * </pre>
  3146. * The default value of the <code>autoScrolls</code>
  3147. * property is <code>false</code>.
  3148. *
  3149. * @param autoscrolls if true, synthetic mouse dragged events
  3150. * are generated when the mouse is dragged outside of a component's
  3151. * bounds and the mouse button continues to be held down; otherwise
  3152. * false
  3153. * @see #getAutoscrolls
  3154. * @see JViewport
  3155. * @see JScrollPane
  3156. *
  3157. * @beaninfo
  3158. * expert: true
  3159. * description: Determines if this component automatically scrolls its contents when dragged.
  3160. */
  3161. public void setAutoscrolls(boolean autoscrolls) {
  3162. setFlag(AUTOSCROLLS_SET, true);
  3163. if (this.autoscrolls != autoscrolls) {
  3164. this.autoscrolls = autoscrolls;
  3165. if (autoscrolls) {
  3166. enableEvents(AWTEvent.MOUSE_EVENT_MASK);
  3167. enableEvents(AWTEvent.MOUSE_MOTION_EVENT_MASK);
  3168. }
  3169. else {
  3170. Autoscroller.stop(this);
  3171. }
  3172. }
  3173. }
  3174.  
  3175. /**
  3176. * Gets the <code>autoscrolls</code> property.
  3177. *
  3178. * @return the value of the <code>autoscrolls</code> property
  3179. * @see JViewport
  3180. * @see #setAutoscrolls
  3181. */
  3182. public boolean getAutoscrolls() {
  3183. return autoscrolls;
  3184. }
  3185.  
  3186. /**
  3187. * Sets the {@code TransferHandler}, which provides support for transfer
  3188. * of data into and out of this component via cut/copy/paste and drag
  3189. * and drop. This may be {@code null} if the component does not support
  3190. * data transfer operations.
  3191. * <p>
  3192. * If the new {@code TransferHandler} is not {@code null}, this method
  3193. * also installs a <b>new</b> {@code DropTarget} on the component to
  3194. * activate drop handling through the {@code TransferHandler} and activate
  3195. * any built-in support (such as calculating and displaying potential drop
  3196. * locations). If you do not wish for this component to respond in any way
  3197. * to drops, you can disable drop support entirely either by removing the
  3198. * drop target ({@code setDropTarget(null)}) or by de-activating it
  3199. * ({@code getDropTaget().setActive(false)}).
  3200. * <p>
  3201. * If the new {@code TransferHandler} is {@code null}, this method removes
  3202. * the drop target.
  3203. * <p>
  3204. * Under two circumstances, this method does not modify the drop target:
  3205. * First, if the existing drop target on this component was explicitly
  3206. * set by the developer to a {@code non-null} value. Second, if the
  3207. * system property {@code suppressSwingDropSupport} is {@code true}. The
  3208. * default value for the system property is {@code false}.
  3209. * <p>
  3210. * Please see
  3211. * <a href="https://docs.oracle.com/javase/tutorial/uiswing/dnd/index.html">
  3212. * How to Use Drag and Drop and Data Transfer</a>,
  3213. * a section in <em>The Java Tutorial</em>, for more information.
  3214. *
  3215. * @param newHandler the new {@code TransferHandler}
  3216. *
  3217. * @see TransferHandler
  3218. * @see #getTransferHandler
  3219. * @since 1.4
  3220. * @beaninfo
  3221. * bound: true
  3222. * hidden: true
  3223. * description: Mechanism for transfer of data to and from the component
  3224. */
  3225. public void setTransferHandler(TransferHandler newHandler) {
  3226. TransferHandler oldHandler = (TransferHandler)getClientProperty(
  3227. JComponent_TRANSFER_HANDLER);
  3228. putClientProperty(JComponent_TRANSFER_HANDLER, newHandler);
  3229.  
  3230. SwingUtilities.installSwingDropTargetAsNecessary(this, newHandler);
  3231. firePropertyChange("transferHandler", oldHandler, newHandler);
  3232. }
  3233.  
  3234. /**
  3235. * Gets the <code>transferHandler</code> property.
  3236. *
  3237. * @return the value of the <code>transferHandler</code> property
  3238. *
  3239. * @see TransferHandler
  3240. * @see #setTransferHandler
  3241. * @since 1.4
  3242. */
  3243. public TransferHandler getTransferHandler() {
  3244. return (TransferHandler)getClientProperty(JComponent_TRANSFER_HANDLER);
  3245. }
  3246.  
  3247. /**
  3248. * Calculates a custom drop location for this type of component,
  3249. * representing where a drop at the given point should insert data.
  3250. * <code>null</code> is returned if this component doesn't calculate
  3251. * custom drop locations. In this case, <code>TransferHandler</code>
  3252. * will provide a default <code>DropLocation</code> containing just
  3253. * the point.
  3254. *
  3255. * @param p the point to calculate a drop location for
  3256. * @return the drop location, or <code>null</code>
  3257. */
  3258. TransferHandler.DropLocation dropLocationForPoint(Point p) {
  3259. return null;
  3260. }
  3261.  
  3262. /**
  3263. * Called to set or clear the drop location during a DnD operation.
  3264. * In some cases, the component may need to use its internal selection
  3265. * temporarily to indicate the drop location. To help facilitate this,
  3266. * this method returns and accepts as a parameter a state object.
  3267. * This state object can be used to store, and later restore, the selection
  3268. * state. Whatever this method returns will be passed back to it in
  3269. * future calls, as the state parameter. If it wants the DnD system to
  3270. * continue storing the same state, it must pass it back every time.
  3271. * Here's how this is used:
  3272. * <p>
  3273. * Let's say that on the first call to this method the component decides
  3274. * to save some state (because it is about to use the selection to show
  3275. * a drop index). It can return a state object to the caller encapsulating
  3276. * any saved selection state. On a second call, let's say the drop location
  3277. * is being changed to something else. The component doesn't need to
  3278. * restore anything yet, so it simply passes back the same state object
  3279. * to have the DnD system continue storing it. Finally, let's say this
  3280. * method is messaged with <code>null</code>. This means DnD
  3281. * is finished with this component for now, meaning it should restore
  3282. * state. At this point, it can use the state parameter to restore
  3283. * said state, and of course return <code>null</code> since there's
  3284. * no longer anything to store.
  3285. *
  3286. * @param location the drop location (as calculated by
  3287. * <code>dropLocationForPoint</code>) or <code>null</code>
  3288. * if there's no longer a valid drop location
  3289. * @param state the state object saved earlier for this component,
  3290. * or <code>null</code>
  3291. * @param forDrop whether or not the method is being called because an
  3292. * actual drop occurred
  3293. * @return any saved state for this component, or <code>null</code> if none
  3294. */
  3295. Object setDropLocation(TransferHandler.DropLocation location,
  3296. Object state,
  3297. boolean forDrop) {
  3298.  
  3299. return null;
  3300. }
  3301.  
  3302. /**
  3303. * Called to indicate to this component that DnD is done.
  3304. * Needed by <code>JTree</code>.
  3305. */
  3306. void dndDone() {
  3307. }
  3308.  
  3309. /**
  3310. * Processes mouse events occurring on this component by
  3311. * dispatching them to any registered
  3312. * <code>MouseListener</code> objects, refer to
  3313. * {@link java.awt.Component#processMouseEvent(MouseEvent)}
  3314. * for a complete description of this method.
  3315. *
  3316. * @param e the mouse event
  3317. * @see java.awt.Component#processMouseEvent
  3318. * @since 1.5
  3319. */
  3320. protected void processMouseEvent(MouseEvent e) {
  3321. if (autoscrolls && e.getID() == MouseEvent.MOUSE_RELEASED) {
  3322. Autoscroller.stop(this);
  3323. }
  3324. super.processMouseEvent(e);
  3325. }
  3326.  
  3327. /**
  3328. * Processes mouse motion events, such as MouseEvent.MOUSE_DRAGGED.
  3329. *
  3330. * @param e the <code>MouseEvent</code>
  3331. * @see MouseEvent
  3332. */
  3333. protected void processMouseMotionEvent(MouseEvent e) {
  3334. boolean dispatch = true;
  3335. if (autoscrolls && e.getID() == MouseEvent.MOUSE_DRAGGED) {
  3336. // We don't want to do the drags when the mouse moves if we're
  3337. // autoscrolling. It makes it feel spastic.
  3338. dispatch = !Autoscroller.isRunning(this);
  3339. Autoscroller.processMouseDragged(e);
  3340. }
  3341. if (dispatch) {
  3342. super.processMouseMotionEvent(e);
  3343. }
  3344. }
  3345.  
  3346. // Inner classes can't get at this method from a super class
  3347. void superProcessMouseMotionEvent(MouseEvent e) {
  3348. super.processMouseMotionEvent(e);
  3349. }
  3350.  
  3351. /**
  3352. * This is invoked by the <code>RepaintManager</code> if
  3353. * <code>createImage</code> is called on the component.
  3354. *
  3355. * @param newValue true if the double buffer image was created from this component
  3356. */
  3357. void setCreatedDoubleBuffer(boolean newValue) {
  3358. setFlag(CREATED_DOUBLE_BUFFER, newValue);
  3359. }
  3360.  
  3361. /**
  3362. * Returns true if the <code>RepaintManager</code>
  3363. * created the double buffer image from the component.
  3364. *
  3365. * @return true if this component had a double buffer image, false otherwise
  3366. */
  3367. boolean getCreatedDoubleBuffer() {
  3368. return getFlag(CREATED_DOUBLE_BUFFER);
  3369. }
  3370.  
  3371. /**
  3372. * <code>ActionStandin</code> is used as a standin for
  3373. * <code>ActionListeners</code> that are
  3374. * added via <code>registerKeyboardAction</code>.
  3375. */
  3376. final class ActionStandin implements Action {
  3377. private final ActionListener actionListener;
  3378. private final String command;
  3379. // This will be non-null if actionListener is an Action.
  3380. private final Action action;
  3381.  
  3382. ActionStandin(ActionListener actionListener, String command) {
  3383. this.actionListener = actionListener;
  3384. if (actionListener instanceof Action) {
  3385. this.action = (Action)actionListener;
  3386. }
  3387. else {
  3388. this.action = null;
  3389. }
  3390. this.command = command;
  3391. }
  3392.  
  3393. public Object getValue(String key) {
  3394. if (key != null) {
  3395. if (key.equals(Action.ACTION_COMMAND_KEY)) {
  3396. return command;
  3397. }
  3398. if (action != null) {
  3399. return action.getValue(key);
  3400. }
  3401. if (key.equals(NAME)) {
  3402. return "ActionStandin";
  3403. }
  3404. }
  3405. return null;
  3406. }
  3407.  
  3408. public boolean isEnabled() {
  3409. if (actionListener == null) {
  3410. // This keeps the old semantics where
  3411. // registerKeyboardAction(null) would essentialy remove
  3412. // the binding. We don't remove the binding from the
  3413. // InputMap as that would still allow parent InputMaps
  3414. // bindings to be accessed.
  3415. return false;
  3416. }
  3417. if (action == null) {
  3418. return true;
  3419. }
  3420. return action.isEnabled();
  3421. }
  3422.  
  3423. public void actionPerformed(ActionEvent ae) {
  3424. if (actionListener != null) {
  3425. actionListener.actionPerformed(ae);
  3426. }
  3427. }
  3428.  
  3429. // We don't allow any values to be added.
  3430. public void putValue(String key, Object value) {}
  3431.  
  3432. // Does nothing, our enabledness is determiend from our asociated
  3433. // action.
  3434. public void setEnabled(boolean b) { }
  3435.  
  3436. public void addPropertyChangeListener
  3437. (PropertyChangeListener listener) {}
  3438. public void removePropertyChangeListener
  3439. (PropertyChangeListener listener) {}
  3440. }
  3441.  
  3442.  
  3443. // This class is used by the KeyboardState class to provide a single
  3444. // instance that can be stored in the AppContext.
  3445. static final class IntVector {
  3446. int array[] = null;
  3447. int count = 0;
  3448. int capacity = 0;
  3449.  
  3450. int size() {
  3451. return count;
  3452. }
  3453.  
  3454. int elementAt(int index) {
  3455. return array[index];
  3456. }
  3457.  
  3458. void addElement(int value) {
  3459. if (count == capacity) {
  3460. capacity = (capacity + 2) * 2;
  3461. int[] newarray = new int[capacity];
  3462. if (count > 0) {
  3463. System.arraycopy(array, 0, newarray, 0, count);
  3464. }
  3465. array = newarray;
  3466. }
  3467. array[count++] = value;
  3468. }
  3469.  
  3470. void setElementAt(int value, int index) {
  3471. array[index] = value;
  3472. }
  3473. }
  3474.  
  3475. @SuppressWarnings("serial")
  3476. static class KeyboardState implements Serializable {
  3477. private static final Object keyCodesKey =
  3478. JComponent.KeyboardState.class;
  3479.  
  3480. // Get the array of key codes from the AppContext.
  3481. static IntVector getKeyCodeArray() {
  3482. IntVector iv =
  3483. (IntVector)SwingUtilities.appContextGet(keyCodesKey);
  3484. if (iv == null) {
  3485. iv = new IntVector();
  3486. SwingUtilities.appContextPut(keyCodesKey, iv);
  3487. }
  3488. return iv;
  3489. }
  3490.  
  3491. static void registerKeyPressed(int keyCode) {
  3492. IntVector kca = getKeyCodeArray();
  3493. int count = kca.size();
  3494. int i;
  3495. for(i=0;i<count;i++) {
  3496. if(kca.elementAt(i) == -1){
  3497. kca.setElementAt(keyCode, i);
  3498. return;
  3499. }
  3500. }
  3501. kca.addElement(keyCode);
  3502. }
  3503.  
  3504. static void registerKeyReleased(int keyCode) {
  3505. IntVector kca = getKeyCodeArray();
  3506. int count = kca.size();
  3507. int i;
  3508. for(i=0;i<count;i++) {
  3509. if(kca.elementAt(i) == keyCode) {
  3510. kca.setElementAt(-1, i);
  3511. return;
  3512. }
  3513. }
  3514. }
  3515.  
  3516. static boolean keyIsPressed(int keyCode) {
  3517. IntVector kca = getKeyCodeArray();
  3518. int count = kca.size();
  3519. int i;
  3520. for(i=0;i<count;i++) {
  3521. if(kca.elementAt(i) == keyCode) {
  3522. return true;
  3523. }
  3524. }
  3525. return false;
  3526. }
  3527.  
  3528. /**
  3529. * Updates internal state of the KeyboardState and returns true
  3530. * if the event should be processed further.
  3531. */
  3532. static boolean shouldProcess(KeyEvent e) {
  3533. switch (e.getID()) {
  3534. case KeyEvent.KEY_PRESSED:
  3535. if (!keyIsPressed(e.getKeyCode())) {
  3536. registerKeyPressed(e.getKeyCode());
  3537. }
  3538. return true;
  3539. case KeyEvent.KEY_RELEASED:
  3540. // We are forced to process VK_PRINTSCREEN separately because
  3541. // the Windows doesn't generate the key pressed event for
  3542. // printscreen and it block the processing of key release
  3543. // event for printscreen.
  3544. if (keyIsPressed(e.getKeyCode()) || e.getKeyCode()==KeyEvent.VK_PRINTSCREEN) {
  3545. registerKeyReleased(e.getKeyCode());
  3546. return true;
  3547. }
  3548. return false;
  3549. case KeyEvent.KEY_TYPED:
  3550. return true;
  3551. default:
  3552. // Not a known KeyEvent type, bail.
  3553. return false;
  3554. }
  3555. }
  3556. }
  3557.  
  3558. static final sun.awt.RequestFocusController focusController =
  3559. new sun.awt.RequestFocusController() {
  3560. public boolean acceptRequestFocus(Component from, Component to,
  3561. boolean temporary, boolean focusedWindowChangeAllowed,
  3562. sun.awt.CausedFocusEvent.Cause cause)
  3563. {
  3564. if ((to == null) || !(to instanceof JComponent)) {
  3565. return true;
  3566. }
  3567.  
  3568. if ((from == null) || !(from instanceof JComponent)) {
  3569. return true;
  3570. }
  3571.  
  3572. JComponent target = (JComponent) to;
  3573. if (!target.getVerifyInputWhenFocusTarget()) {
  3574. return true;
  3575. }
  3576.  
  3577. JComponent jFocusOwner = (JComponent)from;
  3578. InputVerifier iv = jFocusOwner.getInputVerifier();
  3579.  
  3580. if (iv == null) {
  3581. return true;
  3582. } else {
  3583. Object currentSource = SwingUtilities.appContextGet(
  3584. INPUT_VERIFIER_SOURCE_KEY);
  3585. if (currentSource == jFocusOwner) {
  3586. // We're currently calling into the InputVerifier
  3587. // for this component, so allow the focus change.
  3588. return true;
  3589. }
  3590. SwingUtilities.appContextPut(INPUT_VERIFIER_SOURCE_KEY,
  3591. jFocusOwner);
  3592. try {
  3593. return iv.shouldYieldFocus(jFocusOwner);
  3594. } finally {
  3595. if (currentSource != null) {
  3596. // We're already in the InputVerifier for
  3597. // currentSource. By resetting the currentSource
  3598. // we ensure that if the InputVerifier for
  3599. // currentSource does a requestFocus, we don't
  3600. // try and run the InputVerifier again.
  3601. SwingUtilities.appContextPut(
  3602. INPUT_VERIFIER_SOURCE_KEY, currentSource);
  3603. } else {
  3604. SwingUtilities.appContextRemove(
  3605. INPUT_VERIFIER_SOURCE_KEY);
  3606. }
  3607. }
  3608. }
  3609. }
  3610. };
  3611.  
  3612. /*
  3613. * --- Accessibility Support ---
  3614. */
  3615.  
  3616. /**
  3617. * @deprecated As of JDK version 1.1,
  3618. * replaced by <code>java.awt.Component.setEnabled(boolean)</code>.
  3619. */
  3620. @Deprecated
  3621. public void enable() {
  3622. if (isEnabled() != true) {
  3623. super.enable();
  3624. if (accessibleContext != null) {
  3625. accessibleContext.firePropertyChange(
  3626. AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
  3627. null, AccessibleState.ENABLED);
  3628. }
  3629. }
  3630. }
  3631.  
  3632. /**
  3633. * @deprecated As of JDK version 1.1,
  3634. * replaced by <code>java.awt.Component.setEnabled(boolean)</code>.
  3635. */
  3636. @Deprecated
  3637. public void disable() {
  3638. if (isEnabled() != false) {
  3639. super.disable();
  3640. if (accessibleContext != null) {
  3641. accessibleContext.firePropertyChange(
  3642. AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
  3643. AccessibleState.ENABLED, null);
  3644. }
  3645. }
  3646. }
  3647.  
  3648. /**
  3649. * Inner class of JComponent used to provide default support for
  3650. * accessibility. This class is not meant to be used directly by
  3651. * application developers, but is instead meant only to be
  3652. * subclassed by component developers.
  3653. * <p>
  3654. * <strong>Warning:</strong>
  3655. * Serialized objects of this class will not be compatible with
  3656. * future Swing releases. The current serialization support is
  3657. * appropriate for short term storage or RMI between applications running
  3658. * the same version of Swing. As of 1.4, support for long term storage
  3659. * of all JavaBeans&trade;
  3660. * has been added to the <code>java.beans</code> package.
  3661. * Please see {@link java.beans.XMLEncoder}.
  3662. */
  3663. public abstract class AccessibleJComponent extends AccessibleAWTContainer
  3664. implements AccessibleExtendedComponent
  3665. {
  3666. /**
  3667. * Though the class is abstract, this should be called by
  3668. * all sub-classes.
  3669. */
  3670. protected AccessibleJComponent() {
  3671. super();
  3672. }
  3673.  
  3674. /**
  3675. * Number of PropertyChangeListener objects registered. It's used
  3676. * to add/remove ContainerListener and FocusListener to track
  3677. * target JComponent's state
  3678. */
  3679. private volatile transient int propertyListenersCount = 0;
  3680.  
  3681. /**
  3682. * This field duplicates the function of the accessibleAWTFocusHandler field
  3683. * in java.awt.Component.AccessibleAWTComponent, so it has been deprecated.
  3684. */
  3685. @Deprecated
  3686. protected FocusListener accessibleFocusHandler = null;
  3687.  
  3688. /**
  3689. * Fire PropertyChange listener, if one is registered,
  3690. * when children added/removed.
  3691. */
  3692. protected class AccessibleContainerHandler
  3693. implements ContainerListener {
  3694. public void componentAdded(ContainerEvent e) {
  3695. Component c = e.getChild();
  3696. if (c != null && c instanceof Accessible) {
  3697. AccessibleJComponent.this.firePropertyChange(
  3698. AccessibleContext.ACCESSIBLE_CHILD_PROPERTY,
  3699. null, c.getAccessibleContext());
  3700. }
  3701. }
  3702. public void componentRemoved(ContainerEvent e) {
  3703. Component c = e.getChild();
  3704. if (c != null && c instanceof Accessible) {
  3705. AccessibleJComponent.this.firePropertyChange(
  3706. AccessibleContext.ACCESSIBLE_CHILD_PROPERTY,
  3707. c.getAccessibleContext(), null);
  3708. }
  3709. }
  3710. }
  3711.  
  3712. /**
  3713. * Fire PropertyChange listener, if one is registered,
  3714. * when focus events happen
  3715. * @since 1.3
  3716. */
  3717. protected class AccessibleFocusHandler implements FocusListener {
  3718. public void focusGained(FocusEvent event) {
  3719. if (accessibleContext != null) {
  3720. accessibleContext.firePropertyChange(
  3721. AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
  3722. null, AccessibleState.FOCUSED);
  3723. }
  3724. }
  3725. public void focusLost(FocusEvent event) {
  3726. if (accessibleContext != null) {
  3727. accessibleContext.firePropertyChange(
  3728. AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
  3729. AccessibleState.FOCUSED, null);
  3730. }
  3731. }
  3732. } // inner class AccessibleFocusHandler
  3733.  
  3734.  
  3735. /**
  3736. * Adds a PropertyChangeListener to the listener list.
  3737. *
  3738. * @param listener the PropertyChangeListener to be added
  3739. */
  3740. public void addPropertyChangeListener(PropertyChangeListener listener) {
  3741. super.addPropertyChangeListener(listener);
  3742. }
  3743.  
  3744. /**
  3745. * Removes a PropertyChangeListener from the listener list.
  3746. * This removes a PropertyChangeListener that was registered
  3747. * for all properties.
  3748. *
  3749. * @param listener the PropertyChangeListener to be removed
  3750. */
  3751. public void removePropertyChangeListener(PropertyChangeListener listener) {
  3752. super.removePropertyChangeListener(listener);
  3753. }
  3754.  
  3755.  
  3756.  
  3757. /**
  3758. * Recursively search through the border hierarchy (if it exists)
  3759. * for a TitledBorder with a non-null title. This does a depth
  3760. * first search on first the inside borders then the outside borders.
  3761. * The assumption is that titles make really pretty inside borders
  3762. * but not very pretty outside borders in compound border situations.
  3763. * It's rather arbitrary, but hopefully decent UI programmers will
  3764. * not create multiple titled borders for the same component.
  3765. */
  3766. protected String getBorderTitle(Border b) {
  3767. String s;
  3768. if (b instanceof TitledBorder) {
  3769. return ((TitledBorder) b).getTitle();
  3770. } else if (b instanceof CompoundBorder) {
  3771. s = getBorderTitle(((CompoundBorder) b).getInsideBorder());
  3772. if (s == null) {
  3773. s = getBorderTitle(((CompoundBorder) b).getOutsideBorder());
  3774. }
  3775. return s;
  3776. } else {
  3777. return null;
  3778. }
  3779. }
  3780.  
  3781. // AccessibleContext methods
  3782. //
  3783. /**
  3784. * Gets the accessible name of this object. This should almost never
  3785. * return java.awt.Component.getName(), as that generally isn't
  3786. * a localized name, and doesn't have meaning for the user. If the
  3787. * object is fundamentally a text object (such as a menu item), the
  3788. * accessible name should be the text of the object (for example,
  3789. * "save").
  3790. * If the object has a tooltip, the tooltip text may also be an
  3791. * appropriate String to return.
  3792. *
  3793. * @return the localized name of the object -- can be null if this
  3794. * object does not have a name
  3795. * @see AccessibleContext#setAccessibleName
  3796. */
  3797. public String getAccessibleName() {
  3798. String name = accessibleName;
  3799.  
  3800. // fallback to the client name property
  3801. //
  3802. if (name == null) {
  3803. name = (String)getClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY);
  3804. }
  3805.  
  3806. // fallback to the titled border if it exists
  3807. //
  3808. if (name == null) {
  3809. name = getBorderTitle(getBorder());
  3810. }
  3811.  
  3812. // fallback to the label labeling us if it exists
  3813. //
  3814. if (name == null) {
  3815. Object o = getClientProperty(JLabel.LABELED_BY_PROPERTY);
  3816. if (o instanceof Accessible) {
  3817. AccessibleContext ac = ((Accessible) o).getAccessibleContext();
  3818. if (ac != null) {
  3819. name = ac.getAccessibleName();
  3820. }
  3821. }
  3822. }
  3823. return name;
  3824. }
  3825.  
  3826. /**
  3827. * Gets the accessible description of this object. This should be
  3828. * a concise, localized description of what this object is - what
  3829. * is its meaning to the user. If the object has a tooltip, the
  3830. * tooltip text may be an appropriate string to return, assuming
  3831. * it contains a concise description of the object (instead of just
  3832. * the name of the object - for example a "Save" icon on a toolbar that
  3833. * had "save" as the tooltip text shouldn't return the tooltip
  3834. * text as the description, but something like "Saves the current
  3835. * text document" instead).
  3836. *
  3837. * @return the localized description of the object -- can be null if
  3838. * this object does not have a description
  3839. * @see AccessibleContext#setAccessibleDescription
  3840. */
  3841. public String getAccessibleDescription() {
  3842. String description = accessibleDescription;
  3843.  
  3844. // fallback to the client description property
  3845. //
  3846. if (description == null) {
  3847. description = (String)getClientProperty(AccessibleContext.ACCESSIBLE_DESCRIPTION_PROPERTY);
  3848. }
  3849.  
  3850. // fallback to the tool tip text if it exists
  3851. //
  3852. if (description == null) {
  3853. try {
  3854. description = getToolTipText();
  3855. } catch (Exception e) {
  3856. // Just in case the subclass overrode the
  3857. // getToolTipText method and actually
  3858. // requires a MouseEvent.
  3859. // [[[FIXME: WDW - we probably should require this
  3860. // method to take a MouseEvent and just pass it on
  3861. // to getToolTipText. The swing-feedback traffic
  3862. // leads me to believe getToolTipText might change,
  3863. // though, so I was hesitant to make this change at
  3864. // this time.]]]
  3865. }
  3866. }
  3867.  
  3868. // fallback to the label labeling us if it exists
  3869. //
  3870. if (description == null) {
  3871. Object o = getClientProperty(JLabel.LABELED_BY_PROPERTY);
  3872. if (o instanceof Accessible) {
  3873. AccessibleContext ac = ((Accessible) o).getAccessibleContext();
  3874. if (ac != null) {
  3875. description = ac.getAccessibleDescription();
  3876. }
  3877. }
  3878. }
  3879.  
  3880. return description;
  3881. }
  3882.  
  3883. /**
  3884. * Gets the role of this object.
  3885. *
  3886. * @return an instance of AccessibleRole describing the role of the
  3887. * object
  3888. * @see AccessibleRole
  3889. */
  3890. public AccessibleRole getAccessibleRole() {
  3891. return AccessibleRole.SWING_COMPONENT;
  3892. }
  3893.  
  3894. /**
  3895. * Gets the state of this object.
  3896. *
  3897. * @return an instance of AccessibleStateSet containing the current
  3898. * state set of the object
  3899. * @see AccessibleState
  3900. */
  3901. public AccessibleStateSet getAccessibleStateSet() {
  3902. AccessibleStateSet states = super.getAccessibleStateSet();
  3903. if (JComponent.this.isOpaque()) {
  3904. states.add(AccessibleState.OPAQUE);
  3905. }
  3906. return states;
  3907. }
  3908.  
  3909. /**
  3910. * Returns the number of accessible children in the object. If all
  3911. * of the children of this object implement Accessible, than this
  3912. * method should return the number of children of this object.
  3913. *
  3914. * @return the number of accessible children in the object.
  3915. */
  3916. public int getAccessibleChildrenCount() {
  3917. return super.getAccessibleChildrenCount();
  3918. }
  3919.  
  3920. /**
  3921. * Returns the nth Accessible child of the object.
  3922. *
  3923. * @param i zero-based index of child
  3924. * @return the nth Accessible child of the object
  3925. */
  3926. public Accessible getAccessibleChild(int i) {
  3927. return super.getAccessibleChild(i);
  3928. }
  3929.  
  3930. // ----- AccessibleExtendedComponent
  3931.  
  3932. /**
  3933. * Returns the AccessibleExtendedComponent
  3934. *
  3935. * @return the AccessibleExtendedComponent
  3936. */
  3937. AccessibleExtendedComponent getAccessibleExtendedComponent() {
  3938. return this;
  3939. }
  3940.  
  3941. /**
  3942. * Returns the tool tip text
  3943. *
  3944. * @return the tool tip text, if supported, of the object;
  3945. * otherwise, null
  3946. * @since 1.4
  3947. */
  3948. public String getToolTipText() {
  3949. return JComponent.this.getToolTipText();
  3950. }
  3951.  
  3952. /**
  3953. * Returns the titled border text
  3954. *
  3955. * @return the titled border text, if supported, of the object;
  3956. * otherwise, null
  3957. * @since 1.4
  3958. */
  3959. public String getTitledBorderText() {
  3960. Border border = JComponent.this.getBorder();
  3961. if (border instanceof TitledBorder) {
  3962. return ((TitledBorder)border).getTitle();
  3963. } else {
  3964. return null;
  3965. }
  3966. }
  3967.  
  3968. /**
  3969. * Returns key bindings associated with this object
  3970. *
  3971. * @return the key bindings, if supported, of the object;
  3972. * otherwise, null
  3973. * @see AccessibleKeyBinding
  3974. * @since 1.4
  3975. */
  3976. public AccessibleKeyBinding getAccessibleKeyBinding() {
  3977. // Try to get the linked label's mnemonic if it exists
  3978. Object o = getClientProperty(JLabel.LABELED_BY_PROPERTY);
  3979. if (o instanceof Accessible){
  3980. AccessibleContext ac = ((Accessible) o).getAccessibleContext();
  3981. if (ac != null){
  3982. AccessibleComponent comp = ac.getAccessibleComponent();
  3983. if (! (comp instanceof AccessibleExtendedComponent))
  3984. return null;
  3985. return ((AccessibleExtendedComponent)comp).getAccessibleKeyBinding();
  3986. }
  3987. }
  3988. return null;
  3989. }
  3990. } // inner class AccessibleJComponent
  3991.  
  3992.  
  3993. /**
  3994. * Returns an <code>ArrayTable</code> used for
  3995. * key/value "client properties" for this component. If the
  3996. * <code>clientProperties</code> table doesn't exist, an empty one
  3997. * will be created.
  3998. *
  3999. * @return an ArrayTable
  4000. * @see #putClientProperty
  4001. * @see #getClientProperty
  4002. */
  4003. private ArrayTable getClientProperties() {
  4004. if (clientProperties == null) {
  4005. clientProperties = new ArrayTable();
  4006. }
  4007. return clientProperties;
  4008. }
  4009.  
  4010.  
  4011. /**
  4012. * Returns the value of the property with the specified key. Only
  4013. * properties added with <code>putClientProperty</code> will return
  4014. * a non-<code>null</code> value.
  4015. *
  4016. * @param key the being queried
  4017. * @return the value of this property or <code>null</code>
  4018. * @see #putClientProperty
  4019. */
  4020. public final Object getClientProperty(Object key) {
  4021. if (key == SwingUtilities2.AA_TEXT_PROPERTY_KEY) {
  4022. return aaTextInfo;
  4023. } else if (key == SwingUtilities2.COMPONENT_UI_PROPERTY_KEY) {
  4024. return ui;
  4025. }
  4026. if(clientProperties == null) {
  4027. return null;
  4028. } else {
  4029. synchronized(clientProperties) {
  4030. return clientProperties.get(key);
  4031. }
  4032. }
  4033. }
  4034.  
  4035. /**
  4036. * Adds an arbitrary key/value "client property" to this component.
  4037. * <p>
  4038. * The <code>get/putClientProperty</code> methods provide access to
  4039. * a small per-instance hashtable. Callers can use get/putClientProperty
  4040. * to annotate components that were created by another module.
  4041. * For example, a
  4042. * layout manager might store per child constraints this way. For example:
  4043. * <pre>
  4044. * componentA.putClientProperty("to the left of", componentB);
  4045. * </pre>
  4046. * If value is <code>null</code> this method will remove the property.
  4047. * Changes to client properties are reported with
  4048. * <code>PropertyChange</code> events.
  4049. * The name of the property (for the sake of PropertyChange
  4050. * events) is <code>key.toString()</code>.
  4051. * <p>
  4052. * The <code>clientProperty</code> dictionary is not intended to
  4053. * support large
  4054. * scale extensions to JComponent nor should be it considered an
  4055. * alternative to subclassing when designing a new component.
  4056. *
  4057. * @param key the new client property key
  4058. * @param value the new client property value; if <code>null</code>
  4059. * this method will remove the property
  4060. * @see #getClientProperty
  4061. * @see #addPropertyChangeListener
  4062. */
  4063. public final void putClientProperty(Object key, Object value) {
  4064. if (key == SwingUtilities2.AA_TEXT_PROPERTY_KEY) {
  4065. aaTextInfo = value;
  4066. return;
  4067. }
  4068. if (value == null && clientProperties == null) {
  4069. // Both the value and ArrayTable are null, implying we don't
  4070. // have to do anything.
  4071. return;
  4072. }
  4073. ArrayTable clientProperties = getClientProperties();
  4074. Object oldValue;
  4075. synchronized(clientProperties) {
  4076. oldValue = clientProperties.get(key);
  4077. if (value != null) {
  4078. clientProperties.put(key, value);
  4079. } else if (oldValue != null) {
  4080. clientProperties.remove(key);
  4081. } else {
  4082. // old == new == null
  4083. return;
  4084. }
  4085. }
  4086. clientPropertyChanged(key, oldValue, value);
  4087. firePropertyChange(key.toString(), oldValue, value);
  4088. }
  4089.  
  4090. // Invoked from putClientProperty. This is provided for subclasses
  4091. // in Swing.
  4092. void clientPropertyChanged(Object key, Object oldValue,
  4093. Object newValue) {
  4094. }
  4095.  
  4096.  
  4097. /*
  4098. * Sets the property with the specified name to the specified value if
  4099. * the property has not already been set by the client program.
  4100. * This method is used primarily to set UI defaults for properties
  4101. * with primitive types, where the values cannot be marked with
  4102. * UIResource.
  4103. * @see LookAndFeel#installProperty
  4104. * @param propertyName String containing the name of the property
  4105. * @param value Object containing the property value
  4106. */
  4107. void setUIProperty(String propertyName, Object value) {
  4108. if (propertyName == "opaque") {
  4109. if (!getFlag(OPAQUE_SET)) {
  4110. setOpaque(((Boolean)value).booleanValue());
  4111. setFlag(OPAQUE_SET, false);
  4112. }
  4113. } else if (propertyName == "autoscrolls") {
  4114. if (!getFlag(AUTOSCROLLS_SET)) {
  4115. setAutoscrolls(((Boolean)value).booleanValue());
  4116. setFlag(AUTOSCROLLS_SET, false);
  4117. }
  4118. } else if (propertyName == "focusTraversalKeysForward") {
  4119. if (!getFlag(FOCUS_TRAVERSAL_KEYS_FORWARD_SET)) {
  4120. super.setFocusTraversalKeys(KeyboardFocusManager.
  4121. FORWARD_TRAVERSAL_KEYS,
  4122. (Set<AWTKeyStroke>)value);
  4123. }
  4124. } else if (propertyName == "focusTraversalKeysBackward") {
  4125. if (!getFlag(FOCUS_TRAVERSAL_KEYS_BACKWARD_SET)) {
  4126. super.setFocusTraversalKeys(KeyboardFocusManager.
  4127. BACKWARD_TRAVERSAL_KEYS,
  4128. (Set<AWTKeyStroke>)value);
  4129. }
  4130. } else {
  4131. throw new IllegalArgumentException("property \""+
  4132. propertyName+ "\" cannot be set using this method");
  4133. }
  4134. }
  4135.  
  4136.  
  4137. /**
  4138. * Sets the focus traversal keys for a given traversal operation for this
  4139. * Component.
  4140. * Refer to
  4141. * {@link java.awt.Component#setFocusTraversalKeys}
  4142. * for a complete description of this method.
  4143. * <p>
  4144. * This method may throw a {@code ClassCastException} if any {@code Object}
  4145. * in {@code keystrokes} is not an {@code AWTKeyStroke}.
  4146. *
  4147. * @param id one of KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
  4148. * KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, or
  4149. * KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS
  4150. * @param keystrokes the Set of AWTKeyStroke for the specified operation
  4151. * @see java.awt.KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS
  4152. * @see java.awt.KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS
  4153. * @see java.awt.KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS
  4154. * @throws IllegalArgumentException if id is not one of
  4155. * KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
  4156. * KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, or
  4157. * KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, or if keystrokes
  4158. * contains null, or if any keystroke represents a KEY_TYPED event,
  4159. * or if any keystroke already maps to another focus traversal
  4160. * operation for this Component
  4161. * @since 1.5
  4162. * @beaninfo
  4163. * bound: true
  4164. */
  4165. public void
  4166. setFocusTraversalKeys(int id, Set<? extends AWTKeyStroke> keystrokes)
  4167. {
  4168. if (id == KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS) {
  4169. setFlag(FOCUS_TRAVERSAL_KEYS_FORWARD_SET,true);
  4170. } else if (id == KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS) {
  4171. setFlag(FOCUS_TRAVERSAL_KEYS_BACKWARD_SET,true);
  4172. }
  4173. super.setFocusTraversalKeys(id,keystrokes);
  4174. }
  4175.  
  4176. /* --- Transitional java.awt.Component Support ---
  4177. * The methods and fields in this section will migrate to
  4178. * java.awt.Component in the next JDK release.
  4179. */
  4180.  
  4181. /**
  4182. * Returns true if this component is lightweight, that is, if it doesn't
  4183. * have a native window system peer.
  4184. *
  4185. * @return true if this component is lightweight
  4186. */
  4187. @SuppressWarnings("deprecation")
  4188. public static boolean isLightweightComponent(Component c) {
  4189. return c.getPeer() instanceof LightweightPeer;
  4190. }
  4191.  
  4192.  
  4193. /**
  4194. * @deprecated As of JDK 5,
  4195. * replaced by <code>Component.setBounds(int, int, int, int)</code>.
  4196. * <p>
  4197. * Moves and resizes this component.
  4198. *
  4199. * @param x the new horizontal location
  4200. * @param y the new vertical location
  4201. * @param w the new width
  4202. * @param h the new height
  4203. * @see java.awt.Component#setBounds
  4204. */
  4205. @Deprecated
  4206. public void reshape(int x, int y, int w, int h) {
  4207. super.reshape(x, y, w, h);
  4208. }
  4209.  
  4210.  
  4211. /**
  4212. * Stores the bounds of this component into "return value"
  4213. * <code>rv</code> and returns <code>rv</code>.
  4214. * If <code>rv</code> is <code>null</code> a new <code>Rectangle</code>
  4215. * is allocated. This version of <code>getBounds</code> is useful
  4216. * if the caller wants to avoid allocating a new <code>Rectangle</code>
  4217. * object on the heap.
  4218. *
  4219. * @param rv the return value, modified to the component's bounds
  4220. * @return <code>rv</code>; if <code>rv</code> is <code>null</code>
  4221. * return a newly created <code>Rectangle</code> with this
  4222. * component's bounds
  4223. */
  4224. public Rectangle getBounds(Rectangle rv) {
  4225. if (rv == null) {
  4226. return new Rectangle(getX(), getY(), getWidth(), getHeight());
  4227. }
  4228. else {
  4229. rv.setBounds(getX(), getY(), getWidth(), getHeight());
  4230. return rv;
  4231. }
  4232. }
  4233.  
  4234.  
  4235. /**
  4236. * Stores the width/height of this component into "return value"
  4237. * <code>rv</code> and returns <code>rv</code>.
  4238. * If <code>rv</code> is <code>null</code> a new <code>Dimension</code>
  4239. * object is allocated. This version of <code>getSize</code>
  4240. * is useful if the caller wants to avoid allocating a new
  4241. * <code>Dimension</code> object on the heap.
  4242. *
  4243. * @param rv the return value, modified to the component's size
  4244. * @return <code>rv</code>
  4245. */
  4246. public Dimension getSize(Dimension rv) {
  4247. if (rv == null) {
  4248. return new Dimension(getWidth(), getHeight());
  4249. }
  4250. else {
  4251. rv.setSize(getWidth(), getHeight());
  4252. return rv;
  4253. }
  4254. }
  4255.  
  4256.  
  4257. /**
  4258. * Stores the x,y origin of this component into "return value"
  4259. * <code>rv</code> and returns <code>rv</code>.
  4260. * If <code>rv</code> is <code>null</code> a new <code>Point</code>
  4261. * is allocated. This version of <code>getLocation</code> is useful
  4262. * if the caller wants to avoid allocating a new <code>Point</code>
  4263. * object on the heap.
  4264. *
  4265. * @param rv the return value, modified to the component's location
  4266. * @return <code>rv</code>
  4267. */
  4268. public Point getLocation(Point rv) {
  4269. if (rv == null) {
  4270. return new Point(getX(), getY());
  4271. }
  4272. else {
  4273. rv.setLocation(getX(), getY());
  4274. return rv;
  4275. }
  4276. }
  4277.  
  4278.  
  4279. /**
  4280. * Returns the current x coordinate of the component's origin.
  4281. * This method is preferable to writing
  4282. * <code>component.getBounds().x</code>, or
  4283. * <code>component.getLocation().x</code> because it doesn't cause any
  4284. * heap allocations.
  4285. *
  4286. * @return the current x coordinate of the component's origin
  4287. */
  4288. public int getX() { return super.getX(); }
  4289.  
  4290.  
  4291. /**
  4292. * Returns the current y coordinate of the component's origin.
  4293. * This method is preferable to writing
  4294. * <code>component.getBounds().y</code>, or
  4295. * <code>component.getLocation().y</code> because it doesn't cause any
  4296. * heap allocations.
  4297. *
  4298. * @return the current y coordinate of the component's origin
  4299. */
  4300. public int getY() { return super.getY(); }
  4301.  
  4302.  
  4303. /**
  4304. * Returns the current width of this component.
  4305. * This method is preferable to writing
  4306. * <code>component.getBounds().width</code>, or
  4307. * <code>component.getSize().width</code> because it doesn't cause any
  4308. * heap allocations.
  4309. *
  4310. * @return the current width of this component
  4311. */
  4312. public int getWidth() { return super.getWidth(); }
  4313.  
  4314.  
  4315. /**
  4316. * Returns the current height of this component.
  4317. * This method is preferable to writing
  4318. * <code>component.getBounds().height</code>, or
  4319. * <code>component.getSize().height</code> because it doesn't cause any
  4320. * heap allocations.
  4321. *
  4322. * @return the current height of this component
  4323. */
  4324. public int getHeight() { return super.getHeight(); }
  4325.  
  4326. /**
  4327. * Returns true if this component is completely opaque.
  4328. * <p>
  4329. * An opaque component paints every pixel within its
  4330. * rectangular bounds. A non-opaque component paints only a subset of
  4331. * its pixels or none at all, allowing the pixels underneath it to
  4332. * "show through". Therefore, a component that does not fully paint
  4333. * its pixels provides a degree of transparency.
  4334. * <p>
  4335. * Subclasses that guarantee to always completely paint their contents
  4336. * should override this method and return true.
  4337. *
  4338. * @return true if this component is completely opaque
  4339. * @see #setOpaque
  4340. */
  4341. public boolean isOpaque() {
  4342. return getFlag(IS_OPAQUE);
  4343. }
  4344.  
  4345. /**
  4346. * If true the component paints every pixel within its bounds.
  4347. * Otherwise, the component may not paint some or all of its
  4348. * pixels, allowing the underlying pixels to show through.
  4349. * <p>
  4350. * The default value of this property is false for <code>JComponent</code>.
  4351. * However, the default value for this property on most standard
  4352. * <code>JComponent</code> subclasses (such as <code>JButton</code> and
  4353. * <code>JTree</code>) is look-and-feel dependent.
  4354. *
  4355. * @param isOpaque true if this component should be opaque
  4356. * @see #isOpaque
  4357. * @beaninfo
  4358. * bound: true
  4359. * expert: true
  4360. * description: The component's opacity
  4361. */
  4362. public void setOpaque(boolean isOpaque) {
  4363. boolean oldValue = getFlag(IS_OPAQUE);
  4364. setFlag(IS_OPAQUE, isOpaque);
  4365. setFlag(OPAQUE_SET, true);
  4366. firePropertyChange("opaque", oldValue, isOpaque);
  4367. }
  4368.  
  4369.  
  4370. /**
  4371. * If the specified rectangle is completely obscured by any of this
  4372. * component's opaque children then returns true. Only direct children
  4373. * are considered, more distant descendants are ignored. A
  4374. * <code>JComponent</code> is opaque if
  4375. * <code>JComponent.isOpaque()</code> returns true, other lightweight
  4376. * components are always considered transparent, and heavyweight components
  4377. * are always considered opaque.
  4378. *
  4379. * @param x x value of specified rectangle
  4380. * @param y y value of specified rectangle
  4381. * @param width width of specified rectangle
  4382. * @param height height of specified rectangle
  4383. * @return true if the specified rectangle is obscured by an opaque child
  4384. */
  4385. boolean rectangleIsObscured(int x,int y,int width,int height)
  4386. {
  4387. int numChildren = getComponentCount();
  4388.  
  4389. for(int i = 0; i < numChildren; i++) {
  4390. Component child = getComponent(i);
  4391. int cx, cy, cw, ch;
  4392.  
  4393. cx = child.getX();
  4394. cy = child.getY();
  4395. cw = child.getWidth();
  4396. ch = child.getHeight();
  4397.  
  4398. if (x >= cx && (x + width) <= (cx + cw) &&
  4399. y >= cy && (y + height) <= (cy + ch) && child.isVisible()) {
  4400.  
  4401. if(child instanceof JComponent) {
  4402. // System.out.println("A) checking opaque: " + ((JComponent)child).isOpaque() + " " + child);
  4403. // System.out.print("B) ");
  4404. // Thread.dumpStack();
  4405. return child.isOpaque();
  4406. } else {
  4407. /** Sometimes a heavy weight can have a bound larger than its peer size
  4408. * so we should always draw under heavy weights
  4409. */
  4410. return false;
  4411. }
  4412. }
  4413. }
  4414.  
  4415. return false;
  4416. }
  4417.  
  4418.  
  4419. /**
  4420. * Returns the <code>Component</code>'s "visible rect rectangle" - the
  4421. * intersection of the visible rectangles for the component <code>c</code>
  4422. * and all of its ancestors. The return value is stored in
  4423. * <code>visibleRect</code>.
  4424. *
  4425. * @param c the component
  4426. * @param visibleRect a <code>Rectangle</code> computed as the
  4427. * intersection of all visible rectangles for the component
  4428. * <code>c</code> and all of its ancestors -- this is the
  4429. * return value for this method
  4430. * @see #getVisibleRect
  4431. */
  4432. static final void computeVisibleRect(Component c, Rectangle visibleRect) {
  4433. Container p = c.getParent();
  4434. Rectangle bounds = c.getBounds();
  4435.  
  4436. if (p == null || p instanceof Window || p instanceof Applet) {
  4437. visibleRect.setBounds(0, 0, bounds.width, bounds.height);
  4438. } else {
  4439. computeVisibleRect(p, visibleRect);
  4440. visibleRect.x -= bounds.x;
  4441. visibleRect.y -= bounds.y;
  4442. SwingUtilities.computeIntersection(0,0,bounds.width,bounds.height,visibleRect);
  4443. }
  4444. }
  4445.  
  4446.  
  4447. /**
  4448. * Returns the <code>Component</code>'s "visible rect rectangle" - the
  4449. * intersection of the visible rectangles for this component
  4450. * and all of its ancestors. The return value is stored in
  4451. * <code>visibleRect</code>.
  4452. *
  4453. * @param visibleRect a <code>Rectangle</code> computed as the
  4454. * intersection of all visible rectangles for this
  4455. * component and all of its ancestors -- this is the return
  4456. * value for this method
  4457. * @see #getVisibleRect
  4458. */
  4459. public void computeVisibleRect(Rectangle visibleRect) {
  4460. computeVisibleRect(this, visibleRect);
  4461. }
  4462.  
  4463.  
  4464. /**
  4465. * Returns the <code>Component</code>'s "visible rectangle" - the
  4466. * intersection of this component's visible rectangle,
  4467. * <code>new Rectangle(0, 0, getWidth(), getHeight())</code>,
  4468. * and all of its ancestors' visible rectangles.
  4469. *
  4470. * @return the visible rectangle
  4471. */
  4472. public Rectangle getVisibleRect() {
  4473. Rectangle visibleRect = new Rectangle();
  4474.  
  4475. computeVisibleRect(visibleRect);
  4476. return visibleRect;
  4477. }
  4478.  
  4479. /**
  4480. * Support for reporting bound property changes for boolean properties.
  4481. * This method can be called when a bound property has changed and it will
  4482. * send the appropriate PropertyChangeEvent to any registered
  4483. * PropertyChangeListeners.
  4484. *
  4485. * @param propertyName the property whose value has changed
  4486. * @param oldValue the property's previous value
  4487. * @param newValue the property's new value
  4488. */
  4489. public void firePropertyChange(String propertyName,
  4490. boolean oldValue, boolean newValue) {
  4491. super.firePropertyChange(propertyName, oldValue, newValue);
  4492. }
  4493.  
  4494.  
  4495. /**
  4496. * Support for reporting bound property changes for integer properties.
  4497. * This method can be called when a bound property has changed and it will
  4498. * send the appropriate PropertyChangeEvent to any registered
  4499. * PropertyChangeListeners.
  4500. *
  4501. * @param propertyName the property whose value has changed
  4502. * @param oldValue the property's previous value
  4503. * @param newValue the property's new value
  4504. */
  4505. public void firePropertyChange(String propertyName,
  4506. int oldValue, int newValue) {
  4507. super.firePropertyChange(propertyName, oldValue, newValue);
  4508. }
  4509.  
  4510. // XXX This method is implemented as a workaround to a JLS issue with ambiguous
  4511. // methods. This should be removed once 4758654 is resolved.
  4512. public void firePropertyChange(String propertyName, char oldValue, char newValue) {
  4513. super.firePropertyChange(propertyName, oldValue, newValue);
  4514. }
  4515.  
  4516. /**
  4517. * Supports reporting constrained property changes.
  4518. * This method can be called when a constrained property has changed
  4519. * and it will send the appropriate <code>PropertyChangeEvent</code>
  4520. * to any registered <code>VetoableChangeListeners</code>.
  4521. *
  4522. * @param propertyName the name of the property that was listened on
  4523. * @param oldValue the old value of the property
  4524. * @param newValue the new value of the property
  4525. * @exception java.beans.PropertyVetoException when the attempt to set the
  4526. * property is vetoed by the component
  4527. */
  4528. protected void fireVetoableChange(String propertyName, Object oldValue, Object newValue)
  4529. throws java.beans.PropertyVetoException
  4530. {
  4531. if (vetoableChangeSupport == null) {
  4532. return;
  4533. }
  4534. vetoableChangeSupport.fireVetoableChange(propertyName, oldValue, newValue);
  4535. }
  4536.  
  4537.  
  4538. /**
  4539. * Adds a <code>VetoableChangeListener</code> to the listener list.
  4540. * The listener is registered for all properties.
  4541. *
  4542. * @param listener the <code>VetoableChangeListener</code> to be added
  4543. */
  4544. public synchronized void addVetoableChangeListener(VetoableChangeListener listener) {
  4545. if (vetoableChangeSupport == null) {
  4546. vetoableChangeSupport = new java.beans.VetoableChangeSupport(this);
  4547. }
  4548. vetoableChangeSupport.addVetoableChangeListener(listener);
  4549. }
  4550.  
  4551.  
  4552. /**
  4553. * Removes a <code>VetoableChangeListener</code> from the listener list.
  4554. * This removes a <code>VetoableChangeListener</code> that was registered
  4555. * for all properties.
  4556. *
  4557. * @param listener the <code>VetoableChangeListener</code> to be removed
  4558. */
  4559. public synchronized void removeVetoableChangeListener(VetoableChangeListener listener) {
  4560. if (vetoableChangeSupport == null) {
  4561. return;
  4562. }
  4563. vetoableChangeSupport.removeVetoableChangeListener(listener);
  4564. }
  4565.  
  4566.  
  4567. /**
  4568. * Returns an array of all the vetoable change listeners
  4569. * registered on this component.
  4570. *
  4571. * @return all of the component's <code>VetoableChangeListener</code>s
  4572. * or an empty
  4573. * array if no vetoable change listeners are currently registered
  4574. *
  4575. * @see #addVetoableChangeListener
  4576. * @see #removeVetoableChangeListener
  4577. *
  4578. * @since 1.4
  4579. */
  4580. public synchronized VetoableChangeListener[] getVetoableChangeListeners() {
  4581. if (vetoableChangeSupport == null) {
  4582. return new VetoableChangeListener[0];
  4583. }
  4584. return vetoableChangeSupport.getVetoableChangeListeners();
  4585. }
  4586.  
  4587.  
  4588. /**
  4589. * Returns the top-level ancestor of this component (either the
  4590. * containing <code>Window</code> or <code>Applet</code>),
  4591. * or <code>null</code> if this component has not
  4592. * been added to any container.
  4593. *
  4594. * @return the top-level <code>Container</code> that this component is in,
  4595. * or <code>null</code> if not in any container
  4596. */
  4597. public Container getTopLevelAncestor() {
  4598. for(Container p = this; p != null; p = p.getParent()) {
  4599. if(p instanceof Window || p instanceof Applet) {
  4600. return p;
  4601. }
  4602. }
  4603. return null;
  4604. }
  4605.  
  4606. private AncestorNotifier getAncestorNotifier() {
  4607. return (AncestorNotifier)
  4608. getClientProperty(JComponent_ANCESTOR_NOTIFIER);
  4609. }
  4610.  
  4611. /**
  4612. * Registers <code>listener</code> so that it will receive
  4613. * <code>AncestorEvents</code> when it or any of its ancestors
  4614. * move or are made visible or invisible.
  4615. * Events are also sent when the component or its ancestors are added
  4616. * or removed from the containment hierarchy.
  4617. *
  4618. * @param listener the <code>AncestorListener</code> to register
  4619. * @see AncestorEvent
  4620. */
  4621. public void addAncestorListener(AncestorListener listener) {
  4622. AncestorNotifier ancestorNotifier = getAncestorNotifier();
  4623. if (ancestorNotifier == null) {
  4624. ancestorNotifier = new AncestorNotifier(this);
  4625. putClientProperty(JComponent_ANCESTOR_NOTIFIER,
  4626. ancestorNotifier);
  4627. }
  4628. ancestorNotifier.addAncestorListener(listener);
  4629. }
  4630.  
  4631. /**
  4632. * Unregisters <code>listener</code> so that it will no longer receive
  4633. * <code>AncestorEvents</code>.
  4634. *
  4635. * @param listener the <code>AncestorListener</code> to be removed
  4636. * @see #addAncestorListener
  4637. */
  4638. public void removeAncestorListener(AncestorListener listener) {
  4639. AncestorNotifier ancestorNotifier = getAncestorNotifier();
  4640. if (ancestorNotifier == null) {
  4641. return;
  4642. }
  4643. ancestorNotifier.removeAncestorListener(listener);
  4644. if (ancestorNotifier.listenerList.getListenerList().length == 0) {
  4645. ancestorNotifier.removeAllListeners();
  4646. putClientProperty(JComponent_ANCESTOR_NOTIFIER, null);
  4647. }
  4648. }
  4649.  
  4650. /**
  4651. * Returns an array of all the ancestor listeners
  4652. * registered on this component.
  4653. *
  4654. * @return all of the component's <code>AncestorListener</code>s
  4655. * or an empty
  4656. * array if no ancestor listeners are currently registered
  4657. *
  4658. * @see #addAncestorListener
  4659. * @see #removeAncestorListener
  4660. *
  4661. * @since 1.4
  4662. */
  4663. public AncestorListener[] getAncestorListeners() {
  4664. AncestorNotifier ancestorNotifier = getAncestorNotifier();
  4665. if (ancestorNotifier == null) {
  4666. return new AncestorListener[0];
  4667. }
  4668. return ancestorNotifier.getAncestorListeners();
  4669. }
  4670.  
  4671. /**
  4672. * Returns an array of all the objects currently registered
  4673. * as <code><em>Foo</em>Listener</code>s
  4674. * upon this <code>JComponent</code>.
  4675. * <code><em>Foo</em>Listener</code>s are registered using the
  4676. * <code>add<em>Foo</em>Listener</code> method.
  4677. *
  4678. * <p>
  4679. *
  4680. * You can specify the <code>listenerType</code> argument
  4681. * with a class literal,
  4682. * such as
  4683. * <code><em>Foo</em>Listener.class</code>.
  4684. * For example, you can query a
  4685. * <code>JComponent</code> <code>c</code>
  4686. * for its mouse listeners with the following code:
  4687. * <pre>MouseListener[] mls = (MouseListener[])(c.getListeners(MouseListener.class));</pre>
  4688. * If no such listeners exist, this method returns an empty array.
  4689. *
  4690. * @param listenerType the type of listeners requested; this parameter
  4691. * should specify an interface that descends from
  4692. * <code>java.util.EventListener</code>
  4693. * @return an array of all objects registered as
  4694. * <code><em>Foo</em>Listener</code>s on this component,
  4695. * or an empty array if no such
  4696. * listeners have been added
  4697. * @exception ClassCastException if <code>listenerType</code>
  4698. * doesn't specify a class or interface that implements
  4699. * <code>java.util.EventListener</code>
  4700. *
  4701. * @since 1.3
  4702. *
  4703. * @see #getVetoableChangeListeners
  4704. * @see #getAncestorListeners
  4705. */
  4706. public <T extends EventListener> T[] getListeners(Class<T> listenerType) {
  4707. T[] result;
  4708. if (listenerType == AncestorListener.class) {
  4709. // AncestorListeners are handled by the AncestorNotifier
  4710. result = (T[])getAncestorListeners();
  4711. }
  4712. else if (listenerType == VetoableChangeListener.class) {
  4713. // VetoableChangeListeners are handled by VetoableChangeSupport
  4714. result = (T[])getVetoableChangeListeners();
  4715. }
  4716. else if (listenerType == PropertyChangeListener.class) {
  4717. // PropertyChangeListeners are handled by PropertyChangeSupport
  4718. result = (T[])getPropertyChangeListeners();
  4719. }
  4720. else {
  4721. result = listenerList.getListeners(listenerType);
  4722. }
  4723.  
  4724. if (result.length == 0) {
  4725. return super.getListeners(listenerType);
  4726. }
  4727. return result;
  4728. }
  4729.  
  4730. /**
  4731. * Notifies this component that it now has a parent component.
  4732. * When this method is invoked, the chain of parent components is
  4733. * set up with <code>KeyboardAction</code> event listeners.
  4734. * This method is called by the toolkit internally and should
  4735. * not be called directly by programs.
  4736. *
  4737. * @see #registerKeyboardAction
  4738. */
  4739. public void addNotify() {
  4740. super.addNotify();
  4741. firePropertyChange("ancestor", null, getParent());
  4742.  
  4743. registerWithKeyboardManager(false);
  4744. registerNextFocusableComponent();
  4745. }
  4746.  
  4747.  
  4748. /**
  4749. * Notifies this component that it no longer has a parent component.
  4750. * When this method is invoked, any <code>KeyboardAction</code>s
  4751. * set up in the the chain of parent components are removed.
  4752. * This method is called by the toolkit internally and should
  4753. * not be called directly by programs.
  4754. *
  4755. * @see #registerKeyboardAction
  4756. */
  4757. public void removeNotify() {
  4758. super.removeNotify();
  4759. // This isn't strictly correct. The event shouldn't be
  4760. // fired until *after* the parent is set to null. But
  4761. // we only get notified before that happens
  4762. firePropertyChange("ancestor", getParent(), null);
  4763.  
  4764. unregisterWithKeyboardManager();
  4765. deregisterNextFocusableComponent();
  4766.  
  4767. if (getCreatedDoubleBuffer()) {
  4768. RepaintManager.currentManager(this).resetDoubleBuffer();
  4769. setCreatedDoubleBuffer(false);
  4770. }
  4771. if (autoscrolls) {
  4772. Autoscroller.stop(this);
  4773. }
  4774. }
  4775.  
  4776.  
  4777. /**
  4778. * Adds the specified region to the dirty region list if the component
  4779. * is showing. The component will be repainted after all of the
  4780. * currently pending events have been dispatched.
  4781. *
  4782. * @param tm this parameter is not used
  4783. * @param x the x value of the dirty region
  4784. * @param y the y value of the dirty region
  4785. * @param width the width of the dirty region
  4786. * @param height the height of the dirty region
  4787. * @see #isPaintingOrigin()
  4788. * @see java.awt.Component#isShowing
  4789. * @see RepaintManager#addDirtyRegion
  4790. */
  4791. public void repaint(long tm, int x, int y, int width, int height) {
  4792. RepaintManager.currentManager(SunToolkit.targetToAppContext(this))
  4793. .addDirtyRegion(this, x, y, width, height);
  4794. }
  4795.  
  4796.  
  4797. /**
  4798. * Adds the specified region to the dirty region list if the component
  4799. * is showing. The component will be repainted after all of the
  4800. * currently pending events have been dispatched.
  4801. *
  4802. * @param r a <code>Rectangle</code> containing the dirty region
  4803. * @see #isPaintingOrigin()
  4804. * @see java.awt.Component#isShowing
  4805. * @see RepaintManager#addDirtyRegion
  4806. */
  4807. public void repaint(Rectangle r) {
  4808. repaint(0,r.x,r.y,r.width,r.height);
  4809. }
  4810.  
  4811.  
  4812. /**
  4813. * Supports deferred automatic layout.
  4814. * <p>
  4815. * Calls <code>invalidate</code> and then adds this component's
  4816. * <code>validateRoot</code> to a list of components that need to be
  4817. * validated. Validation will occur after all currently pending
  4818. * events have been dispatched. In other words after this method
  4819. * is called, the first validateRoot (if any) found when walking
  4820. * up the containment hierarchy of this component will be validated.
  4821. * By default, <code>JRootPane</code>, <code>JScrollPane</code>,
  4822. * and <code>JTextField</code> return true
  4823. * from <code>isValidateRoot</code>.
  4824. * <p>
  4825. * This method will automatically be called on this component
  4826. * when a property value changes such that size, location, or
  4827. * internal layout of this component has been affected. This automatic
  4828. * updating differs from the AWT because programs generally no
  4829. * longer need to invoke <code>validate</code> to get the contents of the
  4830. * GUI to update.
  4831. *
  4832. * @see java.awt.Component#invalidate
  4833. * @see java.awt.Container#validate
  4834. * @see #isValidateRoot
  4835. * @see RepaintManager#addInvalidComponent
  4836. */
  4837. public void revalidate() {
  4838. if (getParent() == null) {
  4839. // Note: We don't bother invalidating here as once added
  4840. // to a valid parent invalidate will be invoked (addImpl
  4841. // invokes addNotify which will invoke invalidate on the
  4842. // new Component). Also, if we do add a check to isValid
  4843. // here it can potentially be called before the constructor
  4844. // which was causing some people grief.
  4845. return;
  4846. }
  4847. if (SunToolkit.isDispatchThreadForAppContext(this)) {
  4848. invalidate();
  4849. RepaintManager.currentManager(this).addInvalidComponent(this);
  4850. }
  4851. else {
  4852. // To avoid a flood of Runnables when constructing GUIs off
  4853. // the EDT, a flag is maintained as to whether or not
  4854. // a Runnable has been scheduled.
  4855. if (revalidateRunnableScheduled.getAndSet(true)) {
  4856. return;
  4857. }
  4858. SunToolkit.executeOnEventHandlerThread(this, () -> {
  4859. revalidateRunnableScheduled.set(false);
  4860. revalidate();
  4861. });
  4862. }
  4863. }
  4864.  
  4865. /**
  4866. * If this method returns true, <code>revalidate</code> calls by
  4867. * descendants of this component will cause the entire tree
  4868. * beginning with this root to be validated.
  4869. * Returns false by default. <code>JScrollPane</code> overrides
  4870. * this method and returns true.
  4871. *
  4872. * @return always returns false
  4873. * @see #revalidate
  4874. * @see java.awt.Component#invalidate
  4875. * @see java.awt.Container#validate
  4876. * @see java.awt.Container#isValidateRoot
  4877. */
  4878. @Override
  4879. public boolean isValidateRoot() {
  4880. return false;
  4881. }
  4882.  
  4883.  
  4884. /**
  4885. * Returns true if this component tiles its children -- that is, if
  4886. * it can guarantee that the children will not overlap. The
  4887. * repainting system is substantially more efficient in this
  4888. * common case. <code>JComponent</code> subclasses that can't make this
  4889. * guarantee, such as <code>JLayeredPane</code>,
  4890. * should override this method to return false.
  4891. *
  4892. * @return always returns true
  4893. */
  4894. public boolean isOptimizedDrawingEnabled() {
  4895. return true;
  4896. }
  4897.  
  4898. /**
  4899. * Returns {@code true} if a paint triggered on a child component should cause
  4900. * painting to originate from this Component, or one of its ancestors.
  4901. * <p>
  4902. * Calling {@link #repaint} or {@link #paintImmediately(int, int, int, int)}
  4903. * on a Swing component will result in calling
  4904. * the {@link JComponent#paintImmediately(int, int, int, int)} method of
  4905. * the first ancestor which {@code isPaintingOrigin()} returns {@code true}, if there are any.
  4906. * <p>
  4907. * {@code JComponent} subclasses that need to be painted when any of their
  4908. * children are repainted should override this method to return {@code true}.
  4909. *
  4910. * @return always returns {@code false}
  4911. *
  4912. * @see #paintImmediately(int, int, int, int)
  4913. */
  4914. protected boolean isPaintingOrigin() {
  4915. return false;
  4916. }
  4917.  
  4918. /**
  4919. * Paints the specified region in this component and all of its
  4920. * descendants that overlap the region, immediately.
  4921. * <p>
  4922. * It's rarely necessary to call this method. In most cases it's
  4923. * more efficient to call repaint, which defers the actual painting
  4924. * and can collapse redundant requests into a single paint call.
  4925. * This method is useful if one needs to update the display while
  4926. * the current event is being dispatched.
  4927. * <p>
  4928. * This method is to be overridden when the dirty region needs to be changed
  4929. * for components that are painting origins.
  4930. *
  4931. * @param x the x value of the region to be painted
  4932. * @param y the y value of the region to be painted
  4933. * @param w the width of the region to be painted
  4934. * @param h the height of the region to be painted
  4935. * @see #repaint
  4936. * @see #isPaintingOrigin()
  4937. */
  4938. public void paintImmediately(int x,int y,int w, int h) {
  4939. Component c = this;
  4940. Component parent;
  4941.  
  4942. if(!isShowing()) {
  4943. return;
  4944. }
  4945.  
  4946. JComponent paintingOigin = SwingUtilities.getPaintingOrigin(this);
  4947. if (paintingOigin != null) {
  4948. Rectangle rectangle = SwingUtilities.convertRectangle(
  4949. c, new Rectangle(x, y, w, h), paintingOigin);
  4950. paintingOigin.paintImmediately(rectangle.x, rectangle.y, rectangle.width, rectangle.height);
  4951. return;
  4952. }
  4953.  
  4954. while(!c.isOpaque()) {
  4955. parent = c.getParent();
  4956. if(parent != null) {
  4957. x += c.getX();
  4958. y += c.getY();
  4959. c = parent;
  4960. } else {
  4961. break;
  4962. }
  4963.  
  4964. if(!(c instanceof JComponent)) {
  4965. break;
  4966. }
  4967. }
  4968. if(c instanceof JComponent) {
  4969. ((JComponent)c)._paintImmediately(x,y,w,h);
  4970. } else {
  4971. c.repaint(x,y,w,h);
  4972. }
  4973. }
  4974.  
  4975. /**
  4976. * Paints the specified region now.
  4977. *
  4978. * @param r a <code>Rectangle</code> containing the region to be painted
  4979. */
  4980. public void paintImmediately(Rectangle r) {
  4981. paintImmediately(r.x,r.y,r.width,r.height);
  4982. }
  4983.  
  4984. /**
  4985. * Returns whether this component should be guaranteed to be on top.
  4986. * For example, it would make no sense for <code>Menu</code>s to pop up
  4987. * under another component, so they would always return true.
  4988. * Most components will want to return false, hence that is the default.
  4989. *
  4990. * @return always returns false
  4991. */
  4992. // package private
  4993. boolean alwaysOnTop() {
  4994. return false;
  4995. }
  4996.  
  4997. void setPaintingChild(Component paintingChild) {
  4998. this.paintingChild = paintingChild;
  4999. }
  5000.  
  5001. void _paintImmediately(int x, int y, int w, int h) {
  5002. Graphics g;
  5003. Container c;
  5004. Rectangle b;
  5005.  
  5006. int tmpX, tmpY, tmpWidth, tmpHeight;
  5007. int offsetX=0,offsetY=0;
  5008.  
  5009. boolean hasBuffer = false;
  5010.  
  5011. JComponent bufferedComponent = null;
  5012. JComponent paintingComponent = this;
  5013.  
  5014. RepaintManager repaintManager = RepaintManager.currentManager(this);
  5015. // parent Container's up to Window or Applet. First container is
  5016. // the direct parent. Note that in testing it was faster to
  5017. // alloc a new Vector vs keeping a stack of them around, and gc
  5018. // seemed to have a minimal effect on this.
  5019. java.util.List<Component> path = new java.util.ArrayList<Component>(7);
  5020. int pIndex = -1;
  5021. int pCount = 0;
  5022.  
  5023. tmpX = tmpY = tmpWidth = tmpHeight = 0;
  5024.  
  5025. Rectangle paintImmediatelyClip = fetchRectangle();
  5026. paintImmediatelyClip.x = x;
  5027. paintImmediatelyClip.y = y;
  5028. paintImmediatelyClip.width = w;
  5029. paintImmediatelyClip.height = h;
  5030.  
  5031.  
  5032. // System.out.println("1) ************* in _paintImmediately for " + this);
  5033.  
  5034. boolean ontop = alwaysOnTop() && isOpaque();
  5035. if (ontop) {
  5036. SwingUtilities.computeIntersection(0, 0, getWidth(), getHeight(),
  5037. paintImmediatelyClip);
  5038. if (paintImmediatelyClip.width == 0) {
  5039. recycleRectangle(paintImmediatelyClip);
  5040. return;
  5041. }
  5042. }
  5043. Component child;
  5044. for (c = this, child = null;
  5045. c != null && !(c instanceof Window) && !(c instanceof Applet);
  5046. child = c, c = c.getParent()) {
  5047. JComponent jc = (c instanceof JComponent) ? (JComponent)c :
  5048. null;
  5049. path.add(c);
  5050. if(!ontop && jc != null && !jc.isOptimizedDrawingEnabled()) {
  5051. boolean resetPC;
  5052.  
  5053. // Children of c may overlap, three possible cases for the
  5054. // painting region:
  5055. // . Completely obscured by an opaque sibling, in which
  5056. // case there is no need to paint.
  5057. // . Partially obscured by a sibling: need to start
  5058. // painting from c.
  5059. // . Otherwise we aren't obscured and thus don't need to
  5060. // start painting from parent.
  5061. if (c != this) {
  5062. if (jc.isPaintingOrigin()) {
  5063. resetPC = true;
  5064. }
  5065. else {
  5066. Component[] children = c.getComponents();
  5067. int i = 0;
  5068. for (; i<children.length; i++) {
  5069. if (children[i] == child) break;
  5070. }
  5071. switch (jc.getObscuredState(i,
  5072. paintImmediatelyClip.x,
  5073. paintImmediatelyClip.y,
  5074. paintImmediatelyClip.width,
  5075. paintImmediatelyClip.height)) {
  5076. case NOT_OBSCURED:
  5077. resetPC = false;
  5078. break;
  5079. case COMPLETELY_OBSCURED:
  5080. recycleRectangle(paintImmediatelyClip);
  5081. return;
  5082. default:
  5083. resetPC = true;
  5084. break;
  5085. }
  5086. }
  5087. }
  5088. else {
  5089. resetPC = false;
  5090. }
  5091.  
  5092. if (resetPC) {
  5093. // Get rid of any buffer since we draw from here and
  5094. // we might draw something larger
  5095. paintingComponent = jc;
  5096. pIndex = pCount;
  5097. offsetX = offsetY = 0;
  5098. hasBuffer = false;
  5099. }
  5100. }
  5101. pCount++;
  5102.  
  5103. // look to see if the parent (and therefor this component)
  5104. // is double buffered
  5105. if(repaintManager.isDoubleBufferingEnabled() && jc != null &&
  5106. jc.isDoubleBuffered()) {
  5107. hasBuffer = true;
  5108. bufferedComponent = jc;
  5109. }
  5110.  
  5111. // if we aren't on top, include the parent's clip
  5112. if (!ontop) {
  5113. int bx = c.getX();
  5114. int by = c.getY();
  5115. tmpWidth = c.getWidth();
  5116. tmpHeight = c.getHeight();
  5117. SwingUtilities.computeIntersection(tmpX,tmpY,tmpWidth,tmpHeight,paintImmediatelyClip);
  5118. paintImmediatelyClip.x += bx;
  5119. paintImmediatelyClip.y += by;
  5120. offsetX += bx;
  5121. offsetY += by;
  5122. }
  5123. }
  5124.  
  5125. // If the clip width or height is negative, don't bother painting
  5126. if(c == null || c.getPeer() == null ||
  5127. paintImmediatelyClip.width <= 0 ||
  5128. paintImmediatelyClip.height <= 0) {
  5129. recycleRectangle(paintImmediatelyClip);
  5130. return;
  5131. }
  5132.  
  5133. paintingComponent.setFlag(IS_REPAINTING, true);
  5134.  
  5135. paintImmediatelyClip.x -= offsetX;
  5136. paintImmediatelyClip.y -= offsetY;
  5137.  
  5138. // Notify the Components that are going to be painted of the
  5139. // child component to paint to.
  5140. if(paintingComponent != this) {
  5141. Component comp;
  5142. int i = pIndex;
  5143. for(; i > 0 ; i--) {
  5144. comp = path.get(i);
  5145. if(comp instanceof JComponent) {
  5146. ((JComponent)comp).setPaintingChild(path.get(i-1));
  5147. }
  5148. }
  5149. }
  5150. try {
  5151. if ((g = safelyGetGraphics(paintingComponent, c)) != null) {
  5152. try {
  5153. if (hasBuffer) {
  5154. RepaintManager rm = RepaintManager.currentManager(
  5155. bufferedComponent);
  5156. rm.beginPaint();
  5157. try {
  5158. rm.paint(paintingComponent, bufferedComponent, g,
  5159. paintImmediatelyClip.x,
  5160. paintImmediatelyClip.y,
  5161. paintImmediatelyClip.width,
  5162. paintImmediatelyClip.height);
  5163. } finally {
  5164. rm.endPaint();
  5165. }
  5166. } else {
  5167. g.setClip(paintImmediatelyClip.x, paintImmediatelyClip.y,
  5168. paintImmediatelyClip.width, paintImmediatelyClip.height);
  5169. paintingComponent.paint(g);
  5170. }
  5171. } finally {
  5172. g.dispose();
  5173. }
  5174. }
  5175. }
  5176. finally {
  5177. // Reset the painting child for the parent components.
  5178. if(paintingComponent != this) {
  5179. Component comp;
  5180. int i = pIndex;
  5181. for(; i > 0 ; i--) {
  5182. comp = path.get(i);
  5183. if(comp instanceof JComponent) {
  5184. ((JComponent)comp).setPaintingChild(null);
  5185. }
  5186. }
  5187. }
  5188. paintingComponent.setFlag(IS_REPAINTING, false);
  5189. }
  5190. recycleRectangle(paintImmediatelyClip);
  5191. }
  5192.  
  5193. /**
  5194. * Paints to the specified graphics. This does not set the clip and it
  5195. * does not adjust the Graphics in anyway, callers must do that first.
  5196. * This method is package-private for RepaintManager.PaintManager and
  5197. * its subclasses to call, it is NOT intended for general use outside
  5198. * of that.
  5199. */
  5200. void paintToOffscreen(Graphics g, int x, int y, int w, int h, int maxX,
  5201. int maxY) {
  5202. try {
  5203. setFlag(ANCESTOR_USING_BUFFER, true);
  5204. if ((y + h) < maxY || (x + w) < maxX) {
  5205. setFlag(IS_PAINTING_TILE, true);
  5206. }
  5207. if (getFlag(IS_REPAINTING)) {
  5208. // Called from paintImmediately (RepaintManager) to fill
  5209. // repaint request
  5210. paint(g);
  5211. } else {
  5212. // Called from paint() (AWT) to repair damage
  5213. if(!rectangleIsObscured(x, y, w, h)) {
  5214. paintComponent(g);
  5215. paintBorder(g);
  5216. }
  5217. paintChildren(g);
  5218. }
  5219. } finally {
  5220. setFlag(ANCESTOR_USING_BUFFER, false);
  5221. setFlag(IS_PAINTING_TILE, false);
  5222. }
  5223. }
  5224.  
  5225. /**
  5226. * Returns whether or not the region of the specified component is
  5227. * obscured by a sibling.
  5228. *
  5229. * @return NOT_OBSCURED if non of the siblings above the Component obscure
  5230. * it, COMPLETELY_OBSCURED if one of the siblings completely
  5231. * obscures the Component or PARTIALLY_OBSCURED if the Component is
  5232. * only partially obscured.
  5233. */
  5234. private int getObscuredState(int compIndex, int x, int y, int width,
  5235. int height) {
  5236. int retValue = NOT_OBSCURED;
  5237. Rectangle tmpRect = fetchRectangle();
  5238.  
  5239. for (int i = compIndex - 1 ; i >= 0 ; i--) {
  5240. Component sibling = getComponent(i);
  5241. if (!sibling.isVisible()) {
  5242. continue;
  5243. }
  5244. Rectangle siblingRect;
  5245. boolean opaque;
  5246. if (sibling instanceof JComponent) {
  5247. opaque = sibling.isOpaque();
  5248. if (!opaque) {
  5249. if (retValue == PARTIALLY_OBSCURED) {
  5250. continue;
  5251. }
  5252. }
  5253. }
  5254. else {
  5255. opaque = true;
  5256. }
  5257. siblingRect = sibling.getBounds(tmpRect);
  5258. if (opaque && x >= siblingRect.x && (x + width) <=
  5259. (siblingRect.x + siblingRect.width) &&
  5260. y >= siblingRect.y && (y + height) <=
  5261. (siblingRect.y + siblingRect.height)) {
  5262. recycleRectangle(tmpRect);
  5263. return COMPLETELY_OBSCURED;
  5264. }
  5265. else if (retValue == NOT_OBSCURED &&
  5266. !((x + width <= siblingRect.x) ||
  5267. (y + height <= siblingRect.y) ||
  5268. (x >= siblingRect.x + siblingRect.width) ||
  5269. (y >= siblingRect.y + siblingRect.height))) {
  5270. retValue = PARTIALLY_OBSCURED;
  5271. }
  5272. }
  5273. recycleRectangle(tmpRect);
  5274. return retValue;
  5275. }
  5276.  
  5277. /**
  5278. * Returns true, which implies that before checking if a child should
  5279. * be painted it is first check that the child is not obscured by another
  5280. * sibling. This is only checked if <code>isOptimizedDrawingEnabled</code>
  5281. * returns false.
  5282. *
  5283. * @return always returns true
  5284. */
  5285. boolean checkIfChildObscuredBySibling() {
  5286. return true;
  5287. }
  5288.  
  5289.  
  5290. private void setFlag(int aFlag, boolean aValue) {
  5291. if(aValue) {
  5292. flags |= (1 << aFlag);
  5293. } else {
  5294. flags &= ~(1 << aFlag);
  5295. }
  5296. }
  5297. private boolean getFlag(int aFlag) {
  5298. int mask = (1 << aFlag);
  5299. return ((flags & mask) == mask);
  5300. }
  5301. // These functions must be static so that they can be called from
  5302. // subclasses inside the package, but whose inheritance hierarhcy includes
  5303. // classes outside of the package below JComponent (e.g., JTextArea).
  5304. static void setWriteObjCounter(JComponent comp, byte count) {
  5305. comp.flags = (comp.flags & ~(0xFF << WRITE_OBJ_COUNTER_FIRST)) |
  5306. (count << WRITE_OBJ_COUNTER_FIRST);
  5307. }
  5308. static byte getWriteObjCounter(JComponent comp) {
  5309. return (byte)((comp.flags >> WRITE_OBJ_COUNTER_FIRST) & 0xFF);
  5310. }
  5311.  
  5312. /** Buffering **/
  5313.  
  5314. /**
  5315. * Sets whether this component should use a buffer to paint.
  5316. * If set to true, all the drawing from this component will be done
  5317. * in an offscreen painting buffer. The offscreen painting buffer will
  5318. * the be copied onto the screen.
  5319. * If a <code>Component</code> is buffered and one of its ancestor
  5320. * is also buffered, the ancestor buffer will be used.
  5321. *
  5322. * @param aFlag if true, set this component to be double buffered
  5323. */
  5324. public void setDoubleBuffered(boolean aFlag) {
  5325. setFlag(IS_DOUBLE_BUFFERED,aFlag);
  5326. }
  5327.  
  5328. /**
  5329. * Returns whether this component should use a buffer to paint.
  5330. *
  5331. * @return true if this component is double buffered, otherwise false
  5332. */
  5333. public boolean isDoubleBuffered() {
  5334. return getFlag(IS_DOUBLE_BUFFERED);
  5335. }
  5336.  
  5337. /**
  5338. * Returns the <code>JRootPane</code> ancestor for this component.
  5339. *
  5340. * @return the <code>JRootPane</code> that contains this component,
  5341. * or <code>null</code> if no <code>JRootPane</code> is found
  5342. */
  5343. public JRootPane getRootPane() {
  5344. return SwingUtilities.getRootPane(this);
  5345. }
  5346.  
  5347.  
  5348. /** Serialization **/
  5349.  
  5350. /**
  5351. * This is called from Component by way of reflection. Do NOT change
  5352. * the name unless you change the code in Component as well.
  5353. */
  5354. void compWriteObjectNotify() {
  5355. byte count = JComponent.getWriteObjCounter(this);
  5356. JComponent.setWriteObjCounter(this, (byte)(count + 1));
  5357. if (count != 0) {
  5358. return;
  5359. }
  5360.  
  5361. uninstallUIAndProperties();
  5362.  
  5363. /* JTableHeader is in a separate package, which prevents it from
  5364. * being able to override this package-private method the way the
  5365. * other components can. We don't want to make this method protected
  5366. * because it would introduce public-api for a less-than-desirable
  5367. * serialization scheme, so we compromise with this 'instanceof' hack
  5368. * for now.
  5369. */
  5370. if (getToolTipText() != null ||
  5371. this instanceof javax.swing.table.JTableHeader) {
  5372. ToolTipManager.sharedInstance().unregisterComponent(JComponent.this);
  5373. }
  5374. }
  5375.  
  5376. /**
  5377. * This object is the <code>ObjectInputStream</code> callback
  5378. * that's called after a complete graph of objects (including at least
  5379. * one <code>JComponent</code>) has been read.
  5380. * It sets the UI property of each Swing component
  5381. * that was read to the current default with <code>updateUI</code>.
  5382. * <p>
  5383. * As each component is read in we keep track of the current set of
  5384. * root components here, in the roots vector. Note that there's only one
  5385. * <code>ReadObjectCallback</code> per <code>ObjectInputStream</code>,
  5386. * they're stored in the static <code>readObjectCallbacks</code>
  5387. * hashtable.
  5388. *
  5389. * @see java.io.ObjectInputStream#registerValidation
  5390. * @see SwingUtilities#updateComponentTreeUI
  5391. */
  5392. private class ReadObjectCallback implements ObjectInputValidation
  5393. {
  5394. private final Vector<JComponent> roots = new Vector<JComponent>(1);
  5395. private final ObjectInputStream inputStream;
  5396.  
  5397. ReadObjectCallback(ObjectInputStream s) throws Exception {
  5398. inputStream = s;
  5399. s.registerValidation(this, 0);
  5400. }
  5401.  
  5402. /**
  5403. * This is the method that's called after the entire graph
  5404. * of objects has been read in. It initializes
  5405. * the UI property of all of the copmonents with
  5406. * <code>SwingUtilities.updateComponentTreeUI</code>.
  5407. */
  5408. public void validateObject() throws InvalidObjectException {
  5409. try {
  5410. for (JComponent root : roots) {
  5411. SwingUtilities.updateComponentTreeUI(root);
  5412. }
  5413. }
  5414. finally {
  5415. readObjectCallbacks.remove(inputStream);
  5416. }
  5417. }
  5418.  
  5419. /**
  5420. * If <code>c</code> isn't a descendant of a component we've already
  5421. * seen, then add it to the roots <code>Vector</code>.
  5422. *
  5423. * @param c the <code>JComponent</code> to add
  5424. */
  5425. private void registerComponent(JComponent c)
  5426. {
  5427. /* If the Component c is a descendant of one of the
  5428. * existing roots (or it IS an existing root), we're done.
  5429. */
  5430. for (JComponent root : roots) {
  5431. for(Component p = c; p != null; p = p.getParent()) {
  5432. if (p == root) {
  5433. return;
  5434. }
  5435. }
  5436. }
  5437.  
  5438. /* Otherwise: if Component c is an ancestor of any of the
  5439. * existing roots then remove them and add c (the "new root")
  5440. * to the roots vector.
  5441. */
  5442. for(int i = 0; i < roots.size(); i++) {
  5443. JComponent root = roots.elementAt(i);
  5444. for(Component p = root.getParent(); p != null; p = p.getParent()) {
  5445. if (p == c) {
  5446. roots.removeElementAt(i--); // !!
  5447. break;
  5448. }
  5449. }
  5450. }
  5451.  
  5452. roots.addElement(c);
  5453. }
  5454. }
  5455.  
  5456.  
  5457. /**
  5458. * We use the <code>ObjectInputStream</code> "registerValidation"
  5459. * callback to update the UI for the entire tree of components
  5460. * after they've all been read in.
  5461. *
  5462. * @param s the <code>ObjectInputStream</code> from which to read
  5463. */
  5464. private void readObject(ObjectInputStream s)
  5465. throws IOException, ClassNotFoundException
  5466. {
  5467. s.defaultReadObject();
  5468.  
  5469. /* If there's no ReadObjectCallback for this stream yet, that is, if
  5470. * this is the first call to JComponent.readObject() for this
  5471. * graph of objects, then create a callback and stash it
  5472. * in the readObjectCallbacks table. Note that the ReadObjectCallback
  5473. * constructor takes care of calling s.registerValidation().
  5474. */
  5475. ReadObjectCallback cb = readObjectCallbacks.get(s);
  5476. if (cb == null) {
  5477. try {
  5478. readObjectCallbacks.put(s, cb = new ReadObjectCallback(s));
  5479. }
  5480. catch (Exception e) {
  5481. throw new IOException(e.toString());
  5482. }
  5483. }
  5484. cb.registerComponent(this);
  5485.  
  5486. // Read back the client properties.
  5487. int cpCount = s.readInt();
  5488. if (cpCount > 0) {
  5489. clientProperties = new ArrayTable();
  5490. for (int counter = 0; counter < cpCount; counter++) {
  5491. clientProperties.put(s.readObject(),
  5492. s.readObject());
  5493. }
  5494. }
  5495. if (getToolTipText() != null) {
  5496. ToolTipManager.sharedInstance().registerComponent(this);
  5497. }
  5498. setWriteObjCounter(this, (byte)0);
  5499. revalidateRunnableScheduled = new AtomicBoolean(false);
  5500. }
  5501.  
  5502.  
  5503. /**
  5504. * Before writing a <code>JComponent</code> to an
  5505. * <code>ObjectOutputStream</code> we temporarily uninstall its UI.
  5506. * This is tricky to do because we want to uninstall
  5507. * the UI before any of the <code>JComponent</code>'s children
  5508. * (or its <code>LayoutManager</code> etc.) are written,
  5509. * and we don't want to restore the UI until the most derived
  5510. * <code>JComponent</code> subclass has been been stored.
  5511. *
  5512. * @param s the <code>ObjectOutputStream</code> in which to write
  5513. */
  5514. private void writeObject(ObjectOutputStream s) throws IOException {
  5515. s.defaultWriteObject();
  5516. if (getUIClassID().equals(uiClassID)) {
  5517. byte count = JComponent.getWriteObjCounter(this);
  5518. JComponent.setWriteObjCounter(this, --count);
  5519. if (count == 0 && ui != null) {
  5520. ui.installUI(this);
  5521. }
  5522. }
  5523. ArrayTable.writeArrayTable(s, clientProperties);
  5524. }
  5525.  
  5526.  
  5527. /**
  5528. * Returns a string representation of this <code>JComponent</code>.
  5529. * This method
  5530. * is intended to be used only for debugging purposes, and the
  5531. * content and format of the returned string may vary between
  5532. * implementations. The returned string may be empty but may not
  5533. * be <code>null</code>.
  5534. *
  5535. * @return a string representation of this <code>JComponent</code>
  5536. */
  5537. protected String paramString() {
  5538. String preferredSizeString = (isPreferredSizeSet() ?
  5539. getPreferredSize().toString() : "");
  5540. String minimumSizeString = (isMinimumSizeSet() ?
  5541. getMinimumSize().toString() : "");
  5542. String maximumSizeString = (isMaximumSizeSet() ?
  5543. getMaximumSize().toString() : "");
  5544. String borderString = (border == null ? ""
  5545. : (border == this ? "this" : border.toString()));
  5546.  
  5547. return super.paramString() +
  5548. ",alignmentX=" + alignmentX +
  5549. ",alignmentY=" + alignmentY +
  5550. ",border=" + borderString +
  5551. ",flags=" + flags + // should beef this up a bit
  5552. ",maximumSize=" + maximumSizeString +
  5553. ",minimumSize=" + minimumSizeString +
  5554. ",preferredSize=" + preferredSizeString;
  5555. }
  5556.  
  5557. /**
  5558. * {@inheritDoc}
  5559. */
  5560. @Override
  5561. @Deprecated
  5562. public void hide() {
  5563. boolean showing = isShowing();
  5564. super.hide();
  5565. if (showing) {
  5566. Container parent = getParent();
  5567. if (parent != null) {
  5568. Rectangle r = getBounds();
  5569. parent.repaint(r.x, r.y, r.width, r.height);
  5570. }
  5571. revalidate();
  5572. }
  5573. }
  5574.  
  5575. }
Add Comment
Please, Sign In to add comment