| 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 */  | 
 | 
 | 
 | 
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;  | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 */  | 
 | 
public class SynthSliderUI extends BasicSliderUI  | 
 | 
                           implements PropertyChangeListener, SynthUI { | 
 | 
    private Rectangle valueRect = new Rectangle();  | 
 | 
    private boolean paintValue;  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    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;   | 
 | 
    private transient boolean thumbPressed;   | 
 | 
 | 
 | 
    ///////////////////////////////////////////////////  | 
 | 
    // ComponentUI Interface Implementation methods  | 
 | 
    ///////////////////////////////////////////////////  | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public static ComponentUI createUI(JComponent c) { | 
 | 
        return new SynthSliderUI((JSlider)c);  | 
 | 
    }  | 
 | 
 | 
 | 
    protected SynthSliderUI(JSlider c) { | 
 | 
        super(c);  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    @Override  | 
 | 
    protected void installDefaults(JSlider slider) { | 
 | 
        updateStyle(slider);  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    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;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    @Override  | 
 | 
    protected void installListeners(JSlider slider) { | 
 | 
        super.installListeners(slider);  | 
 | 
        slider.addPropertyChangeListener(this);  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    @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  | 
 | 
              | 
 | 
            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();  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    @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);  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    @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()) { | 
 | 
              | 
 | 
            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 {  | 
 | 
                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;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    @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;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    @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;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    @Override  | 
 | 
    protected void calculateGeometry() { | 
 | 
        calculateThumbSize();  | 
 | 
        layout();  | 
 | 
        calculateThumbLocation();  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    protected void layout() { | 
 | 
        SynthContext context = getContext(slider);  | 
 | 
        SynthGraphicsUtils synthGraphics = style.getGraphicsUtils(context);  | 
 | 
 | 
 | 
          | 
 | 
        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  | 
 | 
              | 
 | 
            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;  | 
 | 
 | 
 | 
              | 
 | 
            int pad = 0;  | 
 | 
            if (slider.getPaintLabels()) { | 
 | 
                // Calculate the track rectangle.  It is necessary for  | 
 | 
                  | 
 | 
                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  | 
 | 
                      | 
 | 
                    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  | 
 | 
                      | 
 | 
                    pad = getPadForLabel(firstLblIdx);  | 
 | 
                    pad = Math.max(pad, getPadForLabel(lastLblIdx));  | 
 | 
                }  | 
 | 
            }  | 
 | 
            // Calculate the painting rectangles for each of the different  | 
 | 
              | 
 | 
            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  | 
 | 
              | 
 | 
            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);  | 
 | 
            }  | 
 | 
 | 
 | 
              | 
 | 
            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;  | 
 | 
 | 
 | 
              | 
 | 
            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;  | 
 | 
 | 
 | 
                startX += labelRect.width + 2;  | 
 | 
                tickRect.x = startX;  | 
 | 
                trackRect.x = startX + tickRect.width + trackInsets.left;  | 
 | 
            }  | 
 | 
        }  | 
 | 
        context.dispose();  | 
 | 
        lastSize = slider.getSize();  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    private int getPadForLabel(int i) { | 
 | 
        int pad = 0;  | 
 | 
 | 
 | 
        JComponent c = (JComponent) slider.getLabelTable().get(i);  | 
 | 
        if (c != null) { | 
 | 
            int centerX = xPositionForValue(i);  | 
 | 
            int cHalfWidth = c.getPreferredSize().width / 2;  | 
 | 
            if (centerX - cHalfWidth < insetCache.left) { | 
 | 
                pad = Math.max(pad, insetCache.left - (centerX - cHalfWidth));  | 
 | 
            }  | 
 | 
 | 
 | 
            if (centerX + cHalfWidth > slider.getWidth() - insetCache.right) { | 
 | 
                pad = Math.max(pad, (centerX + cHalfWidth) -  | 
 | 
                        (slider.getWidth() - insetCache.right));  | 
 | 
            }  | 
 | 
        }  | 
 | 
        return pad;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    @Override  | 
 | 
    protected void calculateThumbLocation() { | 
 | 
        super.calculateThumbLocation();  | 
 | 
        if (slider.getOrientation() == JSlider.HORIZONTAL) { | 
 | 
            thumbRect.y += trackBorder;  | 
 | 
        } else { | 
 | 
            thumbRect.x += trackBorder;  | 
 | 
        }  | 
 | 
        Point mousePosition = slider.getMousePosition();  | 
 | 
        if(mousePosition != null) { | 
 | 
        updateThumbState(mousePosition.x, mousePosition.y);  | 
 | 
       }  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    @Override  | 
 | 
    public void setThumbLocation(int x, int y) { | 
 | 
        super.setThumbLocation(x, y);  | 
 | 
        // Value rect is tied to the thumb location.  We need to repaint when  | 
 | 
          | 
 | 
        slider.repaint(valueRect.x, valueRect.y,  | 
 | 
                valueRect.width, valueRect.height);  | 
 | 
        setThumbActive(false);  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    @Override  | 
 | 
    protected int xPositionForValue(int value) { | 
 | 
        int min = slider.getMinimum();  | 
 | 
        int max = slider.getMaximum();  | 
 | 
        int trackLeft = trackRect.x + thumbRect.width / 2 + trackBorder;  | 
 | 
        int trackRight = trackRect.x + trackRect.width - thumbRect.width / 2  | 
 | 
            - trackBorder;  | 
 | 
        int trackLength = trackRight - trackLeft;  | 
 | 
        double valueRange = (double)max - (double)min;  | 
 | 
        double pixelsPerValue = (double)trackLength / valueRange;  | 
 | 
        int xPosition;  | 
 | 
 | 
 | 
        if (!drawInverted()) { | 
 | 
            xPosition = trackLeft;  | 
 | 
            xPosition += Math.round( pixelsPerValue * ((double)value - min));  | 
 | 
        } else { | 
 | 
            xPosition = trackRight;  | 
 | 
            xPosition -= Math.round( pixelsPerValue * ((double)value - min));  | 
 | 
        }  | 
 | 
 | 
 | 
        xPosition = Math.max(trackLeft, xPosition);  | 
 | 
        xPosition = Math.min(trackRight, xPosition);  | 
 | 
 | 
 | 
        return xPosition;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    @Override  | 
 | 
    protected int yPositionForValue(int value, int trackY, int trackHeight) { | 
 | 
        int min = slider.getMinimum();  | 
 | 
        int max = slider.getMaximum();  | 
 | 
        int trackTop = trackY + thumbRect.height / 2 + trackBorder;  | 
 | 
        int trackBottom = trackY + trackHeight - thumbRect.height / 2 -  | 
 | 
                trackBorder;  | 
 | 
        int trackLength = trackBottom - trackTop;  | 
 | 
        double valueRange = (double)max - (double)min;  | 
 | 
        double pixelsPerValue = (double)trackLength / valueRange;  | 
 | 
        int yPosition;  | 
 | 
 | 
 | 
        if (!drawInverted()) { | 
 | 
            yPosition = trackTop;  | 
 | 
            yPosition += Math.round(pixelsPerValue * ((double)max - value));  | 
 | 
        } else { | 
 | 
            yPosition = trackTop;  | 
 | 
            yPosition += Math.round(pixelsPerValue * ((double)value - min));  | 
 | 
        }  | 
 | 
 | 
 | 
        yPosition = Math.max(trackTop, yPosition);  | 
 | 
        yPosition = Math.min(trackBottom, yPosition);  | 
 | 
 | 
 | 
        return yPosition;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    @Override  | 
 | 
    public int valueForYPosition(int yPos) { | 
 | 
        int value;  | 
 | 
        int minValue = slider.getMinimum();  | 
 | 
        int maxValue = slider.getMaximum();  | 
 | 
        int trackTop = trackRect.y + thumbRect.height / 2 + trackBorder;  | 
 | 
        int trackBottom = trackRect.y + trackRect.height  | 
 | 
            - thumbRect.height / 2 - trackBorder;  | 
 | 
        int trackLength = trackBottom - trackTop;  | 
 | 
 | 
 | 
        if (yPos <= trackTop) { | 
 | 
            value = drawInverted() ? minValue : maxValue;  | 
 | 
        } else if (yPos >= trackBottom) { | 
 | 
            value = drawInverted() ? maxValue : minValue;  | 
 | 
        } else { | 
 | 
            int distanceFromTrackTop = yPos - trackTop;  | 
 | 
            double valueRange = (double)maxValue - (double)minValue;  | 
 | 
            double valuePerPixel = valueRange / (double)trackLength;  | 
 | 
            int valueFromTrackTop =  | 
 | 
                (int)Math.round(distanceFromTrackTop * valuePerPixel);  | 
 | 
            value = drawInverted() ?  | 
 | 
                minValue + valueFromTrackTop : maxValue - valueFromTrackTop;  | 
 | 
        }  | 
 | 
        return value;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    @Override  | 
 | 
    public int valueForXPosition(int xPos) { | 
 | 
        int value;  | 
 | 
        int minValue = slider.getMinimum();  | 
 | 
        int maxValue = slider.getMaximum();  | 
 | 
        int trackLeft = trackRect.x + thumbRect.width / 2 + trackBorder;  | 
 | 
        int trackRight = trackRect.x + trackRect.width  | 
 | 
            - thumbRect.width / 2 - trackBorder;  | 
 | 
        int trackLength = trackRight - trackLeft;  | 
 | 
 | 
 | 
        if (xPos <= trackLeft) { | 
 | 
            value = drawInverted() ? maxValue : minValue;  | 
 | 
        } else if (xPos >= trackRight) { | 
 | 
            value = drawInverted() ? minValue : maxValue;  | 
 | 
        } else { | 
 | 
            int distanceFromTrackLeft = xPos - trackLeft;  | 
 | 
            double valueRange = (double)maxValue - (double)minValue;  | 
 | 
            double valuePerPixel = valueRange / (double)trackLength;  | 
 | 
            int valueFromTrackLeft =  | 
 | 
                (int)Math.round(distanceFromTrackLeft * valuePerPixel);  | 
 | 
            value = drawInverted() ?  | 
 | 
                maxValue - valueFromTrackLeft : minValue + valueFromTrackLeft;  | 
 | 
        }  | 
 | 
        return value;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    @Override  | 
 | 
    protected Dimension getThumbSize() { | 
 | 
        Dimension size = new Dimension();  | 
 | 
 | 
 | 
        if (slider.getOrientation() == JSlider.VERTICAL) { | 
 | 
            size.width = thumbHeight;  | 
 | 
            size.height = thumbWidth;  | 
 | 
        } else { | 
 | 
            size.width = thumbWidth;  | 
 | 
            size.height = thumbHeight;  | 
 | 
        }  | 
 | 
        return size;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    @Override  | 
 | 
    protected void recalculateIfInsetsChanged() { | 
 | 
        SynthContext context = getContext(slider);  | 
 | 
        Insets newInsets = style.getInsets(context, null);  | 
 | 
        Insets compInsets = slider.getInsets();  | 
 | 
        newInsets.left += compInsets.left; newInsets.right += compInsets.right;  | 
 | 
        newInsets.top += compInsets.top; newInsets.bottom += compInsets.bottom;  | 
 | 
        if (!newInsets.equals(insetCache)) { | 
 | 
            insetCache = newInsets;  | 
 | 
            calculateGeometry();  | 
 | 
        }  | 
 | 
        context.dispose();  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    @Override  | 
 | 
    public SynthContext getContext(JComponent c) { | 
 | 
        return getContext(c, SynthLookAndFeel.getComponentState(c));  | 
 | 
    }  | 
 | 
 | 
 | 
    private SynthContext getContext(JComponent c, int state) { | 
 | 
        return SynthContext.getContext(c, style, state);  | 
 | 
    }  | 
 | 
 | 
 | 
    private SynthContext getContext(JComponent c, Region subregion) { | 
 | 
        return getContext(c, subregion, getComponentState(c, subregion));  | 
 | 
    }  | 
 | 
 | 
 | 
    private SynthContext getContext(JComponent c, Region subregion, int state) { | 
 | 
        SynthStyle style = null;  | 
 | 
 | 
 | 
        if (subregion == Region.SLIDER_TRACK) { | 
 | 
            style = sliderTrackStyle;  | 
 | 
        } else if (subregion == Region.SLIDER_THUMB) { | 
 | 
            style = sliderThumbStyle;  | 
 | 
        }  | 
 | 
        return SynthContext.getContext(c, subregion, style, state);  | 
 | 
    }  | 
 | 
 | 
 | 
    private int getComponentState(JComponent c, Region region) { | 
 | 
        if (region == Region.SLIDER_THUMB && thumbActive &&c.isEnabled()) { | 
 | 
            int state = thumbPressed ? PRESSED : MOUSE_OVER;  | 
 | 
            if (c.isFocusOwner()) state |= FOCUSED;  | 
 | 
            return state;  | 
 | 
        }  | 
 | 
        return SynthLookAndFeel.getComponentState(c);  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    @Override  | 
 | 
    public void update(Graphics g, JComponent c) { | 
 | 
        SynthContext context = getContext(c);  | 
 | 
        SynthLookAndFeel.update(context, g);  | 
 | 
        context.getPainter().paintSliderBackground(context,  | 
 | 
                          g, 0, 0, c.getWidth(), c.getHeight(),  | 
 | 
                          slider.getOrientation());  | 
 | 
        paint(context, g);  | 
 | 
        context.dispose();  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    @Override  | 
 | 
    public void paint(Graphics g, JComponent c) { | 
 | 
        SynthContext context = getContext(c);  | 
 | 
        paint(context, g);  | 
 | 
        context.dispose();  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    protected void paint(SynthContext context, Graphics g) { | 
 | 
        recalculateIfInsetsChanged();  | 
 | 
        recalculateIfOrientationChanged();  | 
 | 
        Rectangle clip = g.getClipBounds();  | 
 | 
 | 
 | 
        if (lastSize == null || !lastSize.equals(slider.getSize())) { | 
 | 
            calculateGeometry();  | 
 | 
        }  | 
 | 
 | 
 | 
        if (paintValue) { | 
 | 
            FontMetrics fm = SwingUtilities2.getFontMetrics(slider, g);  | 
 | 
            int labelWidth = context.getStyle().getGraphicsUtils(context).  | 
 | 
                computeStringWidth(context, g.getFont(), fm,  | 
 | 
                    "" + slider.getValue());  | 
 | 
            valueRect.x = thumbRect.x + (thumbRect.width - labelWidth) / 2;  | 
 | 
 | 
 | 
            // For horizontal sliders, make sure value is not painted  | 
 | 
              | 
 | 
            if (slider.getOrientation() == JSlider.HORIZONTAL) { | 
 | 
                if (valueRect.x + labelWidth > insetCache.left + contentRect.width) { | 
 | 
                    valueRect.x =  (insetCache.left + contentRect.width) - labelWidth;  | 
 | 
                }  | 
 | 
                valueRect.x = Math.max(valueRect.x, 0);  | 
 | 
            }  | 
 | 
 | 
 | 
            g.setColor(context.getStyle().getColor(  | 
 | 
                    context, ColorType.TEXT_FOREGROUND));  | 
 | 
            context.getStyle().getGraphicsUtils(context).paintText(  | 
 | 
                    context, g, "" + slider.getValue(), valueRect.x,  | 
 | 
                    valueRect.y, -1);  | 
 | 
        }  | 
 | 
 | 
 | 
        if (slider.getPaintTrack() && clip.intersects(trackRect)) { | 
 | 
            SynthContext subcontext = getContext(slider, Region.SLIDER_TRACK);  | 
 | 
            paintTrack(subcontext, g, trackRect);  | 
 | 
            subcontext.dispose();  | 
 | 
        }  | 
 | 
 | 
 | 
        if (clip.intersects(thumbRect)) { | 
 | 
            SynthContext subcontext = getContext(slider, Region.SLIDER_THUMB);  | 
 | 
            paintThumb(subcontext, g, thumbRect);  | 
 | 
            subcontext.dispose();  | 
 | 
        }  | 
 | 
 | 
 | 
        if (slider.getPaintTicks() && clip.intersects(tickRect)) { | 
 | 
            paintTicks(g);  | 
 | 
        }  | 
 | 
 | 
 | 
        if (slider.getPaintLabels() && clip.intersects(labelRect)) { | 
 | 
            paintLabels(g);  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    @Override  | 
 | 
    public void paintBorder(SynthContext context, Graphics g, int x,  | 
 | 
                            int y, int w, int h) { | 
 | 
        context.getPainter().paintSliderBorder(context, g, x, y, w, h,  | 
 | 
                                               slider.getOrientation());  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    protected void paintThumb(SynthContext context, Graphics g,  | 
 | 
            Rectangle thumbBounds)  { | 
 | 
        int orientation = slider.getOrientation();  | 
 | 
        SynthLookAndFeel.updateSubregion(context, g, thumbBounds);  | 
 | 
        context.getPainter().paintSliderThumbBackground(context, g,  | 
 | 
                             thumbBounds.x, thumbBounds.y, thumbBounds.width,  | 
 | 
                             thumbBounds.height, orientation);  | 
 | 
        context.getPainter().paintSliderThumbBorder(context, g,  | 
 | 
                             thumbBounds.x, thumbBounds.y, thumbBounds.width,  | 
 | 
                             thumbBounds.height, orientation);  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    protected void paintTrack(SynthContext context, Graphics g,  | 
 | 
            Rectangle trackBounds) { | 
 | 
        int orientation = slider.getOrientation();  | 
 | 
        SynthLookAndFeel.updateSubregion(context, g, trackBounds);  | 
 | 
        context.getPainter().paintSliderTrackBackground(context, g,  | 
 | 
                trackBounds.x, trackBounds.y, trackBounds.width,  | 
 | 
                trackBounds.height, orientation);  | 
 | 
        context.getPainter().paintSliderTrackBorder(context, g,  | 
 | 
                trackBounds.x, trackBounds.y, trackBounds.width,  | 
 | 
                trackBounds.height, orientation);  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    @Override  | 
 | 
    public void propertyChange(PropertyChangeEvent e) { | 
 | 
        if (SynthLookAndFeel.shouldUpdateStyle(e)) { | 
 | 
            updateStyle((JSlider)e.getSource());  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
    //////////////////////////////////////////////////  | 
 | 
    /// Track Listener Class  | 
 | 
    //////////////////////////////////////////////////  | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    private class SynthTrackListener extends TrackListener { | 
 | 
 | 
 | 
        @Override public void mouseExited(MouseEvent e) { | 
 | 
            setThumbActive(false);  | 
 | 
        }  | 
 | 
 | 
 | 
        @Override public void mousePressed(MouseEvent e) { | 
 | 
            super.mousePressed(e);  | 
 | 
            setThumbPressed(thumbRect.contains(e.getX(), e.getY()));  | 
 | 
        }  | 
 | 
 | 
 | 
        @Override public void mouseReleased(MouseEvent e) { | 
 | 
            super.mouseReleased(e);  | 
 | 
            updateThumbState(e.getX(), e.getY(), false);  | 
 | 
        }  | 
 | 
 | 
 | 
        @Override public void mouseDragged(MouseEvent e) { | 
 | 
            int thumbMiddle;  | 
 | 
 | 
 | 
            if (!slider.isEnabled()) { | 
 | 
                return;  | 
 | 
            }  | 
 | 
 | 
 | 
            currentMouseX = e.getX();  | 
 | 
            currentMouseY = e.getY();  | 
 | 
 | 
 | 
            if (!isDragging()) { | 
 | 
                return;  | 
 | 
            }  | 
 | 
 | 
 | 
            slider.setValueIsAdjusting(true);  | 
 | 
 | 
 | 
            switch (slider.getOrientation()) { | 
 | 
            case JSlider.VERTICAL:  | 
 | 
                int halfThumbHeight = thumbRect.height / 2;  | 
 | 
                int thumbTop = e.getY() - offset;  | 
 | 
                int trackTop = trackRect.y;  | 
 | 
                int trackBottom = trackRect.y + trackRect.height  | 
 | 
                    - halfThumbHeight - trackBorder;  | 
 | 
                int vMax = yPositionForValue(slider.getMaximum() -  | 
 | 
                    slider.getExtent());  | 
 | 
 | 
 | 
                if (drawInverted()) { | 
 | 
                    trackBottom = vMax;  | 
 | 
                    trackTop = trackTop + halfThumbHeight;  | 
 | 
                } else { | 
 | 
                    trackTop = vMax;  | 
 | 
                }  | 
 | 
                thumbTop = Math.max(thumbTop, trackTop - halfThumbHeight);  | 
 | 
                thumbTop = Math.min(thumbTop, trackBottom - halfThumbHeight);  | 
 | 
 | 
 | 
                setThumbLocation(thumbRect.x, thumbTop);  | 
 | 
 | 
 | 
                thumbMiddle = thumbTop + halfThumbHeight;  | 
 | 
                slider.setValue(valueForYPosition(thumbMiddle));  | 
 | 
                break;  | 
 | 
            case JSlider.HORIZONTAL:  | 
 | 
                int halfThumbWidth = thumbRect.width / 2;  | 
 | 
                int thumbLeft = e.getX() - offset;  | 
 | 
                int trackLeft = trackRect.x + halfThumbWidth + trackBorder;  | 
 | 
                int trackRight = trackRect.x + trackRect.width  | 
 | 
                    - halfThumbWidth - trackBorder;  | 
 | 
                int hMax = xPositionForValue(slider.getMaximum() -  | 
 | 
                    slider.getExtent());  | 
 | 
 | 
 | 
                if (drawInverted()) { | 
 | 
                    trackLeft = hMax;  | 
 | 
                } else { | 
 | 
                    trackRight = hMax;  | 
 | 
                }  | 
 | 
                thumbLeft = Math.max(thumbLeft, trackLeft - halfThumbWidth);  | 
 | 
                thumbLeft = Math.min(thumbLeft, trackRight - halfThumbWidth);  | 
 | 
 | 
 | 
                setThumbLocation(thumbLeft, thumbRect.y);  | 
 | 
 | 
 | 
                thumbMiddle = thumbLeft + halfThumbWidth;  | 
 | 
                slider.setValue(valueForXPosition(thumbMiddle));  | 
 | 
                break;  | 
 | 
            default:  | 
 | 
                return;  | 
 | 
            }  | 
 | 
 | 
 | 
            if (slider.getValueIsAdjusting()) { | 
 | 
                setThumbActive(true);  | 
 | 
            }  | 
 | 
        }  | 
 | 
 | 
 | 
        @Override public void mouseMoved(MouseEvent e) { | 
 | 
            updateThumbState(e.getX(), e.getY());  | 
 | 
        }  | 
 | 
    }  | 
 | 
}  |