1. /*
  2. * @(#)JComponent.java 2.211 03/08/26
  3. *
  4. * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package javax.swing;
  8. import java.util.Hashtable;
  9. import java.util.Dictionary;
  10. import java.util.Enumeration;
  11. import java.util.Locale;
  12. import java.util.Vector;
  13. import java.util.EventListener;
  14. import java.util.Set;
  15. import java.util.TreeSet;
  16. import java.awt.*;
  17. import java.awt.event.*;
  18. import java.awt.image.VolatileImage;
  19. import java.awt.Graphics2D;
  20. import java.awt.peer.LightweightPeer;
  21. import java.awt.dnd.DropTarget;
  22. import java.beans.*;
  23. import java.applet.Applet;
  24. import java.io.Serializable;
  25. import java.io.ObjectOutputStream;
  26. import java.io.ObjectInputStream;
  27. import java.io.IOException;
  28. import java.io.ObjectInputValidation;
  29. import java.io.InvalidObjectException;
  30. import javax.swing.border.*;
  31. import javax.swing.event.*;
  32. import javax.swing.plaf.*;
  33. import javax.accessibility.*;
  34. /**
  35. * The base class for all Swing components except top-level containers.
  36. * To use a component that inherits from <code>JComponent</code>,
  37. * you must place the component in a containment hierarchy
  38. * whose root is a top-level Swing container.
  39. * Top-level Swing containers --
  40. * such as <code>JFrame</code>, <code>JDialog</code>,
  41. * and <code>JApplet</code> --
  42. * are specialized components
  43. * that provide a place for other Swing components to paint themselves.
  44. * For an explanation of containment hierarchies, see
  45. * <a
  46. href="http://java.sun.com/docs/books/tutorial/uiswing/overview/hierarchy.html">Swing Components and the Containment Hierarchy</a>,
  47. * a section in <em>The Java Tutorial</em>.
  48. *
  49. * <p>
  50. * The <code>JComponent</code> class provides:
  51. * <ul>
  52. * <li>The base class for both standard and custom components
  53. * that use the Swing architecture.
  54. * <li>A "pluggable look and feel" (L&F) that can be specified by the
  55. * programmer or (optionally) selected by the user at runtime.
  56. * The look and feel for each component is provided by a
  57. * <em>UI delegate</em> -- an object that descends from
  58. * {@link javax.swing.plaf.ComponentUI}.
  59. * See <a
  60. * href="http://java.sun.com/docs/books/tutorial/uiswing/misc/plaf.html">How
  61. * to Set the Look and Feel</a>
  62. * in <em>The Java Tutorial</em>
  63. * for more information.
  64. * <li>Comprehensive keystroke handling.
  65. * See the document <a
  66. * href="http://java.sun.com/products/jfc/tsc/special_report/kestrel/keybindings.html">Keyboard
  67. * Bindings in Swing</a>,
  68. * an article in <em>The Swing Connection</em>,
  69. * for more information.
  70. * <li>Support for tool tips --
  71. * short descriptions that pop up when the cursor lingers
  72. * over a component.
  73. * See <a
  74. * href="http://java.sun.com/docs/books/tutorial/uiswing/components/tooltip.html">How
  75. * to Use Tool Tips</a>
  76. * in <em>The Java Tutorial</em>
  77. * for more information.
  78. * <li>Support for accessibility.
  79. * <code>JComponent</code> contains all of the methods in the
  80. * <code>Accessible</code> interface,
  81. * but it doesn't actually implement the interface. That is the
  82. * responsibility of the individual classes
  83. * that extend <code>JComponent</code>.
  84. * <li>Support for component-specific properties.
  85. * With the {@link #putClientProperty}
  86. * and {@link #getClientProperty} methods,
  87. * you can associate name-object pairs
  88. * with any object that descends from <code>JComponent</code>.
  89. * <li>An infrastructure for painting
  90. * that includes double buffering and support for borders.
  91. * For more information see <a
  92. * href="http://java.sun.com/docs/books/tutorial/uiswing/overview/draw.html">Painting</a> and
  93. * <a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/border.html">How
  94. * to Use Borders</a>,
  95. * both of which are sections in <em>The Java Tutorial</em>.
  96. * </ul>
  97. * For more information on these subjects, see the
  98. * <a href="package-summary.html#package_description">Swing package description</a>
  99. * and <em>The Java Tutorial</em> section
  100. * <a href="http://java.sun.com/docs/books/tutorial/uiswing/components/jcomponent.html">The JComponent Class</a>.
  101. * <p>
  102. * <strong>Warning:</strong>
  103. * Serialized objects of this class will not be compatible with
  104. * future Swing releases. The current serialization support is
  105. * appropriate for short term storage or RMI between applications running
  106. * the same version of Swing. As of 1.4, support for long term storage
  107. * of all JavaBeans<sup><font size="-2">TM</font></sup>
  108. * has been added to the <code>java.beans</code> package.
  109. * Please see {@link java.beans.XMLEncoder}.
  110. *
  111. * @see KeyStroke
  112. * @see Action
  113. * @see #setBorder
  114. * @see #registerKeyboardAction
  115. * @see JOptionPane
  116. * @see #setDebugGraphicsOptions
  117. * @see #setToolTipText
  118. * @see #setAutoscrolls
  119. *
  120. * @version 2.130 07/09/99
  121. * @author Hans Muller
  122. * @author Arnaud Weber
  123. */
  124. public abstract class JComponent extends Container implements Serializable
  125. {
  126. /**
  127. * @see #getUIClassID
  128. * @see #writeObject
  129. */
  130. private static final String uiClassID = "ComponentUI";
  131. /**
  132. * @see ReadObjectCallback
  133. * @see #readObject
  134. */
  135. private static final Hashtable readObjectCallbacks = new Hashtable(1);
  136. /**
  137. * Keys to use for forward focus traversal when the JComponent is
  138. * managing focus.
  139. */
  140. private static Set managingFocusForwardTraversalKeys;
  141. /**
  142. * Keys to use for backward focus traversal when the JComponent is
  143. * managing focus.
  144. */
  145. private static Set managingFocusBackwardTraversalKeys;
  146. /**
  147. * Indicates if we should register a <code>DropTarget</code> for a
  148. * non-null <code>TransferHandler</code>. Use
  149. * <code>getSuppressDropTarget</code> to check.
  150. */
  151. private static boolean suppressDropSupport;
  152. /**
  153. * Indiciates if we've checked the system property for suppressing
  154. * drop support.
  155. */
  156. private static boolean checkedSuppressDropSupport;
  157. // Following are the possible return values from getObscuredState.
  158. private static final int NOT_OBSCURED = 0;
  159. private static final int PARTIALLY_OBSCURED = 1;
  160. private static final int COMPLETELY_OBSCURED = 2;
  161. /* The following fields support set methods for the corresponding
  162. * java.awt.Component properties.
  163. */
  164. private Dimension preferredSize;
  165. private Dimension minimumSize;
  166. private Dimension maximumSize;
  167. private Float alignmentX;
  168. private Float alignmentY;
  169. private AncestorNotifier ancestorNotifier;
  170. Rectangle _bounds = new Rectangle();
  171. /**
  172. * Backing store for JComponent properties and listeners
  173. */
  174. /** The look and feel delegate for this component. */
  175. protected transient ComponentUI ui;
  176. /** A list of event listeners for this component. */
  177. protected EventListenerList listenerList = new EventListenerList();
  178. private Hashtable clientProperties;
  179. private VetoableChangeSupport vetoableChangeSupport;
  180. private Autoscroller autoscroller;
  181. private Border border;
  182. private int flags;
  183. private TransferHandler transfer;
  184. /* Input verifier for this component */
  185. private InputVerifier inputVerifier = null;
  186. private boolean verifyInputWhenFocusTarget = true;
  187. /* A "scratch pad" rectangle used by the painting code.
  188. */
  189. private transient Rectangle tmpRect;
  190. /**
  191. * Set in <code>_paintImmediately</code>.
  192. * Will indicate the child that initiated the painting operation.
  193. * If <code>paintingChild</code> is opaque, no need to paint
  194. * any child components after <code>paintingChild</code>.
  195. * Test used in <code>paintChildren</code>.
  196. */
  197. transient Component paintingChild;
  198. /**
  199. * Constant used for <code>registerKeyboardAction</code> that
  200. * means that the command should be invoked when
  201. * the component has the focus.
  202. */
  203. public static final int WHEN_FOCUSED = 0;
  204. /**
  205. * Constant used for <code>registerKeyboardAction</code> that
  206. * means that the command should be invoked when the receiving
  207. * component is an ancestor of the focused component or is
  208. * itself the focused component.
  209. */
  210. public static final int WHEN_ANCESTOR_OF_FOCUSED_COMPONENT = 1;
  211. /**
  212. * Constant used for <code>registerKeyboardAction</code> that
  213. * means that the command should be invoked when
  214. * the receiving component is in the window that has the focus
  215. * or is itself the focused component.
  216. */
  217. public static final int WHEN_IN_FOCUSED_WINDOW = 2;
  218. /**
  219. * Constant used by some of the APIs to mean that no condition is defined.
  220. */
  221. public static final int UNDEFINED_CONDITION = -1;
  222. /**
  223. * The key used by <code>JComponent</code> to access keyboard bindings.
  224. */
  225. private static final String KEYBOARD_BINDINGS_KEY = "_KeyboardBindings";
  226. /**
  227. * An array of <code>KeyStroke</code>s used for
  228. * <code>WHEN_IN_FOCUSED_WINDOW</code> are stashed
  229. * in the client properties under this string.
  230. */
  231. private static final String WHEN_IN_FOCUSED_WINDOW_BINDINGS = "_WhenInFocusedWindow";
  232. /**
  233. * The comment to display when the cursor is over the component,
  234. * also known as a "value tip", "flyover help", or "flyover label".
  235. */
  236. public static final String TOOL_TIP_TEXT_KEY = "ToolTipText";
  237. private static final String NEXT_FOCUS = "nextFocus";
  238. /** Private flags **/
  239. private static final int IS_DOUBLE_BUFFERED = 0;
  240. private static final int ANCESTOR_USING_BUFFER = 1;
  241. private static final int IS_PAINTING_TILE = 2;
  242. private static final int IS_OPAQUE = 3;
  243. private static final int KEY_EVENTS_ENABLED = 4;
  244. private static final int FOCUS_INPUTMAP_CREATED = 5;
  245. private static final int ANCESTOR_INPUTMAP_CREATED = 6;
  246. private static final int WIF_INPUTMAP_CREATED = 7;
  247. private static final int ACTIONMAP_CREATED = 8;
  248. private static final int CREATED_DOUBLE_BUFFER = 9;
  249. // Bit 10 is free
  250. private static final int IS_PRINTING = 11;
  251. private static final int IS_PRINTING_ALL = 12;
  252. private static final int IS_REPAINTING = 13;
  253. /** Bits 14-21 are used to handle nested writeObject calls. **/
  254. private static final int WRITE_OBJ_COUNTER_FIRST = 14;
  255. private static final int RESERVED_1 = 15;
  256. private static final int RESERVED_2 = 16;
  257. private static final int RESERVED_3 = 17;
  258. private static final int RESERVED_4 = 18;
  259. private static final int RESERVED_5 = 19;
  260. private static final int RESERVED_6 = 20;
  261. private static final int WRITE_OBJ_COUNTER_LAST = 21;
  262. private static final int REQUEST_FOCUS_DISABLED = 22;
  263. /** Used for <code>WHEN_FOCUSED</code> bindings. */
  264. private InputMap focusInputMap;
  265. /** Used for <code>WHEN_ANCESTOR_OF_FOCUSED_COMPONENT</code> bindings. */
  266. private InputMap ancestorInputMap;
  267. /** Used for <code>WHEN_IN_FOCUSED_KEY</code> bindings. */
  268. private ComponentInputMap windowInputMap;
  269. /** ActionMap. */
  270. private ActionMap actionMap;
  271. /** Key used to store the default locale in an AppContext **/
  272. private static final String defaultLocale = "JComponent.defaultLocale";
  273. /**
  274. * Returns the Set of <code>KeyStroke</code>s to use if the component
  275. * is managing focus for forward focus traversal.
  276. */
  277. static Set getManagingFocusForwardTraversalKeys() {
  278. if (managingFocusForwardTraversalKeys == null) {
  279. managingFocusForwardTraversalKeys = new TreeSet();
  280. managingFocusForwardTraversalKeys.add(
  281. KeyStroke.getKeyStroke(KeyEvent.VK_TAB, InputEvent.CTRL_MASK));
  282. }
  283. return managingFocusForwardTraversalKeys;
  284. }
  285. /**
  286. * Returns the Set of <code>KeyStroke</code>s to use if the component
  287. * is managing focus for backward focus traversal.
  288. */
  289. static Set getManagingFocusBackwardTraversalKeys() {
  290. if (managingFocusBackwardTraversalKeys == null) {
  291. managingFocusBackwardTraversalKeys = new TreeSet();
  292. managingFocusBackwardTraversalKeys.add(
  293. KeyStroke.getKeyStroke(KeyEvent.VK_TAB,
  294. InputEvent.SHIFT_MASK |
  295. InputEvent.CTRL_MASK));
  296. }
  297. return managingFocusBackwardTraversalKeys;
  298. }
  299. /**
  300. * Returns true if <code>setTransferHandler</code> should install
  301. * a <code>DropTarget</code>.
  302. */
  303. private static boolean getSuppressDropTarget() {
  304. if (!checkedSuppressDropSupport) {
  305. Boolean b = (Boolean)java.security.AccessController.doPrivileged(
  306. new java.security.PrivilegedAction() {
  307. public Object run() {
  308. String value = System.getProperty(
  309. "suppressSwingDropSupport");
  310. if (value != null) {
  311. return Boolean.valueOf(value);
  312. }
  313. return Boolean.FALSE;
  314. }
  315. }
  316. );
  317. suppressDropSupport = b.booleanValue();
  318. checkedSuppressDropSupport = true;
  319. }
  320. return suppressDropSupport;
  321. }
  322. /**
  323. * Default <code>JComponent</code> constructor. This constructor does
  324. * very little initialization beyond calling the <code>Container</code>
  325. * constructor. For example, the initial layout manager is
  326. * <code>null</code>. It does, however, set the component's locale
  327. * property to the value returned by
  328. * <code>JComponent.getDefaultLocale</code>.
  329. *
  330. * @see #getDefaultLocale
  331. */
  332. public JComponent() {
  333. super();
  334. // We enable key events on all JComponents so that accessibility
  335. // bindings will work everywhere. This is a partial fix to BugID
  336. // 4282211.
  337. enableEvents(AWTEvent.KEY_EVENT_MASK);
  338. enableSerialization();
  339. if (isManagingFocus()) {
  340. setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
  341. getManagingFocusForwardTraversalKeys());
  342. setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
  343. getManagingFocusBackwardTraversalKeys());
  344. }
  345. super.setLocale( JComponent.getDefaultLocale() );
  346. }
  347. /**
  348. * Resets the UI property to a value from the current look and feel.
  349. * <code>JComponent</code> subclasses must override this method
  350. * like this:
  351. * <pre>
  352. * public void updateUI() {
  353. * setUI((SliderUI)UIManager.getUI(this);
  354. * }
  355. * </pre>
  356. *
  357. * @see #setUI
  358. * @see UIManager#getLookAndFeel
  359. * @see UIManager#getUI
  360. */
  361. public void updateUI() {}
  362. /**
  363. * Sets the look and feel delegate for this component.
  364. * <code>JComponent</code> subclasses generally override this method
  365. * to narrow the argument type. For example, in <code>JSlider</code>:
  366. * <pre>
  367. * public void setUI(SliderUI newUI) {
  368. * super.setUI(newUI);
  369. * }
  370. * </pre>
  371. * <p>
  372. * Additionally <code>JComponent</code> subclasses must provide a
  373. * <code>getUI</code> method that returns the correct type. For example:
  374. * <pre>
  375. * public SliderUI getUI() {
  376. * return (SliderUI)ui;
  377. * }
  378. * </pre>
  379. *
  380. * @param newUI the new UI delegate
  381. * @see #updateUI
  382. * @see UIManager#getLookAndFeel
  383. * @see UIManager#getUI
  384. * @beaninfo
  385. * bound: true
  386. * hidden: true
  387. * attribute: visualUpdate true
  388. * description: The component's look and feel delegate.
  389. */
  390. protected void setUI(ComponentUI newUI) {
  391. /* We do not check that the UI instance is different
  392. * before allowing the switch in order to enable the
  393. * same UI instance *with different default settings*
  394. * to be installed.
  395. */
  396. if (ui != null) {
  397. ui.uninstallUI(this);
  398. }
  399. ComponentUI oldUI = ui;
  400. ui = newUI;
  401. if (ui != null) {
  402. ui.installUI(this);
  403. }
  404. firePropertyChange("UI", oldUI, newUI);
  405. revalidate();
  406. repaint();
  407. }
  408. /**
  409. * Returns the <code>UIDefaults</code> key used to
  410. * look up the name of the <code>swing.plaf.ComponentUI</code>
  411. * class that defines the look and feel
  412. * for this component. Most applications will never need to
  413. * call this method. Subclasses of <code>JComponent</code> that support
  414. * pluggable look and feel should override this method to
  415. * return a <code>UIDefaults</code> key that maps to the
  416. * <code>ComponentUI</code> subclass that defines their look and feel.
  417. *
  418. * @return the <code>UIDefaults</code> key for a
  419. * <code>ComponentUI</code> subclass
  420. * @see UIDefaults#getUI
  421. * @beaninfo
  422. * expert: true
  423. * description: UIClassID
  424. */
  425. public String getUIClassID() {
  426. return uiClassID;
  427. }
  428. /**
  429. * Returns the graphics object used to paint this component.
  430. * If <code>DebugGraphics</code> is turned on we create a new
  431. * <code>DebugGraphics</code> object if necessary.
  432. * Otherwise we just configure the
  433. * specified graphics object's foreground and font.
  434. *
  435. * @param g the original <code>Graphics</code> object
  436. * @return a <code>Graphics</code> object configured for this component
  437. */
  438. protected Graphics getComponentGraphics(Graphics g) {
  439. Graphics componentGraphics = g;
  440. if (ui != null) {
  441. if ((DebugGraphics.debugComponentCount() != 0) &&
  442. (shouldDebugGraphics() != 0) &&
  443. !(g instanceof DebugGraphics)) {
  444. if(g instanceof SwingGraphics) {
  445. if(!(((SwingGraphics)g).subGraphics() instanceof DebugGraphics)) {
  446. Graphics dbgGraphics = new DebugGraphics(((SwingGraphics)g).subGraphics(),this);
  447. componentGraphics = SwingGraphics.createSwingGraphics(dbgGraphics);
  448. dbgGraphics.dispose();
  449. }
  450. } else {
  451. componentGraphics = new DebugGraphics(g,this);
  452. }
  453. }
  454. }
  455. componentGraphics.setColor(getForeground());
  456. componentGraphics.setFont(getFont());
  457. return componentGraphics;
  458. }
  459. /**
  460. * Calls the UI delegate's paint method, if the UI delegate
  461. * is non-<code>null</code>. We pass the delegate a copy of the
  462. * <code>Graphics</code> object to protect the rest of the
  463. * paint code from irrevocable changes
  464. * (for example, <code>Graphics.translate</code>).
  465. * <p>
  466. * If you override this in a subclass you should not make permanent
  467. * changes to the passed in <code>Graphics</code>. For example, you
  468. * should not alter the clip <code>Rectangle</code> or modify the
  469. * transform. If you need to do these operations you may find it
  470. * easier to create a new <code>Graphics</code> from the passed in
  471. * <code>Graphics</code> and manipulate it. Further, if you do not
  472. * invoker super's implementation you must honor the opaque property,
  473. * that is
  474. * if this component is opaque, you must completely fill in the background
  475. * in a non-opaque color. If you do not honor the opaque property you
  476. * will likely see visual artifacts.
  477. *
  478. * @param g the <code>Graphics</code> object to protect
  479. * @see #paint
  480. * @see ComponentUI
  481. */
  482. protected void paintComponent(Graphics g) {
  483. if (ui != null) {
  484. Graphics scratchGraphics = SwingGraphics.createSwingGraphics(g);
  485. try {
  486. ui.update(scratchGraphics, this);
  487. }
  488. finally {
  489. scratchGraphics.dispose();
  490. }
  491. }
  492. }
  493. /**
  494. * Paints this component's children.
  495. * If <code>shouldUseBuffer</code> is true,
  496. * no component ancestor has a buffer and
  497. * the component children can use a buffer if they have one.
  498. * Otherwise, one ancestor has a buffer currently in use and children
  499. * should not use a buffer to paint.
  500. * @param g the <code>Graphics</code> context in which to paint
  501. * @see #paint
  502. * @see java.awt.Container#paint
  503. */
  504. protected void paintChildren(Graphics g) {
  505. boolean isJComponent;
  506. Graphics sg = null;
  507. try {
  508. synchronized(getTreeLock()) {
  509. int i = getComponentCount() - 1;
  510. if (i < 0) {
  511. return;
  512. }
  513. sg = SwingGraphics.createSwingGraphics(g);
  514. // If we are only to paint to a specific child, determine
  515. // its index.
  516. if (paintingChild != null &&
  517. (paintingChild instanceof JComponent) &&
  518. ((JComponent)paintingChild).isOpaque()) {
  519. for (; i >= 0; i--) {
  520. if (getComponent(i) == paintingChild){
  521. break;
  522. }
  523. }
  524. }
  525. if(tmpRect == null) {
  526. tmpRect = new Rectangle();
  527. }
  528. boolean checkSiblings = (!isOptimizedDrawingEnabled() &&
  529. checkIfChildObscuredBySibling());
  530. Rectangle clipBounds = null;
  531. if (checkSiblings) {
  532. clipBounds = sg.getClipBounds();
  533. if (clipBounds == null) {
  534. clipBounds = new Rectangle(0, 0, _bounds.width,
  535. _bounds.height);
  536. }
  537. }
  538. boolean printing = getFlag(IS_PRINTING);
  539. for (; i >= 0 ; i--) {
  540. Component comp = getComponent(i);
  541. if (comp != null && isLightweightComponent(comp) &&
  542. (comp.isVisible() == true)) {
  543. Rectangle cr;
  544. isJComponent = (comp instanceof JComponent);
  545. if(isJComponent) {
  546. cr = tmpRect;
  547. ((JComponent)comp).getBounds(cr);
  548. } else {
  549. cr = comp.getBounds();
  550. }
  551. boolean hitClip = g.hitClip(cr.x, cr.y, cr.width, cr.height);
  552. if (hitClip) {
  553. if (checkSiblings && i > 0) {
  554. int x = cr.x;
  555. int y = cr.y;
  556. int width = cr.width;
  557. int height = cr.height;
  558. SwingUtilities.computeIntersection
  559. (clipBounds.x, clipBounds.y,
  560. clipBounds.width, clipBounds.height, cr);
  561. if(getObscuredState(i, cr.x, cr.y, cr.width,
  562. cr.height) == COMPLETELY_OBSCURED) {
  563. continue;
  564. }
  565. cr.x = x;
  566. cr.y = y;
  567. cr.width = width;
  568. cr.height = height;
  569. }
  570. Graphics cg = SwingGraphics.createSwingGraphics(
  571. sg, cr.x, cr.y, cr.width, cr.height);
  572. cg.setColor(comp.getForeground());
  573. cg.setFont(comp.getFont());
  574. boolean shouldSetFlagBack = false;
  575. try {
  576. if(isJComponent) {
  577. if(getFlag(ANCESTOR_USING_BUFFER)) {
  578. ((JComponent)comp).setFlag(ANCESTOR_USING_BUFFER,true);
  579. shouldSetFlagBack = true;
  580. }
  581. if(getFlag(IS_PAINTING_TILE)) {
  582. ((JComponent)comp).setFlag(IS_PAINTING_TILE,true);
  583. shouldSetFlagBack = true;
  584. }
  585. if(!printing) {
  586. ((JComponent)comp).paint(cg);
  587. }
  588. else {
  589. if (!getFlag(IS_PRINTING_ALL)) {
  590. comp.print(cg);
  591. }
  592. else {
  593. comp.printAll(cg);
  594. }
  595. }
  596. } else {
  597. if (!printing) {
  598. comp.paint(cg);
  599. }
  600. else {
  601. if (!getFlag(IS_PRINTING_ALL)) {
  602. comp.print(cg);
  603. }
  604. else {
  605. comp.printAll(cg);
  606. }
  607. }
  608. }
  609. } finally {
  610. cg.dispose();
  611. if(shouldSetFlagBack) {
  612. ((JComponent)comp).setFlag(ANCESTOR_USING_BUFFER,false);
  613. ((JComponent)comp).setFlag(IS_PAINTING_TILE,false);
  614. }
  615. }
  616. }
  617. }
  618. }
  619. }
  620. } finally {
  621. if (sg != null) {
  622. sg.dispose();
  623. }
  624. }
  625. }
  626. /**
  627. * Paints the component's border.
  628. * <p>
  629. * If you override this in a subclass you should not make permanent
  630. * changes to the passed in <code>Graphics</code>. For example, you
  631. * should not alter the clip <code>Rectangle</code> or modify the
  632. * transform. If you need to do these operations you may find it
  633. * easier to create a new <code>Graphics</code> from the passed in
  634. * <code>Graphics</code> and manipulate it.
  635. *
  636. * @param g the <code>Graphics</code> context in which to paint
  637. *
  638. * @see #paint
  639. * @see #setBorder
  640. */
  641. protected void paintBorder(Graphics g) {
  642. Border border = getBorder();
  643. if (border != null) {
  644. border.paintBorder(this, g, 0, 0, getWidth(), getHeight());
  645. }
  646. }
  647. /**
  648. * Calls <code>paint</code>. Doesn't clear the background but see
  649. * <code>ComponentUI.update</code>, which is called by
  650. * <code>paintComponent</code>.
  651. *
  652. * @param g the <code>Graphics</code> context in which to paint
  653. * @see #paint
  654. * @see #paintComponent
  655. * @see javax.swing.plaf.ComponentUI
  656. */
  657. public void update(Graphics g) {
  658. paint(g);
  659. }
  660. /**
  661. * Invoked by Swing to draw components.
  662. * Applications should not invoke <code>paint</code> directly,
  663. * but should instead use the <code>repaint</code> method to
  664. * schedule the component for redrawing.
  665. * <p>
  666. * This method actually delegates the work of painting to three
  667. * protected methods: <code>paintComponent</code>,
  668. * <code>paintBorder</code>,
  669. * and <code>paintChildren</code>. They're called in the order
  670. * listed to ensure that children appear on top of component itself.
  671. * Generally speaking, the component and its children should not
  672. * paint in the insets area allocated to the border. Subclasses can
  673. * just override this method, as always. A subclass that just
  674. * wants to specialize the UI (look and feel) delegate's
  675. * <code>paint</code> method should just override
  676. * <code>paintComponent</code>.
  677. *
  678. * @param g the <code>Graphics</code> context in which to paint
  679. * @see #paintComponent
  680. * @see #paintBorder
  681. * @see #paintChildren
  682. * @see #getComponentGraphics
  683. * @see #repaint
  684. */
  685. public void paint(Graphics g) {
  686. boolean shouldClearPaintFlags = false;
  687. boolean paintCompleted = false;
  688. if ((getWidth() <= 0) || (getHeight() <= 0)) {
  689. return;
  690. }
  691. Graphics componentGraphics = getComponentGraphics(g);
  692. Graphics co = SwingGraphics.createSwingGraphics(componentGraphics);
  693. try {
  694. RepaintManager repaintManager = RepaintManager.currentManager(this);
  695. Rectangle clipRect = co.getClipBounds();
  696. int clipX;
  697. int clipY;
  698. int clipW;
  699. int clipH;
  700. if (clipRect == null) {
  701. clipX = clipY = 0;
  702. clipW = _bounds.width;
  703. clipH = _bounds.height;
  704. }
  705. else {
  706. clipX = clipRect.x;
  707. clipY = clipRect.y;
  708. clipW = clipRect.width;
  709. clipH = clipRect.height;
  710. }
  711. if(clipW > getWidth()) {
  712. clipW = getWidth();
  713. }
  714. if(clipH > getHeight()) {
  715. clipH = getHeight();
  716. }
  717. if(getParent() != null && !(getParent() instanceof JComponent)) {
  718. adjustPaintFlags();
  719. shouldClearPaintFlags = true;
  720. }
  721. int bw,bh;
  722. boolean printing = getFlag(IS_PRINTING);
  723. if(!printing && repaintManager.isDoubleBufferingEnabled() &&
  724. !getFlag(ANCESTOR_USING_BUFFER) && isDoubleBuffered()) {
  725. paintCompleted = paintDoubleBuffered(this, this, co, clipX, clipY, clipW, clipH);
  726. }
  727. if (!paintCompleted) {
  728. // Will ocassionaly happen in 1.2, especially when printing.
  729. if (clipRect == null) {
  730. co.setClip(clipX, clipY, clipW, clipH);
  731. }
  732. if (!rectangleIsObscured(clipX,clipY,clipW,clipH)) {
  733. if (!printing) {
  734. paintComponent(co);
  735. paintBorder(co);
  736. }
  737. else {
  738. printComponent(co);
  739. printBorder(co);
  740. }
  741. }
  742. if (!printing) {
  743. paintChildren(co);
  744. }
  745. else {
  746. printChildren(co);
  747. }
  748. }
  749. } finally {
  750. co.dispose();
  751. if(shouldClearPaintFlags) {
  752. setFlag(ANCESTOR_USING_BUFFER,false);
  753. setFlag(IS_PAINTING_TILE,false);
  754. setFlag(IS_PRINTING,false);
  755. setFlag(IS_PRINTING_ALL,false);
  756. }
  757. }
  758. }
  759. private void adjustPaintFlags() {
  760. JComponent jparent = null;
  761. Container parent;
  762. for(parent = getParent() ; parent != null ; parent =
  763. parent.getParent()) {
  764. if(parent instanceof JComponent) {
  765. jparent = (JComponent) parent;
  766. if(jparent.getFlag(ANCESTOR_USING_BUFFER))
  767. setFlag(ANCESTOR_USING_BUFFER, true);
  768. if(jparent.getFlag(IS_PAINTING_TILE))
  769. setFlag(IS_PAINTING_TILE, true);
  770. if(jparent.getFlag(IS_PRINTING))
  771. setFlag(IS_PRINTING, true);
  772. if(jparent.getFlag(IS_PRINTING_ALL))
  773. setFlag(IS_PRINTING_ALL, true);
  774. break;
  775. }
  776. }
  777. }
  778. /**
  779. * Invoke this method to print the component. This method invokes
  780. * <code>print</code> on the component.
  781. *
  782. * @param g the <code>Graphics</code> context in which to paint
  783. * @see #print
  784. * @see #printComponent
  785. * @see #printBorder
  786. * @see #printChildren
  787. */
  788. public void printAll(Graphics g) {
  789. setFlag(IS_PRINTING_ALL, true);
  790. try {
  791. print(g);
  792. }
  793. finally {
  794. setFlag(IS_PRINTING_ALL, false);
  795. }
  796. }
  797. /**
  798. * Invoke this method to print the component. This method will
  799. * result in invocations to <code>printComponent</code>,
  800. * <code>printBorder</code> and <code>printChildren</code>. It is
  801. * not recommended that you override this method, instead override
  802. * one of the previously mentioned methods. This method sets the
  803. * component's state such that the double buffer will not be used, eg
  804. * painting will be done directly on the passed in <code>Graphics</code>.
  805. *
  806. * @param g the <code>Graphics</code> context in which to paint
  807. * @see #printComponent
  808. * @see #printBorder
  809. * @see #printChildren
  810. */
  811. public void print(Graphics g) {
  812. setFlag(IS_PRINTING, true);
  813. try {
  814. paint(g);
  815. }
  816. finally {
  817. setFlag(IS_PRINTING, false);
  818. }
  819. }
  820. /**
  821. * This is invoked during a printing operation. This is implemented to
  822. * invoke <code>paintComponent</code> on the component. Override this
  823. * if you wish to add special painting behavior when printing.
  824. *
  825. * @param g the <code>Graphics</code> context in which to paint
  826. * @see #print
  827. * @since 1.3
  828. */
  829. protected void printComponent(Graphics g) {
  830. paintComponent(g);
  831. }
  832. /**
  833. * Prints this component's children. This is implemented to invoke
  834. * <code>paintChildren</code> on the component. Override this if you
  835. * wish to print the children differently than painting.
  836. *
  837. * @param g the <code>Graphics</code> context in which to paint
  838. * @see #print
  839. * @since 1.3
  840. */
  841. protected void printChildren(Graphics g) {
  842. paintChildren(g);
  843. }
  844. /**
  845. * Prints the component's border. This is implemented to invoke
  846. * <code>paintBorder</code> on the component. Override this if you
  847. * wish to print the border differently that it is painted.
  848. *
  849. * @param g the <code>Graphics</code> context in which to paint
  850. * @see #print
  851. * @since 1.3
  852. */
  853. protected void printBorder(Graphics g) {
  854. paintBorder(g);
  855. }
  856. /**
  857. * Returns true if the component is currently painting a tile.
  858. * If this method returns true, paint will be called again for another
  859. * tile. This method returns false if you are not painting a tile or
  860. * if the last tile is painted.
  861. * Use this method to keep some state you might need between tiles.
  862. *
  863. * @return true if the component is currently painting a tile,
  864. * false otherwise
  865. */
  866. public boolean isPaintingTile() {
  867. return getFlag(IS_PAINTING_TILE);
  868. }
  869. /**
  870. * Changes this <code>JComponent</code>'s focus traversal keys to
  871. * CTRL+TAB and CTRL+SHIFT+TAB. Also prevents
  872. * <code>SortingFocusTraversalPolicy</code> from considering descendants
  873. * of this JComponent when computing a focus traversal cycle.
  874. *
  875. * @see java.awt.Component#setFocusTraversalKeys
  876. * @see SortingFocusTraversalPolicy
  877. * @deprecated As of 1.4, replaced by
  878. * <code>Component.setFocusTraversalKeys(int, Set)</code> and
  879. * <code>Container.setFocusCycleRoot(boolean)</code>.
  880. */
  881. public boolean isManagingFocus() {
  882. return false;
  883. }
  884. private void registerNextFocusableComponent() {
  885. registerNextFocusableComponent(getNextFocusableComponent());
  886. }
  887. private void registerNextFocusableComponent(Component
  888. nextFocusableComponent) {
  889. if (nextFocusableComponent == null) {
  890. return;
  891. }
  892. Container nearestRoot =
  893. (isFocusCycleRoot()) ? this : getFocusCycleRootAncestor();
  894. FocusTraversalPolicy policy = nearestRoot.getFocusTraversalPolicy();
  895. if (!(policy instanceof LegacyGlueFocusTraversalPolicy)) {
  896. policy = new LegacyGlueFocusTraversalPolicy(policy);
  897. nearestRoot.setFocusTraversalPolicy(policy);
  898. }
  899. ((LegacyGlueFocusTraversalPolicy)policy).
  900. setNextFocusableComponent(this, nextFocusableComponent);
  901. }
  902. private void deregisterNextFocusableComponent() {
  903. Component nextFocusableComponent = getNextFocusableComponent();
  904. if (nextFocusableComponent == null) {
  905. return;
  906. }
  907. Container nearestRoot =
  908. (isFocusCycleRoot()) ? this : getFocusCycleRootAncestor();
  909. if (nearestRoot == null) {
  910. return;
  911. }
  912. FocusTraversalPolicy policy = nearestRoot.getFocusTraversalPolicy();
  913. if (policy instanceof LegacyGlueFocusTraversalPolicy) {
  914. ((LegacyGlueFocusTraversalPolicy)policy).
  915. unsetNextFocusableComponent(this, nextFocusableComponent);
  916. }
  917. }
  918. /**
  919. * Overrides the default <code>FocusTraversalPolicy</code> for this
  920. * <code>JComponent</code>'s focus traversal cycle by unconditionally
  921. * setting the specified <code>Component</code> as the next
  922. * <code>Component</code> in the cycle, and this <code>JComponent</code>
  923. * as the specified <code>Component</code>'s previous
  924. * <code>Component</code> in the cycle.
  925. *
  926. * @param aComponent the <code>Component</code> that should follow this
  927. * <code>JComponent</code> in the focus traversal cycle
  928. *
  929. * @see #getNextFocusableComponent
  930. * @see java.awt.FocusTraversalPolicy
  931. * @deprecated As of 1.4, replaced by <code>FocusTraversalPolicy</code>
  932. */
  933. public void setNextFocusableComponent(Component aComponent) {
  934. boolean displayable = isDisplayable();
  935. if (displayable) {
  936. deregisterNextFocusableComponent();
  937. }
  938. putClientProperty(NEXT_FOCUS, aComponent);
  939. if (displayable) {
  940. registerNextFocusableComponent(aComponent);
  941. }
  942. }
  943. /**
  944. * Returns the <code>Component</code> set by a prior call to
  945. * <code>setNextFocusableComponent(Component)</code> on this
  946. * <code>JComponent</code>.
  947. *
  948. * @return the <code>Component</code> that will follow this
  949. * <code>JComponent</code> in the focus traversal cycle, or
  950. * <code>null</code> if none has been explicitly specified
  951. *
  952. * @see #setNextFocusableComponent
  953. * @deprecated As of 1.4, replaced by <code>FocusTraversalPolicy</code>.
  954. */
  955. public Component getNextFocusableComponent() {
  956. return (Component)getClientProperty(NEXT_FOCUS);
  957. }
  958. /**
  959. * Provides a hint as to whether or not this <code>JComponent</code>
  960. * should get focus. This is only a hint, and it is up to consumers that
  961. * are requesting focus to honor this property. This is typically honored
  962. * for mouse operations, but not keyboard operations. For example, look
  963. * and feels could verify this property is true before requesting focus
  964. * during a mouse operation. This would often times be used if you did
  965. * not want a mouse press on a <code>JComponent</code> to steal focus,
  966. * but did want the <code>JComponent</code> to be traversable via the
  967. * keyboard. If you do not want this <code>JComponent</code> focusable at
  968. * all, use the <code>setFocusable</code> method instead.
  969. *
  970. * @param requestFocusEnabled Indicates if you want this JComponent to
  971. * be focusable or not
  972. * @see <a href="../../java/awt/doc-files/FocusSpec.html">Focus Specification</a>
  973. * @see java.awt.Component#setFocusable
  974. */
  975. public void setRequestFocusEnabled(boolean requestFocusEnabled) {
  976. setFlag(REQUEST_FOCUS_DISABLED, !requestFocusEnabled);
  977. }
  978. /**
  979. * Returns <code>true</code> if this <code>JComponent</code> should
  980. * get focus; otherwise returns <code>false</code>.
  981. *
  982. * @return <code>true</code> if this component should get focus,
  983. * otherwise returns <code>false</code>
  984. * @see #setRequestFocusEnabled
  985. * @see <a href="../../java/awt/doc-files/FocusSpec.html">Focus
  986. * Specification</a>
  987. * @see java.awt.Component#isFocusable
  988. */
  989. public boolean isRequestFocusEnabled() {
  990. return !getFlag(REQUEST_FOCUS_DISABLED);
  991. }
  992. private boolean runInputVerifier() {
  993. Component focusOwner =
  994. KeyboardFocusManager.getCurrentKeyboardFocusManager().
  995. getFocusOwner();
  996. if (focusOwner == this) {
  997. return true;
  998. }
  999. if (!getVerifyInputWhenFocusTarget()) {
  1000. return true;
  1001. }
  1002. if (focusOwner == null || !(focusOwner instanceof JComponent)) {
  1003. return true;
  1004. }
  1005. JComponent jFocusOwner = (JComponent)focusOwner;
  1006. InputVerifier iv = jFocusOwner.getInputVerifier();
  1007. if (iv == null) {
  1008. return true;
  1009. } else {
  1010. return iv.shouldYieldFocus(jFocusOwner);
  1011. }
  1012. }
  1013. public void requestFocus() {
  1014. if (runInputVerifier()) {
  1015. super.requestFocus();
  1016. }
  1017. }
  1018. /**
  1019. * <code>JComponent</code> overrides <code>requestFocus</code> solely
  1020. * to make the method public so that UI implementations can cause
  1021. * temporary focus changes. This method is not meant for general use,
  1022. * instead developers are urged to call the noarg <code>requestFocus</code>
  1023. * or <code>requestFocusInWindow</code> methods. If the
  1024. * <code>JComponent</code> has an <code>InputVerifier</code>associated
  1025. * with it, the <code>InputVerifier</code> will be messaged.
  1026. * <p>
  1027. * Refer to {@link java.awt.Component#requestFocus(boolean)
  1028. * Component.requestFocus(boolean)} for a complete description
  1029. * of this method.
  1030. *
  1031. * @param temporary boolean indicating if the focus change is temporary
  1032. * @return <code>false</code> if the focus change request is guaranteed to
  1033. * fail; <code>true</code> if it is likely to succeed
  1034. * @see java.awt.Component#requestFocus()
  1035. * @see java.awt.Component#requestFocusInWindow()
  1036. * @see java.awt.Component#requestFocus(boolean)
  1037. * @see java.awt.Component#requestFocusInWindow(boolean)
  1038. * @since 1.4
  1039. */
  1040. public boolean requestFocus(boolean temporary) {
  1041. return (runInputVerifier())
  1042. ? super.requestFocus(temporary)
  1043. : false;
  1044. }
  1045. public boolean requestFocusInWindow() {
  1046. return (runInputVerifier())
  1047. ? super.requestFocusInWindow()
  1048. : false;
  1049. }
  1050. /**
  1051. * <code>JComponent</code> overrides <code>requestFocusInWindow</code>
  1052. * solely to make the method public so that UI implementations can cause
  1053. * temporary focus changes. This method is not meant for general use,
  1054. * instead developers are urged to call the noarg <code>requestFocus</code>
  1055. * or <code>requestFocusInWindow</code> methods. If the
  1056. * <code>JComponent</code> has an <code>InputVerifier</code>associated
  1057. * with it, the <code>InputVerifier</code> will be messaged.
  1058. * <p>
  1059. * Refer to {@link java.awt.Component#requestFocusInWindow(boolean)
  1060. * Component.requestFocusInWindow(boolean)} for a complete description of
  1061. * this method.
  1062. *
  1063. * @param temporary boolean indicating if the focus change is temporary
  1064. * @return <code>false</code> if the focus change request is guaranteed to
  1065. * fail; <code>true</code> if it is likely to succeed
  1066. * @see java.awt.Component#requestFocus()
  1067. * @see java.awt.Component#requestFocusInWindow()
  1068. * @see java.awt.Component#requestFocus(boolean)
  1069. * @see java.awt.Component#requestFocusInWindow(boolean)
  1070. * @since 1.4
  1071. */
  1072. protected boolean requestFocusInWindow(boolean temporary) {
  1073. return (runInputVerifier())
  1074. ? super.requestFocusInWindow(temporary)
  1075. : false;
  1076. }
  1077. /**
  1078. * Requests that this Component get the input focus, and that this
  1079. * Component's top-level ancestor become the focused Window. This component
  1080. * must be displayable, visible, and focusable for the request to be
  1081. * granted.
  1082. * <p>
  1083. * This method is intended for use by focus implementations. Client code
  1084. * should not use this method; instead, it should use
  1085. * <code>requestFocus()</code>.
  1086. *
  1087. * @see #requestFocus()
  1088. */
  1089. public void grabFocus() {
  1090. requestFocus();
  1091. }
  1092. /**
  1093. * Sets the value to indicate whether input verifier for the
  1094. * current focus owner will be called before this component requests
  1095. * focus. The default is true. Set to false on components such as a
  1096. * Cancel button or a scrollbar, which should activate even if the
  1097. * input in the current focus owner is not "passed" by the input
  1098. * verifier for that component.
  1099. *
  1100. * @param verifyInputWhenFocusTarget value for the
  1101. * <code>verifyInputWhenFocusTarget</code> property
  1102. * @see InputVerifier
  1103. * @see #setInputVerifier
  1104. * @see #getInputVerifier
  1105. * @see #getVerifyInputWhenFocusTarget
  1106. *
  1107. * @since 1.3
  1108. * @beaninfo
  1109. * bound: true
  1110. * description: Whether the Component verifies input before accepting
  1111. * focus.
  1112. */
  1113. public void setVerifyInputWhenFocusTarget(boolean
  1114. verifyInputWhenFocusTarget) {
  1115. boolean oldVerifyInputWhenFocusTarget =
  1116. this.verifyInputWhenFocusTarget;
  1117. this.verifyInputWhenFocusTarget = verifyInputWhenFocusTarget;
  1118. firePropertyChange("verifyInputWhenFocusTarget",
  1119. oldVerifyInputWhenFocusTarget,
  1120. verifyInputWhenFocusTarget);
  1121. }
  1122. /**
  1123. * Returns the value that indicates whether the input verifier for the
  1124. * current focus owner will be called before this component requests
  1125. * focus.
  1126. *
  1127. * @return value of the <code>verifyInputWhenFocusTarget</code> property
  1128. *
  1129. * @see InputVerifier
  1130. * @see #setInputVerifier
  1131. * @see #getInputVerifier
  1132. * @see #setVerifyInputWhenFocusTarget
  1133. *
  1134. * @since 1.3
  1135. */
  1136. public boolean getVerifyInputWhenFocusTarget() {
  1137. return verifyInputWhenFocusTarget;
  1138. }
  1139. /**
  1140. * Sets the preferred size of this component.
  1141. * If <code>preferredSize</code> is <code>null</code>, the UI will
  1142. * be asked for the preferred size.
  1143. * @beaninfo
  1144. * preferred: true
  1145. * bound: true
  1146. * description: The preferred size of the component.
  1147. */
  1148. public void setPreferredSize(Dimension preferredSize) {
  1149. Dimension old = this.preferredSize;
  1150. this.preferredSize = preferredSize;
  1151. firePropertyChange("preferredSize", old, preferredSize);
  1152. }
  1153. /**
  1154. * If the <code>preferredSize</code> has been set to a
  1155. * non-<code>null</code> value just returns it.
  1156. * If the UI delegate's <code>getPreferredSize</code>
  1157. * method returns a non <code>null</code> value then return that;
  1158. * otherwise defer to the component's layout manager.
  1159. *
  1160. * @return the value of the <code>preferredSize</code> property
  1161. * @see #setPreferredSize
  1162. * @see ComponentUI
  1163. */
  1164. public Dimension getPreferredSize() {
  1165. if (preferredSize != null) {
  1166. return preferredSize;
  1167. }
  1168. Dimension size = null;
  1169. if (ui != null) {
  1170. size = ui.getPreferredSize(this);
  1171. }
  1172. return (size != null) ? size : super.getPreferredSize();
  1173. }
  1174. /**
  1175. * Sets the maximum size of this component to a constant
  1176. * value. Subsequent calls to <code>getMaximumSize</code> will always
  1177. * return this value; the component's UI will not be asked
  1178. * to compute it. Setting the maximum size to <code>null</code>
  1179. * restores the default behavior.
  1180. *
  1181. * @param maximumSize a <code>Dimension</code> containing the
  1182. * desired maximum allowable size
  1183. * @see #getMaximumSize
  1184. * @beaninfo
  1185. * bound: true
  1186. * description: The maximum size of the component.
  1187. */
  1188. public void setMaximumSize(Dimension maximumSize) {
  1189. Dimension old = this.maximumSize;
  1190. this.maximumSize = maximumSize;
  1191. firePropertyChange("maximumSize", old, maximumSize);
  1192. }
  1193. /**
  1194. * If the maximum size has been set to a non-<code>null</code> value
  1195. * just returns it. If the UI delegate's <code>getMaximumSize</code>
  1196. * method returns a non-<code>null</code> value then return that;
  1197. * otherwise defer to the component's layout manager.
  1198. *
  1199. * @return the value of the <code>maximumSize</code> property
  1200. * @see #setMaximumSize
  1201. * @see ComponentUI
  1202. */
  1203. public Dimension getMaximumSize() {
  1204. if (maximumSize != null) {
  1205. return maximumSize;
  1206. }
  1207. Dimension size = null;
  1208. if (ui != null) {
  1209. size = ui.getMaximumSize(this);
  1210. }
  1211. return (size != null) ? size : super.getMaximumSize();
  1212. }
  1213. /**
  1214. * Sets the minimum size of this component to a constant
  1215. * value. Subsequent calls to <code>getMinimumSize</code> will always
  1216. * return this value; the component's UI will not be asked
  1217. * to compute it. Setting the minimum size to <code>null</code>
  1218. * restores the default behavior.
  1219. *
  1220. * @param minimumSize the new minimum size of this component
  1221. * @see #getMinimumSize
  1222. * @beaninfo
  1223. * bound: true
  1224. * description: The minimum size of the component.
  1225. */
  1226. public void setMinimumSize(Dimension minimumSize) {
  1227. Dimension old = this.minimumSize;
  1228. this.minimumSize = minimumSize;
  1229. firePropertyChange("minimumSize", old, minimumSize);
  1230. }
  1231. /**
  1232. * If the minimum size has been set to a non-<code>null</code> value
  1233. * just returns it. If the UI delegate's <code>getMinimumSize</code>
  1234. * method returns a non-<code>null</code> value then return that; otherwise
  1235. * defer to the component's layout manager.
  1236. *
  1237. * @return the value of the <code>minimumSize</code> property
  1238. * @see #setMinimumSize
  1239. * @see ComponentUI
  1240. */
  1241. public Dimension getMinimumSize() {
  1242. if (minimumSize != null) {
  1243. return minimumSize;
  1244. }
  1245. Dimension size = null;
  1246. if (ui != null) {
  1247. size = ui.getMinimumSize(this);
  1248. }
  1249. return (size != null) ? size : super.getMinimumSize();
  1250. }
  1251. /**
  1252. * Returns true if the minimum size has been set to a non-<code>null</code>
  1253. * value otherwise returns false.
  1254. *
  1255. * @return true if <code>minimumSize</code> is non-<code>null</code>,
  1256. * false otherwise
  1257. * @since 1.3
  1258. */
  1259. public boolean isMinimumSizeSet() {
  1260. return minimumSize != null;
  1261. }
  1262. /**
  1263. * Returns true if the preferred size has been set to a
  1264. * non-<code>null</code> value otherwise returns false.
  1265. *
  1266. * @return true if <code>preferredSize</code> is non-<code>null</code>,
  1267. * false otherwise
  1268. * @since 1.3
  1269. */
  1270. public boolean isPreferredSizeSet() {
  1271. return preferredSize != null;
  1272. }
  1273. /**
  1274. * Returns true if the maximum size has been set to a non-<code>null</code>
  1275. * value otherwise returns false.
  1276. *
  1277. * @return true if <code>maximumSize</code> is non-<code>null</code>,
  1278. * false otherwise
  1279. * @since 1.3
  1280. */
  1281. public boolean isMaximumSizeSet() {
  1282. return maximumSize != null;
  1283. }
  1284. /**
  1285. * Gives the UI delegate an opportunity to define the precise
  1286. * shape of this component for the sake of mouse processing.
  1287. *
  1288. * @return true if this component logically contains x,y
  1289. * @see java.awt.Component#contains(int, int)
  1290. * @see ComponentUI
  1291. */
  1292. public boolean contains(int x, int y) {
  1293. return (ui != null) ? ui.contains(this, x, y) : super.contains(x, y);
  1294. }
  1295. /**
  1296. * Sets the border of this component. The <code>Border</code> object is
  1297. * responsible for defining the insets for the component
  1298. * (overriding any insets set directly on the component) and
  1299. * for optionally rendering any border decorations within the
  1300. * bounds of those insets. Borders should be used (rather
  1301. * than insets) for creating both decorative and non-decorative
  1302. * (such as margins and padding) regions for a swing component.
  1303. * Compound borders can be used to nest multiple borders within a
  1304. * single component.
  1305. * <p>
  1306. * This is a bound property.
  1307. *
  1308. * @param border the border to be rendered for this component
  1309. * @see Border
  1310. * @see CompoundBorder
  1311. * @beaninfo
  1312. * bound: true
  1313. * preferred: true
  1314. * attribute: visualUpdate true
  1315. * description: The component's border.
  1316. */
  1317. public void setBorder(Border border) {
  1318. Border oldBorder = this.border;
  1319. this.border = border;
  1320. firePropertyChange("border", oldBorder, border);
  1321. if (border != oldBorder) {
  1322. if (border == null || oldBorder == null ||
  1323. !(border.getBorderInsets(this).equals(oldBorder.getBorderInsets(this)))) {
  1324. revalidate();
  1325. }
  1326. repaint();
  1327. }
  1328. }
  1329. /**
  1330. * Returns the border of this component or <code>null</code> if no
  1331. * border is currently set.
  1332. *
  1333. * @return the border object for this component
  1334. * @see #setBorder
  1335. */
  1336. public Border getBorder() {
  1337. return border;
  1338. }
  1339. /**
  1340. * If a border has been set on this component, returns the
  1341. * border's insets; otherwise calls <code>super.getInsets</code>.
  1342. *
  1343. * @return the value of the insets property
  1344. * @see #setBorder
  1345. */
  1346. public Insets getInsets() {
  1347. if (border != null) {
  1348. return border.getBorderInsets(this);
  1349. }
  1350. return super.getInsets();
  1351. }
  1352. /**
  1353. * Returns an <code>Insets</code> object containing this component's inset
  1354. * values. The passed-in <code>Insets</code> object will be reused
  1355. * if possible.
  1356. * Calling methods cannot assume that the same object will be returned,
  1357. * however. All existing values within this object are overwritten.
  1358. * If <code>insets</code> is null, this will allocate a new one.
  1359. *
  1360. * @param insets the <code>Insets</code> object, which can be reused
  1361. * @return the <code>Insets</code> object
  1362. * @see #getInsets
  1363. * @beaninfo
  1364. * expert: true
  1365. */
  1366. public Insets getInsets(Insets insets) {
  1367. if (insets == null) {
  1368. insets = new Insets(0, 0, 0, 0);
  1369. }
  1370. if (border != null) {
  1371. if (border instanceof AbstractBorder) {
  1372. return ((AbstractBorder)border).getBorderInsets(this, insets);
  1373. } else {
  1374. // Can't reuse border insets because the Border interface
  1375. // can't be enhanced.
  1376. return border.getBorderInsets(this);
  1377. }
  1378. } else {
  1379. // super.getInsets() always returns an Insets object with
  1380. // all of its value zeroed. No need for a new object here.
  1381. insets.left = insets.top = insets.right = insets.bottom = 0;
  1382. return insets;
  1383. }
  1384. }
  1385. /**
  1386. * Overrides <code>Container.getAlignmentY</code> to return
  1387. * the horizontal alignment.
  1388. *
  1389. * @return the value of the <code>alignmentY</code> property
  1390. * @see #setAlignmentY
  1391. * @see java.awt.Component#getAlignmentY
  1392. */
  1393. public float getAlignmentY() {
  1394. return (alignmentY != null) ? alignmentY.floatValue() : super.getAlignmentY();
  1395. }
  1396. /**
  1397. * Sets the the horizontal alignment.
  1398. *
  1399. * @param alignmentY the new horizontal alignment
  1400. * @see #getAlignmentY
  1401. * @beaninfo
  1402. * description: The preferred vertical alignment of the component.
  1403. */
  1404. public void setAlignmentY(float alignmentY) {
  1405. this.alignmentY = new Float(alignmentY > 1.0f ? 1.0f : alignmentY < 0.0f ? 0.0f : alignmentY);
  1406. }
  1407. /**
  1408. * Overrides