1008 lines · 35.4 KB · Java
RawDownload
/* * Copyright (c) 2002, 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.synth; import java.awt.event.*;import java.awt.Graphics;import java.awt.Dimension;import java.awt.FontMetrics;import java.awt.Rectangle;import java.awt.Point;import java.awt.Insets;import java.beans.*;import java.util.Dictionary;import java.util.Enumeration;import javax.swing.*;import javax.swing.plaf.*;import javax.swing.plaf.basic.BasicSliderUI;import sun.swing.SwingUtilities2;  /** * Provides the Synth L&F UI delegate for * {@link JSlider}. * * @author Joshua Outwater * @since 1.7 */public class SynthSliderUI extends BasicSliderUI                           implements PropertyChangeListener, SynthUI {    private Rectangle valueRect = new Rectangle();    private boolean paintValue;     /**     * When a JSlider is used as a renderer in a JTable, its layout is not     * being recomputed even though the size is changing. Even though there     * is a ComponentListener installed, it is not being notified. As such,     * at times when being asked to paint the layout should first be redone.     * At the end of the layout method we set this lastSize variable, which     * represents the size of the slider the last time it was layed out.     *     * In the paint method we then check to see that this is accurate, that     * the slider has not changed sizes since being last layed out. If necessary     * we recompute the layout.     */    private Dimension lastSize;     private int trackHeight;    private int trackBorder;    private int thumbWidth;    private int thumbHeight;     private SynthStyle style;    private SynthStyle sliderTrackStyle;    private SynthStyle sliderThumbStyle;     /** Used to determine the color to paint the thumb. */    private transient boolean thumbActive; //happens on rollover, and when pressed    private transient boolean thumbPressed; //happens when mouse was depressed while over thumb     ///////////////////////////////////////////////////    // ComponentUI Interface Implementation methods    ///////////////////////////////////////////////////    /**     * Creates a new UI object for the given component.     *     * @param c component to create UI object for     * @return the UI object     */    public static ComponentUI createUI(JComponent c) {        return new SynthSliderUI((JSlider)c);    }     protected SynthSliderUI(JSlider c) {        super(c);    }     /**     * @inheritDoc     */    @Override    protected void installDefaults(JSlider slider) {        updateStyle(slider);    }     /**     * Uninstalls default setting. This method is called when a     * {@code LookAndFeel} is uninstalled.     */    protected void uninstallDefaults(JSlider slider) {        SynthContext context = getContext(slider, ENABLED);        style.uninstallDefaults(context);        context.dispose();        style = null;         context = getContext(slider, Region.SLIDER_TRACK, ENABLED);        sliderTrackStyle.uninstallDefaults(context);        context.dispose();        sliderTrackStyle = null;         context = getContext(slider, Region.SLIDER_THUMB, ENABLED);        sliderThumbStyle.uninstallDefaults(context);        context.dispose();        sliderThumbStyle = null;    }     /**     * @inheritDoc     */    @Override    protected void installListeners(JSlider slider) {        super.installListeners(slider);        slider.addPropertyChangeListener(this);    }     /**     * @inheritDoc     */    @Override    protected void uninstallListeners(JSlider slider) {        slider.removePropertyChangeListener(this);        super.uninstallListeners(slider);    }     private void updateStyle(JSlider c) {        SynthContext context = getContext(c, ENABLED);        SynthStyle oldStyle = style;        style = SynthLookAndFeel.updateStyle(context, this);         if (style != oldStyle) {            thumbWidth =                style.getInt(context, "Slider.thumbWidth", 30);             thumbHeight =                style.getInt(context, "Slider.thumbHeight", 14);             // 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)slider.getClientProperty(                    "JComponent.sizeVariant");            if (scaleKey != null){                if ("large".equals(scaleKey)){                    thumbWidth *= 1.15;                    thumbHeight *= 1.15;                } else if ("small".equals(scaleKey)){                    thumbWidth *= 0.857;                    thumbHeight *= 0.857;                } else if ("mini".equals(scaleKey)){                    thumbWidth *= 0.784;                    thumbHeight *= 0.784;                }            }             trackBorder =                style.getInt(context, "Slider.trackBorder", 1);             trackHeight = thumbHeight + trackBorder * 2;             paintValue = style.getBoolean(context,                    "Slider.paintValue", true);            if (oldStyle != null) {                uninstallKeyboardActions(c);                installKeyboardActions(c);            }        }        context.dispose();         context = getContext(c, Region.SLIDER_TRACK, ENABLED);        sliderTrackStyle =            SynthLookAndFeel.updateStyle(context, this);        context.dispose();         context = getContext(c, Region.SLIDER_THUMB, ENABLED);        sliderThumbStyle =            SynthLookAndFeel.updateStyle(context, this);        context.dispose();    }     /**     * @inheritDoc     */    @Override    protected TrackListener createTrackListener(JSlider s) {        return new SynthTrackListener();    }     private void updateThumbState(int x, int y) {        setThumbActive(thumbRect.contains(x, y));    }     private void updateThumbState(int x, int y, boolean pressed) {        updateThumbState(x, y);        setThumbPressed(pressed);    }     private void setThumbActive(boolean active) {        if (thumbActive != active) {            thumbActive = active;            slider.repaint(thumbRect);        }    }     private void setThumbPressed(boolean pressed) {        if (thumbPressed != pressed) {            thumbPressed = pressed;            slider.repaint(thumbRect);        }    }     /**     * @inheritDoc     */    @Override    public int getBaseline(JComponent c, int width, int height) {        if (c == null) {            throw new NullPointerException("Component must be non-null");        }        if (width < 0 || height < 0) {            throw new IllegalArgumentException(                    "Width and height must be >= 0");        }        if (slider.getPaintLabels() && labelsHaveSameBaselines()) {            // Get the insets for the track.            Insets trackInsets = new Insets(0, 0, 0, 0);            SynthContext trackContext = getContext(slider,                                                   Region.SLIDER_TRACK);            style.getInsets(trackContext, trackInsets);            trackContext.dispose();            if (slider.getOrientation() == JSlider.HORIZONTAL) {                int valueHeight = 0;                if (paintValue) {                    SynthContext context = getContext(slider);                    valueHeight = context.getStyle().getGraphicsUtils(context).                            getMaximumCharHeight(context);                    context.dispose();                }                int tickHeight = 0;                if (slider.getPaintTicks()) {                    tickHeight = getTickLength();                }                int labelHeight = getHeightOfTallestLabel();                int contentHeight = valueHeight + trackHeight +                        trackInsets.top + trackInsets.bottom +                        tickHeight + labelHeight + 4;                int centerY = height / 2 - contentHeight / 2;                centerY += valueHeight + 2;                centerY += trackHeight + trackInsets.top + trackInsets.bottom;                centerY += tickHeight + 2;                JComponent label = (JComponent) slider.getLabelTable().elements().nextElement();                Dimension pref = label.getPreferredSize();                return centerY + label.getBaseline(pref.width, pref.height);            }            else { // VERTICAL                Integer value = slider.getInverted() ? getLowestValue() :                                                       getHighestValue();                if (value != null) {                    int valueY = insetCache.top;                    int valueHeight = 0;                    if (paintValue) {                        SynthContext context = getContext(slider);                        valueHeight = context.getStyle().getGraphicsUtils(                                context).getMaximumCharHeight(context);                        context.dispose();                    }                    int contentHeight = height - insetCache.top -                            insetCache.bottom;                    int trackY = valueY + valueHeight;                    int trackHeight = contentHeight - valueHeight;                    int yPosition = yPositionForValue(value.intValue(), trackY,                                                      trackHeight);                    JComponent label = (JComponent) slider.getLabelTable().get(value);                    Dimension pref = label.getPreferredSize();                    return yPosition - pref.height / 2 +                            label.getBaseline(pref.width, pref.height);                }            }        }        return -1;    }     /**     * @inheritDoc     */    @Override    public Dimension getPreferredSize(JComponent c)  {        recalculateIfInsetsChanged();        Dimension d = new Dimension(contentRect.width, contentRect.height);        if (slider.getOrientation() == JSlider.VERTICAL) {            d.height = 200;        } else {            d.width = 200;        }        Insets i = slider.getInsets();        d.width += i.left + i.right;        d.height += i.top + i.bottom;        return d;    }     /**     * @inheritDoc     */    @Override    public Dimension getMinimumSize(JComponent c) {        recalculateIfInsetsChanged();        Dimension d = new Dimension(contentRect.width, contentRect.height);        if (slider.getOrientation() == JSlider.VERTICAL) {            d.height = thumbRect.height + insetCache.top + insetCache.bottom;        } else {            d.width = thumbRect.width + insetCache.left + insetCache.right;        }        return d;    }     /**     * @inheritDoc     */    @Override    protected void calculateGeometry() {        calculateThumbSize();        layout();        calculateThumbLocation();    }     /**     * Lays out the slider.     */    protected void layout() {        SynthContext context = getContext(slider);        SynthGraphicsUtils synthGraphics = style.getGraphicsUtils(context);         // Get the insets for the track.        Insets trackInsets = new Insets(0, 0, 0, 0);        SynthContext trackContext = getContext(slider, Region.SLIDER_TRACK);        style.getInsets(trackContext, trackInsets);        trackContext.dispose();         if (slider.getOrientation() == JSlider.HORIZONTAL) {            // Calculate the height of all the subcomponents so we can center            // them.            valueRect.height = 0;            if (paintValue) {                valueRect.height =                    synthGraphics.getMaximumCharHeight(context);            }             trackRect.height = trackHeight;             tickRect.height = 0;            if (slider.getPaintTicks()) {                tickRect.height = getTickLength();            }             labelRect.height = 0;            if (slider.getPaintLabels()) {                labelRect.height = getHeightOfTallestLabel();            }             contentRect.height = valueRect.height + trackRect.height                + trackInsets.top + trackInsets.bottom                + tickRect.height + labelRect.height + 4;            contentRect.width = slider.getWidth() - insetCache.left                - insetCache.right;             // Check if any of the labels will paint out of bounds.            int pad = 0;            if (slider.getPaintLabels()) {                // Calculate the track rectangle.  It is necessary for                // xPositionForValue to return correct values.                trackRect.x = insetCache.left;                trackRect.width = contentRect.width;                 Dictionary dictionary = slider.getLabelTable();                if (dictionary != null) {                    int minValue = slider.getMinimum();                    int maxValue = slider.getMaximum();                     // Iterate through the keys in the dictionary and find the                    // first and last labels indices that fall within the                    // slider range.                    int firstLblIdx = Integer.MAX_VALUE;                    int lastLblIdx = Integer.MIN_VALUE;                    for (Enumeration keys = dictionary.keys();                            keys.hasMoreElements(); ) {                        int keyInt = ((Integer)keys.nextElement()).intValue();                        if (keyInt >= minValue && keyInt < firstLblIdx) {                            firstLblIdx = keyInt;                        }                        if (keyInt <= maxValue && keyInt > lastLblIdx) {                            lastLblIdx = keyInt;                        }                    }                    // Calculate the pad necessary for the labels at the first                    // and last visible indices.                    pad = getPadForLabel(firstLblIdx);                    pad = Math.max(pad, getPadForLabel(lastLblIdx));                }            }            // Calculate the painting rectangles for each of the different            // slider areas.            valueRect.x = trackRect.x = tickRect.x = labelRect.x =                (insetCache.left + pad);            valueRect.width = trackRect.width = tickRect.width =                labelRect.width = (contentRect.width - (pad * 2));             int centerY = slider.getHeight() / 2 - contentRect.height / 2;             valueRect.y = centerY;            centerY += valueRect.height + 2;             trackRect.y = centerY + trackInsets.top;            centerY += trackRect.height + trackInsets.top + trackInsets.bottom;             tickRect.y = centerY;            centerY += tickRect.height + 2;             labelRect.y = centerY;            centerY += labelRect.height;        } else {            // Calculate the width of all the subcomponents so we can center            // them.            trackRect.width = trackHeight;             tickRect.width = 0;            if (slider.getPaintTicks()) {                tickRect.width = getTickLength();            }             labelRect.width = 0;            if (slider.getPaintLabels()) {                labelRect.width = getWidthOfWidestLabel();            }             valueRect.y = insetCache.top;            valueRect.height = 0;            if (paintValue) {                valueRect.height =                    synthGraphics.getMaximumCharHeight(context);            }             // Get the max width of the min or max value of the slider.            FontMetrics fm = slider.getFontMetrics(slider.getFont());            valueRect.width = Math.max(                synthGraphics.computeStringWidth(context, slider.getFont(),                    fm, "" + slider.getMaximum()),                synthGraphics.computeStringWidth(context, slider.getFont(),                    fm, "" + slider.getMinimum()));             int l = valueRect.width / 2;            int w1 = trackInsets.left + trackRect.width / 2;            int w2 = trackRect.width / 2 + trackInsets.right +                              tickRect.width + labelRect.width;            contentRect.width = Math.max(w1, l) + Math.max(w2, l) +                    2 + insetCache.left + insetCache.right;            contentRect.height = slider.getHeight() -                                    insetCache.top - insetCache.bottom;             // Layout the components.            trackRect.y = tickRect.y = labelRect.y =                valueRect.y + valueRect.height;            trackRect.height = tickRect.height = labelRect.height =                contentRect.height - valueRect.height;             int startX = slider.getWidth() / 2 - contentRect.width / 2;            if (SynthLookAndFeel.isLeftToRight(slider)) {                if (l > w1) {                    startX += (l - w1);                }                trackRect.x = startX + trackInsets.left;                 startX += trackInsets.left + trackRect.width + trackInsets.right;                tickRect.x = startX;                labelRect.x = startX + tickRect.width + 2;            } else {                if (l > w2) {                    startX += (l - w2);                }                labelRect.x = startX;

Lines 1–500 of 1008.