1. /*
  2. * @(#)JSplitPane.java 1.52 01/11/29
  3. *
  4. * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package javax.swing;
  8. import javax.swing.border.Border;
  9. import javax.swing.plaf.*;
  10. import javax.accessibility.*;
  11. import java.awt.*;
  12. import java.io.ObjectOutputStream;
  13. import java.io.ObjectInputStream;
  14. import java.io.IOException;
  15. /**
  16. * JSplitPane is used to divide two (and only two) Components. The two
  17. * Components are graphically divided based on the look and feel
  18. * implementation, and the two Components can then be interactively
  19. * resized by the user.
  20. * <p>
  21. * The two Components can be aligned left to right using
  22. * <code>JSplitPane.HORIZONTAL_SPLIT</code>, or top to bottom using
  23. * <code>JSplitPane.VERTICAL_SPLIT</code>.
  24. * The preferred way to change the size of the Components is to invoke
  25. * <code>setDividerLocation</code> where <code>location</code> is either
  26. * the new x or y position, depending on the orientation of the
  27. * JSplitPane. If one component changes, JSplitPane also attempts to
  28. * reposition the other component.
  29. * <p>
  30. * To resize the Components to their preferred sizes invoke
  31. * <code>resetToPreferredSizes</code>.
  32. * <p>
  33. * When the user is resizing the Components the minimum size of the
  34. * Components is used to determine the maximum/minimum position the
  35. * Components can be set to. So that if the minimum size of the two
  36. * components is greater than the size of the splitpane the divider
  37. * will not allow you to resize it. To alter the minimum size of a
  38. * JComponent, see {@link JComponent#setMinimumSize}.
  39. * <p>
  40. * For the keyboard keys used by this component in the standard Look and
  41. * Feel (L&F) renditions, see the
  42. * <a href="doc-files/Key-Index.html#JSplitPane">JSplitPane</a> key
  43. * assignments.
  44. * <p>
  45. * <strong>Warning:</strong>
  46. * Serialized objects of this class will not be compatible with
  47. * future Swing releases. The current serialization support is appropriate
  48. * for short term storage or RMI between applications running the same
  49. * version of Swing. A future release of Swing will provide support for
  50. * long term persistence.
  51. *
  52. * @see #setDividerLocation
  53. * @see #resetToPreferredSizes
  54. *
  55. * @version 1.52 11/29/01
  56. * @author Scott Violet
  57. */
  58. public class JSplitPane extends JComponent implements Accessible
  59. {
  60. /**
  61. * @see #getUIClassID
  62. * @see #readObject
  63. */
  64. private static final String uiClassID = "SplitPaneUI";
  65. /**
  66. * Vertical split indicates the Components are split along the
  67. * y axis, eg the two Components will be split one on top of the other.
  68. */
  69. public final static int VERTICAL_SPLIT = 0;
  70. /**
  71. * Horizontal split indicates the Components are split along the
  72. * x axis, eg the two Components will be split one to the left of the
  73. * other.
  74. */
  75. public final static int HORIZONTAL_SPLIT = 1;
  76. /**
  77. * Used to add a Component to the left of the other Component.
  78. */
  79. public final static String LEFT = "left";
  80. /**
  81. * Used to add a Component to the right of the other Component.
  82. */
  83. public final static String RIGHT = "right";
  84. /**
  85. * Used to add a Component above the other Component.
  86. */
  87. public final static String TOP = "top";
  88. /**
  89. * Used to add a Component below the other Component.
  90. */
  91. public final static String BOTTOM = "bottom";
  92. /**
  93. * Used to add a Component that will represent the divider.
  94. */
  95. public final static String DIVIDER = "divider";
  96. /**
  97. * Bound property name for orientation (horizontal or vertical).
  98. */
  99. public final static String ORIENTATION_PROPERTY = "orientation";
  100. /**
  101. * Bound property name for continuousLayout.
  102. */
  103. public final static String CONTINUOUS_LAYOUT_PROPERTY = "continuousLayout";
  104. /**
  105. * Bound property name for border.
  106. */
  107. public final static String DIVIDER_SIZE_PROPERTY = "dividerSize";
  108. /**
  109. * Bound property for oneTouchExpandable.
  110. */
  111. public final static String ONE_TOUCH_EXPANDABLE_PROPERTY =
  112. "oneTouchExpandable";
  113. /**
  114. * Bound property for lastLocation.
  115. */
  116. public final static String LAST_DIVIDER_LOCATION_PROPERTY =
  117. "lastDividerLocation";
  118. /**
  119. * How the views are split.
  120. */
  121. protected int orientation;
  122. /**
  123. * Whether or not the views are continuously redisplayed while
  124. * resizing.
  125. */
  126. protected boolean continuousLayout;
  127. /**
  128. * The left or top component.
  129. */
  130. protected Component leftComponent;
  131. /**
  132. * The right or bottom component.
  133. */
  134. protected Component rightComponent;
  135. /**
  136. * Size of the divider.
  137. */
  138. protected int dividerSize;
  139. /**
  140. * Is a little widget provided to quickly expand/collapse the
  141. * split pane?
  142. */
  143. protected boolean oneTouchExpandable;
  144. /**
  145. * Previous location of the split pane.
  146. */
  147. protected int lastDividerLocation;
  148. /**
  149. * Returns a new JSplitPane configured to arrange the child
  150. * components side-by-side horizontally with no continuous
  151. * layout, using two buttons for the compoents.
  152. */
  153. public JSplitPane() {
  154. this(JSplitPane.HORIZONTAL_SPLIT, false, new JButton("left button"),
  155. new JButton("right button"));
  156. }
  157. /**
  158. * Returns a new JSplitPane configured with the specified orientation
  159. * and no continuous layout.
  160. *
  161. * @param newOrientation an int specifying the horizontal or vertical
  162. * orientation
  163. */
  164. public JSplitPane(int newOrientation) {
  165. this(newOrientation, false);
  166. }
  167. /**
  168. * Returns a new JSplitPane with the specified orientation and
  169. * redrawing style.
  170. *
  171. * @param newOrientation an int specifying the horizontal or vertical
  172. * orientation
  173. * @param newContinuousLayout a boolean, true for the components to
  174. * redraw continuously as the divider changes position, false
  175. * to wait until the divider position stops changing to redraw
  176. */
  177. public JSplitPane(int newOrientation,
  178. boolean newContinuousLayout) {
  179. this(newOrientation, newContinuousLayout, null, null);
  180. }
  181. /**
  182. * Returns a new JSplitPane with the specified orientation and
  183. * with the specifiied components that does not do continuous
  184. * redrawing.
  185. *
  186. * @param newOrientation an int specifying the horizontal or vertical
  187. * orientation
  188. * @param newContinuousLayout a boolean, true for the components to
  189. * redraw continuously as the divider changes position, false
  190. * to wait until the divider position stops changing to redraw
  191. * @param newLeftComponent the Component that will appear on the left
  192. * of a horizontally-split pane, or at the top of a
  193. * vertically-split pane.
  194. */
  195. public JSplitPane(int newOrientation,
  196. Component newLeftComponent,
  197. Component newRightComponent){
  198. this(newOrientation, false, newLeftComponent, newRightComponent);
  199. }
  200. /**
  201. * Returns a new JSplitPane with the specified orientation and
  202. * redrawing style, and with the specified components.
  203. *
  204. * @param newOrientation an int specifying the horizontal or vertical
  205. * orientation
  206. * @param newContinuousLayout a boolean, true for the components to
  207. * redraw continuously as the divider changes position, false
  208. * to wait until the divider position stops changing to redraw
  209. * @param newLeftComponent the Component that will appear on the left
  210. * of a horizontally-split pane, or at the top of a
  211. * vertically-split pane.
  212. */
  213. public JSplitPane(int newOrientation,
  214. boolean newContinuousLayout,
  215. Component newLeftComponent,
  216. Component newRightComponent){
  217. super();
  218. setLayout(null);
  219. setOpaque(true);
  220. orientation = newOrientation;
  221. if (orientation != HORIZONTAL_SPLIT && orientation != VERTICAL_SPLIT)
  222. throw new IllegalArgumentException("cannot create JSplitPane, " +
  223. "orientation must be one of " +
  224. "JSplitPane.HORIZONTAL_SPLIT " +
  225. "or JSplitPane.VERTICAL_SPLIT");
  226. continuousLayout = newContinuousLayout;
  227. if (newLeftComponent != null)
  228. setLeftComponent(newLeftComponent);
  229. if (newRightComponent != null)
  230. setRightComponent(newRightComponent);
  231. updateUI();
  232. }
  233. /**
  234. * Sets the L&F object that renders this component.
  235. *
  236. * @param ui the SplitPaneUI L&F object
  237. * @see UIDefaults#getUI
  238. */
  239. public void setUI(SplitPaneUI ui) {
  240. if ((SplitPaneUI)this.ui != ui) {
  241. super.setUI(ui);
  242. revalidate();
  243. }
  244. }
  245. /**
  246. * Returns the SplitPaneUI that is providing the current look and
  247. * feel.
  248. *
  249. * @return the SplitPaneUI object that renders this component
  250. * @beaninfo
  251. * expert: true
  252. * description: The L&F object that renders this component.
  253. */
  254. public SplitPaneUI getUI() {
  255. return (SplitPaneUI)ui;
  256. }
  257. /**
  258. * Notification from the UIManager that the L&F has changed.
  259. * Replaces the current UI object with the latest version from the
  260. * UIManager.
  261. *
  262. * @see JComponent#updateUI
  263. */
  264. public void updateUI() {
  265. setUI((SplitPaneUI)UIManager.getUI(this));
  266. revalidate();
  267. }
  268. /**
  269. * Returns the name of the L&F class that renders this component.
  270. *
  271. * @return "SplitPaneUI"
  272. * @see JComponent#getUIClassID
  273. * @see UIDefaults#getUI
  274. * @beaninfo
  275. * expert: true
  276. * description: A string that specifies the name of the L&F class.
  277. */
  278. public String getUIClassID() {
  279. return uiClassID;
  280. }
  281. /**
  282. * Sets the size of the divider.
  283. *
  284. * @param newSize an int giving the size of the divider in pixels
  285. * @beaninfo
  286. * bound: true
  287. * description: The size of the divider.
  288. */
  289. public void setDividerSize(int newSize) {
  290. int oldSize = dividerSize;
  291. if (oldSize != newSize) {
  292. dividerSize = newSize;
  293. firePropertyChange(DIVIDER_SIZE_PROPERTY, oldSize, newSize);
  294. }
  295. }
  296. /**
  297. * Returns the size of the divider.
  298. *
  299. * @return an int giving the size of the divider in pixels
  300. */
  301. public int getDividerSize() {
  302. return dividerSize;
  303. }
  304. /**
  305. * Sets the component to the left (or above) the divider.
  306. *
  307. * @param comp the Component to display in that position
  308. */
  309. public void setLeftComponent(Component comp) {
  310. if (comp == null) {
  311. if (leftComponent != null) {
  312. remove(leftComponent);
  313. leftComponent = null;
  314. }
  315. } else {
  316. add(comp, JSplitPane.LEFT);
  317. }
  318. }
  319. /**
  320. * Returns the component to the left (or above) the divider.
  321. *
  322. * @return the Component displayed in that position
  323. * @beaninfo
  324. * preferred: true
  325. * description: The component to the left (or above) the divider.
  326. */
  327. public Component getLeftComponent() {
  328. return leftComponent;
  329. }
  330. /**
  331. * Sets the component above, or to the left of the divider.
  332. *
  333. * @param comp the Component to display in that position
  334. * @beaninfo
  335. * description: The component above, or to the left of the divider.
  336. */
  337. public void setTopComponent(Component comp) {
  338. setLeftComponent(comp);
  339. }
  340. /**
  341. * Returns the component above, or to the left of the divider.
  342. *
  343. * @return the Component displayed in that position
  344. */
  345. public Component getTopComponent() {
  346. return leftComponent;
  347. }
  348. /**
  349. * Sets the component to the right (or below) the divider.
  350. *
  351. * @param comp the Component to display in that position
  352. * @beaninfo
  353. * preferred: true
  354. * description: The component to the right (or below) the divider.
  355. */
  356. public void setRightComponent(Component comp) {
  357. if (comp == null) {
  358. if (rightComponent != null) {
  359. remove(rightComponent);
  360. rightComponent = null;
  361. }
  362. } else {
  363. add(comp, JSplitPane.RIGHT);
  364. }
  365. }
  366. /**
  367. * Returns the component to the right (or below) the divider.
  368. *
  369. * @return the Component displayed in that position
  370. */
  371. public Component getRightComponent() {
  372. return rightComponent;
  373. }
  374. /**
  375. * Sets the component below, or to the right of the divider.
  376. *
  377. * @param comp the Component to display in that position
  378. * @beaninfo
  379. * description: The component below, or to the right of the divider.
  380. */
  381. public void setBottomComponent(Component comp) {
  382. setRightComponent(comp);
  383. }
  384. /**
  385. * Returns the component below, or to the right of the divider.
  386. *
  387. * @return the Component displayed in that position
  388. */
  389. public Component getBottomComponent() {
  390. return rightComponent;
  391. }
  392. /**
  393. * Determines whether the JSplitPane provides a UI widget
  394. * on the divider to quickly expand/collapse the divider.
  395. *
  396. * @param newValue a boolean, where true means to provide a
  397. * collapse/expand widget
  398. * @beaninfo
  399. * bound: true
  400. * description: UI widget on the divider to quickly
  401. * expand/collapse the divider.
  402. */
  403. public void setOneTouchExpandable(boolean newValue) {
  404. boolean oldValue = oneTouchExpandable;
  405. oneTouchExpandable = newValue;
  406. firePropertyChange(ONE_TOUCH_EXPANDABLE_PROPERTY, oldValue, newValue);
  407. repaint();
  408. }
  409. /**
  410. * Returns true if the pane provides a UI widget to collapse/expand
  411. * the divider.
  412. *
  413. * @return true if the split pane provides a collapse/expand widget
  414. */
  415. public boolean isOneTouchExpandable() {
  416. return oneTouchExpandable;
  417. }
  418. /**
  419. * Sets the last location the divider was at to
  420. * <code>newLastLocation</code>.
  421. *
  422. * @param newLastLocation an int specifying the last divider location
  423. * in pixels, from the left (or upper) edge of the pane to the
  424. * left (or upper) edge of the divider
  425. * @beaninfo
  426. * bound: true
  427. * description: The last location the divider was at.
  428. */
  429. public void setLastDividerLocation(int newLastLocation) {
  430. int oldLocation = lastDividerLocation;
  431. lastDividerLocation = newLastLocation;
  432. firePropertyChange(LAST_DIVIDER_LOCATION_PROPERTY, oldLocation,
  433. newLastLocation);
  434. }
  435. /**
  436. * Returns the last location the divider was at.
  437. *
  438. * @return an int specifying the last divider location as a count
  439. * of pixels from the left (or upper) edge of the pane to the
  440. * left (or upper) edge of the divider
  441. */
  442. public int getLastDividerLocation() {
  443. return lastDividerLocation;
  444. }
  445. /**
  446. * Sets the orientation, or how the splitter is divided. The options
  447. * are:<ul>
  448. * <li>JSplitPane.VERTICAL_SPLIT (above/below orientation of components)
  449. * <li>JSplitPane.HORIZONTAL_SPLIT (left/right orientation of components)
  450. * </ul>
  451. *
  452. * @param orientation an int specifying the orientation
  453. * @beaninfo
  454. * bound: true
  455. * description: The orientation, or how the splitter is divided.
  456. * enum: HORIZONTAL_SPLIT JSplitPane.HORIZONTAL_SPLIT
  457. * VERTICAL_SPLIT JSplitPane.VERTICAL_SPLIT
  458. */
  459. public void setOrientation(int orientation) {
  460. if ((orientation != VERTICAL_SPLIT) &&
  461. (orientation != HORIZONTAL_SPLIT)) {
  462. throw new IllegalArgumentException("JSplitPane: orientation must " +
  463. "be one of " +
  464. "JSplitPane.VERTICAL_SPLIT or " +
  465. "JSplitPane.HORIZONTAL_SPLIT");
  466. }
  467. int oldOrientation = this.orientation;
  468. this.orientation = orientation;
  469. firePropertyChange(ORIENTATION_PROPERTY, oldOrientation, orientation);
  470. }
  471. /**
  472. * Returns the orientation.
  473. *
  474. * @return an int giving the orientation
  475. * @see #setOrientation
  476. */
  477. public int getOrientation() {
  478. return orientation;
  479. }
  480. /**
  481. * Sets whether or not the child components are continuously
  482. * redisplayed and layed out during user intervention.
  483. *
  484. * @param newContinuousLayout a boolean, true if the components
  485. * are continuously redrawn as the divider changes position
  486. * @beaninfo
  487. * bound: true
  488. * description: Whether or not the child components are
  489. * continuously redisplayed and layed out during
  490. * user intervention.
  491. */
  492. public void setContinuousLayout(boolean newContinuousLayout) {
  493. boolean oldCD = continuousLayout;
  494. continuousLayout = newContinuousLayout;
  495. firePropertyChange(CONTINUOUS_LAYOUT_PROPERTY, oldCD,
  496. newContinuousLayout);
  497. }
  498. /**
  499. * Returns true if the child comopnents are continuously redisplayed and
  500. * layed out during user intervention.
  501. *
  502. * @return true if the components are continuously redrawn as the
  503. * divider changes position
  504. */
  505. public boolean isContinuousLayout() {
  506. return continuousLayout;
  507. }
  508. /**
  509. * Messaged to relayout the JSplitPane based on the preferred size
  510. * of the children components.
  511. */
  512. public void resetToPreferredSizes() {
  513. SplitPaneUI ui = getUI();
  514. if (ui != null) {
  515. ui.resetToPreferredSizes(this);
  516. }
  517. }
  518. /**
  519. * Sets the divider location as a percentage of the JSplitPane's size.
  520. *
  521. * @param proportionalLocation a double-precision floating point value
  522. * that specifies a percentage, from zero (top/left) to 1.0
  523. * (bottom/right)
  524. * @exception IllegalArgumentException if the specified location is < 0
  525. * or > 1.0
  526. * @beaninfo
  527. * description: The location of the divider.
  528. */
  529. public void setDividerLocation(double proportionalLocation) {
  530. if (proportionalLocation < 0.0 ||
  531. proportionalLocation > 1.0) {
  532. throw new IllegalArgumentException("proportional location must " +
  533. "be between 0.0 and 1.0.");
  534. }
  535. if (getOrientation() == VERTICAL_SPLIT) {
  536. setDividerLocation((int)((double)(getHeight() - getDividerSize()) *
  537. proportionalLocation));
  538. } else {
  539. setDividerLocation((int)((double)(getWidth() - getDividerSize()) *
  540. proportionalLocation));
  541. }
  542. }
  543. /**
  544. * Sets the location of the divider. This is passed off to the
  545. * look and feel implementation.
  546. *
  547. * @param location an int specifying a UI-specific value (typically a
  548. * pixel count)
  549. */
  550. public void setDividerLocation(int location) {
  551. SplitPaneUI ui = getUI();
  552. if (ui != null) {
  553. ui.setDividerLocation(this, location);
  554. }
  555. }
  556. /**
  557. * Returns the location of the divider from the look and feel
  558. * implementation.
  559. *
  560. * @return an int specifying a UI-specific value (typically a
  561. * pixel count)
  562. */
  563. public int getDividerLocation() {
  564. SplitPaneUI ui = getUI();
  565. if (ui != null) {
  566. return ui.getDividerLocation(this);
  567. }
  568. return -1;
  569. }
  570. /**
  571. * Returns the minimum location of the divider from the look and feel
  572. * implementation.
  573. *
  574. * @return an int specifying a UI-specific value for the minimum
  575. * location (typically a pixel count)
  576. * @beaninfo
  577. * description: The minimum location of the divider from the L&F.
  578. */
  579. public int getMinimumDividerLocation() {
  580. SplitPaneUI ui = getUI();
  581. if (ui != null) {
  582. return ui.getMinimumDividerLocation(this);
  583. }
  584. return -1;
  585. }
  586. /**
  587. * Returns the maximum location of the divider from the look and feel
  588. * implementation.
  589. *
  590. * @return an int specifying a UI-specific value for the maximum
  591. * location (typically a pixel count)
  592. */
  593. public int getMaximumDividerLocation() {
  594. SplitPaneUI ui = getUI();
  595. if (ui != null) {
  596. return ui.getMaximumDividerLocation(this);
  597. }
  598. return -1;
  599. }
  600. /**
  601. * Removes the child component, <code>component</code> from the
  602. * pane. Resets the leftComponent or rightComponent instance
  603. * variable, as necessary.
  604. *
  605. * @param component the Component to remove
  606. */
  607. public void remove(Component component) {
  608. if (component == leftComponent) {
  609. leftComponent = null;
  610. } else if (component == rightComponent) {
  611. rightComponent = null;
  612. }
  613. super.remove(component);
  614. // Update the JSplitPane on the screen
  615. revalidate();
  616. repaint();
  617. }
  618. /**
  619. * Removes the Component at the specified index. Updates the
  620. * leftComponent and rightComponent instance variables
  621. * as necessary, and then messages super.
  622. *
  623. * @param index an int specifying the component to remove, where
  624. * 1 specifies the left/top component and 2 specifies the
  625. * bottom/right component
  626. */
  627. public void remove(int index) {
  628. Component comp = getComponent(index);
  629. if (comp == leftComponent) {
  630. leftComponent = null;
  631. } else if (comp == rightComponent) {
  632. rightComponent = null;
  633. }
  634. super.remove(index);
  635. // Update the JSplitPane on the screen
  636. revalidate();
  637. repaint();
  638. }
  639. /**
  640. * Removes all the child components from the receiver. Resets the
  641. * leftComonent and rightComponent instance variables.
  642. */
  643. public void removeAll() {
  644. leftComponent = rightComponent = null;
  645. super.removeAll();
  646. // Update the JSplitPane on the screen
  647. revalidate();
  648. repaint();
  649. }
  650. /**
  651. * Calls to revalidate() on any descendant of this JSplitPane,
  652. * will cause a request to be queued that
  653. * will validate the JSplitPane and all its descendants.
  654. *
  655. * @return true
  656. * @see JComponent#revalidate
  657. *
  658. * @beaninfo
  659. * hidden: true
  660. */
  661. public boolean isValidateRoot() {
  662. return true;
  663. }
  664. /**
  665. * If <code>constraints</code> identifies the left/top or
  666. * right/bottom child component, and a component with that identifier
  667. * was previously added, it will be removed and then <code>comp</code>
  668. * will be added in its place. If <code>constraints</code> is not
  669. * one of the known identifers the layout manager may throw an
  670. * IllegalArgumentException.
  671. * <p>
  672. * The possible constraints objects (Strings) are:<ul>
  673. * <li>JSplitPane.TOP
  674. * <li>JSplitPane.LEFT
  675. * <li>JSplitPane.BOTTOM
  676. * <li>JSplitPane.RIGHT
  677. * </ul>
  678. * If the constraints object is null, the component is added in the
  679. * first available position (left/top if open, else right/bottom).
  680. *
  681. * @param comp the component to add
  682. * @param constraints an Object specifying the layout constraints
  683. * (position) for this component
  684. * @param index an int specifying the index in the container's
  685. * list.
  686. * @exception IllegalArgumentException thrown if the constraints object
  687. * does not match an existing component
  688. * @see java.awt.Container#addImpl(Component, Object, int)
  689. */
  690. protected void addImpl(Component comp, Object constraints, int index)
  691. {
  692. Component toRemove;
  693. if (constraints != null && !(constraints instanceof String)) {
  694. throw new IllegalArgumentException("cannot add to layout: " +
  695. "constraint must be a string " +
  696. "(or null)");
  697. }
  698. /* If the constraints are null and the left/right component is
  699. invalid, add it at the left/right component. */
  700. if (constraints == null) {
  701. if (getLeftComponent() == null) {
  702. constraints = JSplitPane.LEFT;
  703. } else if (getRightComponent() == null) {
  704. constraints = JSplitPane.RIGHT;
  705. }
  706. }
  707. /* Find the Component that already exists and remove it. */
  708. if (constraints != null && (constraints.equals(JSplitPane.LEFT) ||
  709. constraints.equals(JSplitPane.TOP))) {
  710. toRemove = getLeftComponent();
  711. if (toRemove != null) {
  712. remove(toRemove);
  713. }
  714. leftComponent = comp;
  715. index = -1;
  716. } else if (constraints != null &&
  717. (constraints.equals(JSplitPane.RIGHT) ||
  718. constraints.equals(JSplitPane.BOTTOM))) {
  719. toRemove = getRightComponent();
  720. if (toRemove != null) {
  721. remove(toRemove);
  722. }
  723. rightComponent = comp;
  724. index = -1;
  725. } else if (constraints != null &&
  726. constraints.equals(JSplitPane.DIVIDER)) {
  727. index = -1;
  728. }
  729. /* LayoutManager should raise for else condition here. */
  730. super.addImpl(comp, constraints, index);
  731. // Update the JSplitPane on the screen
  732. revalidate();
  733. repaint();
  734. }
  735. /**
  736. * Subclassed to message the UI with finishedPaintingChildren after
  737. * super has been messaged, as well as painting the border.
  738. *
  739. * @param g the Graphics context within which to paint
  740. */
  741. protected void paintChildren(Graphics g) {
  742. super.paintChildren(g);
  743. SplitPaneUI ui = getUI();
  744. if (ui != null) {
  745. Graphics tempG = SwingGraphics.createSwingGraphics(g);
  746. ui.finishedPaintingChildren(this, tempG);
  747. tempG.dispose();
  748. }
  749. }
  750. /**
  751. * See readObject() and writeObject() in JComponent for more
  752. * information about serialization in Swing.
  753. */
  754. private void writeObject(ObjectOutputStream s) throws IOException {
  755. s.defaultWriteObject();
  756. if ((ui != null) && (getUIClassID().equals(uiClassID))) {
  757. ui.installUI(this);
  758. }
  759. }
  760. /**
  761. * Returns a string representation of this JSplitPane. This method
  762. * is intended to be used only for debugging purposes, and the
  763. * content and format of the returned string may vary between
  764. * implementations. The returned string may be empty but may not
  765. * be <code>null</code>.
  766. *
  767. * @return a string representation of this JSplitPane.
  768. */
  769. protected String paramString() {
  770. String orientationString = (orientation == HORIZONTAL_SPLIT ?
  771. "HORIZONTAL_SPLIT" : "VERTICAL_SPLIT");
  772. String continuousLayoutString = (continuousLayout ?
  773. "true" : "false");
  774. String oneTouchExpandableString = (oneTouchExpandable ?
  775. "true" : "false");
  776. return super.paramString() +
  777. ",continuousLayout=" + continuousLayoutString +
  778. ",dividerSize=" + dividerSize +
  779. ",lastDividerLocation=" + lastDividerLocation +
  780. ",oneTouchExpandable=" + oneTouchExpandableString +
  781. ",orientation=" + orientationString;
  782. }
  783. ///////////////////////////
  784. // Accessibility support //
  785. ///////////////////////////
  786. /**
  787. * Get the AccessibleContext associated with this JComponent
  788. *
  789. * @return the AccessibleContext of this JComponent
  790. * @beaninfo
  791. * expert: true
  792. * description: The AccessibleContext associated with this Label.
  793. */
  794. public AccessibleContext getAccessibleContext() {
  795. if (accessibleContext == null) {
  796. accessibleContext = new AccessibleJSplitPane();
  797. }
  798. return accessibleContext;
  799. }
  800. /**
  801. * The class used to obtain the accessible role for this object.
  802. * <p>
  803. * <strong>Warning:</strong>
  804. * Serialized objects of this class will not be compatible with
  805. * future Swing releases. The current serialization support is appropriate
  806. * for short term storage or RMI between applications running the same
  807. * version of Swing. A future release of Swing will provide support for
  808. * long term persistence.
  809. */
  810. protected class AccessibleJSplitPane extends AccessibleJComponent
  811. implements AccessibleValue {
  812. /**
  813. * Get the state set of this object.
  814. *
  815. * @return an instance of AccessibleState containing the current state
  816. * of the object
  817. * @see AccessibleState
  818. */
  819. public AccessibleStateSet getAccessibleStateSet() {
  820. AccessibleStateSet states = super.getAccessibleStateSet();
  821. // FIXME: [[[WDW - Should also add BUSY if this implements
  822. // Adjustable at some point. If this happens, we probably
  823. // should also add actions.]]]
  824. if (getOrientation() == VERTICAL_SPLIT) {
  825. states.add(AccessibleState.VERTICAL);
  826. } else {
  827. states.add(AccessibleState.HORIZONTAL);
  828. }
  829. return states;
  830. }
  831. /**
  832. * Get the AccessibleValue associated with this object if one
  833. * exists. Otherwise return null.
  834. */
  835. public AccessibleValue getAccessibleValue() {
  836. return this;
  837. }
  838. /**
  839. * Get the accessible value of this object.
  840. *
  841. * @return a localized String describing the value of this object
  842. */
  843. public Number getCurrentAccessibleValue() {
  844. return new Integer(getDividerLocation());
  845. }
  846. /**
  847. * Set the value of this object as a Number.
  848. *
  849. * @return True if the value was set.
  850. */
  851. public boolean setCurrentAccessibleValue(Number n) {
  852. if (n instanceof Integer) {
  853. setDividerLocation(n.intValue());
  854. return true;
  855. } else {
  856. return false;
  857. }
  858. }
  859. /**
  860. * Get the minimum accessible value of this object.
  861. *
  862. * @return The minimum value of this object.
  863. */
  864. public Number getMinimumAccessibleValue() {
  865. return new Integer(getUI().getMinimumDividerLocation(
  866. JSplitPane.this));
  867. }
  868. /**
  869. * Get the maximum accessible value of this object.
  870. *
  871. * @return The maximum value of this object.
  872. */
  873. public Number getMaximumAccessibleValue() {
  874. return new Integer(getUI().getMaximumDividerLocation(
  875. JSplitPane.this));
  876. }
  877. /**
  878. * Get the role of this object.
  879. *
  880. * @return an instance of AccessibleRole describing the role of
  881. * the object
  882. * @see AccessibleRole
  883. */
  884. public AccessibleRole getAccessibleRole() {
  885. return AccessibleRole.SPLIT_PANE;
  886. }
  887. } // inner class AccessibleJSplitPane
  888. }