History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/javax/swing/JSplitPane.java (1 of 18352 files). Show all

Unified · Split

java/pkg/javax/swing/JSplitPane.java+1253−0
@@ -0,0 +1,1253 @@
1/*
2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26
27
28package javax.swing;
29
30
31
32import java.beans.ConstructorProperties;
33import javax.swing.plaf.*;
34import javax.accessibility.*;
35
36import java.awt.*;
37
38import java.io.ObjectOutputStream;
39import java.io.ObjectInputStream;
40import java.io.IOException;
41
42
43
44/**
45 * <code>JSplitPane</code> is used to divide two (and only two)
46 * <code>Component</code>s. The two <code>Component</code>s
47 * are graphically divided based on the look and feel
48 * implementation, and the two <code>Component</code>s can then be
49 * interactively resized by the user.
50 * Information on using <code>JSplitPane</code> is in
51 * <a
52 href="http://java.sun.com/docs/books/tutorial/uiswing/components/splitpane.html">How to Use Split Panes</a> in
53 * <em>The Java Tutorial</em>.
54 * <p>
55 * The two <code>Component</code>s in a split pane can be aligned
56 * left to right using
57 * <code>JSplitPane.HORIZONTAL_SPLIT</code>, or top to bottom using
58 * <code>JSplitPane.VERTICAL_SPLIT</code>.
59 * The preferred way to change the size of the <code>Component</code>s
60 * is to invoke
61 * <code>setDividerLocation</code> where <code>location</code> is either
62 * the new x or y position, depending on the orientation of the
63 * <code>JSplitPane</code>.
64 * <p>
65 * To resize the <code>Component</code>s to their preferred sizes invoke
66 * <code>resetToPreferredSizes</code>.
67 * <p>
68 * When the user is resizing the <code>Component</code>s the minimum
69 * size of the <code>Components</code> is used to determine the
70 * maximum/minimum position the <code>Component</code>s
71 * can be set to. If the minimum size of the two
72 * components is greater than the size of the split pane the divider
73 * will not allow you to resize it. To alter the minimum size of a
74 * <code>JComponent</code>, see {@link JComponent#setMinimumSize}.
75 * <p>
76 * When the user resizes the split pane the new space is distributed between
77 * the two components based on the <code>resizeWeight</code> property.
78 * A value of 0,
79 * the default, indicates the right/bottom component gets all the space,
80 * where as a value of 1 indicates the left/top component gets all the space.
81 * <p>
82 * <strong>Warning:</strong> Swing is not thread safe. For more
83 * information see <a
84 * href="package-summary.html#threading">Swing's Threading
85 * Policy</a>.
86 * <p>
87 * <strong>Warning:</strong>
88 * Serialized objects of this class will not be compatible with
89 * future Swing releases. The current serialization support is
90 * appropriate for short term storage or RMI between applications running
91 * the same version of Swing. As of 1.4, support for long term storage
92 * of all JavaBeans<sup><font size="-2">TM</font></sup>
93 * has been added to the <code>java.beans</code> package.
94 * Please see {@link java.beans.XMLEncoder}.
95 *
96 * @see #setDividerLocation
97 * @see #resetToPreferredSizes
98 *
99 * @author Scott Violet
100 */
101public class JSplitPane extends JComponent implements Accessible
102{
103 /**
104 * @see #getUIClassID
105 * @see #readObject
106 */
107 private static final String uiClassID = "SplitPaneUI";
108
109 /**
110 * Vertical split indicates the <code>Component</code>s are
111 * split along the y axis. For example the two
112 * <code>Component</code>s will be split one on top of the other.
113 */
114 public final static int VERTICAL_SPLIT = 0;
115
116 /**
117 * Horizontal split indicates the <code>Component</code>s are
118 * split along the x axis. For example the two
119 * <code>Component</code>s will be split one to the left of the
120 * other.
121 */
122 public final static int HORIZONTAL_SPLIT = 1;
123
124 /**
125 * Used to add a <code>Component</code> to the left of the other
126 * <code>Component</code>.
127 */
128 public final static String LEFT = "left";
129
130 /**
131 * Used to add a <code>Component</code> to the right of the other
132 * <code>Component</code>.
133 */
134 public final static String RIGHT = "right";
135
136 /**
137 * Used to add a <code>Component</code> above the other
138 * <code>Component</code>.
139 */
140 public final static String TOP = "top";
141
142 /**
143 * Used to add a <code>Component</code> below the other
144 * <code>Component</code>.
145 */
146 public final static String BOTTOM = "bottom";
147
148 /**
149 * Used to add a <code>Component</code> that will represent the divider.
150 */
151 public final static String DIVIDER = "divider";
152
153 /**
154 * Bound property name for orientation (horizontal or vertical).
155 */
156 public final static String ORIENTATION_PROPERTY = "orientation";
157
158 /**
159 * Bound property name for continuousLayout.
160 */
161 public final static String CONTINUOUS_LAYOUT_PROPERTY = "continuousLayout";
162
163 /**
164 * Bound property name for border.
165 */
166 public final static String DIVIDER_SIZE_PROPERTY = "dividerSize";
167
168 /**
169 * Bound property for oneTouchExpandable.
170 */
171 public final static String ONE_TOUCH_EXPANDABLE_PROPERTY =
172 "oneTouchExpandable";
173
174 /**
175 * Bound property for lastLocation.
176 */
177 public final static String LAST_DIVIDER_LOCATION_PROPERTY =
178 "lastDividerLocation";
179
180 /**
181 * Bound property for the dividerLocation.
182 * @since 1.3
183 */
184 public final static String DIVIDER_LOCATION_PROPERTY = "dividerLocation";
185
186 /**
187 * Bound property for weight.
188 * @since 1.3
189 */
190 public final static String RESIZE_WEIGHT_PROPERTY = "resizeWeight";
191
192 /**
193 * How the views are split.
194 */
195 protected int orientation;
196
197 /**
198 * Whether or not the views are continuously redisplayed while
199 * resizing.
200 */
201 protected boolean continuousLayout;
202
203 /**
204 * The left or top component.
205 */
206 protected Component leftComponent;
207
208 /**
209 * The right or bottom component.
210 */
211 protected Component rightComponent;
212
213 /**
214 * Size of the divider.
215 */
216 protected int dividerSize;
217 private boolean dividerSizeSet = false;
218
219 /**
220 * Is a little widget provided to quickly expand/collapse the
221 * split pane?
222 */
223 protected boolean oneTouchExpandable;
224 private boolean oneTouchExpandableSet;
225
226 /**
227 * Previous location of the split pane.
228 */
229 protected int lastDividerLocation;
230
231 /**
232 * How to distribute extra space.
233 */
234 private double resizeWeight;
235
236 /**
237 * Location of the divider, at least the value that was set, the UI may
238 * have a different value.
239 */
240 private int dividerLocation;
241
242
243 /**
244 * Creates a new <code>JSplitPane</code> configured to arrange the child
245 * components side-by-side horizontally, using two buttons for the components.
246 */
247 public JSplitPane() {
248 this(JSplitPane.HORIZONTAL_SPLIT,
249 UIManager.getBoolean("SplitPane.continuousLayout"),
250 new JButton(UIManager.getString("SplitPane.leftButtonText")),
251 new JButton(UIManager.getString("SplitPane.rightButtonText")));
252 }
253
254
255 /**
256 * Creates a new <code>JSplitPane</code> configured with the
257 * specified orientation.
258 *
259 * @param newOrientation <code>JSplitPane.HORIZONTAL_SPLIT</code> or
260 * <code>JSplitPane.VERTICAL_SPLIT</code>
261 * @exception IllegalArgumentException if <code>orientation</code>
262 * is not one of HORIZONTAL_SPLIT or VERTICAL_SPLIT.
263 */
264 @ConstructorProperties({"orientation"})
265 public JSplitPane(int newOrientation) {
266 this(newOrientation,
267 UIManager.getBoolean("SplitPane.continuousLayout"));
268 }
269
270
271 /**
272 * Creates a new <code>JSplitPane</code> with the specified
273 * orientation and redrawing style.
274 *
275 * @param newOrientation <code>JSplitPane.HORIZONTAL_SPLIT</code> or
276 * <code>JSplitPane.VERTICAL_SPLIT</code>
277 * @param newContinuousLayout a boolean, true for the components to
278 * redraw continuously as the divider changes position, false
279 * to wait until the divider position stops changing to redraw
280 * @exception IllegalArgumentException if <code>orientation</code>
281 * is not one of HORIZONTAL_SPLIT or VERTICAL_SPLIT
282 */
283 public JSplitPane(int newOrientation,
284 boolean newContinuousLayout) {
285 this(newOrientation, newContinuousLayout, null, null);
286 }
287
288
289 /**
290 * Creates a new <code>JSplitPane</code> with the specified
291 * orientation and the specified components.
292 *
293 * @param newOrientation <code>JSplitPane.HORIZONTAL_SPLIT</code> or
294 * <code>JSplitPane.VERTICAL_SPLIT</code>
295 * @param newLeftComponent the <code>Component</code> that will
296 * appear on the left
297 * of a horizontally-split pane, or at the top of a
298 * vertically-split pane
299 * @param newRightComponent the <code>Component</code> that will
300 * appear on the right
301 * of a horizontally-split pane, or at the bottom of a
302 * vertically-split pane
303 * @exception IllegalArgumentException if <code>orientation</code>
304 * is not one of: HORIZONTAL_SPLIT or VERTICAL_SPLIT
305 */
306 public JSplitPane(int newOrientation,
307 Component newLeftComponent,
308 Component newRightComponent){
309 this(newOrientation,
310 UIManager.getBoolean("SplitPane.continuousLayout"),
311 newLeftComponent, newRightComponent);
312 }
313
314
315 /**
316 * Creates a new <code>JSplitPane</code> with the specified
317 * orientation and
318 * redrawing style, and with the specified components.
319 *
320 * @param newOrientation <code>JSplitPane.HORIZONTAL_SPLIT</code> or
321 * <code>JSplitPane.VERTICAL_SPLIT</code>
322 * @param newContinuousLayout a boolean, true for the components to
323 * redraw continuously as the divider changes position, false
324 * to wait until the divider position stops changing to redraw
325 * @param newLeftComponent the <code>Component</code> that will
326 * appear on the left
327 * of a horizontally-split pane, or at the top of a
328 * vertically-split pane
329 * @param newRightComponent the <code>Component</code> that will
330 * appear on the right
331 * of a horizontally-split pane, or at the bottom of a
332 * vertically-split pane
333 * @exception IllegalArgumentException if <code>orientation</code>
334 * is not one of HORIZONTAL_SPLIT or VERTICAL_SPLIT
335 */
336 public JSplitPane(int newOrientation,
337 boolean newContinuousLayout,
338 Component newLeftComponent,
339 Component newRightComponent){
340 super();
341
342 dividerLocation = -1;
343 setLayout(null);
344 setUIProperty("opaque", Boolean.TRUE);
345 orientation = newOrientation;
346 if (orientation != HORIZONTAL_SPLIT && orientation != VERTICAL_SPLIT)
347 throw new IllegalArgumentException("cannot create JSplitPane, " +
348 "orientation must be one of " +
349 "JSplitPane.HORIZONTAL_SPLIT " +
350 "or JSplitPane.VERTICAL_SPLIT");
351 continuousLayout = newContinuousLayout;
352 if (newLeftComponent != null)
353 setLeftComponent(newLeftComponent);
354 if (newRightComponent != null)
355 setRightComponent(newRightComponent);
356 updateUI();
357
358 }
359
360
361 /**
362 * Sets the L&F object that renders this component.
363 *
364 * @param ui the <code>SplitPaneUI</code> L&F object
365 * @see UIDefaults#getUI
366 * @beaninfo
367 * bound: true
368 * hidden: true
369 * attribute: visualUpdate true
370 * description: The UI object that implements the Component's LookAndFeel.
371 */
372 public void setUI(SplitPaneUI ui) {
373 if ((SplitPaneUI)this.ui != ui) {
374 super.setUI(ui);
375 revalidate();
376 }
377 }
378
379
380 /**
381 * Returns the <code>SplitPaneUI</code> that is providing the
382 * current look and feel.
383 *
384 * @return the <code>SplitPaneUI</code> object that renders this component
385 * @beaninfo
386 * expert: true
387 * description: The L&F object that renders this component.
388 */
389 public SplitPaneUI getUI() {
390 return (SplitPaneUI)ui;
391 }
392
393
394 /**
395 * Notification from the <code>UIManager</code> that the L&F has changed.
396 * Replaces the current UI object with the latest version from the
397 * <code>UIManager</code>.
398 *
399 * @see JComponent#updateUI
400 */
401 public void updateUI() {
402 setUI((SplitPaneUI)UIManager.getUI(this));
403 revalidate();
404 }
405
406
407 /**
408 * Returns the name of the L&F class that renders this component.
409 *
410 * @return the string "SplitPaneUI"
411 * @see JComponent#getUIClassID
412 * @see UIDefaults#getUI
413 * @beaninfo
414 * expert: true
415 * description: A string that specifies the name of the L&F class.
416 */
417 public String getUIClassID() {
418 return uiClassID;
419 }
420
421
422 /**
423 * Sets the size of the divider.
424 *
425 * @param newSize an integer giving the size of the divider in pixels
426 * @beaninfo
427 * bound: true
428 * description: The size of the divider.
429 */
430 public void setDividerSize(int newSize) {
431 int oldSize = dividerSize;
432
433 dividerSizeSet = true;
434 if (oldSize != newSize) {
435 dividerSize = newSize;
436 firePropertyChange(DIVIDER_SIZE_PROPERTY, oldSize, newSize);
437 }
438 }
439
440
441 /**
442 * Returns the size of the divider.
443 *
444 * @return an integer giving the size of the divider in pixels
445 */
446 public int getDividerSize() {
447 return dividerSize;
448 }
449
450
451 /**
452 * Sets the component to the left (or above) the divider.
453 *
454 * @param comp the <code>Component</code> to display in that position
455 */
456 public void setLeftComponent(Component comp) {
457 if (comp == null) {
458 if (leftComponent != null) {
459 remove(leftComponent);
460 leftComponent = null;
461 }
462 } else {
463 add(comp, JSplitPane.LEFT);
464 }
465 }
466
467
468 /**
469 * Returns the component to the left (or above) the divider.
470 *
471 * @return the <code>Component</code> displayed in that position
472 * @beaninfo
473 * preferred: true
474 * description: The component to the left (or above) the divider.
475 */
476 public Component getLeftComponent() {
477 return leftComponent;
478 }
479
480
481 /**
482 * Sets the component above, or to the left of the divider.
483 *
484 * @param comp the <code>Component</code> to display in that position
485 * @beaninfo
486 * description: The component above, or to the left of the divider.
487 */
488 public void setTopComponent(Component comp) {
489 setLeftComponent(comp);
490 }
491
492
493 /**
494 * Returns the component above, or to the left of the divider.
495 *
496 * @return the <code>Component</code> displayed in that position
497 */
498 public Component getTopComponent() {
499 return leftComponent;
500 }
501
502
503 /**
504 * Sets the component to the right (or below) the divider.
505 *
506 * @param comp the <code>Component</code> to display in that position
507 * @beaninfo
508 * preferred: true
509 * description: The component to the right (or below) the divider.
510 */
511 public void setRightComponent(Component comp) {
512 if (comp == null) {
513 if (rightComponent != null) {
514 remove(rightComponent);
515 rightComponent = null;
516 }
517 } else {
518 add(comp, JSplitPane.RIGHT);
519 }
520 }
521
522
523 /**
524 * Returns the component to the right (or below) the divider.
525 *
526 * @return the <code>Component</code> displayed in that position
527 */
528 public Component getRightComponent() {
529 return rightComponent;
530 }
531
532
533 /**
534 * Sets the component below, or to the right of the divider.
535 *
536 * @param comp the <code>Component</code> to display in that position
537 * @beaninfo
538 * description: The component below, or to the right of the divider.
539 */
540 public void setBottomComponent(Component comp) {
541 setRightComponent(comp);
542 }
543
544
545 /**
546 * Returns the component below, or to the right of the divider.
547 *
548 * @return the <code>Component</code> displayed in that position
549 */
550 public Component getBottomComponent() {
551 return rightComponent;
552 }
553
554
555 /**
556 * Sets the value of the <code>oneTouchExpandable</code> property,
557 * which must be <code>true</code> for the
558 * <code>JSplitPane</code> to provide a UI widget
559 * on the divider to quickly expand/collapse the divider.
560 * The default value of this property is <code>false</code>.
561 * Some look and feels might not support one-touch expanding;
562 * they will ignore this property.
563 *
564 * @param newValue <code>true</code> to specify that the split pane should provide a
565 * collapse/expand widget
566 * @beaninfo
567 * bound: true
568 * description: UI widget on the divider to quickly
569 * expand/collapse the divider.
570 *
571 * @see #isOneTouchExpandable
572 */
573 public void setOneTouchExpandable(boolean newValue) {
574 boolean oldValue = oneTouchExpandable;
575
576 oneTouchExpandable = newValue;
577 oneTouchExpandableSet = true;
578 firePropertyChange(ONE_TOUCH_EXPANDABLE_PROPERTY, oldValue, newValue);
579 repaint();
580 }
581
582
583 /**
584 * Gets the <code>oneTouchExpandable</code> property.
585 *
586 * @return the value of the <code>oneTouchExpandable</code> property
587 * @see #setOneTouchExpandable
588 */
589 public boolean isOneTouchExpandable() {
590 return oneTouchExpandable;
591 }
592
593
594 /**
595 * Sets the last location the divider was at to
596 * <code>newLastLocation</code>.
597 *
598 * @param newLastLocation an integer specifying the last divider location
599 * in pixels, from the left (or upper) edge of the pane to the
600 * left (or upper) edge of the divider
601 * @beaninfo
602 * bound: true
603 * description: The last location the divider was at.
604 */
605 public void setLastDividerLocation(int newLastLocation) {
606 int oldLocation = lastDividerLocation;
607
608 lastDividerLocation = newLastLocation;
609 firePropertyChange(LAST_DIVIDER_LOCATION_PROPERTY, oldLocation,
610 newLastLocation);
611 }
612
613
614 /**
615 * Returns the last location the divider was at.
616 *
617 * @return an integer specifying the last divider location as a count
618 * of pixels from the left (or upper) edge of the pane to the
619 * left (or upper) edge of the divider
620 */
621 public int getLastDividerLocation() {
622 return lastDividerLocation;
623 }
624
625
626 /**
627 * Sets the orientation, or how the splitter is divided. The options
628 * are:<ul>
629 * <li>JSplitPane.VERTICAL_SPLIT (above/below orientation of components)
630 * <li>JSplitPane.HORIZONTAL_SPLIT (left/right orientation of components)
631 * </ul>
632 *
633 * @param orientation an integer specifying the orientation
634 * @exception IllegalArgumentException if orientation is not one of:
635 * HORIZONTAL_SPLIT or VERTICAL_SPLIT.
636 * @beaninfo
637 * bound: true
638 * description: The orientation, or how the splitter is divided.
639 * enum: HORIZONTAL_SPLIT JSplitPane.HORIZONTAL_SPLIT
640 * VERTICAL_SPLIT JSplitPane.VERTICAL_SPLIT
641 */
642 public void setOrientation(int orientation) {
643 if ((orientation != VERTICAL_SPLIT) &&
644 (orientation != HORIZONTAL_SPLIT)) {
645 throw new IllegalArgumentException("JSplitPane: orientation must " +
646 "be one of " +
647 "JSplitPane.VERTICAL_SPLIT or " +
648 "JSplitPane.HORIZONTAL_SPLIT");
649 }
650
651 int oldOrientation = this.orientation;
652
653 this.orientation = orientation;
654 firePropertyChange(ORIENTATION_PROPERTY, oldOrientation, orientation);
655 }
656
657
658 /**
659 * Returns the orientation.
660 *
661 * @return an integer giving the orientation
662 * @see #setOrientation
663 */
664 public int getOrientation() {
665 return orientation;
666 }
667
668
669 /**
670 * Sets the value of the <code>continuousLayout</code> property,
671 * which must be <code>true</code> for the child components
672 * to be continuously
673 * redisplayed and laid out during user intervention.
674 * The default value of this property is look and feel dependent.
675 * Some look and feels might not support continuous layout;
676 * they will ignore this property.
677 *
678 * @param newContinuousLayout <code>true</code> if the components
679 * should continuously be redrawn as the divider changes position
680 * @beaninfo
681 * bound: true
682 * description: Whether the child components are
683 * continuously redisplayed and laid out during
684 * user intervention.
685 * @see #isContinuousLayout
686 */
687 public void setContinuousLayout(boolean newContinuousLayout) {
688 boolean oldCD = continuousLayout;
689
690 continuousLayout = newContinuousLayout;
691 firePropertyChange(CONTINUOUS_LAYOUT_PROPERTY, oldCD,
692 newContinuousLayout);
693 }
694
695
696 /**
697 * Gets the <code>continuousLayout</code> property.
698 *
699 * @return the value of the <code>continuousLayout</code> property
700 * @see #setContinuousLayout
701 */
702 public boolean isContinuousLayout() {
703 return continuousLayout;
704 }
705
706 /**
707 * Specifies how to distribute extra space when the size of the split pane
708 * changes. A value of 0, the default,
709 * indicates the right/bottom component gets all the extra space (the
710 * left/top component acts fixed), where as a value of 1 specifies the
711 * left/top component gets all the extra space (the right/bottom component
712 * acts fixed). Specifically, the left/top component gets (weight * diff)
713 * extra space and the right/bottom component gets (1 - weight) * diff
714 * extra space.
715 *
716 * @param value as described above
717 * @exception IllegalArgumentException if <code>value</code> is < 0 or > 1
718 * @since 1.3
719 * @beaninfo
720 * bound: true
721 * description: Specifies how to distribute extra space when the split pane
722 * resizes.
723 */
724 public void setResizeWeight(double value) {
725 if (value < 0 || value > 1) {
726 throw new IllegalArgumentException("JSplitPane weight must be between 0 and 1");
727 }
728 double oldWeight = resizeWeight;
729
730 resizeWeight = value;
731 firePropertyChange(RESIZE_WEIGHT_PROPERTY, oldWeight, value);
732 }
733
734 /**
735 * Returns the number that determines how extra space is distributed.
736 * @return how extra space is to be distributed on a resize of the
737 * split pane
738 * @since 1.3
739 */
740 public double getResizeWeight() {
741 return resizeWeight;
742 }
743
744 /**
745 * Lays out the <code>JSplitPane</code> layout based on the preferred size
746 * of the children components. This will likely result in changing
747 * the divider location.
748 */
749 public void resetToPreferredSizes() {
750 SplitPaneUI ui = getUI();
751
752 if (ui != null) {
753 ui.resetToPreferredSizes(this);
754 }
755 }
756
757
758 /**
759 * Sets the divider location as a percentage of the
760 * <code>JSplitPane</code>'s size.
761 * <p>
762 * This method is implemented in terms of
763 * <code>setDividerLocation(int)</code>.
764 * This method immediately changes the size of the split pane based on
765 * its current size. If the split pane is not correctly realized and on
766 * screen, this method will have no effect (new divider location will
767 * become (current size * proportionalLocation) which is 0).
768 *
769 * @param proportionalLocation a double-precision floating point value
770 * that specifies a percentage, from zero (top/left) to 1.0
771 * (bottom/right)
772 * @exception IllegalArgumentException if the specified location is < 0
773 * or > 1.0
774 * @beaninfo
775 * description: The location of the divider.
776 */
777 public void setDividerLocation(double proportionalLocation) {
778 if (proportionalLocation < 0.0 ||
779 proportionalLocation > 1.0) {
780 throw new IllegalArgumentException("proportional location must " +
781 "be between 0.0 and 1.0.");
782 }
783 if (getOrientation() == VERTICAL_SPLIT) {
784 setDividerLocation((int)((double)(getHeight() - getDividerSize()) *
785 proportionalLocation));
786 } else {
787 setDividerLocation((int)((double)(getWidth() - getDividerSize()) *
788 proportionalLocation));
789 }
790 }
791
792
793 /**
794 * Sets the location of the divider. This is passed off to the
795 * look and feel implementation, and then listeners are notified. A value
796 * less than 0 implies the divider should be reset to a value that
797 * attempts to honor the preferred size of the left/top component.
798 * After notifying the listeners, the last divider location is updated,
799 * via <code>setLastDividerLocation</code>.
800 *
801 * @param location an int specifying a UI-specific value (typically a
802 * pixel count)
803 * @beaninfo
804 * bound: true
805 * description: The location of the divider.
806 */
807 public void setDividerLocation(int location) {
808 int oldValue = dividerLocation;
809
810 dividerLocation = location;
811
812 // Notify UI.
813 SplitPaneUI ui = getUI();
814
815 if (ui != null) {
816 ui.setDividerLocation(this, location);
817 }
818
819 // Then listeners
820 firePropertyChange(DIVIDER_LOCATION_PROPERTY, oldValue, location);
821
822 // And update the last divider location.
823 setLastDividerLocation(oldValue);
824 }
825
826
827 /**
828 * Returns the last value passed to <code>setDividerLocation</code>.
829 * The value returned from this method may differ from the actual
830 * divider location (if <code>setDividerLocation</code> was passed a
831 * value bigger than the curent size).
832 *
833 * @return an integer specifying the location of the divider
834 */
835 public int getDividerLocation() {
836 return dividerLocation;
837 }
838
839
840 /**
841 * Returns the minimum location of the divider from the look and feel
842 * implementation.
843 *
844 * @return an integer specifying a UI-specific value for the minimum
845 * location (typically a pixel count); or -1 if the UI is
846 * <code>null</code>
847 * @beaninfo
848 * description: The minimum location of the divider from the L&F.
849 */
850 public int getMinimumDividerLocation() {
851 SplitPaneUI ui = getUI();
852
853 if (ui != null) {
854 return ui.getMinimumDividerLocation(this);
855 }
856 return -1;
857 }
858
859
860 /**
861 * Returns the maximum location of the divider from the look and feel
862 * implementation.
863 *
864 * @return an integer specifying a UI-specific value for the maximum
865 * location (typically a pixel count); or -1 if the UI is
866 * <code>null</code>
867 */
868 public int getMaximumDividerLocation() {
869 SplitPaneUI ui = getUI();
870
871 if (ui != null) {
872 return ui.getMaximumDividerLocation(this);
873 }
874 return -1;
875 }
876
877
878 /**
879 * Removes the child component, <code>component</code> from the
880 * pane. Resets the <code>leftComponent</code> or
881 * <code>rightComponent</code> instance variable, as necessary.
882 *
883 * @param component the <code>Component</code> to remove
884 */
885 public void remove(Component component) {
886 if (component == leftComponent) {
887 leftComponent = null;
888 } else if (component == rightComponent) {
889 rightComponent = null;
890 }
891 super.remove(component);
892
893 // Update the JSplitPane on the screen
894 revalidate();
895 repaint();
896 }
897
898
899 /**
900 * Removes the <code>Component</code> at the specified index.
901 * Updates the <code>leftComponent</code> and <code>rightComponent</code>
902 * instance variables as necessary, and then messages super.
903 *
904 * @param index an integer specifying the component to remove, where
905 * 1 specifies the left/top component and 2 specifies the
906 * bottom/right component
907 */
908 public void remove(int index) {
909 Component comp = getComponent(index);
910
911 if (comp == leftComponent) {
912 leftComponent = null;
913 } else if (comp == rightComponent) {
914 rightComponent = null;
915 }
916 super.remove(index);
917
918 // Update the JSplitPane on the screen
919 revalidate();
920 repaint();
921 }
922
923
924 /**
925 * Removes all the child components from the split pane. Resets the
926 * <code>leftComonent</code> and <code>rightComponent</code>
927 * instance variables.
928 */
929 public void removeAll() {
930 leftComponent = rightComponent = null;
931 super.removeAll();
932
933 // Update the JSplitPane on the screen
934 revalidate();
935 repaint();
936 }
937
938
939 /**
940 * Returns true, so that calls to <code>revalidate</code>
941 * on any descendant of this <code>JSplitPane</code>
942 * will cause a request to be queued that
943 * will validate the <code>JSplitPane</code> and all its descendants.
944 *
945 * @return true
946 * @see JComponent#revalidate
947 * @see java.awt.Container#isValidateRoot
948 *
949 * @beaninfo
950 * hidden: true
951 */
952 @Override
953 public boolean isValidateRoot() {
954 return true;
955 }
956
957
958 /**
959 * Adds the specified component to this split pane.
960 * If <code>constraints</code> identifies the left/top or
961 * right/bottom child component, and a component with that identifier
962 * was previously added, it will be removed and then <code>comp</code>
963 * will be added in its place. If <code>constraints</code> is not
964 * one of the known identifiers the layout manager may throw an
965 * <code>IllegalArgumentException</code>.
966 * <p>
967 * The possible constraints objects (Strings) are:
968 * <ul>
969 * <li>JSplitPane.TOP
970 * <li>JSplitPane.LEFT
971 * <li>JSplitPane.BOTTOM
972 * <li>JSplitPane.RIGHT
973 * </ul>
974 * If the <code>constraints</code> object is <code>null</code>,
975 * the component is added in the
976 * first available position (left/top if open, else right/bottom).
977 *
978 * @param comp the component to add
979 * @param constraints an <code>Object</code> specifying the
980 * layout constraints
981 * (position) for this component
982 * @param index an integer specifying the index in the container's
983 * list.
984 * @exception IllegalArgumentException if the <code>constraints</code>
985 * object does not match an existing component
986 * @see java.awt.Container#addImpl(Component, Object, int)
987 */
988 protected void addImpl(Component comp, Object constraints, int index)
989 {
990 Component toRemove;
991
992 if (constraints != null && !(constraints instanceof String)) {
993 throw new IllegalArgumentException("cannot add to layout: " +
994 "constraint must be a string " +
995 "(or null)");
996 }
997
998 /* If the constraints are null and the left/right component is
999 invalid, add it at the left/right component. */
1000 if (constraints == null) {
1001 if (getLeftComponent() == null) {
1002 constraints = JSplitPane.LEFT;
1003 } else if (getRightComponent() == null) {
1004 constraints = JSplitPane.RIGHT;
1005 }
1006 }
1007
1008 /* Find the Component that already exists and remove it. */
1009 if (constraints != null && (constraints.equals(JSplitPane.LEFT) ||
1010 constraints.equals(JSplitPane.TOP))) {
1011 toRemove = getLeftComponent();
1012 if (toRemove != null) {
1013 remove(toRemove);
1014 }
1015 leftComponent = comp;
1016 index = -1;
1017 } else if (constraints != null &&
1018 (constraints.equals(JSplitPane.RIGHT) ||
1019 constraints.equals(JSplitPane.BOTTOM))) {
1020 toRemove = getRightComponent();
1021 if (toRemove != null) {
1022 remove(toRemove);
1023 }
1024 rightComponent = comp;
1025 index = -1;
1026 } else if (constraints != null &&
1027 constraints.equals(JSplitPane.DIVIDER)) {
1028 index = -1;
1029 }
1030 /* LayoutManager should raise for else condition here. */
1031
1032 super.addImpl(comp, constraints, index);
1033
1034 // Update the JSplitPane on the screen
1035 revalidate();
1036 repaint();
1037 }
1038
1039
1040 /**
1041 * Subclassed to message the UI with <code>finishedPaintingChildren</code>
1042 * after super has been messaged, as well as painting the border.
1043 *
1044 * @param g the <code>Graphics</code> context within which to paint
1045 */
1046 protected void paintChildren(Graphics g) {
1047 super.paintChildren(g);
1048
1049 SplitPaneUI ui = getUI();
1050
1051 if (ui != null) {
1052 Graphics tempG = g.create();
1053 ui.finishedPaintingChildren(this, tempG);
1054 tempG.dispose();
1055 }
1056 }
1057
1058
1059 /**
1060 * See <code>readObject</code> and <code>writeObject</code> in
1061 * <code>JComponent</code> for more
1062 * information about serialization in Swing.
1063 */
1064 private void writeObject(ObjectOutputStream s) throws IOException {
1065 s.defaultWriteObject();
1066 if (getUIClassID().equals(uiClassID)) {
1067 byte count = JComponent.getWriteObjCounter(this);
1068 JComponent.setWriteObjCounter(this, --count);
1069 if (count == 0 && ui != null) {
1070 ui.installUI(this);
1071 }
1072 }
1073 }
1074
1075 void setUIProperty(String propertyName, Object value) {
1076 if (propertyName == "dividerSize") {
1077 if (!dividerSizeSet) {
1078 setDividerSize(((Number)value).intValue());
1079 dividerSizeSet = false;
1080 }
1081 } else if (propertyName == "oneTouchExpandable") {
1082 if (!oneTouchExpandableSet) {
1083 setOneTouchExpandable(((Boolean)value).booleanValue());
1084 oneTouchExpandableSet = false;
1085 }
1086 } else {
1087 super.setUIProperty(propertyName, value);
1088 }
1089 }
1090
1091
1092 /**
1093 * Returns a string representation of this <code>JSplitPane</code>.
1094 * This method
1095 * is intended to be used only for debugging purposes, and the
1096 * content and format of the returned string may vary between
1097 * implementations. The returned string may be empty but may not
1098 * be <code>null</code>.
1099 *
1100 * @return a string representation of this <code>JSplitPane</code>.
1101 */
1102 protected String paramString() {
1103 String orientationString = (orientation == HORIZONTAL_SPLIT ?
1104 "HORIZONTAL_SPLIT" : "VERTICAL_SPLIT");
1105 String continuousLayoutString = (continuousLayout ?
1106 "true" : "false");
1107 String oneTouchExpandableString = (oneTouchExpandable ?
1108 "true" : "false");
1109
1110 return super.paramString() +
1111 ",continuousLayout=" + continuousLayoutString +
1112 ",dividerSize=" + dividerSize +
1113 ",lastDividerLocation=" + lastDividerLocation +
1114 ",oneTouchExpandable=" + oneTouchExpandableString +
1115 ",orientation=" + orientationString;
1116 }
1117
1118
1119
1120 ///////////////////////////
1121 // Accessibility support //
1122 ///////////////////////////
1123
1124
1125 /**
1126 * Gets the AccessibleContext associated with this JSplitPane.
1127 * For split panes, the AccessibleContext takes the form of an
1128 * AccessibleJSplitPane.
1129 * A new AccessibleJSplitPane instance is created if necessary.
1130 *
1131 * @return an AccessibleJSplitPane that serves as the
1132 * AccessibleContext of this JSplitPane
1133 * @beaninfo
1134 * expert: true
1135 * description: The AccessibleContext associated with this SplitPane.
1136 */
1137 public AccessibleContext getAccessibleContext() {
1138 if (accessibleContext == null) {
1139 accessibleContext = new AccessibleJSplitPane();
1140 }
1141 return accessibleContext;
1142 }
1143
1144
1145 /**
1146 * This class implements accessibility support for the
1147 * <code>JSplitPane</code> class. It provides an implementation of the
1148 * Java Accessibility API appropriate to split pane user-interface elements.
1149 * <p>
1150 * <strong>Warning:</strong>
1151 * Serialized objects of this class will not be compatible with
1152 * future Swing releases. The current serialization support is
1153 * appropriate for short term storage or RMI between applications running
1154 * the same version of Swing. As of 1.4, support for long term storage
1155 * of all JavaBeans<sup><font size="-2">TM</font></sup>
1156 * has been added to the <code>java.beans</code> package.
1157 * Please see {@link java.beans.XMLEncoder}.
1158 */
1159 protected class AccessibleJSplitPane extends AccessibleJComponent
1160 implements AccessibleValue {
1161 /**
1162 * Gets the state set of this object.
1163 *
1164 * @return an instance of AccessibleState containing the current state
1165 * of the object
1166 * @see AccessibleState
1167 */
1168 public AccessibleStateSet getAccessibleStateSet() {
1169 AccessibleStateSet states = super.getAccessibleStateSet();
1170 // FIXME: [[[WDW - Should also add BUSY if this implements
1171 // Adjustable at some point. If this happens, we probably
1172 // should also add actions.]]]
1173 if (getOrientation() == VERTICAL_SPLIT) {
1174 states.add(AccessibleState.VERTICAL);
1175 } else {
1176 states.add(AccessibleState.HORIZONTAL);
1177 }
1178 return states;
1179 }
1180
1181
1182 /**
1183 * Get the AccessibleValue associated with this object. In the
1184 * implementation of the Java Accessibility API for this class,
1185 * return this object, which is responsible for implementing the
1186 * AccessibleValue interface on behalf of itself.
1187 *
1188 * @return this object
1189 */
1190 public AccessibleValue getAccessibleValue() {
1191 return this;
1192 }
1193
1194
1195 /**
1196 * Gets the accessible value of this object.
1197 *
1198 * @return a localized String describing the value of this object
1199 */
1200 public Number getCurrentAccessibleValue() {
1201 return Integer.valueOf(getDividerLocation());
1202 }
1203
1204
1205 /**
1206 * Sets the value of this object as a Number.
1207 *
1208 * @return True if the value was set.
1209 */
1210 public boolean setCurrentAccessibleValue(Number n) {
1211 // TIGER - 4422535
1212 if (n == null) {
1213 return false;
1214 }
1215 setDividerLocation(n.intValue());
1216 return true;
1217 }
1218
1219
1220 /**
1221 * Gets the minimum accessible value of this object.
1222 *
1223 * @return The minimum value of this object.
1224 */
1225 public Number getMinimumAccessibleValue() {
1226 return Integer.valueOf(getUI().getMinimumDividerLocation(
1227 JSplitPane.this));
1228 }
1229
1230
1231 /**
1232 * Gets the maximum accessible value of this object.
1233 *
1234 * @return The maximum value of this object.
1235 */
1236 public Number getMaximumAccessibleValue() {
1237 return Integer.valueOf(getUI().getMaximumDividerLocation(
1238 JSplitPane.this));
1239 }
1240
1241
1242 /**
1243 * Gets the role of this object.
1244 *
1245 * @return an instance of AccessibleRole describing the role of
1246 * the object
1247 * @see AccessibleRole
1248 */
1249 public AccessibleRole getAccessibleRole() {
1250 return AccessibleRole.SPLIT_PANE;
1251 }
1252 } // inner class AccessibleJSplitPane
1253}