1. /*
  2. * @(#)Box.java 1.38 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.awt.event.*;
  10. import java.beans.PropertyChangeListener;
  11. import java.util.Locale;
  12. import java.io.Serializable;
  13. import javax.accessibility.*;
  14. /**
  15. * A lightweight container
  16. * that uses a BoxLayout object as its layout manager.
  17. * Box provides several class methods
  18. * that are useful for containers using BoxLayout --
  19. * even non-Box containers.
  20. *
  21. * <p>
  22. *
  23. * The Box class can create several kinds
  24. * of invisible components
  25. * that affect layout:
  26. * glue, struts, and rigid areas.
  27. * If all the components your Box contains
  28. * have a fixed size,
  29. * you might want to use a glue component
  30. * (returned by <code>createGlue</code>)
  31. * to control the components' positions.
  32. * If you need a fixed amount of space between two components,
  33. * try using a strut
  34. * (<code>createHorizontalStrut</code> or <code>createVerticalStrut</code>).
  35. * If you need an invisible component
  36. * that always takes up the same amount of space,
  37. * get it by invoking <code>createRigidArea</code>.
  38. * <p>
  39. * <strong>Warning:</strong>
  40. * Serialized objects of this class will not be compatible with
  41. * future Swing releases. The current serialization support is
  42. * appropriate for short term storage or RMI between applications running
  43. * the same version of Swing. As of 1.4, support for long term storage
  44. * of all JavaBeans<sup><font size="-2">TM</font></sup>
  45. * has been added to the <code>java.beans</code> package.
  46. * Please see {@link java.beans.XMLEncoder}.
  47. *
  48. * @see BoxLayout
  49. *
  50. * @author Timothy Prinzing
  51. * @version 1.38 01/23/03
  52. */
  53. public class Box extends JComponent implements Accessible {
  54. /**
  55. * Creates a <code>Box</code> that displays its components
  56. * along the the specified axis.
  57. *
  58. * @param axis can be either <code>BoxLayout.X_AXIS</code>
  59. * (to display components from left to right) or
  60. * <code>BoxLayout.Y_AXIS</code>
  61. * (to display them from top to bottom)
  62. * @see #createHorizontalBox
  63. * @see #createVerticalBox
  64. */
  65. public Box(int axis) {
  66. super();
  67. super.setLayout(new BoxLayout(this, axis));
  68. }
  69. /**
  70. * Creates a <code>Box</code> that displays its components
  71. * from left to right.
  72. *
  73. * @return the box
  74. */
  75. public static Box createHorizontalBox() {
  76. return new Box(BoxLayout.X_AXIS);
  77. }
  78. /**
  79. * Creates a <code>Box</code> that displays its components
  80. * from top to bottom.
  81. *
  82. * @return the box
  83. */
  84. public static Box createVerticalBox() {
  85. return new Box(BoxLayout.Y_AXIS);
  86. }
  87. /**
  88. * Creates an invisible component that's always the specified size.
  89. * <!-- WHEN WOULD YOU USE THIS AS OPPOSED TO A STRUT? -->
  90. *
  91. * @param d the dimensions of the invisible component
  92. * @return the component
  93. * @see #createGlue
  94. * @see #createHorizontalStrut
  95. * @see #createVerticalStrut
  96. */
  97. public static Component createRigidArea(Dimension d) {
  98. return new Filler(d, d, d);
  99. }
  100. /**
  101. * Creates an invisible, fixed-width component.
  102. * In a horizontal box,
  103. * you typically use this method
  104. * to force a certain amount of space between two components.
  105. * In a vertical box,
  106. * you might use this method
  107. * to force the box to be at least the specified width.
  108. * The invisible component has no height
  109. * unless excess space is available,
  110. * in which case it takes its share of available space,
  111. * just like any other component that has no maximum height.
  112. *
  113. * @param width the width of the invisible component, in pixels >= 0
  114. * @return the component
  115. * @see #createVerticalStrut
  116. * @see #createGlue
  117. * @see #createRigidArea
  118. */
  119. public static Component createHorizontalStrut(int width) {
  120. // PENDING(jeff) change to Integer.MAX_VALUE. This hasn't been done
  121. // to date because BoxLayout alignment breaks.
  122. return new Filler(new Dimension(width,0), new Dimension(width,0),
  123. new Dimension(width, Short.MAX_VALUE));
  124. }
  125. /**
  126. * Creates an invisible, fixed-height component.
  127. * In a vertical box,
  128. * you typically use this method
  129. * to force a certain amount of space between two components.
  130. * In a horizontal box,
  131. * you might use this method
  132. * to force the box to be at least the specified height.
  133. * The invisible component has no width
  134. * unless excess space is available,
  135. * in which case it takes its share of available space,
  136. * just like any other component that has no maximum width.
  137. *
  138. * @param height the height of the invisible component, in pixels >= 0
  139. * @return the component
  140. * @see #createHorizontalStrut
  141. * @see #createGlue
  142. * @see #createRigidArea
  143. */
  144. public static Component createVerticalStrut(int height) {
  145. // PENDING(jeff) change to Integer.MAX_VALUE. This hasn't been done
  146. // to date because BoxLayout alignment breaks.
  147. return new Filler(new Dimension(0,height), new Dimension(0,height),
  148. new Dimension(Short.MAX_VALUE, height));
  149. }
  150. /**
  151. * Creates an invisible "glue" component
  152. * that can be useful in a Box
  153. * whose visible components have a maximum width
  154. * (for a horizontal box)
  155. * or height (for a vertical box).
  156. * You can think of the glue component
  157. * as being a gooey substance
  158. * that expands as much as necessary
  159. * to fill the space between its neighboring components.
  160. *
  161. * <p>
  162. *
  163. * For example, suppose you have
  164. * a horizontal box that contains two fixed-size components.
  165. * If the box gets extra space,
  166. * the fixed-size components won't become larger,
  167. * so where does the extra space go?
  168. * Without glue,
  169. * the extra space goes to the right of the second component.
  170. * If you put glue between the fixed-size components,
  171. * then the extra space goes there.
  172. * If you put glue before the first fixed-size component,
  173. * the extra space goes there,
  174. * and the fixed-size components are shoved against the right
  175. * edge of the box.
  176. * If you put glue before the first fixed-size component
  177. * and after the second fixed-size component,
  178. * the fixed-size components are centered in the box.
  179. *
  180. * <p>
  181. *
  182. * To use glue,
  183. * call <code>Box.createGlue</code>
  184. * and add the returned component to a container.
  185. * The glue component has no minimum or preferred size,
  186. * so it takes no space unless excess space is available.
  187. * If excess space is available,
  188. * then the glue component takes its share of available
  189. * horizontal or vertical space,
  190. * just like any other component that has no maximum width or height.
  191. *
  192. * @return the component
  193. */
  194. public static Component createGlue() {
  195. // PENDING(jeff) change to Integer.MAX_VALUE. This hasn't been done
  196. // to date because BoxLayout alignment breaks.
  197. return new Filler(new Dimension(0,0), new Dimension(0,0),
  198. new Dimension(Short.MAX_VALUE, Short.MAX_VALUE));
  199. }
  200. /**
  201. * Creates a horizontal glue component.
  202. *
  203. * @return the component
  204. */
  205. public static Component createHorizontalGlue() {
  206. // PENDING(jeff) change to Integer.MAX_VALUE. This hasn't been done
  207. // to date because BoxLayout alignment breaks.
  208. return new Filler(new Dimension(0,0), new Dimension(0,0),
  209. new Dimension(Short.MAX_VALUE, 0));
  210. }
  211. /**
  212. * Creates a vertical glue component.
  213. *
  214. * @return the component
  215. */
  216. public static Component createVerticalGlue() {
  217. // PENDING(jeff) change to Integer.MAX_VALUE. This hasn't been done
  218. // to date because BoxLayout alignment breaks.
  219. return new Filler(new Dimension(0,0), new Dimension(0,0),
  220. new Dimension(0, Short.MAX_VALUE));
  221. }
  222. /**
  223. * Throws an AWTError, since a Box can use only a BoxLayout.
  224. *
  225. * @param l the layout manager to use
  226. */
  227. public void setLayout(LayoutManager l) {
  228. throw new AWTError("Illegal request");
  229. }
  230. /**
  231. * An implementation of a lightweight component that participates in
  232. * layout but has no view.
  233. * <p>
  234. * <strong>Warning:</strong>
  235. * Serialized objects of this class will not be compatible with
  236. * future Swing releases. The current serialization support is
  237. * appropriate for short term storage or RMI between applications running
  238. * the same version of Swing. As of 1.4, support for long term storage
  239. * of all JavaBeans<sup><font size="-2">TM</font></sup>
  240. * has been added to the <code>java.beans</code> package.
  241. * Please see {@link java.beans.XMLEncoder}.
  242. */
  243. public static class Filler extends JComponent implements Accessible {
  244. /**
  245. * Constructor to create shape with the given size ranges.
  246. *
  247. * @param min Minimum size
  248. * @param pref Preferred size
  249. * @param max Maximum size
  250. */
  251. public Filler(Dimension min, Dimension pref, Dimension max) {
  252. reqMin = min;
  253. reqPref = pref;
  254. reqMax = max;
  255. }
  256. /**
  257. * Change the size requests for this shape. An invalidate() is
  258. * propagated upward as a result so that layout will eventually
  259. * happen with using the new sizes.
  260. *
  261. * @param min Value to return for getMinimumSize
  262. * @param pref Value to return for getPreferredSize
  263. * @param max Value to return for getMaximumSize
  264. */
  265. public void changeShape(Dimension min, Dimension pref, Dimension max) {
  266. reqMin = min;
  267. reqPref = pref;
  268. reqMax = max;
  269. invalidate();
  270. }
  271. // ---- Component methods ------------------------------------------
  272. /**
  273. * Returns the minimum size of the component.
  274. *
  275. * @return the size
  276. */
  277. public Dimension getMinimumSize() {
  278. return reqMin;
  279. }
  280. /**
  281. * Returns the preferred size of the component.
  282. *
  283. * @return the size
  284. */
  285. public Dimension getPreferredSize() {
  286. return reqPref;
  287. }
  288. /**
  289. * Returns the maximum size of the component.
  290. *
  291. * @return the size
  292. */
  293. public Dimension getMaximumSize() {
  294. return reqMax;
  295. }
  296. // ---- member variables ---------------------------------------
  297. private Dimension reqMin;
  298. private Dimension reqPref;
  299. private Dimension reqMax;
  300. /////////////////
  301. // Accessibility support for Box$Filler
  302. ////////////////
  303. /**
  304. * The currently set AccessibleContext object.
  305. */
  306. protected AccessibleContext accessibleContext = null;
  307. /**
  308. * Gets the AccessibleContext associated with this Box.Filler.
  309. * For box fillers, the AccessibleContext takes the form of an
  310. * AccessibleBoxFiller.
  311. * A new AccessibleAWTBoxFiller instance is created if necessary.
  312. *
  313. * @return an AccessibleBoxFiller that serves as the
  314. * AccessibleContext of this Box.Filler.
  315. */
  316. public AccessibleContext getAccessibleContext() {
  317. if (accessibleContext == null) {
  318. accessibleContext = new AccessibleBoxFiller();
  319. }
  320. return accessibleContext;
  321. }
  322. /**
  323. * This class implements accessibility support for the
  324. * <code>Box.Filler</code> class.
  325. */
  326. protected class AccessibleBoxFiller extends AccessibleAWTComponent {
  327. // AccessibleContext methods
  328. //
  329. /**
  330. * Gets the role of this object.
  331. *
  332. * @return an instance of AccessibleRole describing the role of
  333. * the object (AccessibleRole.FILLER)
  334. * @see AccessibleRole
  335. */
  336. public AccessibleRole getAccessibleRole() {
  337. return AccessibleRole.FILLER;
  338. }
  339. }
  340. }
  341. /////////////////
  342. // Accessibility support for Box
  343. ////////////////
  344. /**
  345. * The currently set AccessibleContext object.
  346. */
  347. protected AccessibleContext accessibleContext = null;
  348. /**
  349. * Gets the AccessibleContext associated with this Box.
  350. * For boxes, the AccessibleContext takes the form of an
  351. * AccessibleBox.
  352. * A new AccessibleAWTBox instance is created if necessary.
  353. *
  354. * @return an AccessibleBox that serves as the
  355. * AccessibleContext of this Box
  356. */
  357. public AccessibleContext getAccessibleContext() {
  358. if (accessibleContext == null) {
  359. accessibleContext = new AccessibleBox();
  360. }
  361. return accessibleContext;
  362. }
  363. /**
  364. * This class implements accessibility support for the
  365. * <code>Box</code> class.
  366. */
  367. protected class AccessibleBox extends AccessibleAWTContainer {
  368. // AccessibleContext methods
  369. //
  370. /**
  371. * Gets the role of this object.
  372. *
  373. * @return an instance of AccessibleRole describing the role of the
  374. * object (AccessibleRole.FILLER)
  375. * @see AccessibleRole
  376. */
  377. public AccessibleRole getAccessibleRole() {
  378. return AccessibleRole.FILLER;
  379. }
  380. } // inner class AccessibleBox
  381. }