OSDN Git Service

libjava/
[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 java.awt.Component;
42 import java.awt.Graphics;
43 import java.beans.PropertyChangeEvent;
44
45 import javax.accessibility.Accessible;
46 import javax.accessibility.AccessibleContext;
47 import javax.accessibility.AccessibleRole;
48 import javax.accessibility.AccessibleState;
49 import javax.accessibility.AccessibleStateSet;
50 import javax.accessibility.AccessibleValue;
51 import javax.swing.plaf.SplitPaneUI;
52
53 /**
54  * This class implements JSplitPane. It is used to divide two components. By
55  * dragging the SplitPane's divider, the user can resize the two components.
56  * Note that the divider cannot resize a component to smaller than it's
57  * minimum size.
58  */
59 public class JSplitPane extends JComponent implements Accessible
60 {
61
62   /**
63    * Provides the accessibility features for the <code>JSplitPane</code>
64    * component.
65    */
66   protected class AccessibleJSplitPane extends JComponent.AccessibleJComponent
67     implements AccessibleValue
68   {
69   private static final long serialVersionUID = -1788116871416305366L;
70   
71     /**
72      * Creates a new <code>AccessibleJSplitPane</code> instance.
73      */
74     protected AccessibleJSplitPane()
75     {
76       // Nothing to do here.
77     }
78
79     /**
80      * Returns a set containing the current state of the {@link JSplitPane} 
81      * component.
82      *
83      * @return The accessible state set.
84      */
85     public AccessibleStateSet getAccessibleStateSet()
86     {
87       AccessibleStateSet result = super.getAccessibleStateSet();
88       if (getOrientation() == HORIZONTAL_SPLIT)
89         {
90           result.add(AccessibleState.HORIZONTAL);
91         }
92       else if (getOrientation() == VERTICAL_SPLIT)
93         {
94           result.add(AccessibleState.VERTICAL);
95         }
96       return result;
97     }
98
99     /**
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 }