1. /*
  2. * @(#)BasicSplitPaneDivider.java 1.31 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.plaf.basic;
  8. import java.awt.*;
  9. import java.awt.event.*;
  10. import javax.swing.*;
  11. import javax.swing.event.*;
  12. import javax.swing.plaf.*;
  13. import javax.swing.border.Border;
  14. import java.beans.*;
  15. import java.io.*;
  16. /**
  17. * Divider used by BasicSplitPaneUI. Subclassers may wish to override
  18. * paint to do something more interesting.
  19. * The border effect is drawn in BasicSplitPaneUI, so if you don't like
  20. * that border, reset it there.
  21. * To conditionally drag from certain areas subclass mousePressed and
  22. * call super when you wish the dragging to begin.
  23. * <p>
  24. * <strong>Warning:</strong>
  25. * Serialized objects of this class will not be compatible with
  26. * future Swing releases. The current serialization support is appropriate
  27. * for short term storage or RMI between applications running the same
  28. * version of Swing. A future release of Swing will provide support for
  29. * long term persistence.
  30. *
  31. * @version 1.31 11/29/01
  32. * @author Scott Violet
  33. */
  34. public class BasicSplitPaneDivider extends Container
  35. implements PropertyChangeListener
  36. {
  37. /**
  38. * Width or height of the divider based on orientation
  39. * BasicSplitPaneUI adds two to this.
  40. */
  41. protected static final int ONE_TOUCH_SIZE = 6;
  42. protected static final int ONE_TOUCH_OFFSET = 2;
  43. /**
  44. * Handles mouse dragging message to do the actual dragging.
  45. */
  46. protected DragController dragger;
  47. /**
  48. * UI this instance was created from.
  49. */
  50. protected BasicSplitPaneUI splitPaneUI;
  51. /**
  52. * Size of the divider.
  53. */
  54. protected int dividerSize = 0; // default - SET TO 0???
  55. /**
  56. * Divider that is used for noncontinuous layout mode.
  57. */
  58. protected Component hiddenDivider;
  59. /**
  60. * JSplitPane the receiver is contained in.
  61. */
  62. protected JSplitPane splitPane;
  63. /**
  64. * Handles mouse events from both this class, and the split pane.
  65. * Mouse events are handled for the splitpane since you want to be able
  66. * to drag when clicking on the border of the divider, which is not
  67. * drawn by the divider.
  68. */
  69. protected MouseHandler mouseHandler;
  70. /**
  71. * Orientation of the JSplitPane.
  72. */
  73. protected int orientation;
  74. /**
  75. * Button for quickly toggling the left component.
  76. */
  77. protected JButton leftButton;
  78. /**
  79. * Button for quickly toggling the right component.
  80. */
  81. protected JButton rightButton;
  82. /**
  83. * Cursor used for HORIZONTAL_SPLIT splitpanes.
  84. */
  85. static final Cursor horizontalCursor =
  86. Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR);
  87. /**
  88. * Cursor used for VERTICAL_SPLIT splitpanes.
  89. */
  90. static final Cursor verticalCursor =
  91. Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR);
  92. /**
  93. * Default cursor.
  94. */
  95. static final Cursor defaultCursor =
  96. Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR);
  97. /**
  98. * Creates an instance of BasicSplitPaneDivider. Registers this
  99. * instance for mouse events and mouse dragged events.
  100. */
  101. public BasicSplitPaneDivider(BasicSplitPaneUI ui) {
  102. setLayout(new DividerLayout());
  103. setBasicSplitPaneUI(ui);
  104. orientation = splitPane.getOrientation();
  105. setBackground(UIManager.getColor("SplitPane.background"));
  106. }
  107. /**
  108. * Sets the SplitPaneUI that is using the receiver.
  109. */
  110. public void setBasicSplitPaneUI(BasicSplitPaneUI newUI) {
  111. if (splitPane != null) {
  112. splitPane.removePropertyChangeListener(this);
  113. if (mouseHandler != null) {
  114. splitPane.removeMouseListener(mouseHandler);
  115. splitPane.removeMouseMotionListener(mouseHandler);
  116. removeMouseListener(mouseHandler);
  117. removeMouseMotionListener(mouseHandler);
  118. mouseHandler = null;
  119. }
  120. }
  121. splitPaneUI = newUI;
  122. if (newUI != null) {
  123. splitPane = newUI.getSplitPane();
  124. if (splitPane != null) {
  125. if (mouseHandler == null) mouseHandler = new MouseHandler();
  126. splitPane.addMouseListener(mouseHandler);
  127. splitPane.addMouseMotionListener(mouseHandler);
  128. addMouseListener(mouseHandler);
  129. addMouseMotionListener(mouseHandler);
  130. splitPane.addPropertyChangeListener(this);
  131. if (splitPane.isOneTouchExpandable()) {
  132. oneTouchExpandableChanged();
  133. }
  134. }
  135. }
  136. else {
  137. splitPane = null;
  138. }
  139. }
  140. /**
  141. * Returns the <code>SplitPaneUI</code> the receiver is currently
  142. * in.
  143. */
  144. public BasicSplitPaneUI getBasicSplitPaneUI() {
  145. return splitPaneUI;
  146. }
  147. /**
  148. * Sets the size of the divider to <code>newSize</code>. That is
  149. * the width if the splitpane is <code>HORIZONTAL_SPLIT</code>, or
  150. * the height of <code>VERTICAL_SPLIT</code>.
  151. */
  152. public void setDividerSize(int newSize) {
  153. dividerSize = newSize;
  154. }
  155. /**
  156. * Returns the size of the divider, that is the width if the splitpane
  157. * is HORIZONTAL_SPLIT, or the height of VERTICAL_SPLIT.
  158. */
  159. public int getDividerSize() {
  160. return dividerSize;
  161. }
  162. /**
  163. * Returns dividerSize x dividerSize
  164. */
  165. public Dimension getPreferredSize() {
  166. return new Dimension(getDividerSize(), getDividerSize());
  167. }
  168. /**
  169. * Property change event, presumably from the JSplitPane, will message
  170. * updateOrientation if necessary.
  171. */
  172. public void propertyChange(PropertyChangeEvent e) {
  173. if (e.getSource() == splitPane) {
  174. if (e.getPropertyName().equals(JSplitPane.ORIENTATION_PROPERTY)) {
  175. orientation = splitPane.getOrientation();
  176. invalidate();
  177. validate();
  178. }
  179. else if (e.getPropertyName().equals(JSplitPane.
  180. ONE_TOUCH_EXPANDABLE_PROPERTY)) {
  181. oneTouchExpandableChanged();
  182. }
  183. }
  184. }
  185. /**
  186. * Paints the divider.
  187. */
  188. public void paint(Graphics g) {
  189. super.paint(g);
  190. }
  191. /**
  192. * Messaged when the oneTouchExpandable value of the JSplitPane the
  193. * receiver is contained in changes. Will create the
  194. * <code>leftButton</code> and <code>rightButton</code> if they
  195. * are null. invalidates the receiver as well.
  196. */
  197. protected void oneTouchExpandableChanged() {
  198. if (splitPane.isOneTouchExpandable() &&
  199. leftButton == null &&
  200. rightButton == null) {
  201. /* Create the left button and add an action listener to
  202. expand/collapse it. */
  203. leftButton = createLeftOneTouchButton();
  204. if (leftButton != null)
  205. leftButton.addActionListener(new LeftActionListener());
  206. /* Create the right button and add an action listener to
  207. expand/collapse it. */
  208. rightButton = createRightOneTouchButton();
  209. if (rightButton != null)
  210. rightButton.addActionListener(new RightActionListener());
  211. if (leftButton != null && rightButton != null) {
  212. add(leftButton);
  213. add(rightButton);
  214. }
  215. }
  216. invalidate();
  217. validate();
  218. }
  219. /**
  220. * Creates and return an instance of JButton that can be used to
  221. * collapse the left component in the split pane.
  222. */
  223. protected JButton createLeftOneTouchButton() {
  224. JButton b = new JButton() {
  225. public void setBorder(Border b) {
  226. }
  227. public void paint(Graphics g) {
  228. if (splitPane != null) {
  229. int[] xs = new int[3];
  230. int[] ys = new int[3];
  231. int blockSize = Math.min(getDividerSize(),
  232. ONE_TOUCH_SIZE);
  233. // Fill the background first ...
  234. g.setColor(this.getBackground());
  235. g.fillRect(0, 0, this.getWidth(),
  236. this.getHeight());
  237. // ... then draw the arrow.
  238. g.setColor(Color.black);
  239. if (orientation == JSplitPane.VERTICAL_SPLIT) {
  240. xs[0] = blockSize;
  241. xs[1] = 0;
  242. xs[2] = blockSize << 1;
  243. ys[0] = 0;
  244. ys[1] = ys[2] = blockSize;
  245. g.drawPolygon(xs, ys, 3); // Little trick to make the
  246. // arrows of equal size
  247. }
  248. else {
  249. xs[0] = xs[2] = blockSize;
  250. xs[1] = 0;
  251. ys[0] = 0;
  252. ys[1] = blockSize;
  253. ys[2] = blockSize << 1;
  254. }
  255. g.fillPolygon(xs, ys, 3);
  256. }
  257. }
  258. // Don't want the button to participate in focus traversable.
  259. public boolean isFocusTraversable() {
  260. return false;
  261. }
  262. };
  263. b.setFocusPainted(false);
  264. b.setBorderPainted(false);
  265. return b;
  266. }
  267. /**
  268. * Creates and return an instance of JButton that can be used to
  269. * collapse the right component in the split pane.
  270. */
  271. protected JButton createRightOneTouchButton() {
  272. JButton b = new JButton() {
  273. public void setBorder(Border border) {
  274. }
  275. public void paint(Graphics g) {
  276. if (splitPane != null) {
  277. int[] xs = new int[3];
  278. int[] ys = new int[3];
  279. int blockSize = Math.min(getDividerSize(),
  280. ONE_TOUCH_SIZE);
  281. // Fill the background first ...
  282. g.setColor(this.getBackground());
  283. g.fillRect(0, 0, this.getWidth(),
  284. this.getHeight());
  285. // ... then draw the arrow.
  286. if (orientation == JSplitPane.VERTICAL_SPLIT) {
  287. xs[0] = blockSize;
  288. xs[1] = blockSize << 1;
  289. xs[2] = 0;
  290. ys[0] = blockSize;
  291. ys[1] = ys[2] = 0;
  292. }
  293. else {
  294. xs[0] = xs[2] = 0;
  295. xs[1] = blockSize;
  296. ys[0] = 0;
  297. ys[1] = blockSize;
  298. ys[2] = blockSize << 1;
  299. }
  300. g.setColor(Color.black);
  301. g.fillPolygon(xs, ys, 3);
  302. }
  303. }
  304. // Don't want the button to participate in focus traversable.
  305. public boolean isFocusTraversable() {
  306. return false;
  307. }
  308. };
  309. b.setFocusPainted(false);
  310. b.setBorderPainted(false);
  311. return b;
  312. }
  313. /**
  314. * Message to prepare for dragging. This messages the BasicSplitPaneUI
  315. * with startDragging.
  316. */
  317. protected void prepareForDragging() {
  318. splitPaneUI.startDragging();
  319. }
  320. /**
  321. * Messages the BasicSplitPaneUI with dragDividerTo that this instance
  322. * is contained in.
  323. */
  324. protected void dragDividerTo(int location) {
  325. splitPaneUI.dragDividerTo(location);
  326. }
  327. /**
  328. * Messages the BasicSplitPaneUI with finishDraggingTo that this instance
  329. * is contained in.
  330. */
  331. protected void finishDraggingTo(int location) {
  332. splitPaneUI.finishDraggingTo(location);
  333. }
  334. /**
  335. * MouseHandler is responsible for converting mouse events
  336. * (released, dragged...) into the appropriate DragController
  337. * methods.
  338. * <p>
  339. */
  340. protected class MouseHandler extends MouseAdapter
  341. implements MouseMotionListener
  342. {
  343. /**
  344. * Starts the dragging session by creating the appropriate instance
  345. * of DragController.
  346. */
  347. public void mousePressed(MouseEvent e) {
  348. if ((e.getSource() == BasicSplitPaneDivider.this ||
  349. e.getSource() == splitPane) &&
  350. dragger == null &&splitPane.isEnabled()) {
  351. Component newHiddenDivider = splitPaneUI.
  352. getNonContinuousLayoutDivider();
  353. if (hiddenDivider != newHiddenDivider) {
  354. if (hiddenDivider != null) {
  355. hiddenDivider.removeMouseListener(this);
  356. hiddenDivider.removeMouseMotionListener(this);
  357. }
  358. hiddenDivider = newHiddenDivider;
  359. if (hiddenDivider != null) {
  360. hiddenDivider.addMouseMotionListener(this);
  361. hiddenDivider.addMouseListener(this);
  362. }
  363. }
  364. if (splitPane.getLeftComponent() != null &&
  365. splitPane.getRightComponent() != null) {
  366. if (orientation == JSplitPane.HORIZONTAL_SPLIT) {
  367. dragger = new DragController(e);
  368. }
  369. else {
  370. dragger = new VerticalDragController(e);
  371. }
  372. if (!dragger.isValid()) {
  373. dragger = null;
  374. }
  375. else {
  376. prepareForDragging();
  377. dragger.continueDrag(e);
  378. }
  379. }
  380. e.consume();
  381. }
  382. }
  383. /**
  384. * If dragger is not null it is messaged with completeDrag.
  385. */
  386. public void mouseReleased(MouseEvent e) {
  387. if (dragger != null) {
  388. if (e.getSource() == splitPane) {
  389. dragger.completeDrag(e.getX(), e.getY());
  390. }
  391. else if (e.getSource() == BasicSplitPaneDivider.this) {
  392. Point ourLoc = getLocation();
  393. dragger.completeDrag(e.getX() + ourLoc.x,
  394. e.getY() + ourLoc.y);
  395. }
  396. else if (e.getSource() == hiddenDivider) {
  397. Point hDividerLoc = hiddenDivider.getLocation();
  398. int ourX = e.getX() + hDividerLoc.x;
  399. int ourY = e.getY() + hDividerLoc.y;
  400. dragger.completeDrag(ourX, ourY);
  401. }
  402. dragger = null;
  403. e.consume();
  404. }
  405. }
  406. //
  407. // MouseMotionListener
  408. //
  409. /**
  410. * If dragger is not null it is messaged with continueDrag.
  411. */
  412. public void mouseDragged(MouseEvent e) {
  413. if (dragger != null) {
  414. if (e.getSource() == splitPane) {
  415. dragger.continueDrag(e.getX(), e.getY());
  416. }
  417. else if (e.getSource() == BasicSplitPaneDivider.this) {
  418. Point ourLoc = getLocation();
  419. dragger.continueDrag(e.getX() + ourLoc.x,
  420. e.getY() + ourLoc.y);
  421. }
  422. else if (e.getSource() == hiddenDivider) {
  423. Point hDividerLoc = hiddenDivider.getLocation();
  424. int ourX = e.getX() + hDividerLoc.x;
  425. int ourY = e.getY() + hDividerLoc.y;
  426. dragger.continueDrag(ourX, ourY);
  427. }
  428. e.consume();
  429. }
  430. }
  431. /**
  432. * Resets the cursor based on the orientation.
  433. */
  434. public void mouseMoved(MouseEvent e) {
  435. if (dragger != null) return;
  436. int eventX = e.getX();
  437. int eventY = e.getY();
  438. Rectangle bounds = getBounds();
  439. Cursor newCursor;
  440. if (e.getSource() == BasicSplitPaneDivider.this) {
  441. if (eventX >= -1 && eventX <= bounds.width &&
  442. eventY >= -1 && eventY <= bounds.height) {
  443. newCursor = (orientation == JSplitPane.HORIZONTAL_SPLIT) ?
  444. horizontalCursor : verticalCursor;
  445. }
  446. else {
  447. newCursor = defaultCursor;
  448. }
  449. }
  450. else {
  451. if (eventX >= (bounds.x - 1) &&
  452. eventX <= (bounds.x + bounds.width) &&
  453. eventY >= (bounds.y - 1) &&
  454. eventY <= (bounds.y + bounds.height)) {
  455. newCursor = (orientation == JSplitPane.HORIZONTAL_SPLIT) ?
  456. horizontalCursor : verticalCursor;
  457. }
  458. else {
  459. newCursor = defaultCursor;
  460. }
  461. }
  462. if (getCursor() != newCursor) {
  463. setCursor(newCursor);
  464. }
  465. }
  466. }
  467. /**
  468. * Handles the events during a dragging session for a
  469. * HORIZONTAL_SPLIT orientated split pane. This continually
  470. * messages dragDividerTo and then when done messages
  471. * finishDraggingTo. When an instance is created it should be
  472. * messaged with isValid() to insure that dragging can happen
  473. * (dragging won't be allowed if the two views can not be resized).
  474. * <p>
  475. * <strong>Warning:</strong>
  476. * Serialized objects of this class will not be compatible with
  477. * future Swing releases. The current serialization support is appropriate
  478. * for short term storage or RMI between applications running the same
  479. * version of Swing. A future release of Swing will provide support for
  480. * long term persistence.
  481. */
  482. protected class DragController
  483. {
  484. /**
  485. * Initial location of the divider.
  486. */
  487. int initialX;
  488. /**
  489. * Maximum and minimum positions to drag to.
  490. */
  491. int maxX, minX;
  492. /**
  493. * Initial location the mouse down happened at.
  494. */
  495. int offset;
  496. protected DragController(MouseEvent e) {
  497. JSplitPane splitPane = splitPaneUI.getSplitPane();
  498. Component leftC = splitPane.getLeftComponent();
  499. Component rightC = splitPane.getRightComponent();
  500. initialX = getLocation().x;
  501. if (e.getSource() == BasicSplitPaneDivider.this) {
  502. offset = e.getX();
  503. }
  504. else { // splitPane
  505. offset = e.getX() - initialX;
  506. }
  507. if (leftC == null || rightC == null || offset < -1 ||
  508. offset > getSize().width) {
  509. // Don't allow dragging.
  510. maxX = -1;
  511. }
  512. else {
  513. // Assume that both sides need the same amount of padding.
  514. int padding = initialX - leftC.getSize().width;
  515. if (leftC.isVisible()) {
  516. minX = leftC.getMinimumSize().width + padding;
  517. }
  518. else {
  519. minX = 0;
  520. }
  521. if (rightC.isVisible()) {
  522. maxX = Math.max(0, splitPane.getSize().width -
  523. (getSize().width + padding) -
  524. rightC.getMinimumSize().width);
  525. }
  526. else {
  527. maxX = Math.max(0, splitPane.getSize().width -
  528. (getSize().width + padding));
  529. }
  530. if (maxX < minX) minX = maxX = 0;
  531. }
  532. }
  533. /**
  534. * Returns true if the dragging session is valid.
  535. */
  536. protected boolean isValid() {
  537. return (maxX > 0);
  538. }
  539. /**
  540. * Returns the new position to put the divider at based on
  541. * the passed in MouseEvent.
  542. */
  543. protected int positionForMouseEvent(MouseEvent e) {
  544. int newX = (e.getSource() == BasicSplitPaneDivider.this) ?
  545. (e.getX() + getLocation().x) : e.getX();
  546. newX = Math.min(maxX, Math.max(minX, newX - offset));
  547. return newX;
  548. }
  549. /**
  550. * Returns the x argument, since this is used for horizontal
  551. * splits.
  552. */
  553. protected int getNeededLocation(int x, int y) {
  554. int newX;
  555. newX = Math.min(maxX, Math.max(minX, x - offset));
  556. return newX;
  557. }
  558. protected void continueDrag(int newX, int newY) {
  559. dragDividerTo(getNeededLocation(newX, newY));
  560. }
  561. /**
  562. * Messages dragDividerTo with the new location for the mouse
  563. * event.
  564. */
  565. protected void continueDrag(MouseEvent e) {
  566. dragDividerTo(positionForMouseEvent(e));
  567. }
  568. protected void completeDrag(int x, int y) {
  569. finishDraggingTo(getNeededLocation(x, y));
  570. }
  571. /**
  572. * Messages finishDraggingTo with the new location for the mouse
  573. * event.
  574. */
  575. protected void completeDrag(MouseEvent e) {
  576. finishDraggingTo(positionForMouseEvent(e));
  577. }
  578. } // End of BasicSplitPaneDivider.DragController
  579. /**
  580. * Handles the events during a dragging session for a
  581. * VERTICAL_SPLIT orientated split pane. This continually
  582. * messages dragDividerTo and then when done messages
  583. * finishDraggingTo. When an instance is created it should be
  584. * messaged with isValid() to insure that dragging can happen
  585. * (dragging won't be allowed if the two views can not be resized).
  586. */
  587. protected class VerticalDragController extends DragController
  588. {
  589. /* DragControllers ivars are now in terms of y, not x. */
  590. protected VerticalDragController(MouseEvent e) {
  591. super(e);
  592. JSplitPane splitPane = splitPaneUI.getSplitPane();
  593. Component leftC = splitPane.getLeftComponent();
  594. Component rightC = splitPane.getRightComponent();
  595. initialX = getLocation().y;
  596. if (e.getSource() == BasicSplitPaneDivider.this) {
  597. offset = e.getY();
  598. }
  599. else {
  600. offset = e.getY() - initialX;
  601. }
  602. if (leftC == null || rightC == null || offset < -1 ||
  603. offset > getSize().height) {
  604. // Don't allow dragging.
  605. maxX = -1;
  606. }
  607. else {
  608. // Assume that both sides need the same amount of padding.
  609. int padding = initialX - leftC.getSize().height;
  610. if (leftC.isVisible()) {
  611. minX = leftC.getMinimumSize().height + padding;
  612. }
  613. else {
  614. minX = 0;
  615. }
  616. if (rightC.isVisible()) {
  617. maxX = Math.max(0, splitPane.getSize().height -
  618. (getSize().height + padding) -
  619. rightC.getMinimumSize().height);
  620. }
  621. else {
  622. maxX = Math.max(0, splitPane.getSize().height -
  623. (getSize().height + padding));
  624. }
  625. if (maxX < minX) minX = maxX = 0;
  626. }
  627. }
  628. /**
  629. * Returns the y argument, since this is used for vertical
  630. * splits.
  631. */
  632. protected int getNeededLocation(int x, int y) {
  633. int newY;
  634. newY = Math.min(maxX, Math.max(minX, y - offset));
  635. return newY;
  636. }
  637. /**
  638. * Returns the new position to put the divider at based on
  639. * the passed in MouseEvent.
  640. */
  641. protected int positionForMouseEvent(MouseEvent e) {
  642. int newY = (e.getSource() == BasicSplitPaneDivider.this) ?
  643. (e.getY() + getLocation().y) : e.getY();
  644. newY = Math.min(maxX, Math.max(minX, newY - offset));
  645. return newY;
  646. }
  647. } // End of BasicSplitPaneDividier.VerticalDragController
  648. /**
  649. * Used to layout a BasicSplitPaneDivider. Layout for the divider
  650. * involves appropraitely moving the left/right buttons around.
  651. * <p>
  652. */
  653. protected class DividerLayout implements LayoutManager
  654. {
  655. public void layoutContainer(Container c) {
  656. if (leftButton != null && rightButton != null &&
  657. c == BasicSplitPaneDivider.this) {
  658. if (splitPane.isOneTouchExpandable()) {
  659. int blockSize = Math.min(getDividerSize(), ONE_TOUCH_SIZE);
  660. if (orientation == JSplitPane.VERTICAL_SPLIT) {
  661. int y = (c.getSize().height - blockSize) / 2;
  662. leftButton.setBounds(ONE_TOUCH_OFFSET, y,
  663. blockSize * 2, blockSize);
  664. rightButton.setBounds(ONE_TOUCH_OFFSET +
  665. ONE_TOUCH_SIZE * 2, y,
  666. blockSize * 2, blockSize);
  667. }
  668. else {
  669. int x = (c.getSize().width - blockSize) / 2;
  670. leftButton.setBounds(x, ONE_TOUCH_OFFSET,
  671. blockSize, blockSize * 2);
  672. rightButton.setBounds(x, ONE_TOUCH_OFFSET +
  673. ONE_TOUCH_SIZE * 2, blockSize,
  674. blockSize * 2);
  675. }
  676. }
  677. else {
  678. leftButton.setBounds(-5, -5, 1, 1);
  679. rightButton.setBounds(-5, -5, 1, 1);
  680. }
  681. }
  682. }
  683. public Dimension minimumLayoutSize(Container c) {
  684. return new Dimension(0,0);
  685. }
  686. public Dimension preferredLayoutSize(Container c) {
  687. return new Dimension(0, 0);
  688. }
  689. public void removeLayoutComponent(Component c) {}
  690. public void addLayoutComponent(String string, Component c) {}
  691. } // End of class BasicSplitPaneDivider.DividerLayout
  692. /**
  693. * Listener for move-left events.
  694. * <p>
  695. */
  696. private class LeftActionListener implements ActionListener
  697. {
  698. public void actionPerformed(ActionEvent e) {
  699. Insets insets = splitPane.getInsets();
  700. int currentLoc;
  701. currentLoc = splitPane.getDividerLocation();
  702. currentLoc += splitPaneUI.getDividerBorderSize();
  703. if (orientation == JSplitPane.VERTICAL_SPLIT) {
  704. if (currentLoc >= (splitPane.getHeight() -
  705. insets.bottom - getDividerSize()))
  706. splitPane.setDividerLocation(splitPane.
  707. getLastDividerLocation());
  708. else
  709. splitPane.setDividerLocation(0);
  710. }
  711. else {
  712. if (currentLoc >= (splitPane.getWidth() -
  713. insets.right - getDividerSize()))
  714. splitPane.setDividerLocation(splitPane.
  715. getLastDividerLocation());
  716. else
  717. splitPane.setDividerLocation(0);
  718. }
  719. }
  720. } // End of class BasicSplitPaneDivider.LeftActionListener
  721. /**
  722. * Listener for move-right events.
  723. * <p>
  724. */
  725. private class RightActionListener implements ActionListener
  726. {
  727. public void actionPerformed(ActionEvent e) {
  728. Insets insets = splitPane.getInsets();
  729. int currentLoc;
  730. currentLoc = splitPane.getDividerLocation();
  731. currentLoc -= splitPaneUI.getDividerBorderSize();
  732. if (orientation == JSplitPane.VERTICAL_SPLIT) {
  733. if (currentLoc == insets.top)
  734. splitPane.setDividerLocation(splitPane
  735. .getLastDividerLocation());
  736. else
  737. splitPane.setDividerLocation(splitPane
  738. .getHeight() - insets.bottom);
  739. }
  740. else {
  741. if (currentLoc == insets.left)
  742. splitPane.setDividerLocation(splitPane.
  743. getLastDividerLocation());
  744. else
  745. splitPane.setDividerLocation(splitPane.
  746. getWidth() - insets.right);
  747. }
  748. }
  749. } // End of class BasicSplitPaneDivider.RightActionListener
  750. }