1090 lines · 36.7 KB · Java
RawDownload
/* * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.  Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */   package javax.swing.plaf.basic;   import java.awt.*;import java.awt.event.*;import javax.swing.*;import javax.swing.event.*;import javax.swing.plaf.*;import javax.swing.border.Border;import java.beans.*;import sun.swing.DefaultLookup;   /** * Divider used by BasicSplitPaneUI. Subclassers may wish to override * paint to do something more interesting. * The border effect is drawn in BasicSplitPaneUI, so if you don't like * that border, reset it there. * To conditionally drag from certain areas subclass mousePressed and * call super when you wish the dragging to begin. * <p> * <strong>Warning:</strong> * 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 applications running * the same version of Swing.  As of 1.4, support for long term storage * of all JavaBeans<sup><font size="-2">TM</font></sup> * has been added to the <code>java.beans</code> package. * Please see {@link java.beans.XMLEncoder}. * * @author Scott Violet */public class BasicSplitPaneDivider extends Container    implements PropertyChangeListener{    /**     * Width or height of the divider based on orientation     * BasicSplitPaneUI adds two to this.     */    protected static final int ONE_TOUCH_SIZE = 6;    protected static final int ONE_TOUCH_OFFSET = 2;     /**     * Handles mouse dragging message to do the actual dragging.     */    protected DragController dragger;     /**     * UI this instance was created from.     */    protected BasicSplitPaneUI splitPaneUI;     /**     * Size of the divider.     */    protected int dividerSize = 0; // default - SET TO 0???     /**     * Divider that is used for noncontinuous layout mode.     */    protected Component hiddenDivider;     /**     * JSplitPane the receiver is contained in.     */    protected JSplitPane splitPane;     /**     * Handles mouse events from both this class, and the split pane.     * Mouse events are handled for the splitpane since you want to be able     * to drag when clicking on the border of the divider, which is not     * drawn by the divider.     */    protected MouseHandler mouseHandler;     /**     * Orientation of the JSplitPane.     */    protected int orientation;     /**     * Button for quickly toggling the left component.     */    protected JButton leftButton;     /**     * Button for quickly toggling the right component.     */    protected JButton rightButton;     /** Border. */    private Border border;     /**     * Is the mouse over the divider?     */    private boolean mouseOver;     private int oneTouchSize;    private int oneTouchOffset;     /**     * If true the one touch buttons are centered on the divider.     */    private boolean centerOneTouchButtons;      /**     * Creates an instance of BasicSplitPaneDivider. Registers this     * instance for mouse events and mouse dragged events.     */    public BasicSplitPaneDivider(BasicSplitPaneUI ui) {        oneTouchSize = DefaultLookup.getInt(ui.getSplitPane(), ui,                "SplitPane.oneTouchButtonSize", ONE_TOUCH_SIZE);        oneTouchOffset = DefaultLookup.getInt(ui.getSplitPane(), ui,                "SplitPane.oneTouchButtonOffset", ONE_TOUCH_OFFSET);        centerOneTouchButtons = DefaultLookup.getBoolean(ui.getSplitPane(),                 ui, "SplitPane.centerOneTouchButtons", true);        setLayout(new DividerLayout());        setBasicSplitPaneUI(ui);        orientation = splitPane.getOrientation();        setCursor((orientation == JSplitPane.HORIZONTAL_SPLIT) ?                  Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR) :                  Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR));        setBackground(UIManager.getColor("SplitPane.background"));    }     private void revalidateSplitPane() {        invalidate();        if (splitPane != null) {            splitPane.revalidate();        }    }     /**     * Sets the SplitPaneUI that is using the receiver.     */    public void setBasicSplitPaneUI(BasicSplitPaneUI newUI) {        if (splitPane != null) {            splitPane.removePropertyChangeListener(this);           if (mouseHandler != null) {               splitPane.removeMouseListener(mouseHandler);               splitPane.removeMouseMotionListener(mouseHandler);               removeMouseListener(mouseHandler);               removeMouseMotionListener(mouseHandler);               mouseHandler = null;           }        }        splitPaneUI = newUI;        if (newUI != null) {            splitPane = newUI.getSplitPane();            if (splitPane != null) {                if (mouseHandler == null) mouseHandler = new MouseHandler();                splitPane.addMouseListener(mouseHandler);                splitPane.addMouseMotionListener(mouseHandler);                addMouseListener(mouseHandler);                addMouseMotionListener(mouseHandler);                splitPane.addPropertyChangeListener(this);                if (splitPane.isOneTouchExpandable()) {                    oneTouchExpandableChanged();                }            }        }        else {            splitPane = null;        }    }      /**     * Returns the <code>SplitPaneUI</code> the receiver is currently     * in.     */    public BasicSplitPaneUI getBasicSplitPaneUI() {        return splitPaneUI;    }      /**     * Sets the size of the divider to <code>newSize</code>. That is     * the width if the splitpane is <code>HORIZONTAL_SPLIT</code>, or     * the height of <code>VERTICAL_SPLIT</code>.     */    public void setDividerSize(int newSize) {        dividerSize = newSize;    }      /**     * Returns the size of the divider, that is the width if the splitpane     * is HORIZONTAL_SPLIT, or the height of VERTICAL_SPLIT.     */    public int getDividerSize() {        return dividerSize;    }      /**     * Sets the border of this component.     * @since 1.3     */    public void setBorder(Border border) {        Border         oldBorder = this.border;         this.border = border;    }     /**     * Returns the border of this component or null if no border is     * currently set.     *     * @return the border object for this component     * @see #setBorder     * @since 1.3     */    public Border getBorder() {        return border;    }     /**     * If a border has been set on this component, returns the     * border's insets, else calls super.getInsets.     *     * @return the value of the insets property.     * @see #setBorder     */    public Insets getInsets() {        Border    border = getBorder();         if (border != null) {            return border.getBorderInsets(this);        }        return super.getInsets();    }     /**     * Sets whether or not the mouse is currently over the divider.     *     * @param mouseOver whether or not the mouse is currently over the divider     * @since 1.5     */    protected void setMouseOver(boolean mouseOver) {        this.mouseOver = mouseOver;    }     /**     * Returns whether or not the mouse is currently over the divider     *     * @return whether or not the mouse is currently over the divider     * @since 1.5     */    public boolean isMouseOver() {        return mouseOver;    }     /**     * Returns dividerSize x dividerSize     */    public Dimension getPreferredSize() {        // Ideally this would return the size from the layout manager,        // but that could result in the layed out size being different from        // the dividerSize, which may break developers as well as        // BasicSplitPaneUI.        if (orientation == JSplitPane.HORIZONTAL_SPLIT) {            return new Dimension(getDividerSize(), 1);        }        return new Dimension(1, getDividerSize());    }     /**     * Returns dividerSize x dividerSize     */    public Dimension getMinimumSize() {        return getPreferredSize();    }      /**     * Property change event, presumably from the JSplitPane, will message     * updateOrientation if necessary.     */    public void propertyChange(PropertyChangeEvent e) {        if (e.getSource() == splitPane) {            if (e.getPropertyName() == JSplitPane.ORIENTATION_PROPERTY) {                orientation = splitPane.getOrientation();                setCursor((orientation == JSplitPane.HORIZONTAL_SPLIT) ?                          Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR) :                          Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR));                revalidateSplitPane();            }            else if (e.getPropertyName() == JSplitPane.                      ONE_TOUCH_EXPANDABLE_PROPERTY) {                oneTouchExpandableChanged();            }        }    }      /**     * Paints the divider.     */    public void paint(Graphics g) {      super.paint(g);       // Paint the border.      Border   border = getBorder();       if (border != null) {          Dimension     size = getSize();           border.paintBorder(this, g, 0, 0, size.width, size.height);      }    }      /**     * Messaged when the oneTouchExpandable value of the JSplitPane the     * receiver is contained in changes. Will create the     * <code>leftButton</code> and <code>rightButton</code> if they     * are null. invalidates the receiver as well.     */    protected void oneTouchExpandableChanged() {        if (!DefaultLookup.getBoolean(splitPane, splitPaneUI,                           "SplitPane.supportsOneTouchButtons", true)) {            // Look and feel doesn't want to support one touch buttons, bail.            return;        }        if (splitPane.isOneTouchExpandable() &&            leftButton == null &&            rightButton == null) {            /* Create the left button and add an action listener to               expand/collapse it. */            leftButton = createLeftOneTouchButton();            if (leftButton != null)                leftButton.addActionListener(new OneTouchActionHandler(true));              /* Create the right button and add an action listener to               expand/collapse it. */            rightButton = createRightOneTouchButton();            if (rightButton != null)                rightButton.addActionListener(new OneTouchActionHandler                    (false));             if (leftButton != null && rightButton != null) {                add(leftButton);                add(rightButton);            }        }        revalidateSplitPane();    }      /**     * Creates and return an instance of JButton that can be used to     * collapse the left component in the split pane.     */    protected JButton createLeftOneTouchButton() {        JButton b = new JButton() {            public void setBorder(Border b) {            }            public void paint(Graphics g) {                if (splitPane != null) {                    int[]   xs = new int[3];                    int[]   ys = new int[3];                    int     blockSize;                     // Fill the background first ...                    g.setColor(this.getBackground());                    g.fillRect(0, 0, this.getWidth(),                               this.getHeight());                     // ... then draw the arrow.                    g.setColor(Color.black);                    if (orientation == JSplitPane.VERTICAL_SPLIT) {                        blockSize = Math.min(getHeight(), oneTouchSize);                        xs[0] = blockSize;                        xs[1] = 0;                        xs[2] = blockSize << 1;                        ys[0] = 0;                        ys[1] = ys[2] = blockSize;                        g.drawPolygon(xs, ys, 3); // Little trick to make the                                                  // arrows of equal size                    }                    else {                        blockSize = Math.min(getWidth(), oneTouchSize);                        xs[0] = xs[2] = blockSize;                        xs[1] = 0;                        ys[0] = 0;                        ys[1] = blockSize;                        ys[2] = blockSize << 1;                    }                    g.fillPolygon(xs, ys, 3);                }            }            // Don't want the button to participate in focus traversable.            public boolean isFocusTraversable() {                return false;            }        };        b.setMinimumSize(new Dimension(oneTouchSize, oneTouchSize));        b.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));        b.setFocusPainted(false);        b.setBorderPainted(false);        b.setRequestFocusEnabled(false);        return b;    }      /**     * Creates and return an instance of JButton that can be used to     * collapse the right component in the split pane.     */    protected JButton createRightOneTouchButton() {        JButton b = new JButton() {            public void setBorder(Border border) {            }            public void paint(Graphics g) {                if (splitPane != null) {                    int[]          xs = new int[3];                    int[]          ys = new int[3];                    int            blockSize;                     // Fill the background first ...                    g.setColor(this.getBackground());                    g.fillRect(0, 0, this.getWidth(),                               this.getHeight());                     // ... then draw the arrow.                    if (orientation == JSplitPane.VERTICAL_SPLIT) {                        blockSize = Math.min(getHeight(), oneTouchSize);                        xs[0] = blockSize;                        xs[1] = blockSize << 1;                        xs[2] = 0;                        ys[0] = blockSize;                        ys[1] = ys[2] = 0;                    }                    else {                        blockSize = Math.min(getWidth(), oneTouchSize);                        xs[0] = xs[2] = 0;                        xs[1] = blockSize;                        ys[0] = 0;                        ys[1] = blockSize;                        ys[2] = blockSize << 1;                    }                    g.setColor(Color.black);                    g.fillPolygon(xs, ys, 3);                }            }            // Don't want the button to participate in focus traversable.            public boolean isFocusTraversable() {                return false;            }        };        b.setMinimumSize(new Dimension(oneTouchSize, oneTouchSize));        b.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));        b.setFocusPainted(false);        b.setBorderPainted(false);        b.setRequestFocusEnabled(false);        return b;    }      /**     * Message to prepare for dragging. This messages the BasicSplitPaneUI     * with startDragging.     */    protected void prepareForDragging() {        splitPaneUI.startDragging();    } 

Lines 1–500 of 1090.