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