home *** CD-ROM | disk | FTP | other *** search
Java Source | 1998-03-20 | 22.9 KB | 726 lines |
- /*
- * @(#)JSplitPane.java 1.32 98/02/03
- *
- * Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
- *
- * This software is the confidential and proprietary information of Sun
- * Microsystems, Inc. ("Confidential Information"). You shall not
- * disclose such Confidential Information and shall use it only in
- * accordance with the terms of the license agreement you entered into
- * with Sun.
- *
- * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
- * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
- * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
- * THIS SOFTWARE OR ITS DERIVATIVES.
- *
- */
-
- package java.awt.swing;
-
- import java.awt.*;
- import java.awt.swing.border.Border;
- import java.awt.swing.plaf.*;
- import java.awt.accessibility.*;
-
- /**
- * JSplitPane is used to divide two (and only two) Components. The two
- * Components are graphically divided based on the look and feel
- * implementation. By user intervention the two Components can be
- * interactively resized.
- * <p>
- * The two Components can be aligned left to right,
- * <code>JSplitPane.HORIZONTAL_SPLIT</code>, or top to bottom,
- * <code>JSplitPane.VERTICAL_SPLIT</code>.
- * The preferred way to change the size of the Componets is to invoke
- * setDividerLocation where location is either the new x or y position
- * depending on the orientation of the JSplitPane. JSplitPane will also
- * try and reposition the other Component if one changes.
- * <p>
- * To resize the Components to their preferred sizes invoke
- * resetPreferredSizes.
- * <p>
- * When the user is resizing the Components the minimum size of the
- * Components is used to determine the maximum/minimum position the
- * Components can be set to. So that if the minimum size of the two
- * components is greater than the size of the splitpane the divider
- * will not allow you to resize it. Refer to JComponent.setMinimumSize
- * for a way to alter the minimum size of a JComponent.
- * <p>
- * Warning: serialized objects of this class will not be compatible with
- * future swing releases. The current serialization support is appropriate
- * for short term storage or RMI between Swing1.0 applications. It will
- * not be possible to load serialized Swing1.0 objects with future releases
- * of Swing. The JDK1.2 release of Swing will be the compatibility
- * baseline for the serialized form of Swing objects.
- *
- * @version 1.32 02/03/98
- * @author Scott Violet
- */
- public class JSplitPane extends JComponent implements Accessible
- {
- /** Vertical split indicates the Components are split along the
- * y axis, eg the two Components will be split one on top of the other. */
- public final static int VERTICAL_SPLIT = 0;
- /** Horizontal split indicates the Components are split along the
- * x axis, eg the two Components will be split one to the left of the
- * other. */
- public final static int HORIZONTAL_SPLIT = 1;
-
- /** Used to add a Component to go on the left side of the other
- * Component. */
- public final static String LEFT = "left";
- /** Used to add a Component to go on the right side of the other
- * Component. */
- public final static String RIGHT = "right";
- /** Used to add a Component above the other Component. */
- public final static String TOP = "top";
- /** Used to add a Component below the other Component. */
- public final static String BOTTOM = "bottom";
- /** Used to add a Component that will represent the divider. */
- public final static String DIVIDER = "divider";
-
- /** Bound property name for orientation. */
- public final static String ORIENTATION_PROPERTY = "orientation";
- /** Bound property name for continuousLayout. */
- public final static String CONTINUOUS_LAYOUT_PROPERTY = "continuousLayout";
- /** Bound property name for border. */
- public final static String DIVIDER_SIZE_PROPERTY = "dividerSize";
- /** Bound property for oneTouchExpandable. */
- public final static String ONE_TOUCH_EXPANDABLE_PROPERTY =
- "oneTouchExpandable";
- /** Bound property for lastLocation. */
- public final static String LAST_DIVIDER_LOCATION_PROPERTY =
- "lastDividerLocation";
-
- /** How the views are split. */
- protected int orientation;
-
- /** Whether or not the views are continuously redisplayed while
- * resizing. */
- protected boolean continuousLayout;
-
- /** The left or top component. */
- protected Component leftComponent;
-
- /* The right or bottom component. */
- protected Component rightComponent;
-
- /** Size of the divider. */
- protected int dividerSize;
-
- /** Is a little widget provided to quickly expand/collapse the
- * split pane. */
- protected boolean oneTouchExpandable;
-
- /** Previous location of the split pane. */
- protected int lastDividerLocation;
-
- /**
- * Returns a new JSplitPane configured to vertically divide
- * the child components and with two buttons.
- */
- public JSplitPane() {
- this(JSplitPane.HORIZONTAL_SPLIT, false, new JButton("left button"),
- new JButton("right button"));
- }
-
- /**
- * Returns a new JSplitPane configured with the passed in orientation
- * and no continuous layout.
- */
- public JSplitPane(int newOrientation) {
- this(newOrientation, false);
- }
-
- /**
- * Returns a new JSplitPane with the specified orientation and
- * continuousLayout.
- */
- public JSplitPane(int newOrientation, boolean newContinuousLayout) {
- this(newOrientation, newContinuousLayout, null, null);
- }
-
- /**
- * Returns a new JSplitPane with the specified orientation,
- * continuousLayout and passed in Components.
- */
- public JSplitPane(int newOrientation,
- Component newLeftComponent, Component newRightComponent){
- this(newOrientation, false, newLeftComponent, newRightComponent);
- }
-
- /**
- * Returns a new JSplitPane with the specified orientation,
- * continuousLayout and passed in Components.
- */
- public JSplitPane(int newOrientation, boolean newContinuousLayout,
- Component newLeftComponent, Component newRightComponent){
- super();
- dividerSize = 5;
- setLayout(null);
- orientation = newOrientation;
- if (orientation != HORIZONTAL_SPLIT && orientation != VERTICAL_SPLIT)
- throw new IllegalArgumentException("cannot create JSplitPane, orientation must be one of JSplitPane.HORIZONTAL_SPLIT or JSplitPane.VERTICAL_SPLIT");
- continuousLayout = newContinuousLayout;
- if (newLeftComponent != null)
- setLeftComponent(newLeftComponent);
- if (newRightComponent != null)
- setRightComponent(newRightComponent);
- updateUI();
- }
-
- /**
- * Sets the TreeUI that will provide the current look and feel.
- */
- public void setUI(SplitPaneUI ui) {
- if ((SplitPaneUI)this.ui != ui) {
- super.setUI(ui);
- invalidate();
- }
- }
-
- /**
- * Returns the SplitPaneUI that is providing the current look and
- * feel.
- * @beaninfo
- * expert: true
- * description: The L&F object that renders this component.
- */
- public SplitPaneUI getUI() {
- return (SplitPaneUI)ui;
- }
-
- /**
- * Called to replace the UI with the latest version from the
- * default UIFactory.
- */
- public void updateUI() {
- setUI((SplitPaneUI)UIManager.getUI(this));
- invalidate();
- }
-
-
- /**
- * @return "SplitPaneUI"
- * @see JComponent#getUIClassID
- * @see UIDefaults#getUI
- * @beaninfo
- * expert: true
- * description: A string that specifies the name of the L&F class.
- */
- public String getUIClassID() {
- return "SplitPaneUI";
- }
-
-
- /**
- * Sets the size of the divider to <code>newSize</code>.
- * @beaninfo
- * bound: true
- * description: The size of the divider.
- */
- public void setDividerSize(int newSize) {
- int oldSize = dividerSize;
-
- if (oldSize != newSize) {
- dividerSize = newSize;
- firePropertyChange(DIVIDER_SIZE_PROPERTY, oldSize, newSize);
- }
- }
-
- /**
- * Returns the size of the divider.
- */
- public int getDividerSize() {
- return dividerSize;
- }
-
- /**
- * Sets the component to the left (or above) the divider.
- */
- public void setLeftComponent(Component comp) {
- if (comp == null) {
- if (leftComponent != null) {
- remove(leftComponent);
- leftComponent = null;
- }
- } else {
- add(comp, JSplitPane.LEFT);
- }
- }
-
- /**
- * Returns the component to the left (or above) the divider.
- * @beaninfo
- * preferred: true
- * description: The component to the left (or above) the divider.
- */
- public Component getLeftComponent() {
- return leftComponent;
- }
-
- /**
- * Sets the component above, or to the left of the divider.
- * @beaninfo
- * description: The component above, or to the left of the divider.
- */
- public void setTopComponent(Component comp) {
- setLeftComponent(comp);
- }
-
- /**
- * Returns the component above, or to the left of the divider.
- */
- public Component getTopComponent() {
- return leftComponent;
- }
-
- /**
- * Sets the component to the right (or below) the divider.
- * @beaninfo
- * preferred: true
- * description: The component to the right (or below) the divider.
- */
- public void setRightComponent(Component comp) {
- if (comp == null) {
- if (rightComponent != null) {
- remove(rightComponent);
- rightComponent = null;
- }
- } else {
- add(comp, JSplitPane.RIGHT);
- }
- }
-
- /**
- * Returns the component to the right (or below) the divider.
- */
- public Component getRightComponent() {
- return rightComponent;
- }
-
- /**
- * Sets the component below, or to the right of the divider.
- * @beaninfo
- * description: The component below, or to the right of the divider.
- */
- public void setBottomComponent(Component comp) {
- setRightComponent(comp);
- }
-
- /**
- * Returns the component below, or to the right of the divider.
- */
- public Component getBottomComponent() {
- return rightComponent;
- }
-
- /**
- * If <code>newValue</code> is true, the reciever will provide
- * UI widgets on the divider to quickly expand/collapse the
- * divider.
- * @beaninfo
- * bound: true
- * description: UI widget on the divider to quickly
- * expand/collapse the divider.
- */
- public void setOneTouchExpandable(boolean newValue) {
- boolean oldValue = oneTouchExpandable;
-
- oneTouchExpandable = newValue;
- firePropertyChange(ONE_TOUCH_EXPANDABLE_PROPERTY, oldValue, newValue);
- repaint();
- }
-
- /**
- * Returns true if the receiver provides a UI widget to collapse/expand
- * the divider.
- */
- public boolean isOneTouchExpandable() {
- return oneTouchExpandable;
- }
-
- /**
- * Sets the last location the divider was at to
- * <code>newLastLocation</code>.
- * @beaninfo
- * bound: true
- * description: The last location the divider was at.
- */
- public void setLastDividerLocation(int newLastLocation) {
- int oldLocation = lastDividerLocation;
-
- lastDividerLocation = newLastLocation;
- firePropertyChange(LAST_DIVIDER_LOCATION_PROPERTY, oldLocation,
- newLastLocation);
- }
-
- /**
- * Returns the last location the divider was at.
- */
- public int getLastDividerLocation() {
- return lastDividerLocation;
- }
-
- /**
- * Sets the orientation, or how the splitter is divided.
- * @beaninfo
- * bound: true
- * description: The orientation, or how the splitter is divided.
- */
- public void setOrientation(int orientation) {
- if (orientation != VERTICAL_SPLIT && orientation != HORIZONTAL_SPLIT) {
- throw new IllegalArgumentException("JSplitPane: orientation must be one of JSplitPane.VERTICAL_SPLIT or JSplitPane.HORIZONTAL_SPLIT");
- }
-
- int oldOrientation = this.orientation;
-
- this.orientation = orientation;
- firePropertyChange(ORIENTATION_PROPERTY, oldOrientation, orientation);
- }
-
- /**
- * Returns the orientation.
- */
- public int getOrientation() {
- return orientation;
- }
-
- /**
- * Sets whether or not the child components are continuously
- * redisplayed and layed out during user intervention.
- * @beaninfo
- * bound: true
- * description: Whether or not the child components are
- * continuously redisplayed and layed out during
- * user intervention.
- */
- public void setContinuousLayout(boolean newContinuousLayout) {
- boolean oldCD = continuousLayout;
-
- continuousLayout = newContinuousLayout;
- firePropertyChange(CONTINUOUS_LAYOUT_PROPERTY, oldCD,
- newContinuousLayout);
- }
-
- /**
- * Returns true if the child comopnents are continuously redisplayed and
- * layed out during user intervention.
- */
- public boolean isContinuousLayout() {
- return continuousLayout;
- }
-
- /**
- * Messaged to relayout the JSplitPane based on the preferred size
- * of the children components.
- */
- public void resetToPreferredSizes() {
- SplitPaneUI ui = getUI();
-
- if (ui != null) {
- ui.resetToPreferredSizes();
- }
- }
-
- /**
- * Messages the receiver with setDividerLocation(proportionalLocation *
- * size). Where size is either getWidth() or getHeight(). This will
- * throw an IllegalArgumentException if <code>proportionalLocation</code>
- * is < 0 or > 1.0.
- * @beaninfo
- * description: The location of the divider.
- */
- public void setDividerLocation(double proportionalLocation) {
- if (proportionalLocation < 0.0 ||
- proportionalLocation > 1.0) {
- throw new IllegalArgumentException("proportional location must be between 0.0 and 1.0.");
- }
- if (getOrientation() == VERTICAL_SPLIT) {
- setDividerLocation((int)((double)(getHeight() - getDividerSize()) *
- proportionalLocation));
- } else {
- setDividerLocation((int)((double)(getWidth() - getDividerSize()) *
- proportionalLocation));
- }
- }
-
- /**
- * Sets the location of the divider. This is passed off to the
- * look and feel implementation.
- */
- public void setDividerLocation(int location) {
- SplitPaneUI ui = getUI();
-
- if (ui != null) {
- ui.setDividerLocation(location);
- }
- }
-
- /**
- * Returns the location of the divider from the look and feel
- * implementation.
- */
- public int getDividerLocation() {
- SplitPaneUI ui = getUI();
-
- if (ui != null) {
- return ui.getDividerLocation();
- }
- return -1;
- }
-
-
- /**
- * Returns the minimum location of the divider from the look and feel
- * implementation.
- * @beaninfo
- * description: The minimum location of the divider from the L&F.
- */
- public int getMinimumDividerLocation() {
- SplitPaneUI ui = getUI();
-
- if (ui != null) {
- return ui.getMinimumDividerLocation();
- }
- return -1;
- }
-
-
- /**
- * Returns the maximum location of the divider from the look and feel
- * implementation.
- */
- public int getMaximumDividerLocation() {
- SplitPaneUI ui = getUI();
-
- if (ui != null) {
- return ui.getMaximumDividerLocation();
- }
- return -1;
- }
-
- /**
- * Removes the child component, <code>component</code> from the
- * receiver. Reset the leftComponent or rightComponent instance
- * variable if necessary.
- */
- public void remove(Component component) {
- if (component == leftComponent) {
- leftComponent = null;
- } else if (component == rightComponent) {
- rightComponent = null;
- }
- super.remove(component);
- }
-
- /**
- * Removes the Component at the passed in index. This updates the
- * leftComponent and rightComponent ivars if necessary, and then
- * messages super.
- */
- public void remove(int index) {
- Component comp = getComponent(index);
-
- if (comp == leftComponent) {
- leftComponent = null;
- } else if (comp == rightComponent) {
- rightComponent = null;
- }
- super.remove(index);
- }
-
- /**
- * Removes all the child components from the receiver. Resets the
- * leftComonent and rightComponent instance variables.
- */
- public void removeAll() {
- leftComponent = rightComponent = null;
- super.removeAll();
- }
-
- /**
- * If <code>constraints</code> identifies the left/top or
- * right/bottom child component, and a component with that identifier
- * was previously added, it will be removed and then <code>comp</code>
- * will be added in its place. If <code>constraints</code> is not
- * one of the known identifers the layout manager may throw an
- * IllegalArgumentException.
- */
- protected void addImpl(Component comp, Object constraints, int index)
- {
- Component toRemove;
-
- if (constraints != null && !(constraints instanceof String)) {
- throw new IllegalArgumentException("cannot add to layout: constraint must be a string (or null)");
- }
-
- /* If the constraints are null and the left/right component is
- invalid, add it at the left/right component. */
- if (constraints == null) {
- if (getLeftComponent() == null) {
- constraints = JSplitPane.LEFT;
- } else if (getRightComponent() == null) {
- constraints = JSplitPane.RIGHT;
- }
- }
-
- /* Find the Component that already exists and remove it. */
- if (constraints != null && (constraints.equals(JSplitPane.LEFT) ||
- constraints.equals(JSplitPane.TOP))) {
- toRemove = getLeftComponent();
- if (toRemove != null) {
- remove(toRemove);
- }
- leftComponent = comp;
- index = -1;
- } else if (constraints != null && (constraints.equals(JSplitPane.RIGHT) ||
- constraints.equals(JSplitPane.BOTTOM))) {
- toRemove = getRightComponent();
- if (toRemove != null) {
- remove(toRemove);
- }
- rightComponent = comp;
- index = -1;
- } else if (constraints != null &&
- constraints.equals(JSplitPane.DIVIDER)) {
- index = -1;
- }
- /* LayoutManager should raise for else condition here. */
-
- super.addImpl(comp, constraints, index);
- }
-
- /**
- * Subclassed to message the UI with finishedPaintingChildren after
- * super has been messaged, as well as painting the border.
- */
- protected void paintChildren(Graphics g) {
- super.paintChildren(g);
-
- SplitPaneUI ui = getUI();
-
- if (ui != null) {
- Graphics tempG = g.create();
- ui.finishedPaintingChildren(this, tempG);
- tempG.dispose();
- }
- }
-
- /////////////////
- // Accessibility support
- ////////////////
-
- /**
- * Get the AccessibleContext associated with this JComponent
- *
- * @return the AccessibleContext of this JComponent
- * @beaninfo
- * expert: true
- * description: The AccessibleContext associated with this Label.
- */
- public AccessibleContext getAccessibleContext() {
- if (accessibleContext == null) {
- accessibleContext = new AccessibleJSplitPane();
- }
- return accessibleContext;
- }
-
- /**
- * The class used to obtain the accessible role for this object.
- * <p>
- * Warning: serialized objects of this class will not be compatible with
- * future swing releases. The current serialization support is appropriate
- * for short term storage or RMI between Swing1.0 applications. It will
- * not be possible to load serialized Swing1.0 objects with future releases
- * of Swing. The JDK1.2 release of Swing will be the compatibility
- * baseline for the serialized form of Swing objects.
- */
- protected class AccessibleJSplitPane extends AccessibleJComponent
- implements AccessibleValue {
-
- /**
- * Get the state set of this object.
- *
- * @return an instance of AccessibleState containing the current state
- * of the object
- * @see AccessibleState
- */
- public AccessibleStateSet getAccessibleStateSet() {
- AccessibleStateSet states = super.getAccessibleStateSet();
- // FIXME: [[[WDW - Should also add BUSY if this implements
- // Adjustable at some point. If this happens, we probably
- // should also add actions.]]]
- if (getOrientation() == VERTICAL_SPLIT) {
- states.add(AccessibleState.VERTICAL);
- } else {
- states.add(AccessibleState.HORIZONTAL);
- }
- return states;
- }
-
- /**
- * Get the AccessibleValue associated with this object if one
- * exists. Otherwise return null.
- */
- public AccessibleValue getAccessibleValue() {
- return this;
- }
-
- /**
- * Get the accessible value of this object.
- *
- * @return a localized String describing the value of this object
- */
- public Number getCurrentAccessibleValue() {
- return new Integer(getDividerLocation());
- }
-
- /**
- * Set the value of this object as a Number.
- *
- * @return True if the value was set.
- */
- public boolean setCurrentAccessibleValue(Number n) {
- if (n instanceof Integer) {
- setDividerLocation(n.intValue());
- return true;
- } else {
- return false;
- }
- }
-
- /**
- * Get the minimum accessible value of this object.
- *
- * @return The minimum value of this object.
- */
- public Number getMinimumAccessibleValue() {
- return new Integer(getUI().getMinimumDividerLocation());
- }
-
- /**
- * Get the maximum accessible value of this object.
- *
- * @return The maximum value of this object.
- */
- public Number getMaximumAccessibleValue() {
- return new Integer(getUI().getMaximumDividerLocation());
- }
-
- /**
- * Get the role of this object.
- *
- * @return an instance of AccessibleRole describing the role of
- * the object
- * @see AccessibleRole
- */
- public AccessibleRole getAccessibleRole() {
- return AccessibleRole.SPLIT_PANE;
- }
- } // inner class AccessibleJSplitPane
- }
-