OSDN Git Service

libjava/ChangeLog:
[pf3gnuchains/gcc-fork.git] / libjava / classpath / javax / swing / JSplitPane.java
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      */
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      */
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      */
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      */
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      */
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      */
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      */
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      */
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    */
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    */
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    */
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    */
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    */
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    */
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    */
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    */
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    */
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    */
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    */
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    */
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    */
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    */
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    */
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    */
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    */
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    */
533   public Component getTopComponent()
534   {
535     return leftComponent;
536   }
537
538   /**
539    * This method returns the UI.
540    *
541    * @return The UI.
542    */
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    */
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    */
563   public boolean isOneTouchExpandable()
564   {
565     return oneTouchExpandable;
566   }
567
568   /**
569    * This method returns true.
570    *
571    * @return true.
572    */
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    */
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    */
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    */
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    */
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    */
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    */
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    */
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    */
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    */
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    */
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    */
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    */
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    */
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    */
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    */
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    */
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    */
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    */
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    */
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    */
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    */
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    */
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 }