416 lines · 17.4 KB · Java
RawDownload
/* * Copyright (c) 1998, 2003, 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.metal; import java.awt.*;import javax.swing.*;import javax.swing.border.*;import javax.swing.plaf.basic.*;  /** * Metal's split pane divider * <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 Steve Wilson * @author Ralph kar */class MetalSplitPaneDivider extends BasicSplitPaneDivider{    private MetalBumps bumps = new MetalBumps(10, 10,                 MetalLookAndFeel.getControlHighlight(),                 MetalLookAndFeel.getControlDarkShadow(),                 MetalLookAndFeel.getControl() );     private MetalBumps focusBumps = new MetalBumps(10, 10,                 MetalLookAndFeel.getPrimaryControlHighlight(),                 MetalLookAndFeel.getPrimaryControlDarkShadow(),                 UIManager.getColor("SplitPane.dividerFocusColor"));     private int inset = 2;     private Color controlColor = MetalLookAndFeel.getControl();    private Color primaryControlColor = UIManager.getColor(                                "SplitPane.dividerFocusColor");     public MetalSplitPaneDivider(BasicSplitPaneUI ui) {        super(ui);    }     public void paint(Graphics g) {        MetalBumps usedBumps;        if (splitPane.hasFocus()) {            usedBumps = focusBumps;            g.setColor(primaryControlColor);        }        else {            usedBumps = bumps;            g.setColor(controlColor);        }        Rectangle clip = g.getClipBounds();        Insets insets = getInsets();        g.fillRect(clip.x, clip.y, clip.width, clip.height);        Dimension  size = getSize();        size.width -= inset * 2;        size.height -= inset * 2;        int drawX = inset;        int drawY = inset;        if (insets != null) {            size.width -= (insets.left + insets.right);            size.height -= (insets.top + insets.bottom);            drawX += insets.left;            drawY += insets.top;        }        usedBumps.setBumpArea(size);        usedBumps.paintIcon(this, g, drawX, drawY);        super.paint(g);    }     /**     * Creates and return an instance of JButton that can be used to     * collapse the left component in the metal split pane.     */    protected JButton createLeftOneTouchButton() {        JButton b = new JButton() {            // Sprite buffer for the arrow image of the left button            int[][]     buffer = {{0, 0, 0, 2, 2, 0, 0, 0, 0},                                  {0, 0, 2, 1, 1, 1, 0, 0, 0},                                  {0, 2, 1, 1, 1, 1, 1, 0, 0},                                  {2, 1, 1, 1, 1, 1, 1, 1, 0},                                  {0, 3, 3, 3, 3, 3, 3, 3, 3}};             public void setBorder(Border b) {            }             public void paint(Graphics g) {                JSplitPane splitPane = getSplitPaneFromSuper();                if(splitPane != null) {                    int         oneTouchSize = getOneTouchSizeFromSuper();                    int         orientation = getOrientationFromSuper();                    int         blockSize = Math.min(getDividerSize(),                                                     oneTouchSize);                     // Initialize the color array                    Color[]     colors = {                            this.getBackground(),                            MetalLookAndFeel.getPrimaryControlDarkShadow(),                            MetalLookAndFeel.getPrimaryControlInfo(),                            MetalLookAndFeel.getPrimaryControlHighlight()};                     // Fill the background first ...                    g.setColor(this.getBackground());                    if (isOpaque()) {                        g.fillRect(0, 0, this.getWidth(),                                   this.getHeight());                    }                     // ... then draw the arrow.                    if (getModel().isPressed()) {                            // Adjust color mapping for pressed button state                            colors[1] = colors[2];                    }                    if(orientation == JSplitPane.VERTICAL_SPLIT) {                            // Draw the image for a vertical split                            for (int i=1; i<=buffer[0].length; i++) {                                    for (int j=1; j<blockSize; j++) {                                            if (buffer[j-1][i-1] == 0) {                                                    continue;                                            }                                            else {                                                g.setColor(                                                    colors[buffer[j-1][i-1]]);                                            }                                            g.drawLine(i, j, i, j);                                    }                            }                    }                    else {                            // Draw the image for a horizontal split                            // by simply swaping the i and j axis.                            // Except the drawLine() call this code is                            // identical to the code block above. This was done                            // in order to remove the additional orientation                            // check for each pixel.                            for (int i=1; i<=buffer[0].length; i++) {                                    for (int j=1; j<blockSize; j++) {                                            if (buffer[j-1][i-1] == 0) {                                                    // Nothing needs                                                    // to be drawn                                                    continue;                                            }                                            else {                                                    // Set the color from the                                                    // color map                                                    g.setColor(                                                    colors[buffer[j-1][i-1]]);                                            }                                            // Draw a pixel                                            g.drawLine(j, i, j, i);                                    }                            }                    }                }            }             // Don't want the button to participate in focus traversable.            public boolean isFocusTraversable() {                return false;            }        };        b.setRequestFocusEnabled(false);        b.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));        b.setFocusPainted(false);        b.setBorderPainted(false);        maybeMakeButtonOpaque(b);        return b;    }     /**     * If necessary <code>c</code> is made opaque.     */    private void maybeMakeButtonOpaque(JComponent c) {        Object opaque = UIManager.get("SplitPane.oneTouchButtonsOpaque");        if (opaque != null) {            c.setOpaque(((Boolean)opaque).booleanValue());        }    }     /**     * Creates and return an instance of JButton that can be used to     * collapse the right component in the metal split pane.     */    protected JButton createRightOneTouchButton() {        JButton b = new JButton() {            // Sprite buffer for the arrow image of the right button            int[][]     buffer = {{2, 2, 2, 2, 2, 2, 2, 2},                                  {0, 1, 1, 1, 1, 1, 1, 3},                                  {0, 0, 1, 1, 1, 1, 3, 0},                                  {0, 0, 0, 1, 1, 3, 0, 0},                                  {0, 0, 0, 0, 3, 0, 0, 0}};             public void setBorder(Border border) {            }             public void paint(Graphics g) {                JSplitPane splitPane = getSplitPaneFromSuper();                if(splitPane != null) {                    int         oneTouchSize = getOneTouchSizeFromSuper();                    int         orientation = getOrientationFromSuper();                    int         blockSize = Math.min(getDividerSize(),                                                     oneTouchSize);                     // Initialize the color array                    Color[]     colors = {                            this.getBackground(),                            MetalLookAndFeel.getPrimaryControlDarkShadow(),                            MetalLookAndFeel.getPrimaryControlInfo(),                            MetalLookAndFeel.getPrimaryControlHighlight()};                     // Fill the background first ...                    g.setColor(this.getBackground());                    if (isOpaque()) {                        g.fillRect(0, 0, this.getWidth(),                                   this.getHeight());                    }                     // ... then draw the arrow.                    if (getModel().isPressed()) {                            // Adjust color mapping for pressed button state                            colors[1] = colors[2];                    }                    if(orientation == JSplitPane.VERTICAL_SPLIT) {                            // Draw the image for a vertical split                            for (int i=1; i<=buffer[0].length; i++) {                                    for (int j=1; j<blockSize; j++) {                                            if (buffer[j-1][i-1] == 0) {                                                    continue;                                            }                                            else {                                                g.setColor(                                                    colors[buffer[j-1][i-1]]);                                            }                                            g.drawLine(i, j, i, j);                                    }                            }                    }                    else {                            // Draw the image for a horizontal split                            // by simply swaping the i and j axis.                            // Except the drawLine() call this code is                            // identical to the code block above. This was done                            // in order to remove the additional orientation                            // check for each pixel.                            for (int i=1; i<=buffer[0].length; i++) {                                    for (int j=1; j<blockSize; j++) {                                            if (buffer[j-1][i-1] == 0) {                                                    // Nothing needs                                                    // to be drawn                                                    continue;                                            }                                            else {                                                    // Set the color from the                                                    // color map                                                    g.setColor(                                                    colors[buffer[j-1][i-1]]);                                            }                                            // Draw a pixel                                            g.drawLine(j, i, j, i);                                    }                            }                    }                }            }             // Don't want the button to participate in focus traversable.            public boolean isFocusTraversable() {                return false;            }        };        b.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));        b.setFocusPainted(false);        b.setBorderPainted(false);        b.setRequestFocusEnabled(false);        maybeMakeButtonOpaque(b);        return b;    }     /**     * Used to layout a MetalSplitPaneDivider. Layout for the divider     * involves appropriately moving the left/right buttons around.     * <p>     * This class should be treated as a &quot;protected&quot; inner class.     * Instantiate it only within subclasses of MetalSplitPaneDivider.     */    public class MetalDividerLayout implements LayoutManager {         // NOTE NOTE NOTE NOTE NOTE        // This class is no longer used, the functionality has        // been rolled into BasicSplitPaneDivider.DividerLayout as a        // defaults property         public void layoutContainer(Container c) {            JButton     leftButton = getLeftButtonFromSuper();            JButton     rightButton = getRightButtonFromSuper();            JSplitPane  splitPane = getSplitPaneFromSuper();            int         orientation = getOrientationFromSuper();            int         oneTouchSize = getOneTouchSizeFromSuper();            int         oneTouchOffset = getOneTouchOffsetFromSuper();            Insets      insets = getInsets();             // This layout differs from the one used in BasicSplitPaneDivider.            // It does not center justify the oneTouchExpadable buttons.            // This was necessary in order to meet the spec of the Metal            // splitpane divider.            if (leftButton != null && rightButton != null &&                c == MetalSplitPaneDivider.this) {                if (splitPane.isOneTouchExpandable()) {                    if (orientation == JSplitPane.VERTICAL_SPLIT) {                        int extraY = (insets != null) ? insets.top : 0;                        int blockSize = getDividerSize();                         if (insets != null) {                            blockSize -= (insets.top + insets.bottom);                        }                        blockSize = Math.min(blockSize, oneTouchSize);                        leftButton.setBounds(oneTouchOffset, extraY,                                             blockSize * 2, blockSize);                        rightButton.setBounds(oneTouchOffset +                                              oneTouchSize * 2, extraY,                                              blockSize * 2, blockSize);                    }                    else {                        int blockSize = getDividerSize();                        int extraX = (insets != null) ? insets.left : 0;                         if (insets != null) {                            blockSize -= (insets.left + insets.right);                        }                        blockSize = Math.min(blockSize, oneTouchSize);                        leftButton.setBounds(extraX, oneTouchOffset,                                             blockSize, blockSize * 2);                        rightButton.setBounds(extraX, oneTouchOffset +                                              oneTouchSize * 2, blockSize,                                              blockSize * 2);                    }                }                else {                    leftButton.setBounds(-5, -5, 1, 1);                    rightButton.setBounds(-5, -5, 1, 1);                }            }        }         public Dimension minimumLayoutSize(Container c) {            return new Dimension(0,0);        }         public Dimension preferredLayoutSize(Container c) {            return new Dimension(0, 0);        }         public void removeLayoutComponent(Component c) {}         public void addLayoutComponent(String string, Component c) {}    }     /*     * The following methods only exist in order to be able to access protected     * members in the superclass, because these are otherwise not available     * in any inner class.     */     int getOneTouchSizeFromSuper() {        return super.ONE_TOUCH_SIZE;    }     int getOneTouchOffsetFromSuper() {        return super.ONE_TOUCH_OFFSET;    }     int getOrientationFromSuper() {        return super.orientation;    }     JSplitPane getSplitPaneFromSuper() {        return super.splitPane;    }     JButton getLeftButtonFromSuper() {        return super.leftButton;    }     JButton getRightButtonFromSuper() {        return super.rightButton;    }}