001 /* JSplitPane.java --
002 Copyright (C) 2004, 2006, Free Software Foundation, Inc.
003
004 This file is part of GNU Classpath.
005
006 GNU Classpath is free software; you can redistribute it and/or modify
007 it under the terms of the GNU General Public License as published by
008 the Free Software Foundation; either version 2, or (at your option)
009 any later version.
010
011 GNU Classpath is distributed in the hope that it will be useful, but
012 WITHOUT ANY WARRANTY; without even the implied warranty of
013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014 General Public License for more details.
015
016 You should have received a copy of the GNU General Public License
017 along with GNU Classpath; see the file COPYING. If not, write to the
018 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
019 02110-1301 USA.
020
021 Linking this library statically or dynamically with other modules is
022 making a combined work based on this library. Thus, the terms and
023 conditions of the GNU General Public License cover the whole
024 combination.
025
026 As a special exception, the copyright holders of this library give you
027 permission to link this library with independent modules to produce an
028 executable, regardless of the license terms of these independent
029 modules, and to copy and distribute the resulting executable under
030 terms of your choice, provided that you also meet, for each linked
031 independent module, the terms and conditions of the license of that
032 module. An independent module is a module which is not derived from
033 or based on this library. If you modify this library, you may extend
034 this exception to your version of the library, but you are not
035 obligated to do so. If you do not wish to do so, delete this
036 exception statement from your version. */
037
038
039 package javax.swing;
040
041 import java.awt.Component;
042 import java.awt.Graphics;
043 import java.beans.PropertyChangeEvent;
044
045 import javax.accessibility.Accessible;
046 import javax.accessibility.AccessibleContext;
047 import javax.accessibility.AccessibleRole;
048 import javax.accessibility.AccessibleState;
049 import javax.accessibility.AccessibleStateSet;
050 import javax.accessibility.AccessibleValue;
051 import javax.swing.plaf.SplitPaneUI;
052
053 /**
054 * This class implements JSplitPane. It is used to divide two components. By
055 * dragging the SplitPane's divider, the user can resize the two components.
056 * Note that the divider cannot resize a component to smaller than it's
057 * minimum size.
058 */
059 public class JSplitPane extends JComponent implements Accessible
060 {
061
062 /**
063 * Provides the accessibility features for the <code>JSplitPane</code>
064 * component.
065 */
066 protected class AccessibleJSplitPane extends JComponent.AccessibleJComponent
067 implements AccessibleValue
068 {
069 private static final long serialVersionUID = -1788116871416305366L;
070
071 /**
072 * Creates a new <code>AccessibleJSplitPane</code> instance.
073 */
074 protected AccessibleJSplitPane()
075 {
076 // Nothing to do here.
077 }
078
079 /**
080 * Returns a set containing the current state of the {@link JSplitPane}
081 * component.
082 *
083 * @return The accessible state set.
084 */
085 public AccessibleStateSet getAccessibleStateSet()
086 {
087 AccessibleStateSet result = super.getAccessibleStateSet();
088 if (getOrientation() == HORIZONTAL_SPLIT)
089 {
090 result.add(AccessibleState.HORIZONTAL);
091 }
092 else if (getOrientation() == VERTICAL_SPLIT)
093 {
094 result.add(AccessibleState.VERTICAL);
095 }
096 return result;
097 }
098
099 /**
100 * Returns the accessible role for the <code>JSplitPane</code> component.
101 *
102 * @return {@link AccessibleRole#SPLIT_PANE}.
103 */
104 public AccessibleRole getAccessibleRole()
105 {
106 return AccessibleRole.SPLIT_PANE;
107 }
108
109 /**
110 * Returns an object that provides access to the current, minimum and
111 * maximum values for the {@link JSplitPane}. Since this class implements
112 * {@link AccessibleValue}, it returns itself.
113 *
114 * @return The accessible value.
115 */
116 public AccessibleValue getAccessibleValue()
117 {
118 return this;
119 }
120
121 /**
122 * Returns the current divider location for the {@link JSplitPane}
123 * component, as an {@link Integer}.
124 *
125 * @return The current divider location.
126 */
127 public Number getCurrentAccessibleValue()
128 {
129 return new Integer(getDividerLocation());
130 }
131
132 /**
133 * Sets the divider location for the {@link JSplitPane} component and sends
134 * a {@link PropertyChangeEvent} (with the property name
135 * {@link AccessibleContext#ACCESSIBLE_VALUE_PROPERTY}) to all registered
136 * listeners. If the supplied value is <code>null</code>, this method
137 * does nothing and returns <code>false</code>.
138 *
139 * @param value the new divider location (<code>null</code> permitted).
140 *
141 * @return <code>true</code> if the divider location value is updated, and
142 * <code>false</code> otherwise.
143 */
144 public boolean setCurrentAccessibleValue(Number value)
145 {
146 if (value == null)
147 return false;
148 Number oldValue = getCurrentAccessibleValue();
149 setDividerLocation(value.intValue());
150 firePropertyChange(AccessibleContext.ACCESSIBLE_VALUE_PROPERTY, oldValue,
151 new Integer(value.intValue()));
152 return true;
153 }
154
155 /**
156 * Returns the minimum divider location for the {@link JSplitPane}
157 * component, as an {@link Integer}.
158 *
159 * @return The minimum divider location.
160 */
161 public Number getMinimumAccessibleValue()
162 {
163 return new Integer(getMinimumDividerLocation());
164 }
165
166 /**
167 * Returns the maximum divider location for the {@link JSplitPane}
168 * component, as an {@link Integer}.
169 *
170 * @return The maximum divider location.
171 */
172 public Number getMaximumAccessibleValue()
173 {
174 return new Integer(getMaximumDividerLocation());
175 }
176 }
177
178 private static final long serialVersionUID = -5634142046175988380L;
179
180 /** The constraints string used to add components to the bottom. */
181 public static final String BOTTOM = "bottom";
182
183 /** The property fired when the continuousLayout property changes. */
184 public static final String CONTINUOUS_LAYOUT_PROPERTY = "continuousLayout";
185
186 /** The property fired when the divider property changes. */
187 public static final String DIVIDER = "divider";
188
189 /** The property fired when the divider location property changes. */
190 public static final String DIVIDER_LOCATION_PROPERTY = "dividerLocation";
191
192 /** The property fired when the divider size property changes. */
193 public static final String DIVIDER_SIZE_PROPERTY = "dividerSize";
194
195 /**
196 * The value of the orientation when the components are split horizontally.
197 */
198 public static final int HORIZONTAL_SPLIT = 1;
199
200 /** The property fired when the last divider location property changes. */
201 public static final String LAST_DIVIDER_LOCATION_PROPERTY =
202 "lastDividerLocation";
203
204 /** The constraints string used to add components to the left. */
205 public static final String LEFT = "left";
206
207 /** The property fired when the one touch expandable property changes. */
208 public static final String ONE_TOUCH_EXPANDABLE_PROPERTY =
209 "oneTouchExpandable";
210
211 /** The property fired when the orientation property changes. */
212 public static final String ORIENTATION_PROPERTY = "orientation";
213
214 /** The property fired when the resize weight property changes. */
215 public static final String RESIZE_WEIGHT_PROPERTY = "resizeWeight";
216
217 /** The constraints string used to add components to the right. */
218 public static final String RIGHT = "right";
219
220 /** The constraints string used to add components to the top. */
221 public static final String TOP = "top";
222
223 /** The value of the orientation when the components are split vertically. */
224 public static final int VERTICAL_SPLIT = 0;
225
226 /** Whether the JSplitPane uses continuous layout. */
227 protected boolean continuousLayout;
228
229 /** Whether the JSplitPane uses one touch expandable buttons. */
230 protected boolean oneTouchExpandable = false;
231
232 // This is the master dividerSize variable and sets the
233 // BasicSplitPaneDivider one accordingly
234
235 /** The size of the divider. */
236 protected int dividerSize = 10;
237
238 /** The last location of the divider given by the UI. */
239 protected int lastDividerLocation;
240
241 /** The orientation of the JSplitPane. */
242 protected int orientation;
243
244 /** The component on the top or left. */
245 protected Component leftComponent;
246
247 /** The component on the right or bottom. */
248 protected Component rightComponent;
249
250 /**
251 * The divider location.
252 */
253 private int dividerLocation;
254
255 /** Determines how extra space should be allocated. */
256 private transient double resizeWeight;
257
258 /**
259 * Indicates if the dividerSize property has been set by a client program or
260 * by the UI.
261 *
262 * @see #setUIProperty(String, Object)
263 * @see LookAndFeel#installProperty(JComponent, String, Object)
264 */
265 private boolean clientDividerSizeSet = false;
266
267 /**
268 * Indicates if the oneTouchExpandable property has been set by a client
269 * program or by the UI.
270 *
271 * @see #setUIProperty(String, Object)
272 * @see LookAndFeel#installProperty(JComponent, String, Object)
273 */
274 private boolean clientOneTouchExpandableSet = false;
275
276 /**
277 * Creates a new JSplitPane object with the given orientation, layout mode,
278 * and left and right components.
279 *
280 * @param newOrientation The orientation to use.
281 * @param newContinuousLayout The layout mode to use.
282 * @param newLeftComponent The left component.
283 * @param newRightComponent The right component.
284 *
285 * @throws IllegalArgumentException DOCUMENT ME!
286 */
287 public JSplitPane(int newOrientation, boolean newContinuousLayout,
288 Component newLeftComponent, Component newRightComponent)
289 {
290 if (newOrientation != HORIZONTAL_SPLIT && newOrientation != VERTICAL_SPLIT)
291 throw new IllegalArgumentException("orientation is invalid.");
292 orientation = newOrientation;
293 continuousLayout = newContinuousLayout;
294 setLeftComponent(newLeftComponent);
295 setRightComponent(newRightComponent);
296 dividerLocation = -1;
297 updateUI();
298 }
299
300 /**
301 * Creates a new JSplitPane object using nonContinuousLayout mode, the given
302 * orientation and left and right components.
303 *
304 * @param newOrientation The orientation to use.
305 * @param newLeftComponent The left component.
306 * @param newRightComponent The right component.
307 */
308 public JSplitPane(int newOrientation, Component newLeftComponent,
309 Component newRightComponent)
310 {
311 this(newOrientation, false, newLeftComponent, newRightComponent);
312 }
313
314 /**
315 * Creates a new JSplitPane object with the given layout mode and
316 * orientation.
317 *
318 * @param newOrientation The orientation to use.
319 * @param newContinuousLayout The layout mode to use.
320 */
321 public JSplitPane(int newOrientation, boolean newContinuousLayout)
322 {
323 this(newOrientation, newContinuousLayout, null, null);
324 }
325
326 /**
327 * Creates a new JSplitPane object using a nonContinuousLayout mode and the
328 * given orientation.
329 *
330 * @param newOrientation The orientation to use.
331 */
332 public JSplitPane(int newOrientation)
333 {
334 this(newOrientation, false, null, null);
335 }
336
337 /**
338 * Creates a new JSplitPane object using HORIZONTAL_SPLIT and a
339 * nonContinuousLayout mode.
340 */
341 public JSplitPane()
342 {
343 this(HORIZONTAL_SPLIT, false, new JButton("left button"),
344 new JButton("right button"));
345 }
346
347 /**
348 * This method adds a component to the JSplitPane. The constraints object is
349 * a string that identifies where this component should go. If the
350 * constraints is not a known one, it will throw an
351 * IllegalArgumentException. The valid constraints are LEFT, TOP, RIGHT,
352 * BOTTOM and DIVIDER.
353 *
354 * @param comp The component to add.
355 * @param constraints The constraints string to use.
356 * @param index Where to place to component in the list of components.
357 *
358 * @throws IllegalArgumentException When the constraints is not a known
359 * identifier.
360 */
361 protected void addImpl(Component comp, Object constraints, int index)
362 {
363 if (constraints == null)
364 {
365 if (leftComponent == null)
366 constraints = LEFT;
367 else if (rightComponent == null)
368 constraints = RIGHT;
369 }
370
371 if (constraints instanceof String)
372 {
373 String placement = (String) constraints;
374
375 if (placement.equals(BOTTOM) || placement.equals(RIGHT))
376 {
377 if (rightComponent != null)
378 remove(rightComponent);
379 rightComponent = comp;
380 }
381 else if (placement.equals(LEFT) || placement.equals(TOP))
382 {
383 if (leftComponent != null)
384 remove(leftComponent);
385 leftComponent = comp;
386 }
387 else if (placement.equals(DIVIDER))
388 constraints = null;
389 else
390 throw new
391 IllegalArgumentException("Constraints is not a known identifier.");
392
393 // If no dividerLocation has been set, then we need to trigger an
394 // initial layout.
395 if (getDividerLocation() != -1)
396 resetToPreferredSizes();
397
398 super.addImpl(comp, constraints, index);
399 }
400 }
401
402 /**
403 * Returns the object that provides accessibility features for this
404 * <code>JSplitPane</code> component.
405 *
406 * @return The accessible context (an instance of
407 * {@link AccessibleJSplitPane}).
408 */
409 public AccessibleContext getAccessibleContext()
410 {
411 if (accessibleContext == null)
412 accessibleContext = new AccessibleJSplitPane();
413
414 return accessibleContext;
415 }
416
417 /**
418 * This method returns the bottom component.
419 *
420 * @return The bottom component.
421 */
422 public Component getBottomComponent()
423 {
424 return rightComponent;
425 }
426
427 /**
428 * This method returns the location of the divider. This method is passed to
429 * the UI.
430 *
431 * @return The location of the divider.
432 */
433 public int getDividerLocation()
434 {
435 return dividerLocation;
436 }
437
438 /**
439 * This method returns the size of the divider.
440 *
441 * @return The size of the divider.
442 */
443 public int getDividerSize()
444 {
445 return dividerSize;
446 }
447
448 /**
449 * This method returns the last divider location.
450 *
451 * @return The last divider location.
452 */
453 public int getLastDividerLocation()
454 {
455 return lastDividerLocation;
456 }
457
458 /**
459 * This method returns the left component.
460 *
461 * @return The left component.
462 */
463 public Component getLeftComponent()
464 {
465 return leftComponent;
466 }
467
468 /**
469 * This method returns the maximum divider location. This method is passed
470 * to the UI.
471 *
472 * @return DOCUMENT ME!
473 */
474 public int getMaximumDividerLocation()
475 {
476 if (ui != null)
477 return ((SplitPaneUI) ui).getMaximumDividerLocation(this);
478 else
479 return -1;
480 }
481
482 /**
483 * This method returns the minimum divider location. This method is passed
484 * to the UI.
485 *
486 * @return The minimum divider location.
487 */
488 public int getMinimumDividerLocation()
489 {
490 if (ui != null)
491 return ((SplitPaneUI) ui).getMinimumDividerLocation(this);
492 else
493 return -1;
494 }
495
496 /**
497 * This method returns the orientation that the JSplitPane is using.
498 *
499 * @return The current orientation.
500 */
501 public int getOrientation()
502 {
503 return orientation;
504 }
505
506 /**
507 * This method returns the current resize weight.
508 *
509 * @return The current resize weight.
510 */
511 public double getResizeWeight()
512 {
513 return resizeWeight;
514 }
515
516 /**
517 * This method returns the right component.
518 *
519 * @return The right component.
520 */
521 public Component getRightComponent()
522 {
523 return rightComponent;
524 }
525
526 /**
527 * This method returns the top component.
528 *
529 * @return The top component.
530 */
531 public Component getTopComponent()
532 {
533 return leftComponent;
534 }
535
536 /**
537 * This method returns the UI.
538 *
539 * @return The UI.
540 */
541 public SplitPaneUI getUI()
542 {
543 return (SplitPaneUI) ui;
544 }
545
546 /**
547 * This method returns true if the JSplitPane is using a continuousLayout.
548 *
549 * @return True if using a continuousLayout.
550 */
551 public boolean isContinuousLayout()
552 {
553 return continuousLayout;
554 }
555
556 /**
557 * This method returns true if the divider has one touch expandable buttons.
558 *
559 * @return True if one touch expandable is used.
560 */
561 public boolean isOneTouchExpandable()
562 {
563 return oneTouchExpandable;
564 }
565
566 /**
567 * This method returns true.
568 *
569 * @return true.
570 */
571 public boolean isValidateRoot()
572 {
573 return true;
574 }
575
576 /**
577 * This method overrides JComponent's paintChildren so the UI can be
578 * messaged when the children have finished painting.
579 *
580 * @param g The Graphics object to paint with.
581 */
582 protected void paintChildren(Graphics g)
583 {
584 super.paintChildren(g);
585 if (ui != null)
586 ((SplitPaneUI) ui).finishedPaintingChildren(this, g);
587 }
588
589 /**
590 * Returns an implementation-dependent string describing the attributes of
591 * this <code>JSplitPane</code>.
592 *
593 * @return A string describing the attributes of this <code>JSplitPane</code>
594 * (never <code>null</code>).
595 */
596 protected String paramString()
597 {
598 // FIXME: the next line can be restored once PR27208 is fixed
599 String superParamStr = ""; //super.paramString();
600 StringBuffer sb = new StringBuffer();
601 sb.append(",continuousLayout=").append(isContinuousLayout());
602 sb.append(",dividerSize=").append(getDividerSize());
603 sb.append(",lastDividerLocation=").append(getLastDividerLocation());
604 sb.append(",oneTouchExpandable=").append(isOneTouchExpandable());
605 sb.append(",orientation=");
606 if (orientation == HORIZONTAL_SPLIT)
607 sb.append("HORIZONTAL_SPLIT");
608 else
609 sb.append("VERTICAL_SPLIT");
610 return superParamStr + sb.toString();
611 }
612
613 /**
614 * This method removes the given component from the JSplitPane.
615 *
616 * @param component The Component to remove.
617 */
618 public void remove(Component component)
619 {
620 if (component == leftComponent)
621 leftComponent = null;
622 else if (component == rightComponent)
623 rightComponent = null;
624 super.remove(component);
625 }
626
627 /**
628 * This method removes the component at the given index.
629 *
630 * @param index The index of the component to remove.
631 */
632 public void remove(int index)
633 {
634 Component component = getComponent(index);
635 if (component == leftComponent)
636 leftComponent = null;
637 else if (component == rightComponent)
638 rightComponent = null;
639 super.remove(index);
640 }
641
642 /**
643 * This method removes all components from the JSplitPane.
644 */
645 public void removeAll()
646 {
647 leftComponent = null;
648 rightComponent = null;
649 super.removeAll();
650 }
651
652 /**
653 * This method resets all children of the JSplitPane to their preferred
654 * sizes.
655 */
656 public void resetToPreferredSizes()
657 {
658 if (ui != null)
659 ((SplitPaneUI) ui).resetToPreferredSizes(this);
660 }
661
662 /**
663 * This method sets the bottom component.
664 *
665 * @param comp The Component to be placed at the bottom.
666 */
667 public void setBottomComponent(Component comp)
668 {
669 if (comp != null)
670 add(comp, BOTTOM);
671 else
672 add(new JButton("right button"), BOTTOM);
673 }
674
675 /**
676 * This method sets the layout mode for the JSplitPane.
677 *
678 * @param newContinuousLayout Whether the JSplitPane is in continuousLayout
679 * mode.
680 */
681 public void setContinuousLayout(boolean newContinuousLayout)
682 {
683 if (newContinuousLayout != continuousLayout)
684 {
685 boolean oldValue = continuousLayout;
686 continuousLayout = newContinuousLayout;
687 firePropertyChange(CONTINUOUS_LAYOUT_PROPERTY, oldValue,
688 continuousLayout);
689 }
690 }
691
692 /**
693 * This method sets the location of the divider. A value of 0 sets the
694 * divider to the farthest left. A value of 1 sets the divider to the
695 * farthest right.
696 *
697 * @param proportionalLocation A double that describes the location of the
698 * divider.
699 *
700 * @throws IllegalArgumentException if <code>proportionalLocation</code> is
701 * not in the range from 0.0 to 1.0 inclusive.
702 */
703 public void setDividerLocation(double proportionalLocation)
704 {
705 if (proportionalLocation > 1 || proportionalLocation < 0)
706 throw new IllegalArgumentException
707 ("proportion has to be between 0 and 1.");
708
709 int max = ((orientation == HORIZONTAL_SPLIT) ? getWidth() : getHeight())
710 - getDividerSize();
711 setDividerLocation((int) (proportionalLocation * max));
712 }
713
714 /**
715 * This method sets the location of the divider.
716 *
717 * @param location The location of the divider. The negative value forces to
718 * compute the new location from the preferred sizes of the split
719 * pane components.
720 */
721 public void setDividerLocation(int location)
722 {
723 int oldLocation = dividerLocation;
724 dividerLocation = location;
725 SplitPaneUI ui = getUI();
726 if (ui != null)
727 ui.setDividerLocation(this, location);
728 firePropertyChange(DIVIDER_LOCATION_PROPERTY, oldLocation,
729 location);
730 }
731
732 /**
733 * This method sets the size of the divider.
734 *
735 * @param newSize The size of the divider.
736 */
737 public void setDividerSize(int newSize)
738 {
739 clientDividerSizeSet = true;
740 if (newSize != dividerSize)
741 {
742 int oldSize = dividerSize;
743 dividerSize = newSize;
744 firePropertyChange(DIVIDER_SIZE_PROPERTY, oldSize, dividerSize);
745 }
746 }
747
748 // This doesn't appear to do anything when set from user side.
749 // so it probably is only used from the UI side to change the
750 // lastDividerLocation var.
751
752 /**
753 * This method sets the last location of the divider.
754 *
755 * @param newLastLocation The last location of the divider.
756 */
757 public void setLastDividerLocation(int newLastLocation)
758 {
759 if (newLastLocation != lastDividerLocation)
760 {
761 int oldValue = lastDividerLocation;
762 lastDividerLocation = newLastLocation;
763 firePropertyChange(LAST_DIVIDER_LOCATION_PROPERTY, oldValue,
764 lastDividerLocation);
765 }
766 }
767
768 /**
769 * This method sets the left component.
770 *
771 * @param comp The left component.
772 */
773 public void setLeftComponent(Component comp)
774 {
775 if (comp != null)
776 add(comp, LEFT);
777 else
778 remove (leftComponent);
779 }
780
781 /**
782 * This method sets whether the divider has one touch expandable buttons.
783 * The one touch expandable buttons can expand the size of either component
784 * to the maximum allowed size.
785 *
786 * @param newValue Whether the divider will have one touch expandable
787 * buttons.
788 */
789 public void setOneTouchExpandable(boolean newValue)
790 {
791 clientOneTouchExpandableSet = true;
792 if (newValue != oneTouchExpandable)
793 {
794 boolean oldValue = oneTouchExpandable;
795 oneTouchExpandable = newValue;
796 firePropertyChange(ONE_TOUCH_EXPANDABLE_PROPERTY, oldValue,
797 oneTouchExpandable);
798 }
799 }
800
801 /**
802 * Sets the orientation for the <code>JSplitPane</code> and sends a
803 * {@link PropertyChangeEvent} (with the property name
804 * {@link #ORIENTATION_PROPERTY}) to all registered listeners.
805 *
806 * @param orientation the orientation (either {@link #HORIZONTAL_SPLIT}
807 * or {@link #VERTICAL_SPLIT}).
808 *
809 * @throws IllegalArgumentException if <code>orientation</code> is not one of
810 * the listed values.
811 */
812 public void setOrientation(int orientation)
813 {
814 if (orientation != HORIZONTAL_SPLIT && orientation != VERTICAL_SPLIT)
815 throw new IllegalArgumentException
816 ("orientation must be one of VERTICAL_SPLIT, HORIZONTAL_SPLIT");
817 if (orientation != this.orientation)
818 {
819 int oldOrientation = this.orientation;
820 this.orientation = orientation;
821 firePropertyChange(ORIENTATION_PROPERTY, oldOrientation,
822 this.orientation);
823 }
824 }
825
826 /**
827 * This method determines how extra space will be distributed among the left
828 * and right components. A value of 0 will allocate all extra space to the
829 * right component. A value of 1 indicates that all extra space will go to
830 * the left component. A value in between 1 and 0 will split the space
831 * accordingly.
832 *
833 * @param value The resize weight.
834 */
835 public void setResizeWeight(double value)
836 {
837 if (value < 0.0 || value > 1.0)
838 throw new IllegalArgumentException("Value outside permitted range.");
839 if (this.resizeWeight != value)
840 {
841 double old = resizeWeight;
842 resizeWeight = value;
843 firePropertyChange(RESIZE_WEIGHT_PROPERTY, old, value);
844 }
845 }
846
847 /**
848 * This method sets the right component.
849 *
850 * @param comp The right component.
851 */
852 public void setRightComponent(Component comp)
853 {
854 if (comp != null)
855 add(comp, RIGHT);
856 else
857 remove (rightComponent);
858 }
859
860 /**
861 * This method sets the top component.
862 *
863 * @param comp The top component.
864 */
865 public void setTopComponent(Component comp)
866 {
867 if (comp != null)
868 add(comp, TOP);
869 else
870 add(new JButton("left button"), TOP);
871 }
872
873 /**
874 * This method sets the UI used by the JSplitPane.
875 *
876 * @param ui The UI to use.
877 */
878 public void setUI(SplitPaneUI ui)
879 {
880 super.setUI(ui);
881 }
882
883 /**
884 * This method resets the UI to the one specified by the current Look and
885 * Feel.
886 */
887 public void updateUI()
888 {
889 setUI((SplitPaneUI) UIManager.getUI(this));
890 }
891
892 /**
893 * This method returns a string identifier to determine which UI class it
894 * needs.
895 *
896 * @return A string that identifies it's UI class.
897 */
898 public String getUIClassID()
899 {
900 return "SplitPaneUI";
901 }
902
903 /**
904 * Helper method for
905 * {@link LookAndFeel#installProperty(JComponent, String, Object)}.
906 *
907 * @param propertyName the name of the property
908 * @param value the value of the property
909 *
910 * @throws IllegalArgumentException if the specified property cannot be set
911 * by this method
912 * @throws ClassCastException if the property value does not match the
913 * property type
914 * @throws NullPointerException if <code>c</code> or
915 * <code>propertyValue</code> is <code>null</code>
916 */
917 void setUIProperty(String propertyName, Object value)
918 {
919 if (propertyName.equals("dividerSize"))
920 {
921 if (! clientDividerSizeSet)
922 {
923 setDividerSize(((Integer) value).intValue());
924 clientDividerSizeSet = false;
925 }
926 }
927 else if (propertyName.equals("oneTouchExpandable"))
928 {
929 if (! clientOneTouchExpandableSet)
930 {
931 setOneTouchExpandable(((Boolean) value).booleanValue());
932 clientOneTouchExpandableSet = false;
933 }
934 }
935 else
936 {
937 super.setUIProperty(propertyName, value);
938 }
939 }
940 }