1. /*
  2. * @(#)OverlayLayout.java 1.27 03/12/19
  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.*;
  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.27 12/19/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 maximum 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 <code>getInset</code>.
  129. *
  130. * @param target the component that needs to be laid out
  131. * @return a <code>Dimension</code> object containing the maximum
  132. * dimensions
  133. * @see #preferredLayoutSize
  134. */
  135. public Dimension maximumLayoutSize(Container target) {
  136. checkContainer(target);
  137. checkRequests();
  138. Dimension size = new Dimension(xTotal.maximum, yTotal.maximum);
  139. Insets insets = target.getInsets();
  140. size.width += insets.left + insets.right;
  141. size.height += insets.top + insets.bottom;
  142. return size;
  143. }
  144. /**
  145. * Returns the alignment along the x axis for the container.
  146. *
  147. * @param target the container
  148. * @return the alignment >= 0.0f && <= 1.0f
  149. */
  150. public float getLayoutAlignmentX(Container target) {
  151. checkContainer(target);
  152. checkRequests();
  153. return xTotal.alignment;
  154. }
  155. /**
  156. * Returns the alignment along the y axis for the container.
  157. *
  158. * @param target the container
  159. * @return the alignment >= 0.0f && <= 1.0f
  160. */
  161. public float getLayoutAlignmentY(Container target) {
  162. checkContainer(target);
  163. checkRequests();
  164. return yTotal.alignment;
  165. }
  166. /**
  167. * Called by the AWT when the specified container needs to be laid out.
  168. *
  169. * @param target the container to lay out
  170. *
  171. * @exception AWTError if the target isn't the container specified to the
  172. * constructor
  173. */
  174. public void layoutContainer(Container target) {
  175. checkContainer(target);
  176. checkRequests();
  177. int nChildren = target.getComponentCount();
  178. int[] xOffsets = new int[nChildren];
  179. int[] xSpans = new int[nChildren];
  180. int[] yOffsets = new int[nChildren];
  181. int[] ySpans = new int[nChildren];
  182. // determine the child placements
  183. Dimension alloc = target.getSize();
  184. Insets in = target.getInsets();
  185. alloc.width -= in.left + in.right;
  186. alloc.height -= in.top + in.bottom;
  187. SizeRequirements.calculateAlignedPositions(alloc.width, xTotal,
  188. xChildren, xOffsets,
  189. xSpans);
  190. SizeRequirements.calculateAlignedPositions(alloc.height, yTotal,
  191. yChildren, yOffsets,
  192. ySpans);
  193. // flush changes to the container
  194. for (int i = 0; i < nChildren; i++) {
  195. Component c = target.getComponent(i);
  196. c.setBounds(in.left + xOffsets[i], in.top + yOffsets[i],
  197. xSpans[i], ySpans[i]);
  198. }
  199. }
  200. void checkContainer(Container target) {
  201. if (this.target != target) {
  202. throw new AWTError("OverlayLayout can't be shared");
  203. }
  204. }
  205. void checkRequests() {
  206. if (xChildren == null || yChildren == null) {
  207. // The requests have been invalidated... recalculate
  208. // the request information.
  209. int n = target.getComponentCount();
  210. xChildren = new SizeRequirements[n];
  211. yChildren = new SizeRequirements[n];
  212. for (int i = 0; i < n; i++) {
  213. Component c = target.getComponent(i);
  214. Dimension min = c.getMinimumSize();
  215. Dimension typ = c.getPreferredSize();
  216. Dimension max = c.getMaximumSize();
  217. xChildren[i] = new SizeRequirements(min.width, typ.width,
  218. max.width,
  219. c.getAlignmentX());
  220. yChildren[i] = new SizeRequirements(min.height, typ.height,
  221. max.height,
  222. c.getAlignmentY());
  223. }
  224. xTotal = SizeRequirements.getAlignedSizeRequirements(xChildren);
  225. yTotal = SizeRequirements.getAlignedSizeRequirements(yChildren);
  226. }
  227. }
  228. private Container target;
  229. private SizeRequirements[] xChildren;
  230. private SizeRequirements[] yChildren;
  231. private SizeRequirements xTotal;
  232. private SizeRequirements yTotal;
  233. }