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