1618 lines · 57.9 KB · Java
RawDownload
/* * Copyright (c) 1997, 2010, 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 sun.swing.DefaultLookup;import sun.swing.UIAction; import java.awt.*;import java.awt.event.*; import java.beans.*; import javax.swing.*;import javax.swing.event.*;import javax.swing.plaf.*;  /** * Implementation of ScrollBarUI for the Basic Look and Feel * * @author Rich Schiavi * @author David Kloba * @author Hans Muller */public class BasicScrollBarUI    extends ScrollBarUI implements LayoutManager, SwingConstants{    private static final int POSITIVE_SCROLL = 1;    private static final int NEGATIVE_SCROLL = -1;     private static final int MIN_SCROLL = 2;    private static final int MAX_SCROLL = 3;     // NOTE: DO NOT use this field directly, SynthScrollBarUI assumes you'll    // call getMinimumThumbSize to access it.    protected Dimension minimumThumbSize;    protected Dimension maximumThumbSize;     protected Color thumbHighlightColor;    protected Color thumbLightShadowColor;    protected Color thumbDarkShadowColor;    protected Color thumbColor;    protected Color trackColor;    protected Color trackHighlightColor;     protected JScrollBar scrollbar;    protected JButton incrButton;    protected JButton decrButton;    protected boolean isDragging;    protected TrackListener trackListener;    protected ArrowButtonListener buttonListener;    protected ModelListener modelListener;     protected Rectangle thumbRect;    protected Rectangle trackRect;     protected int trackHighlight;     protected static final int NO_HIGHLIGHT = 0;    protected static final int DECREASE_HIGHLIGHT = 1;    protected static final int INCREASE_HIGHLIGHT = 2;     protected ScrollListener scrollListener;    protected PropertyChangeListener propertyChangeListener;    protected Timer scrollTimer;     private final static int scrollSpeedThrottle = 60; // delay in milli seconds     /** True indicates a middle click will absolutely position the     * scrollbar. */    private boolean supportsAbsolutePositioning;     /**     * Hint as to what width (when vertical) or height (when horizontal)     * should be.     *     * @since 1.7     */    protected int scrollBarWidth;     private Handler handler;     private boolean thumbActive;     /**     * Determine whether scrollbar layout should use cached value or adjusted     * value returned by scrollbar's <code>getValue</code>.     */    private boolean useCachedValue = false;    /**     * The scrollbar value is cached to save real value if the view is adjusted.     */    private int scrollBarValue;     /**     * Distance between the increment button and the track. This may be a negative     * number. If negative, then an overlap between the button and track will occur,     * which is useful for shaped buttons.     *     * @since 1.7     */    protected int incrGap;     /**     * Distance between the decrement button and the track. This may be a negative     * number. If negative, then an overlap between the button and track will occur,     * which is useful for shaped buttons.     *     * @since 1.7     */    protected int decrGap;     static void loadActionMap(LazyActionMap map) {        map.put(new Actions(Actions.POSITIVE_UNIT_INCREMENT));        map.put(new Actions(Actions.POSITIVE_BLOCK_INCREMENT));        map.put(new Actions(Actions.NEGATIVE_UNIT_INCREMENT));        map.put(new Actions(Actions.NEGATIVE_BLOCK_INCREMENT));        map.put(new Actions(Actions.MIN_SCROLL));        map.put(new Actions(Actions.MAX_SCROLL));    }      public static ComponentUI createUI(JComponent c)    {        return new BasicScrollBarUI();    }      protected void configureScrollBarColors()    {        LookAndFeel.installColors(scrollbar, "ScrollBar.background",                                  "ScrollBar.foreground");        thumbHighlightColor = UIManager.getColor("ScrollBar.thumbHighlight");        thumbLightShadowColor = UIManager.getColor("ScrollBar.thumbShadow");        thumbDarkShadowColor = UIManager.getColor("ScrollBar.thumbDarkShadow");        thumbColor = UIManager.getColor("ScrollBar.thumb");        trackColor = UIManager.getColor("ScrollBar.track");        trackHighlightColor = UIManager.getColor("ScrollBar.trackHighlight");    }      public void installUI(JComponent c)   {        scrollbar = (JScrollBar)c;        thumbRect = new Rectangle(0, 0, 0, 0);        trackRect = new Rectangle(0, 0, 0, 0);        installDefaults();        installComponents();        installListeners();        installKeyboardActions();    }     public void uninstallUI(JComponent c) {        scrollbar = (JScrollBar)c;        uninstallListeners();        uninstallDefaults();        uninstallComponents();        uninstallKeyboardActions();        thumbRect = null;        scrollbar = null;        incrButton = null;        decrButton = null;    }      protected void installDefaults()    {        scrollBarWidth = UIManager.getInt("ScrollBar.width");        if (scrollBarWidth <= 0) {            scrollBarWidth = 16;        }        minimumThumbSize = (Dimension)UIManager.get("ScrollBar.minimumThumbSize");        maximumThumbSize = (Dimension)UIManager.get("ScrollBar.maximumThumbSize");         Boolean absB = (Boolean)UIManager.get("ScrollBar.allowsAbsolutePositioning");        supportsAbsolutePositioning = (absB != null) ? absB.booleanValue() :                                      false;         trackHighlight = NO_HIGHLIGHT;        if (scrollbar.getLayout() == null ||                     (scrollbar.getLayout() instanceof UIResource)) {            scrollbar.setLayout(this);        }        configureScrollBarColors();        LookAndFeel.installBorder(scrollbar, "ScrollBar.border");        LookAndFeel.installProperty(scrollbar, "opaque", Boolean.TRUE);         scrollBarValue = scrollbar.getValue();         incrGap = UIManager.getInt("ScrollBar.incrementButtonGap");        decrGap = UIManager.getInt("ScrollBar.decrementButtonGap");         // TODO this can be removed when incrGap/decrGap become protected        // handle scaling for sizeVarients for special case components. The        // key "JComponent.sizeVariant" scales for large/small/mini        // components are based on Apples LAF        String scaleKey = (String)scrollbar.getClientProperty(                "JComponent.sizeVariant");        if (scaleKey != null){            if ("large".equals(scaleKey)){                scrollBarWidth *= 1.15;                incrGap *= 1.15;                decrGap *= 1.15;            } else if ("small".equals(scaleKey)){                scrollBarWidth *= 0.857;                incrGap *= 0.857;                decrGap *= 0.714;            } else if ("mini".equals(scaleKey)){                scrollBarWidth *= 0.714;                incrGap *= 0.714;                decrGap *= 0.714;            }        }    }      protected void installComponents(){        switch (scrollbar.getOrientation()) {        case JScrollBar.VERTICAL:            incrButton = createIncreaseButton(SOUTH);            decrButton = createDecreaseButton(NORTH);            break;         case JScrollBar.HORIZONTAL:            if (scrollbar.getComponentOrientation().isLeftToRight()) {                incrButton = createIncreaseButton(EAST);                decrButton = createDecreaseButton(WEST);            } else {                incrButton = createIncreaseButton(WEST);                decrButton = createDecreaseButton(EAST);            }            break;        }        scrollbar.add(incrButton);        scrollbar.add(decrButton);        // Force the children's enabled state to be updated.        scrollbar.setEnabled(scrollbar.isEnabled());    }     protected void uninstallComponents(){        scrollbar.remove(incrButton);        scrollbar.remove(decrButton);    }      protected void installListeners(){        trackListener = createTrackListener();        buttonListener = createArrowButtonListener();        modelListener = createModelListener();        propertyChangeListener = createPropertyChangeListener();         scrollbar.addMouseListener(trackListener);        scrollbar.addMouseMotionListener(trackListener);        scrollbar.getModel().addChangeListener(modelListener);        scrollbar.addPropertyChangeListener(propertyChangeListener);        scrollbar.addFocusListener(getHandler());         if (incrButton != null) {            incrButton.addMouseListener(buttonListener);        }        if (decrButton != null) {            decrButton.addMouseListener(buttonListener);        }         scrollListener = createScrollListener();        scrollTimer = new Timer(scrollSpeedThrottle, scrollListener);        scrollTimer.setInitialDelay(300);  // default InitialDelay?    }      protected void installKeyboardActions(){        LazyActionMap.installLazyActionMap(scrollbar, BasicScrollBarUI.class,                                           "ScrollBar.actionMap");         InputMap inputMap = getInputMap(JComponent.WHEN_FOCUSED);        SwingUtilities.replaceUIInputMap(scrollbar, JComponent.WHEN_FOCUSED,                                         inputMap);        inputMap = getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);        SwingUtilities.replaceUIInputMap(scrollbar,                   JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, inputMap);    }     protected void uninstallKeyboardActions(){        SwingUtilities.replaceUIInputMap(scrollbar, JComponent.WHEN_FOCUSED,                                         null);        SwingUtilities.replaceUIActionMap(scrollbar, null);    }     private InputMap getInputMap(int condition) {        if (condition == JComponent.WHEN_FOCUSED) {            InputMap keyMap = (InputMap)DefaultLookup.get(                        scrollbar, this, "ScrollBar.focusInputMap");            InputMap rtlKeyMap;             if (scrollbar.getComponentOrientation().isLeftToRight() ||                ((rtlKeyMap = (InputMap)DefaultLookup.get(scrollbar, this, "ScrollBar.focusInputMap.RightToLeft")) == null)) {                return keyMap;            } else {                rtlKeyMap.setParent(keyMap);                return rtlKeyMap;            }        }        else if (condition == JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT) {            InputMap keyMap = (InputMap)DefaultLookup.get(                        scrollbar, this, "ScrollBar.ancestorInputMap");            InputMap rtlKeyMap;             if (scrollbar.getComponentOrientation().isLeftToRight() ||                ((rtlKeyMap = (InputMap)DefaultLookup.get(scrollbar, this, "ScrollBar.ancestorInputMap.RightToLeft")) == null)) {                return keyMap;            } else {                rtlKeyMap.setParent(keyMap);                return rtlKeyMap;            }        }        return null;    }      protected void uninstallListeners() {        scrollTimer.stop();        scrollTimer = null;         if (decrButton != null){            decrButton.removeMouseListener(buttonListener);        }        if (incrButton != null){            incrButton.removeMouseListener(buttonListener);        }         scrollbar.getModel().removeChangeListener(modelListener);        scrollbar.removeMouseListener(trackListener);        scrollbar.removeMouseMotionListener(trackListener);        scrollbar.removePropertyChangeListener(propertyChangeListener);        scrollbar.removeFocusListener(getHandler());        handler = null;    }      protected void uninstallDefaults(){        LookAndFeel.uninstallBorder(scrollbar);        if (scrollbar.getLayout() == this) {            scrollbar.setLayout(null);        }    }      private Handler getHandler() {        if (handler == null) {            handler = new Handler();        }        return handler;    }     protected TrackListener createTrackListener(){        return new TrackListener();    }     protected ArrowButtonListener createArrowButtonListener(){        return new ArrowButtonListener();    }     protected ModelListener createModelListener(){        return new ModelListener();    }     protected ScrollListener createScrollListener(){        return new ScrollListener();    }     protected PropertyChangeListener createPropertyChangeListener() {        return getHandler();    }     private void updateThumbState(int x, int y) {        Rectangle rect = getThumbBounds();         setThumbRollover(rect.contains(x, y));    }     /**     * Sets whether or not the mouse is currently over the thumb.     *     * @param active True indicates the thumb is currently active.     * @since 1.5     */    protected void setThumbRollover(boolean active) {        if (thumbActive != active) {            thumbActive = active;            scrollbar.repaint(getThumbBounds());        }    }     /**     * Returns true if the mouse is currently over the thumb.     *     * @return true if the thumb is currently active     * @since 1.5     */    public boolean isThumbRollover() {        return thumbActive;    }     public void paint(Graphics g, JComponent c) {        paintTrack(g, c, getTrackBounds());        Rectangle thumbBounds = getThumbBounds();        if (thumbBounds.intersects(g.getClipBounds())) {            paintThumb(g, c, thumbBounds);        }    }      /**     * A vertical scrollbar's preferred width is the maximum of     * preferred widths of the (non <code>null</code>)     * increment/decrement buttons,     * and the minimum width of the thumb. The preferred height is the     * sum of the preferred heights of the same parts.  The basis for     * the preferred size of a horizontal scrollbar is similar.     * <p>     * The <code>preferredSize</code> is only computed once, subsequent     * calls to this method just return a cached size.     *     * @param c the <code>JScrollBar</code> that's delegating this method to us     * @return the preferred size of a Basic JScrollBar     * @see #getMaximumSize     * @see #getMinimumSize     */    public Dimension getPreferredSize(JComponent c) {        return (scrollbar.getOrientation() == JScrollBar.VERTICAL)            ? new Dimension(scrollBarWidth, 48)            : new Dimension(48, scrollBarWidth);    }      /**     * @param c The JScrollBar that's delegating this method to us.     * @return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);     * @see #getMinimumSize     * @see #getPreferredSize     */    public Dimension getMaximumSize(JComponent c) {        return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);    }     protected JButton createDecreaseButton(int orientation)  {        return new BasicArrowButton(orientation,                                    UIManager.getColor("ScrollBar.thumb"),                                    UIManager.getColor("ScrollBar.thumbShadow"),                                    UIManager.getColor("ScrollBar.thumbDarkShadow"),                                    UIManager.getColor("ScrollBar.thumbHighlight"));    }     protected JButton createIncreaseButton(int orientation)  {        return new BasicArrowButton(orientation,                                    UIManager.getColor("ScrollBar.thumb"),                                    UIManager.getColor("ScrollBar.thumbShadow"),                                    UIManager.getColor("ScrollBar.thumbDarkShadow"),                                    UIManager.getColor("ScrollBar.thumbHighlight"));    }      protected void paintDecreaseHighlight(Graphics g)    {        Insets insets = scrollbar.getInsets();        Rectangle thumbR = getThumbBounds();        g.setColor(trackHighlightColor);         if (scrollbar.getOrientation() == JScrollBar.VERTICAL) {            //paint the distance between the start of the track and top of the thumb            int x = insets.left;            int y = trackRect.y;            int w = scrollbar.getWidth() - (insets.left + insets.right);            int h = thumbR.y - y;            g.fillRect(x, y, w, h);        } else {            //if left-to-right, fill the area between the start of the track and            //the left edge of the thumb. If right-to-left, fill the area between            //the end of the thumb and end of the track.

Lines 1–500 of 1618.