1. /*
  2. * @(#)JLayeredPane.java 1.54 04/05/05
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package javax.swing;
  8. import java.awt.Component;
  9. import java.util.ArrayList;
  10. import java.util.Hashtable;
  11. import java.awt.Color;
  12. import java.awt.Graphics;
  13. import java.awt.Rectangle;
  14. import javax.accessibility.*;
  15. /**
  16. * <code>JLayeredPane</code> adds depth to a JFC/Swing container,
  17. * allowing components to overlap each other when needed.
  18. * An <code>Integer</code> object specifies each component's depth in the
  19. * container, where higher-numbered components sit "on top" of other
  20. * components.
  21. * For task-oriented documentation and examples of using layered panes see
  22. * <a href="http://java.sun.com/docs/books/tutorial/uiswing/components/layeredpane.html">How to Use a Layered Pane</a>,
  23. * a section in <em>The Java Tutorial</em>.
  24. * <P>
  25. * <TABLE ALIGN="RIGHT" BORDER="0" SUMMARY="layout">
  26. * <TR>
  27. * <TD ALIGN="CENTER">
  28. * <P ALIGN="CENTER"><IMG SRC="doc-files/JLayeredPane-1.gif"
  29. * alt="The following text describes this image."
  30. * WIDTH="269" HEIGHT="264" ALIGN="BOTTOM" BORDER="0">
  31. * </TD>
  32. * </TR>
  33. * </TABLE>
  34. * For convenience, <code>JLayeredPane</code> divides the depth-range
  35. * into several different layers. Putting a component into one of those
  36. * layers makes it easy to ensure that components overlap properly,
  37. * without having to worry about specifying numbers for specific depths:
  38. * <DL>
  39. * <DT><FONT SIZE="2">DEFAULT_LAYER</FONT></DT>
  40. * <DD>The standard layer, where most components go. This the bottommost
  41. * layer.
  42. * <DT><FONT SIZE="2">PALETTE_LAYER</FONT></DT>
  43. * <DD>The palette layer sits over the default layer. Useful for floating
  44. * toolbars and palettes, so they can be positioned above other components.
  45. * <DT><FONT SIZE="2">MODAL_LAYER</FONT></DT>
  46. * <DD>The layer used for modal dialogs. They will appear on top of any
  47. * toolbars, palettes, or standard components in the container.
  48. * <DT><FONT SIZE="2">POPUP_LAYER</FONT></DT>
  49. * <DD>The popup layer displays above dialogs. That way, the popup windows
  50. * associated with combo boxes, tooltips, and other help text will appear
  51. * above the component, palette, or dialog that generated them.
  52. * <DT><FONT SIZE="2">DRAG_LAYER</FONT></DT>
  53. * <DD>When dragging a component, reassigning it to the drag layer ensures
  54. * that it is positioned over every other component in the container. When
  55. * finished dragging, it can be reassigned to its normal layer.
  56. * </DL>
  57. * The <code>JLayeredPane</code> methods <code>moveToFront(Component)</code>,
  58. * <code>moveToBack(Component)</code> and <code>setPosition</code> can be used
  59. * to reposition a component within its layer. The <code>setLayer</code> method
  60. * can also be used to change the component's current layer.
  61. *
  62. * <h2>Details</h2>
  63. * <code>JLayeredPane</code> manages its list of children like
  64. * <code>Container</code>, but allows for the definition of a several
  65. * layers within itself. Children in the same layer are managed exactly
  66. * like the normal <code>Container</code> object,
  67. * with the added feature that when children components overlap, children
  68. * in higher layers display above the children in lower layers.
  69. * <p>
  70. * Each layer is a distinct integer number. The layer attribute can be set
  71. * on a <code>Component</code> by passing an <code>Integer</code>
  72. * object during the add call.<br> For example:
  73. * <PRE>
  74. * layeredPane.add(child, JLayeredPane.DEFAULT_LAYER);
  75. * or
  76. * layeredPane.add(child, new Integer(10));
  77. * </PRE>
  78. * The layer attribute can also be set on a Component by calling<PRE>
  79. * layeredPaneParent.setLayer(child, 10)</PRE>
  80. * on the <code>JLayeredPane</code> that is the parent of component. The layer
  81. * should be set <i>before</i> adding the child to the parent.
  82. * <p>
  83. * Higher number layers display above lower number layers. So, using
  84. * numbers for the layers and letters for individual components, a
  85. * representative list order would look like this:<PRE>
  86. * 5a, 5b, 5c, 2a, 2b, 2c, 1a </PRE>
  87. * where the leftmost components are closest to the top of the display.
  88. * <p>
  89. * A component can be moved to the top or bottom position within its
  90. * layer by calling <code>moveToFront</code> or <code>moveToBack</code>.
  91. * <p>
  92. * The position of a component within a layer can also be specified directly.
  93. * Valid positions range from 0 up to one less than the number of
  94. * components in that layer. A value of -1 indicates the bottommost
  95. * position. A value of 0 indicates the topmost position. Unlike layer
  96. * numbers, higher position values are <i>lower</i> in the display.
  97. * <blockquote>
  98. * <b>Note:</b> This sequence (defined by java.awt.Container) is the reverse
  99. * of the layer numbering sequence. Usually though, you will use <code>moveToFront</code>,
  100. * <code>moveToBack</code>, and <code>setLayer</code>.
  101. * </blockquote>
  102. * Here are some examples using the method add(Component, layer, position):
  103. * Calling add(5x, 5, -1) results in:<PRE>
  104. * 5a, 5b, 5c, 5x, 2a, 2b, 2c, 1a </PRE>
  105. *
  106. * Calling add(5z, 5, 2) results in:<PRE>
  107. * 5a, 5b, 5z, 5c, 5x, 2a, 2b, 2c, 1a </PRE>
  108. *
  109. * Calling add(3a, 3, 7) results in:<PRE>
  110. * 5a, 5b, 5z, 5c, 5x, 3a, 2a, 2b, 2c, 1a </PRE>
  111. *
  112. * Using normal paint/event mechanics results in 1a appearing at the bottom
  113. * and 5a being above all other components.
  114. * <p>
  115. * <b>Note:</b> that these layers are simply a logical construct and LayoutManagers
  116. * will affect all child components of this container without regard for
  117. * layer settings.
  118. * <p>
  119. * <strong>Warning:</strong>
  120. * Serialized objects of this class will not be compatible with
  121. * future Swing releases. The current serialization support is
  122. * appropriate for short term storage or RMI between applications running
  123. * the same version of Swing. As of 1.4, support for long term storage
  124. * of all JavaBeans<sup><font size="-2">TM</font></sup>
  125. * has been added to the <code>java.beans</code> package.
  126. * Please see {@link java.beans.XMLEncoder}.
  127. *
  128. * @version 1.36 02/02/00
  129. * @author David Kloba
  130. */
  131. public class JLayeredPane extends JComponent implements Accessible {
  132. /// Watch the values in getObjectForLayer()
  133. /** Convenience object defining the Default layer. Equivalent to new Integer(0).*/
  134. public final static Integer DEFAULT_LAYER = new Integer(0);
  135. /** Convenience object defining the Palette layer. Equivalent to new Integer(100).*/
  136. public final static Integer PALETTE_LAYER = new Integer(100);
  137. /** Convenience object defining the Modal layer. Equivalent to new Integer(200).*/
  138. public final static Integer MODAL_LAYER = new Integer(200);
  139. /** Convenience object defining the Popup layer. Equivalent to new Integer(300).*/
  140. public final static Integer POPUP_LAYER = new Integer(300);
  141. /** Convenience object defining the Drag layer. Equivalent to new Integer(400).*/
  142. public final static Integer DRAG_LAYER = new Integer(400);
  143. /** Convenience object defining the Frame Content layer.
  144. * This layer is normally only use to positon the contentPane and menuBar
  145. * components of JFrame.
  146. * Equivalent to new Integer(-30000).
  147. * @see JFrame
  148. */
  149. public final static Integer FRAME_CONTENT_LAYER = new Integer(-30000);
  150. /** Bound property */
  151. public final static String LAYER_PROPERTY = "layeredContainerLayer";
  152. // Hashtable to store layer values for non-JComponent components
  153. private Hashtable<Component,Integer> componentToLayer;
  154. private boolean optimizedDrawingPossible = true;
  155. //////////////////////////////////////////////////////////////////////////////
  156. //// Container Override methods
  157. //////////////////////////////////////////////////////////////////////////////
  158. /** Create a new JLayeredPane */
  159. public JLayeredPane() {
  160. setLayout(null);
  161. }
  162. private void validateOptimizedDrawing() {
  163. boolean layeredComponentFound = false;
  164. synchronized(getTreeLock()) {
  165. Integer layer = null;
  166. for (Component c : getComponents()) {
  167. layer = null;
  168. if(c instanceof JInternalFrame || (c instanceof JComponent &&
  169. (layer = (Integer)((JComponent)c).getClientProperty(
  170. LAYER_PROPERTY)) != null)) {
  171. if(layer != null && layer.equals(FRAME_CONTENT_LAYER))
  172. continue;
  173. layeredComponentFound = true;
  174. break;
  175. }
  176. }
  177. }
  178. if(layeredComponentFound)
  179. optimizedDrawingPossible = false;
  180. else
  181. optimizedDrawingPossible = true;
  182. }
  183. protected void addImpl(Component comp, Object constraints, int index) {
  184. int layer = DEFAULT_LAYER.intValue();
  185. int pos;
  186. if(constraints instanceof Integer) {
  187. layer = ((Integer)constraints).intValue();
  188. setLayer(comp, layer);
  189. } else
  190. layer = getLayer(comp);
  191. pos = insertIndexForLayer(layer, index);
  192. super.addImpl(comp, constraints, pos);
  193. comp.validate();
  194. comp.repaint();
  195. validateOptimizedDrawing();
  196. }
  197. /**
  198. * Remove the indexed component from this pane.
  199. * This is the absolute index, ignoring layers.
  200. *
  201. * @param index an int specifying the component to remove
  202. * @see #getIndexOf
  203. */
  204. public void remove(int index) {
  205. Component c = getComponent(index);
  206. super.remove(index);
  207. if (c != null && !(c instanceof JComponent)) {
  208. getComponentToLayer().remove(c);
  209. }
  210. validateOptimizedDrawing();
  211. }
  212. /**
  213. * Removes all the components from this container.
  214. *
  215. * @since 1.5
  216. */
  217. public void removeAll() {
  218. Component[] children = getComponents();
  219. Hashtable cToL = getComponentToLayer();
  220. for (int counter = children.length - 1; counter >= 0; counter--) {
  221. Component c = children[counter];
  222. if (c != null && !(c instanceof JComponent)) {
  223. cToL.remove(c);
  224. }
  225. }
  226. super.removeAll();
  227. }
  228. /**
  229. * Returns false if components in the pane can overlap, which makes
  230. * optimized drawing impossible. Otherwise, returns true.
  231. *
  232. * @return false if components can overlap, else true
  233. * @see JComponent#isOptimizedDrawingEnabled
  234. */
  235. public boolean isOptimizedDrawingEnabled() {
  236. return optimizedDrawingPossible;
  237. }
  238. //////////////////////////////////////////////////////////////////////////////
  239. //// New methods for managing layers
  240. //////////////////////////////////////////////////////////////////////////////
  241. /** Sets the layer property on a JComponent. This method does not cause
  242. * any side effects like setLayer() (painting, add/remove, etc).
  243. * Normally you should use the instance method setLayer(), in order to
  244. * get the desired side-effects (like repainting).
  245. *
  246. * @param c the JComponent to move
  247. * @param layer an int specifying the layer to move it to
  248. * @see #setLayer
  249. */
  250. public static void putLayer(JComponent c, int layer) {
  251. /// MAKE SURE THIS AND setLayer(Component c, int layer, int position) are SYNCED
  252. Integer layerObj;
  253. layerObj = new Integer(layer);
  254. c.putClientProperty(LAYER_PROPERTY, layerObj);
  255. }
  256. /** Gets the layer property for a JComponent, it
  257. * does not cause any side effects like setLayer(). (painting, add/remove, etc)
  258. * Normally you should use the instance method getLayer().
  259. *
  260. * @param c the JComponent to check
  261. * @return an int specifying the component's layer
  262. */
  263. public static int getLayer(JComponent c) {
  264. Integer i;
  265. if((i = (Integer)c.getClientProperty(LAYER_PROPERTY)) != null)
  266. return i.intValue();
  267. return DEFAULT_LAYER.intValue();
  268. }
  269. /** Convenience method that returns the first JLayeredPane which
  270. * contains the specified component. Note that all JFrames have a
  271. * JLayeredPane at their root, so any component in a JFrame will
  272. * have a JLayeredPane parent.
  273. *
  274. * @param c the Component to check
  275. * @return the JLayeredPane that contains the component, or
  276. * null if no JLayeredPane is found in the component
  277. * hierarchy
  278. * @see JFrame
  279. * @see JRootPane
  280. */
  281. public static JLayeredPane getLayeredPaneAbove(Component c) {
  282. if(c == null) return null;
  283. Component parent = c.getParent();
  284. while(parent != null && !(parent instanceof JLayeredPane))
  285. parent = parent.getParent();
  286. return (JLayeredPane)parent;
  287. }
  288. /** Sets the layer attribute on the specified component,
  289. * making it the bottommost component in that layer.
  290. * Should be called before adding to parent.
  291. *
  292. * @param c the Component to set the layer for
  293. * @param layer an int specifying the layer to set, where
  294. * lower numbers are closer to the bottom
  295. */
  296. public void setLayer(Component c, int layer) {
  297. setLayer(c, layer, -1);
  298. }
  299. /** Sets the layer attribute for the specified component and
  300. * also sets its position within that layer.
  301. *
  302. * @param c the Component to set the layer for
  303. * @param layer an int specifying the layer to set, where
  304. * lower numbers are closer to the bottom
  305. * @param position an int specifying the position within the
  306. * layer, where 0 is the topmost position and -1
  307. * is the bottommost position
  308. */
  309. public void setLayer(Component c, int layer, int position) {
  310. Integer layerObj;
  311. layerObj = getObjectForLayer(layer);
  312. if(layer == getLayer(c) && position == getPosition(c)) {
  313. repaint(c.getBounds());
  314. return;
  315. }
  316. /// MAKE SURE THIS AND putLayer(JComponent c, int layer) are SYNCED
  317. if(c instanceof JComponent)
  318. ((JComponent)c).putClientProperty(LAYER_PROPERTY, layerObj);
  319. else
  320. getComponentToLayer().put((Component)c, layerObj);
  321. if(c.getParent() == null || c.getParent() != this) {
  322. repaint(c.getBounds());
  323. return;
  324. }
  325. int index = insertIndexForLayer(c, layer, position);
  326. setComponentZOrder(c, index);
  327. repaint(c.getBounds());
  328. }
  329. /**
  330. * Returns the layer attribute for the specified Component.
  331. *
  332. * @param c the Component to check
  333. * @return an int specifying the component's current layer
  334. */
  335. public int getLayer(Component c) {
  336. Integer i;
  337. if(c instanceof JComponent)
  338. i = (Integer)((JComponent)c).getClientProperty(LAYER_PROPERTY);
  339. else
  340. i = (Integer)getComponentToLayer().get((Component)c);
  341. if(i == null)
  342. return DEFAULT_LAYER.intValue();
  343. return i.intValue();
  344. }
  345. /**
  346. * Returns the index of the specified Component.
  347. * This is the absolute index, ignoring layers.
  348. * Index numbers, like position numbers, have the topmost component
  349. * at index zero. Larger numbers are closer to the bottom.
  350. *
  351. * @param c the Component to check
  352. * @return an int specifying the component's index
  353. */
  354. public int getIndexOf(Component c) {
  355. int i, count;
  356. count = getComponentCount();
  357. for(i = 0; i < count; i++) {
  358. if(c == getComponent(i))
  359. return i;
  360. }
  361. return -1;
  362. }
  363. /**
  364. * Moves the component to the top of the components in its current layer
  365. * (position 0).
  366. *
  367. * @param c the Component to move
  368. * @see #setPosition(Component, int)
  369. */
  370. public void moveToFront(Component c) {
  371. setPosition(c, 0);
  372. }
  373. /**
  374. * Moves the component to the bottom of the components in its current layer
  375. * (position -1).
  376. *
  377. * @param c the Component to move
  378. * @see #setPosition(Component, int)
  379. */
  380. public void moveToBack(Component c) {
  381. setPosition(c, -1);
  382. }
  383. /**
  384. * Moves the component to <code>position</code> within its current layer,
  385. * where 0 is the topmost position within the layer and -1 is the bottommost
  386. * position.
  387. * <p>
  388. * <b>Note:</b> Position numbering is defined by java.awt.Container, and
  389. * is the opposite of layer numbering. Lower position numbers are closer
  390. * to the top (0 is topmost), and higher position numbers are closer to
  391. * the bottom.
  392. *
  393. * @param c the Component to move
  394. * @param position an int in the range -1..N-1, where N is the number of
  395. * components in the component's current layer
  396. */
  397. public void setPosition(Component c, int position) {
  398. setLayer(c, getLayer(c), position);
  399. }
  400. /**
  401. * Get the relative position of the component within its layer.
  402. *
  403. * @param c the Component to check
  404. * @return an int giving the component's position, where 0 is the
  405. * topmost position and the highest index value = the count
  406. * count of components at that layer, minus 1
  407. *
  408. * @see #getComponentCountInLayer
  409. */
  410. public int getPosition(Component c) {
  411. int i, count, startLayer, curLayer, startLocation, pos = 0;
  412. count = getComponentCount();
  413. startLocation = getIndexOf(c);
  414. if(startLocation == -1)
  415. return -1;
  416. startLayer = getLayer(c);
  417. for(i = startLocation - 1; i >= 0; i--) {
  418. curLayer = getLayer(getComponent(i));
  419. if(curLayer == startLayer)
  420. pos++;
  421. else
  422. return pos;
  423. }
  424. return pos;
  425. }
  426. /** Returns the highest layer value from all current children.
  427. * Returns 0 if there are no children.
  428. *
  429. * @return an int indicating the layer of the topmost component in the
  430. * pane, or zero if there are no children
  431. */
  432. public int highestLayer() {
  433. if(getComponentCount() > 0)
  434. return getLayer(getComponent(0));
  435. return 0;
  436. }
  437. /** Returns the lowest layer value from all current children.
  438. * Returns 0 if there are no children.
  439. *
  440. * @return an int indicating the layer of the bottommost component in the
  441. * pane, or zero if there are no children
  442. */
  443. public int lowestLayer() {
  444. int count = getComponentCount();
  445. if(count > 0)
  446. return getLayer(getComponent(count-1));
  447. return 0;
  448. }
  449. /**
  450. * Returns the number of children currently in the specified layer.
  451. *
  452. * @param layer an int specifying the layer to check
  453. * @return an int specifying the number of components in that layer
  454. */
  455. public int getComponentCountInLayer(int layer) {
  456. int i, count, curLayer;
  457. int layerCount = 0;
  458. count = getComponentCount();
  459. for(i = 0; i < count; i++) {
  460. curLayer = getLayer(getComponent(i));
  461. if(curLayer == layer) {
  462. layerCount++;
  463. /// Short circut the counting when we have them all
  464. } else if(layerCount > 0 || curLayer < layer) {
  465. break;
  466. }
  467. }
  468. return layerCount;
  469. }
  470. /**
  471. * Returns an array of the components in the specified layer.
  472. *
  473. * @param layer an int specifying the layer to check
  474. * @return an array of Components contained in that layer
  475. */
  476. public Component[] getComponentsInLayer(int layer) {
  477. int i, count, curLayer;
  478. int layerCount = 0;
  479. Component[] results;
  480. results = new Component[getComponentCountInLayer(layer)];
  481. count = getComponentCount();
  482. for(i = 0; i < count; i++) {
  483. curLayer = getLayer(getComponent(i));
  484. if(curLayer == layer) {
  485. results[layerCount++] = getComponent(i);
  486. /// Short circut the counting when we have them all
  487. } else if(layerCount > 0 || curLayer < layer) {
  488. break;
  489. }
  490. }
  491. return results;
  492. }
  493. /**
  494. * Paints this JLayeredPane within the specified graphics context.
  495. *
  496. * @param g the Graphics context within which to paint
  497. */
  498. public void paint(Graphics g) {
  499. if(isOpaque()) {
  500. Rectangle r = g.getClipBounds();
  501. Color c = getBackground();
  502. if(c == null)
  503. c = Color.lightGray;
  504. g.setColor(c);
  505. if (r != null) {
  506. g.fillRect(r.x, r.y, r.width, r.height);
  507. }
  508. else {
  509. g.fillRect(0, 0, getWidth(), getHeight());
  510. }
  511. }
  512. super.paint(g);
  513. }
  514. //////////////////////////////////////////////////////////////////////////////
  515. //// Implementation Details
  516. //////////////////////////////////////////////////////////////////////////////
  517. /**
  518. * Returns the hashtable that maps components to layers.
  519. *
  520. * @return the Hashtable used to map components to their layers
  521. */
  522. protected Hashtable<Component,Integer> getComponentToLayer() {
  523. if(componentToLayer == null)
  524. componentToLayer = new Hashtable<Component,Integer>(4);
  525. return componentToLayer;
  526. }
  527. /**
  528. * Returns the Integer object associated with a specified layer.
  529. *
  530. * @param layer an int specifying the layer
  531. * @return an Integer object for that layer
  532. */
  533. protected Integer getObjectForLayer(int layer) {
  534. Integer layerObj;
  535. switch(layer) {
  536. case 0:
  537. layerObj = DEFAULT_LAYER;
  538. break;
  539. case 100:
  540. layerObj = PALETTE_LAYER;
  541. break;
  542. case 200:
  543. layerObj = MODAL_LAYER;
  544. break;
  545. case 300:
  546. layerObj = POPUP_LAYER;
  547. break;
  548. case 400:
  549. layerObj = DRAG_LAYER;
  550. break;
  551. default:
  552. layerObj = new Integer(layer);
  553. }
  554. return layerObj;
  555. }
  556. /**
  557. * Primitive method that determines the proper location to
  558. * insert a new child based on layer and position requests.
  559. *
  560. * @param layer an int specifying the layer
  561. * @param position an int specifying the position within the layer
  562. * @return an int giving the (absolute) insertion-index
  563. *
  564. * @see #getIndexOf
  565. */
  566. protected int insertIndexForLayer(int layer, int position) {
  567. return insertIndexForLayer(null, layer, position);
  568. }
  569. /**
  570. * This method is an extended version of insertIndexForLayer()
  571. * to support setLayer which uses Container.setZOrder which does
  572. * not remove the component from the containment heirarchy though
  573. * we need to ignore it when calculating the insertion index.
  574. *
  575. * @param comp component to ignore when determining index
  576. * @param layer an int specifying the layer
  577. * @param position an int specifying the position within the layer
  578. * @return an int giving the (absolute) insertion-index
  579. *
  580. * @see #getIndexOf
  581. */
  582. private int insertIndexForLayer(Component comp, int layer, int position) {
  583. int i, count, curLayer;
  584. int layerStart = -1;
  585. int layerEnd = -1;
  586. int componentCount = getComponentCount();
  587. ArrayList<Component> compList =
  588. new ArrayList<Component>(componentCount);
  589. for (int index = 0; index < componentCount; index++) {
  590. if (getComponent(index) != comp) {
  591. compList.add(getComponent(index));
  592. }
  593. }
  594. count = compList.size();
  595. for (i = 0; i < count; i++) {
  596. curLayer = getLayer(compList.get(i));
  597. if (layerStart == -1 && curLayer == layer) {
  598. layerStart = i;
  599. }
  600. if (curLayer < layer) {
  601. if (i == 0) {
  602. // layer is greater than any current layer
  603. // [ ASSERT(layer > highestLayer()) ]
  604. layerStart = 0;
  605. layerEnd = 0;
  606. } else {
  607. layerEnd = i;
  608. }
  609. break;
  610. }
  611. }
  612. // layer requested is lower than any current layer
  613. // [ ASSERT(layer < lowestLayer()) ]
  614. // put it on the bottom of the stack
  615. if (layerStart == -1 && layerEnd == -1)
  616. return count;
  617. // In the case of a single layer entry handle the degenerative cases
  618. if (layerStart != -1 && layerEnd == -1)
  619. layerEnd = count;
  620. if (layerEnd != -1 && layerStart == -1)
  621. layerStart = layerEnd;
  622. // If we are adding to the bottom, return the last element
  623. if (position == -1)
  624. return layerEnd;
  625. // Otherwise make sure the requested position falls in the
  626. // proper range
  627. if (position > -1 && layerStart + position <= layerEnd)
  628. return layerStart + position;
  629. // Otherwise return the end of the layer
  630. return layerEnd;
  631. }
  632. /**
  633. * Returns a string representation of this JLayeredPane. This method
  634. * is intended to be used only for debugging purposes, and the
  635. * content and format of the returned string may vary between
  636. * implementations. The returned string may be empty but may not
  637. * be <code>null</code>.
  638. *
  639. * @return a string representation of this JLayeredPane.
  640. */
  641. protected String paramString() {
  642. String optimizedDrawingPossibleString = (optimizedDrawingPossible ?
  643. "true" : "false");
  644. return super.paramString() +
  645. ",optimizedDrawingPossible=" + optimizedDrawingPossibleString;
  646. }
  647. /////////////////
  648. // Accessibility support
  649. ////////////////
  650. /**
  651. * Gets the AccessibleContext associated with this JLayeredPane.
  652. * For layered panes, the AccessibleContext takes the form of an
  653. * AccessibleJLayeredPane.
  654. * A new AccessibleJLayeredPane instance is created if necessary.
  655. *
  656. * @return an AccessibleJLayeredPane that serves as the
  657. * AccessibleContext of this JLayeredPane
  658. */
  659. public AccessibleContext getAccessibleContext() {
  660. if (accessibleContext == null) {
  661. accessibleContext = new AccessibleJLayeredPane();
  662. }
  663. return accessibleContext;
  664. }
  665. /**
  666. * This class implements accessibility support for the
  667. * <code>JLayeredPane</code> class. It provides an implementation of the
  668. * Java Accessibility API appropriate to layered pane user-interface
  669. * elements.
  670. * <p>
  671. * <strong>Warning:</strong>
  672. * Serialized objects of this class will not be compatible with
  673. * future Swing releases. The current serialization support is
  674. * appropriate for short term storage or RMI between applications running
  675. * the same version of Swing. As of 1.4, support for long term storage
  676. * of all JavaBeans<sup><font size="-2">TM</font></sup>
  677. * has been added to the <code>java.beans</code> package.
  678. * Please see {@link java.beans.XMLEncoder}.
  679. */
  680. protected class AccessibleJLayeredPane extends AccessibleJComponent {
  681. /**
  682. * Get the role of this object.
  683. *
  684. * @return an instance of AccessibleRole describing the role of the
  685. * object
  686. * @see AccessibleRole
  687. */
  688. public AccessibleRole getAccessibleRole() {
  689. return AccessibleRole.LAYERED_PANE;
  690. }
  691. }
  692. }