1. /*
  2. * @(#)OverlayLayout.java 1.25 03/01/23
  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.awt.*;
  9. import java.io.Serializable;
  10. /**
  11. * A layout manager to arrange components over the top
  12. * of each other. The requested size of the container
  13. * will be the largest requested size of the children,
  14. * taking alignment needs into consideration.
  15. *
  16. * The alignment is based upon what is needed to properly
  17. * fit the children in the allocation area. The children
  18. * will be placed such that their alignment points are all
  19. * on top of each other.
  20. * <p>
  21. * <strong>Warning:</strong>
  22. * Serialized objects of this class will not be compatible with
  23. * future Swing releases. The current serialization support is
  24. * appropriate for short term storage or RMI between applications running
  25. * the same version of Swing. As of 1.4, support for long term storage
  26. * of all JavaBeans<sup><font size="-2">TM</font></sup>
  27. * has been added to the <code>java.beans</code> package.
  28. * Please see {@link java.beans.XMLEncoder}.
  29. *
  30. * @version 1.25 01/23/03
  31. * @author Timothy Prinzing
  32. */
  33. public class OverlayLayout implements LayoutManager2,Serializable {
  34. /**
  35. * Constructs a layout manager that performs overlay
  36. * arrangement of the children. The layout manager
  37. * created is dedicated to the given container.
  38. *
  39. * @param target the container to do layout against
  40. */
  41. public OverlayLayout(Container target) {
  42. this.target = target;
  43. }
  44. /**
  45. * Indicates a child has changed its layout related information,
  46. * which causes any cached calculations to be flushed.
  47. *
  48. * @param target the container
  49. */
  50. public void invalidateLayout(Container target) {
  51. checkContainer(target);
  52. xChildren = null;
  53. yChildren = null;
  54. xTotal = null;
  55. yTotal = null;
  56. }
  57. /**
  58. * Adds the specified component to the layout. Used by
  59. * this class to know when to invalidate layout.
  60. *
  61. * @param name the name of the component
  62. * @param comp the the component to be added
  63. */
  64. public void addLayoutComponent(String name, Component comp) {
  65. invalidateLayout(comp.getParent());
  66. }
  67. /**
  68. * Removes the specified component from the layout. Used by
  69. * this class to know when to invalidate layout.
  70. *
  71. * @param comp the component to remove
  72. */
  73. public void removeLayoutComponent(Component comp) {
  74. invalidateLayout(comp.getParent());
  75. }
  76. /**
  77. * Adds the specified component to the layout, using the specified
  78. * constraint object. Used by this class to know when to invalidate
  79. * layout.
  80. *
  81. * @param comp the component to be added
  82. * @param constraints where/how the component is added to the layout.
  83. */
  84. public void addLayoutComponent(Component comp, Object constraints) {
  85. invalidateLayout(comp.getParent());
  86. }
  87. /**
  88. * Returns the preferred dimensions for this layout given the components
  89. * in the specified target container. Recomputes the layout if it
  90. * has been invalidated. Factors in the current inset setting returned
  91. * by getInsets().
  92. *
  93. * @param target the component which needs to be laid out
  94. * @return a Dimension object containing the preferred dimensions
  95. * @see #minimumLayoutSize
  96. */
  97. public Dimension preferredLayoutSize(Container target) {
  98. checkContainer(target);
  99. checkRequests();
  100. Dimension size = new Dimension(xTotal.preferred, yTotal.preferred);
  101. Insets insets = target.getInsets();
  102. size.width += insets.left + insets.right;
  103. size.height += insets.top + insets.bottom;
  104. return size;
  105. }
  106. /**
  107. * Returns the minimum dimensions needed to lay out the components
  108. * contained in the specified target container. Recomputes the layout
  109. * if it has been invalidated, and factors in the current inset setting.
  110. *
  111. * @param target the component which needs to be laid out
  112. * @return a Dimension object containing the minimum dimensions
  113. * @see #preferredLayoutSize
  114. */
  115. public Dimension minimumLayoutSize(Container target) {
  116. checkContainer(target);
  117. checkRequests();
  118. Dimension size = new Dimension(xTotal.minimum, yTotal.minimum);
  119. Insets insets = target.getInsets();
  120. size.width += insets.left + insets.right;
  121. size.height += insets.top + insets.bottom;
  122. return size;
  123. }
  124. /**
  125. * Returns the minimum dimensions needed to lay out the components
  126. * contained in the specified target container. Recomputes the
  127. * layout if it has been invalidated, and factors in the inset setting
  128. * returned by getInset().
  129. *
  130. * @param target the component which needs to be laid out
  131. * @return a Dimension object containing the maximum dimensions
  132. * @see #preferredLayoutSize
  133. */
  134. public Dimension maximumLayoutSize(Container target) {
  135. checkContainer(target);
  136. checkRequests();
  137. Dimension size = new Dimension(xTotal.maximum, yTotal.maximum);
  138. Insets insets = target.getInsets();
  139. size.width += insets.left + insets.right;
  140. size.height += insets.top + insets.bottom;
  141. return size;
  142. }
  143. /**
  144. * Returns the alignment along the x axis for the container.
  145. *
  146. * @param target the container
  147. * @return the alignment >= 0.0f && <= 1.0f
  148. */
  149. public float getLayoutAlignmentX(Container target) {
  150. checkContainer(target);
  151. checkRequests();
  152. return xTotal.alignment;
  153. }
  154. /**
  155. * Returns the alignment along the y axis for the container.
  156. *
  157. * @param target the container
  158. * @return the alignment >= 0.0f && <= 1.0f
  159. */
  160. public float getLayoutAlignmentY(Container target) {
  161. checkContainer(target);
  162. checkRequests();
  163. return yTotal.alignment;
  164. }
  165. /**
  166. * Called by the AWT when the specified container needs to be laid out.
  167. *
  168. * @param target the container to lay out
  169. *
  170. * @exception AWTError if the target isn't the container specified to the
  171. * constructor
  172. */
  173. public void layoutContainer(Container target) {
  174. checkContainer(target);
  175. checkRequests();
  176. int nChildren = target.getComponentCount();
  177. int[] xOffsets = new int[nChildren];
  178. int[] xSpans = new int[nChildren];
  179. int[] yOffsets = new int[nChildren];
  180. int[] ySpans = new int[nChildren];
  181. // determine the child placements
  182. Dimension alloc = target.getSize();
  183. Insets in = target.getInsets();
  184. alloc.width -= in.left + in.right;
  185. alloc.height -= in.top + in.bottom;
  186. SizeRequirements.calculateAlignedPositions(alloc.width, xTotal,
  187. xChildren, xOffsets,
  188. xSpans);
  189. SizeRequirements.calculateAlignedPositions(alloc.height, yTotal,
  190. yChildren, yOffsets,
  191. ySpans);
  192. // flush changes to the container
  193. for (int i = 0; i < nChildren; i++) {
  194. Component c = target.getComponent(i);
  195. c.setBounds(in.left + xOffsets[i], in.top + yOffsets[i],
  196. xSpans[i], ySpans[i]);
  197. }
  198. }
  199. void checkContainer(Container target) {
  200. if (this.target != target) {
  201. throw new AWTError("OverlayLayout can't be shared");
  202. }
  203. }
  204. void checkRequests() {
  205. if (xChildren == null || yChildren == null) {
  206. // The requests have been invalidated... recalculate
  207. // the request information.
  208. int n = target.getComponentCount();
  209. xChildren = new SizeRequirements[n];
  210. yChildren = new SizeRequirements[n];
  211. for (int i = 0; i < n; i++) {
  212. Component c = target.getComponent(i);
  213. Dimension min = c.getMinimumSize();
  214. Dimension typ = c.getPreferredSize();
  215. Dimension max = c.getMaximumSize();
  216. xChildren[i] = new SizeRequirements(min.width, typ.width,
  217. max.width,
  218. c.getAlignmentX());
  219. yChildren[i] = new SizeRequirements(min.height, typ.height,
  220. max.height,
  221. c.getAlignmentY());
  222. }
  223. xTotal = SizeRequirements.getAlignedSizeRequirements(xChildren);
  224. yTotal = SizeRequirements.getAlignedSizeRequirements(yChildren);
  225. }
  226. }
  227. private Container target;
  228. private SizeRequirements[] xChildren;
  229. private SizeRequirements[] yChildren;
  230. private SizeRequirements xTotal;
  231. private SizeRequirements yTotal;
  232. }