Home » openjdk-7 » javax » swing » [javadoc | source]

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

Home » openjdk-7 » javax » swing » [javadoc | source]