Source Code Cross Referenced for BasicSliderUI.java in  » 6.0-JDK-Core » swing » javax » swing » plaf » basic » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Home
Java Source Code / Java Documentation
1.6.0 JDK Core
2.6.0 JDK Modules
3.6.0 JDK Modules com.sun
4.6.0 JDK Modules com.sun.java
5.6.0 JDK Modules sun
6.6.0 JDK Platform
7.Ajax
8.Apache Harmony Java SE
9.Aspect oriented
10.Authentication Authorization
11.Blogger System
12.Build
13.Byte Code
14.Cache
15.Chart
16.Chat
17.Code Analyzer
18.Collaboration
19.Content Management System
20.Database Client
21.Database DBMS
22.Database JDBC Connection Pool
23.Database ORM
24.Development
25.EJB Server
26.ERP CRM Financial
27.ESB
28.Forum
29.Game
30.GIS
31.Graphic 3D
32.Graphic Library
33.Groupware
34.HTML Parser
35.IDE
36.IDE Eclipse
37.IDE Netbeans
38.Installer
39.Internationalization Localization
40.Inversion of Control
41.Issue Tracking
42.J2EE
43.J2ME
44.JBoss
45.JMS
46.JMX
47.Library
48.Mail Clients
49.Music
50.Net
51.Parser
52.PDF
53.Portal
54.Profiler
55.Project Management
56.Report
57.RSS RDF
58.Rule Engine
59.Science
60.Scripting
61.Search Engine
62.Security
63.Sevlet Container
64.Source Control
65.Swing Library
66.Template Engine
67.Test Coverage
68.Testing
69.UML
70.Web Crawler
71.Web Framework
72.Web Mail
73.Web Server
74.Web Services
75.Web Services apache cxf 2.2.6
76.Web Services AXIS2
77.Wiki Engine
78.Workflow Engines
79.XML
80.XML UI
Java Source Code / Java Documentation » 6.0 JDK Core » swing » javax.swing.plaf.basic 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001        /*
0002         * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
0003         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004         *
0005         * This code is free software; you can redistribute it and/or modify it
0006         * under the terms of the GNU General Public License version 2 only, as
0007         * published by the Free Software Foundation.  Sun designates this
0008         * particular file as subject to the "Classpath" exception as provided
0009         * by Sun in the LICENSE file that accompanied this code.
0010         *
0011         * This code is distributed in the hope that it will be useful, but WITHOUT
0012         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
0014         * version 2 for more details (a copy is included in the LICENSE file that
0015         * accompanied this code).
0016         *
0017         * You should have received a copy of the GNU General Public License version
0018         * 2 along with this work; if not, write to the Free Software Foundation,
0019         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020         *
0021         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022         * CA 95054 USA or visit www.sun.com if you need additional information or
0023         * have any questions.
0024         */
0025
0026        package javax.swing.plaf.basic;
0027
0028        import java.awt.Component;
0029        import java.awt.Container;
0030        import java.awt.Adjustable;
0031        import java.awt.event.*;
0032        import java.awt.FontMetrics;
0033        import java.awt.Graphics;
0034        import java.awt.Dimension;
0035        import java.awt.Rectangle;
0036        import java.awt.Point;
0037        import java.awt.Insets;
0038        import java.awt.Color;
0039        import java.awt.IllegalComponentStateException;
0040        import java.awt.Polygon;
0041        import java.beans.*;
0042        import java.util.Dictionary;
0043        import java.util.Enumeration;
0044
0045        import javax.swing.border.AbstractBorder;
0046
0047        import javax.swing.*;
0048        import javax.swing.event.*;
0049        import javax.swing.plaf.*;
0050        import sun.swing.DefaultLookup;
0051        import sun.swing.UIAction;
0052
0053        /**
0054         * A Basic L&F implementation of SliderUI.
0055         *
0056         * @version 1.113 05/05/07
0057         * @author Tom Santos
0058         */
0059        public class BasicSliderUI extends SliderUI {
0060            // Old actions forward to an instance of this.
0061            private static final Actions SHARED_ACTION = new Actions();
0062
0063            public static final int POSITIVE_SCROLL = +1;
0064            public static final int NEGATIVE_SCROLL = -1;
0065            public static final int MIN_SCROLL = -2;
0066            public static final int MAX_SCROLL = +2;
0067
0068            protected Timer scrollTimer;
0069            protected JSlider slider;
0070
0071            protected Insets focusInsets = null;
0072            protected Insets insetCache = null;
0073            protected boolean leftToRightCache = true;
0074            protected Rectangle focusRect = null;
0075            protected Rectangle contentRect = null;
0076            protected Rectangle labelRect = null;
0077            protected Rectangle tickRect = null;
0078            protected Rectangle trackRect = null;
0079            protected Rectangle thumbRect = null;
0080
0081            protected int trackBuffer = 0; // The distance that the track is from the side of the control
0082
0083            private transient boolean isDragging;
0084
0085            protected TrackListener trackListener;
0086            protected ChangeListener changeListener;
0087            protected ComponentListener componentListener;
0088            protected FocusListener focusListener;
0089            protected ScrollListener scrollListener;
0090            protected PropertyChangeListener propertyChangeListener;
0091            private Handler handler;
0092            private int lastValue;
0093
0094            // Colors
0095            private Color shadowColor;
0096            private Color highlightColor;
0097            private Color focusColor;
0098
0099            /**
0100             * Whther or not sameLabelBaselines is up to date.
0101             */
0102            private boolean checkedLabelBaselines;
0103            /**
0104             * Whether or not all the entries in the labeltable have the same
0105             * baseline.
0106             */
0107            private boolean sameLabelBaselines;
0108
0109            protected Color getShadowColor() {
0110                return shadowColor;
0111            }
0112
0113            protected Color getHighlightColor() {
0114                return highlightColor;
0115            }
0116
0117            protected Color getFocusColor() {
0118                return focusColor;
0119            }
0120
0121            /**
0122             * Returns true if the user is dragging the slider.
0123             *
0124             * @return true if the user is dragging the slider
0125             * @since 1.5
0126             */
0127            protected boolean isDragging() {
0128                return isDragging;
0129            }
0130
0131            /////////////////////////////////////////////////////////////////////////////
0132            // ComponentUI Interface Implementation methods
0133            /////////////////////////////////////////////////////////////////////////////
0134            public static ComponentUI createUI(JComponent b) {
0135                return new BasicSliderUI((JSlider) b);
0136            }
0137
0138            public BasicSliderUI(JSlider b) {
0139            }
0140
0141            public void installUI(JComponent c) {
0142                slider = (JSlider) c;
0143
0144                checkedLabelBaselines = false;
0145
0146                slider.setEnabled(slider.isEnabled());
0147                LookAndFeel.installProperty(slider, "opaque", Boolean.TRUE);
0148
0149                isDragging = false;
0150                trackListener = createTrackListener(slider);
0151                changeListener = createChangeListener(slider);
0152                componentListener = createComponentListener(slider);
0153                focusListener = createFocusListener(slider);
0154                scrollListener = createScrollListener(slider);
0155                propertyChangeListener = createPropertyChangeListener(slider);
0156
0157                installDefaults(slider);
0158                installListeners(slider);
0159                installKeyboardActions(slider);
0160
0161                scrollTimer = new Timer(100, scrollListener);
0162                scrollTimer.setInitialDelay(300);
0163
0164                insetCache = slider.getInsets();
0165                leftToRightCache = BasicGraphicsUtils.isLeftToRight(slider);
0166                focusRect = new Rectangle();
0167                contentRect = new Rectangle();
0168                labelRect = new Rectangle();
0169                tickRect = new Rectangle();
0170                trackRect = new Rectangle();
0171                thumbRect = new Rectangle();
0172                lastValue = slider.getValue();
0173
0174                calculateGeometry(); // This figures out where the labels, ticks, track, and thumb are.
0175            }
0176
0177            public void uninstallUI(JComponent c) {
0178                if (c != slider)
0179                    throw new IllegalComponentStateException(this 
0180                            + " was asked to deinstall() " + c
0181                            + " when it only knows about " + slider + ".");
0182
0183                LookAndFeel.uninstallBorder(slider);
0184
0185                scrollTimer.stop();
0186                scrollTimer = null;
0187
0188                uninstallListeners(slider);
0189                uninstallKeyboardActions(slider);
0190
0191                focusInsets = null;
0192                insetCache = null;
0193                leftToRightCache = true;
0194                focusRect = null;
0195                contentRect = null;
0196                labelRect = null;
0197                tickRect = null;
0198                trackRect = null;
0199                thumbRect = null;
0200                trackListener = null;
0201                changeListener = null;
0202                componentListener = null;
0203                focusListener = null;
0204                scrollListener = null;
0205                propertyChangeListener = null;
0206                slider = null;
0207            }
0208
0209            protected void installDefaults(JSlider slider) {
0210                LookAndFeel.installBorder(slider, "Slider.border");
0211                LookAndFeel.installColorsAndFont(slider, "Slider.background",
0212                        "Slider.foreground", "Slider.font");
0213                highlightColor = UIManager.getColor("Slider.highlight");
0214
0215                shadowColor = UIManager.getColor("Slider.shadow");
0216                focusColor = UIManager.getColor("Slider.focus");
0217
0218                focusInsets = (Insets) UIManager.get("Slider.focusInsets");
0219            }
0220
0221            protected TrackListener createTrackListener(JSlider slider) {
0222                return new TrackListener();
0223            }
0224
0225            protected ChangeListener createChangeListener(JSlider slider) {
0226                return getHandler();
0227            }
0228
0229            protected ComponentListener createComponentListener(JSlider slider) {
0230                return getHandler();
0231            }
0232
0233            protected FocusListener createFocusListener(JSlider slider) {
0234                return getHandler();
0235            }
0236
0237            protected ScrollListener createScrollListener(JSlider slider) {
0238                return new ScrollListener();
0239            }
0240
0241            protected PropertyChangeListener createPropertyChangeListener(
0242                    JSlider slider) {
0243                return getHandler();
0244            }
0245
0246            private Handler getHandler() {
0247                if (handler == null) {
0248                    handler = new Handler();
0249                }
0250                return handler;
0251            }
0252
0253            protected void installListeners(JSlider slider) {
0254                slider.addMouseListener(trackListener);
0255                slider.addMouseMotionListener(trackListener);
0256                slider.addFocusListener(focusListener);
0257                slider.addComponentListener(componentListener);
0258                slider.addPropertyChangeListener(propertyChangeListener);
0259                slider.getModel().addChangeListener(changeListener);
0260            }
0261
0262            protected void uninstallListeners(JSlider slider) {
0263                slider.removeMouseListener(trackListener);
0264                slider.removeMouseMotionListener(trackListener);
0265                slider.removeFocusListener(focusListener);
0266                slider.removeComponentListener(componentListener);
0267                slider.removePropertyChangeListener(propertyChangeListener);
0268                slider.getModel().removeChangeListener(changeListener);
0269                handler = null;
0270            }
0271
0272            protected void installKeyboardActions(JSlider slider) {
0273                InputMap km = getInputMap(JComponent.WHEN_FOCUSED, slider);
0274                SwingUtilities.replaceUIInputMap(slider,
0275                        JComponent.WHEN_FOCUSED, km);
0276                LazyActionMap.installLazyActionMap(slider, BasicSliderUI.class,
0277                        "Slider.actionMap");
0278            }
0279
0280            InputMap getInputMap(int condition, JSlider slider) {
0281                if (condition == JComponent.WHEN_FOCUSED) {
0282                    InputMap keyMap = (InputMap) DefaultLookup.get(slider,
0283                            this , "Slider.focusInputMap");
0284                    InputMap rtlKeyMap;
0285
0286                    if (slider.getComponentOrientation().isLeftToRight()
0287                            || ((rtlKeyMap = (InputMap) DefaultLookup.get(
0288                                    slider, this ,
0289                                    "Slider.focusInputMap.RightToLeft")) == null)) {
0290                        return keyMap;
0291                    } else {
0292                        rtlKeyMap.setParent(keyMap);
0293                        return rtlKeyMap;
0294                    }
0295                }
0296                return null;
0297            }
0298
0299            /**
0300             * Populates ComboBox's actions.
0301             */
0302            static void loadActionMap(LazyActionMap map) {
0303                map.put(new Actions(Actions.POSITIVE_UNIT_INCREMENT));
0304                map.put(new Actions(Actions.POSITIVE_BLOCK_INCREMENT));
0305                map.put(new Actions(Actions.NEGATIVE_UNIT_INCREMENT));
0306                map.put(new Actions(Actions.NEGATIVE_BLOCK_INCREMENT));
0307                map.put(new Actions(Actions.MIN_SCROLL_INCREMENT));
0308                map.put(new Actions(Actions.MAX_SCROLL_INCREMENT));
0309            }
0310
0311            protected void uninstallKeyboardActions(JSlider slider) {
0312                SwingUtilities.replaceUIActionMap(slider, null);
0313                SwingUtilities.replaceUIInputMap(slider,
0314                        JComponent.WHEN_FOCUSED, null);
0315            }
0316
0317            /**
0318             * Returns the baseline.
0319             *
0320             * @throws NullPointerException {@inheritDoc}
0321             * @throws IllegalArgumentException {@inheritDoc}
0322             * @see javax.swing.JComponent#getBaseline(int, int)
0323             * @since 1.6
0324             */
0325            public int getBaseline(JComponent c, int width, int height) {
0326                super .getBaseline(c, width, height);
0327                if (slider.getPaintLabels() && labelsHaveSameBaselines()) {
0328                    FontMetrics metrics = slider.getFontMetrics(slider
0329                            .getFont());
0330                    Insets insets = slider.getInsets();
0331                    Dimension thumbSize = getThumbSize();
0332                    if (slider.getOrientation() == JSlider.HORIZONTAL) {
0333                        int tickLength = getTickLength();
0334                        int contentHeight = height - insets.top - insets.bottom
0335                                - focusInsets.top - focusInsets.bottom;
0336                        int thumbHeight = thumbSize.height;
0337                        int centerSpacing = thumbHeight;
0338                        if (slider.getPaintTicks()) {
0339                            centerSpacing += tickLength;
0340                        }
0341                        // Assume uniform labels.
0342                        centerSpacing += getHeightOfTallestLabel();
0343                        int trackY = insets.top + focusInsets.top
0344                                + (contentHeight - centerSpacing - 1) / 2;
0345                        int trackHeight = thumbHeight;
0346                        int tickY = trackY + trackHeight;
0347                        int tickHeight = tickLength;
0348                        if (!slider.getPaintTicks()) {
0349                            tickHeight = 0;
0350                        }
0351                        int labelY = tickY + tickHeight;
0352                        return labelY + metrics.getAscent();
0353                    } else { // vertical
0354                        boolean inverted = slider.getInverted();
0355                        Integer value = inverted ? getLowestValue()
0356                                : getHighestValue();
0357                        if (value != null) {
0358                            int thumbHeight = thumbSize.height;
0359                            int trackBuffer = Math.max(metrics.getHeight() / 2,
0360                                    thumbHeight / 2);
0361                            int contentY = focusInsets.top + insets.top;
0362                            int trackY = contentY + trackBuffer;
0363                            int trackHeight = height - focusInsets.top
0364                                    - focusInsets.bottom - insets.top
0365                                    - insets.bottom - trackBuffer - trackBuffer;
0366                            int yPosition = yPositionForValue(value, trackY,
0367                                    trackHeight);
0368                            return yPosition - metrics.getHeight() / 2
0369                                    + metrics.getAscent();
0370                        }
0371                    }
0372                }
0373                return 0;
0374            }
0375
0376            /**
0377             * Returns an enum indicating how the baseline of the component
0378             * changes as the size changes.
0379             *
0380             * @throws NullPointerException {@inheritDoc}
0381             * @see javax.swing.JComponent#getBaseline(int, int)
0382             * @since 1.6
0383             */
0384            public Component.BaselineResizeBehavior getBaselineResizeBehavior(
0385                    JComponent c) {
0386                super .getBaselineResizeBehavior(c);
0387                // NOTE: BasicSpinner really provides for CENTER_OFFSET, but
0388                // the default min/pref size is smaller than it should be
0389                // so that getBaseline() doesn't implement the contract
0390                // for CENTER_OFFSET as defined in Component.
0391                return Component.BaselineResizeBehavior.OTHER;
0392            }
0393
0394            /**
0395             * Returns true if all the labels from the label table have the same
0396             * baseline.
0397             *
0398             * @return true if all the labels from the label table have the
0399             *         same baseline
0400             * @since 1.6
0401             */
0402            protected boolean labelsHaveSameBaselines() {
0403                if (!checkedLabelBaselines) {
0404                    checkedLabelBaselines = true;
0405                    Dictionary dictionary = slider.getLabelTable();
0406                    if (dictionary != null) {
0407                        sameLabelBaselines = true;
0408                        Enumeration elements = dictionary.elements();
0409                        int baseline = -1;
0410                        while (elements.hasMoreElements()) {
0411                            Component label = (Component) elements
0412                                    .nextElement();
0413                            Dimension pref = label.getPreferredSize();
0414                            int labelBaseline = label.getBaseline(pref.width,
0415                                    pref.height);
0416                            if (labelBaseline >= 0) {
0417                                if (baseline == -1) {
0418                                    baseline = labelBaseline;
0419                                } else if (baseline != labelBaseline) {
0420                                    sameLabelBaselines = false;
0421                                    break;
0422                                }
0423                            } else {
0424                                sameLabelBaselines = false;
0425                                break;
0426                            }
0427                        }
0428                    } else {
0429                        sameLabelBaselines = false;
0430                    }
0431                }
0432                return sameLabelBaselines;
0433            }
0434
0435            public Dimension getPreferredHorizontalSize() {
0436                Dimension horizDim = (Dimension) DefaultLookup.get(slider,
0437                        this , "Slider.horizontalSize");
0438                if (horizDim == null) {
0439                    horizDim = new Dimension(200, 21);
0440                }
0441                return horizDim;
0442            }
0443
0444            public Dimension getPreferredVerticalSize() {
0445                Dimension vertDim = (Dimension) DefaultLookup.get(slider, this ,
0446                        "Slider.verticalSize");
0447                if (vertDim == null) {
0448                    vertDim = new Dimension(21, 200);
0449                }
0450                return vertDim;
0451            }
0452
0453            public Dimension getMinimumHorizontalSize() {
0454                Dimension minHorizDim = (Dimension) DefaultLookup.get(slider,
0455                        this , "Slider.minimumHorizontalSize");
0456                if (minHorizDim == null) {
0457                    minHorizDim = new Dimension(36, 21);
0458                }
0459                return minHorizDim;
0460            }
0461
0462            public Dimension getMinimumVerticalSize() {
0463                Dimension minVertDim = (Dimension) DefaultLookup.get(slider,
0464                        this , "Slider.minimumVerticalSize");
0465                if (minVertDim == null) {
0466                    minVertDim = new Dimension(21, 36);
0467                }
0468                return minVertDim;
0469            }
0470
0471            public Dimension getPreferredSize(JComponent c) {
0472                recalculateIfInsetsChanged();
0473                Dimension d;
0474                if (slider.getOrientation() == JSlider.VERTICAL) {
0475                    d = new Dimension(getPreferredVerticalSize());
0476                    d.width = insetCache.left + insetCache.right;
0477                    d.width += focusInsets.left + focusInsets.right;
0478                    d.width += trackRect.width + tickRect.width
0479                            + labelRect.width;
0480                } else {
0481                    d = new Dimension(getPreferredHorizontalSize());
0482                    d.height = insetCache.top + insetCache.bottom;
0483                    d.height += focusInsets.top + focusInsets.bottom;
0484                    d.height += trackRect.height + tickRect.height
0485                            + labelRect.height;
0486                }
0487
0488                return d;
0489            }
0490
0491            public Dimension getMinimumSize(JComponent c) {
0492                recalculateIfInsetsChanged();
0493                Dimension d;
0494
0495                if (slider.getOrientation() == JSlider.VERTICAL) {
0496                    d = new Dimension(getMinimumVerticalSize());
0497                    d.width = insetCache.left + insetCache.right;
0498                    d.width += focusInsets.left + focusInsets.right;
0499                    d.width += trackRect.width + tickRect.width
0500                            + labelRect.width;
0501                } else {
0502                    d = new Dimension(getMinimumHorizontalSize());
0503                    d.height = insetCache.top + insetCache.bottom;
0504                    d.height += focusInsets.top + focusInsets.bottom;
0505                    d.height += trackRect.height + tickRect.height
0506                            + labelRect.height;
0507                }
0508
0509                return d;
0510            }
0511
0512            public Dimension getMaximumSize(JComponent c) {
0513                Dimension d = getPreferredSize(c);
0514                if (slider.getOrientation() == JSlider.VERTICAL) {
0515                    d.height = Short.MAX_VALUE;
0516                } else {
0517                    d.width = Short.MAX_VALUE;
0518                }
0519
0520                return d;
0521            }
0522
0523            protected void calculateGeometry() {
0524                calculateFocusRect();
0525                calculateContentRect();
0526                calculateThumbSize();
0527                calculateTrackBuffer();
0528                calculateTrackRect();
0529                calculateTickRect();
0530                calculateLabelRect();
0531                calculateThumbLocation();
0532            }
0533
0534            protected void calculateFocusRect() {
0535                focusRect.x = insetCache.left;
0536                focusRect.y = insetCache.top;
0537                focusRect.width = slider.getWidth()
0538                        - (insetCache.left + insetCache.right);
0539                focusRect.height = slider.getHeight()
0540                        - (insetCache.top + insetCache.bottom);
0541            }
0542
0543            protected void calculateThumbSize() {
0544                Dimension size = getThumbSize();
0545                thumbRect.setSize(size.width, size.height);
0546            }
0547
0548            protected void calculateContentRect() {
0549                contentRect.x = focusRect.x + focusInsets.left;
0550                contentRect.y = focusRect.y + focusInsets.top;
0551                contentRect.width = focusRect.width
0552                        - (focusInsets.left + focusInsets.right);
0553                contentRect.height = focusRect.height
0554                        - (focusInsets.top + focusInsets.bottom);
0555            }
0556
0557            protected void calculateThumbLocation() {
0558                if (slider.getSnapToTicks()) {
0559                    int sliderValue = slider.getValue();
0560                    int snappedValue = sliderValue;
0561                    int majorTickSpacing = slider.getMajorTickSpacing();
0562                    int minorTickSpacing = slider.getMinorTickSpacing();
0563                    int tickSpacing = 0;
0564
0565                    if (minorTickSpacing > 0) {
0566                        tickSpacing = minorTickSpacing;
0567                    } else if (majorTickSpacing > 0) {
0568                        tickSpacing = majorTickSpacing;
0569                    }
0570
0571                    if (tickSpacing != 0) {
0572                        // If it's not on a tick, change the value
0573                        if ((sliderValue - slider.getMinimum()) % tickSpacing != 0) {
0574                            float temp = (float) (sliderValue - slider
0575                                    .getMinimum())
0576                                    / (float) tickSpacing;
0577                            int whichTick = Math.round(temp);
0578
0579                            // This is the fix for the bug #6401380
0580                            if (temp - (int) temp == .5
0581                                    && sliderValue < lastValue) {
0582                                whichTick--;
0583                            }
0584                            snappedValue = slider.getMinimum()
0585                                    + (whichTick * tickSpacing);
0586                        }
0587
0588                        if (snappedValue != sliderValue) {
0589                            slider.setValue(snappedValue);
0590                        }
0591                    }
0592                }
0593
0594                if (slider.getOrientation() == JSlider.HORIZONTAL) {
0595                    int valuePosition = xPositionForValue(slider.getValue());
0596
0597                    thumbRect.x = valuePosition - (thumbRect.width / 2);
0598                    thumbRect.y = trackRect.y;
0599                } else {
0600                    int valuePosition = yPositionForValue(slider.getValue());
0601
0602                    thumbRect.x = trackRect.x;
0603                    thumbRect.y = valuePosition - (thumbRect.height / 2);
0604                }
0605            }
0606
0607            protected void calculateTrackBuffer() {
0608                if (slider.getPaintLabels() && slider.getLabelTable() != null) {
0609                    Component highLabel = getHighestValueLabel();
0610                    Component lowLabel = getLowestValueLabel();
0611
0612                    if (slider.getOrientation() == JSlider.HORIZONTAL) {
0613                        trackBuffer = Math.max(highLabel.getBounds().width,
0614                                lowLabel.getBounds().width) / 2;
0615                        trackBuffer = Math
0616                                .max(trackBuffer, thumbRect.width / 2);
0617                    } else {
0618                        trackBuffer = Math.max(highLabel.getBounds().height,
0619                                lowLabel.getBounds().height) / 2;
0620                        trackBuffer = Math.max(trackBuffer,
0621                                thumbRect.height / 2);
0622                    }
0623                } else {
0624                    if (slider.getOrientation() == JSlider.HORIZONTAL) {
0625                        trackBuffer = thumbRect.width / 2;
0626                    } else {
0627                        trackBuffer = thumbRect.height / 2;
0628                    }
0629                }
0630            }
0631
0632            protected void calculateTrackRect() {
0633                int centerSpacing = 0; // used to center sliders added using BorderLayout.CENTER (bug 4275631)
0634                if (slider.getOrientation() == JSlider.HORIZONTAL) {
0635                    centerSpacing = thumbRect.height;
0636                    if (slider.getPaintTicks())
0637                        centerSpacing += getTickLength();
0638                    if (slider.getPaintLabels())
0639                        centerSpacing += getHeightOfTallestLabel();
0640                    trackRect.x = contentRect.x + trackBuffer;
0641                    trackRect.y = contentRect.y
0642                            + (contentRect.height - centerSpacing - 1) / 2;
0643                    trackRect.width = contentRect.width - (trackBuffer * 2);
0644                    trackRect.height = thumbRect.height;
0645                } else {
0646                    centerSpacing = thumbRect.width;
0647                    if (BasicGraphicsUtils.isLeftToRight(slider)) {
0648                        if (slider.getPaintTicks())
0649                            centerSpacing += getTickLength();
0650                        if (slider.getPaintLabels())
0651                            centerSpacing += getWidthOfWidestLabel();
0652                    } else {
0653                        if (slider.getPaintTicks())
0654                            centerSpacing -= getTickLength();
0655                        if (slider.getPaintLabels())
0656                            centerSpacing -= getWidthOfWidestLabel();
0657                    }
0658                    trackRect.x = contentRect.x
0659                            + (contentRect.width - centerSpacing - 1) / 2;
0660                    trackRect.y = contentRect.y + trackBuffer;
0661                    trackRect.width = thumbRect.width;
0662                    trackRect.height = contentRect.height - (trackBuffer * 2);
0663                }
0664
0665            }
0666
0667            /**
0668             * Gets the height of the tick area for horizontal sliders and the width of the
0669             * tick area for vertical sliders.  BasicSliderUI uses the returned value to
0670             * determine the tick area rectangle.  If you want to give your ticks some room,
0671             * make this larger than you need and paint your ticks away from the sides in paintTicks().
0672             */
0673            protected int getTickLength() {
0674                return 8;
0675            }
0676
0677            protected void calculateTickRect() {
0678                if (slider.getOrientation() == JSlider.HORIZONTAL) {
0679                    tickRect.x = trackRect.x;
0680                    tickRect.y = trackRect.y + trackRect.height;
0681                    tickRect.width = trackRect.width;
0682                    tickRect.height = (slider.getPaintTicks()) ? getTickLength()
0683                            : 0;
0684                } else {
0685                    tickRect.width = (slider.getPaintTicks()) ? getTickLength()
0686                            : 0;
0687                    if (BasicGraphicsUtils.isLeftToRight(slider)) {
0688                        tickRect.x = trackRect.x + trackRect.width;
0689                    } else {
0690                        tickRect.x = trackRect.x - tickRect.width;
0691                    }
0692                    tickRect.y = trackRect.y;
0693                    tickRect.height = trackRect.height;
0694                }
0695            }
0696
0697            protected void calculateLabelRect() {
0698                if (slider.getPaintLabels()) {
0699                    if (slider.getOrientation() == JSlider.HORIZONTAL) {
0700                        labelRect.x = tickRect.x - trackBuffer;
0701                        labelRect.y = tickRect.y + tickRect.height;
0702                        labelRect.width = tickRect.width + (trackBuffer * 2);
0703                        labelRect.height = getHeightOfTallestLabel();
0704                    } else {
0705                        if (BasicGraphicsUtils.isLeftToRight(slider)) {
0706                            labelRect.x = tickRect.x + tickRect.width;
0707                            labelRect.width = getWidthOfWidestLabel();
0708                        } else {
0709                            labelRect.width = getWidthOfWidestLabel();
0710                            labelRect.x = tickRect.x - labelRect.width;
0711                        }
0712                        labelRect.y = tickRect.y - trackBuffer;
0713                        labelRect.height = tickRect.height + (trackBuffer * 2);
0714                    }
0715                } else {
0716                    if (slider.getOrientation() == JSlider.HORIZONTAL) {
0717                        labelRect.x = tickRect.x;
0718                        labelRect.y = tickRect.y + tickRect.height;
0719                        labelRect.width = tickRect.width;
0720                        labelRect.height = 0;
0721                    } else {
0722                        if (BasicGraphicsUtils.isLeftToRight(slider)) {
0723                            labelRect.x = tickRect.x + tickRect.width;
0724                        } else {
0725                            labelRect.x = tickRect.x;
0726                        }
0727                        labelRect.y = tickRect.y;
0728                        labelRect.width = 0;
0729                        labelRect.height = tickRect.height;
0730                    }
0731                }
0732            }
0733
0734            protected Dimension getThumbSize() {
0735                Dimension size = new Dimension();
0736
0737                if (slider.getOrientation() == JSlider.VERTICAL) {
0738                    size.width = 20;
0739                    size.height = 11;
0740                } else {
0741                    size.width = 11;
0742                    size.height = 20;
0743                }
0744
0745                return size;
0746            }
0747
0748            public class PropertyChangeHandler implements 
0749                    PropertyChangeListener {
0750                // NOTE: This class exists only for backward compatability. All
0751                // its functionality has been moved into Handler. If you need to add
0752                // new functionality add it to the Handler, but make sure this      
0753                // class calls into the Handler.
0754                public void propertyChange(PropertyChangeEvent e) {
0755                    getHandler().propertyChange(e);
0756                }
0757            }
0758
0759            protected int getWidthOfWidestLabel() {
0760                Dictionary dictionary = slider.getLabelTable();
0761                int widest = 0;
0762                if (dictionary != null) {
0763                    Enumeration keys = dictionary.keys();
0764                    while (keys.hasMoreElements()) {
0765                        Component label = (Component) dictionary.get(keys
0766                                .nextElement());
0767                        widest = Math.max(label.getPreferredSize().width,
0768                                widest);
0769                    }
0770                }
0771                return widest;
0772            }
0773
0774            protected int getHeightOfTallestLabel() {
0775                Dictionary dictionary = slider.getLabelTable();
0776                int tallest = 0;
0777                if (dictionary != null) {
0778                    Enumeration keys = dictionary.keys();
0779                    while (keys.hasMoreElements()) {
0780                        Component label = (Component) dictionary.get(keys
0781                                .nextElement());
0782                        tallest = Math.max(label.getPreferredSize().height,
0783                                tallest);
0784                    }
0785                }
0786                return tallest;
0787            }
0788
0789            protected int getWidthOfHighValueLabel() {
0790                Component label = getHighestValueLabel();
0791                int width = 0;
0792
0793                if (label != null) {
0794                    width = label.getPreferredSize().width;
0795                }
0796
0797                return width;
0798            }
0799
0800            protected int getWidthOfLowValueLabel() {
0801                Component label = getLowestValueLabel();
0802                int width = 0;
0803
0804                if (label != null) {
0805                    width = label.getPreferredSize().width;
0806                }
0807
0808                return width;
0809            }
0810
0811            protected int getHeightOfHighValueLabel() {
0812                Component label = getHighestValueLabel();
0813                int height = 0;
0814
0815                if (label != null) {
0816                    height = label.getPreferredSize().height;
0817                }
0818
0819                return height;
0820            }
0821
0822            protected int getHeightOfLowValueLabel() {
0823                Component label = getLowestValueLabel();
0824                int height = 0;
0825
0826                if (label != null) {
0827                    height = label.getPreferredSize().height;
0828                }
0829
0830                return height;
0831            }
0832
0833            protected boolean drawInverted() {
0834                if (slider.getOrientation() == JSlider.HORIZONTAL) {
0835                    if (BasicGraphicsUtils.isLeftToRight(slider)) {
0836                        return slider.getInverted();
0837                    } else {
0838                        return !slider.getInverted();
0839                    }
0840                } else {
0841                    return slider.getInverted();
0842                }
0843            }
0844
0845            /**
0846             * Returns the biggest value that has an entry in the label table.
0847             *
0848             * @return biggest value that has an entry in the label table, or
0849             *         null.
0850             * @since 1.6
0851             */
0852            protected Integer getHighestValue() {
0853                Dictionary dictionary = slider.getLabelTable();
0854                if (dictionary != null) {
0855                    Enumeration keys = dictionary.keys();
0856                    int max = slider.getMinimum() - 1;
0857                    while (keys.hasMoreElements()) {
0858                        max = Math.max(max, ((Integer) keys.nextElement())
0859                                .intValue());
0860                    }
0861                    if (max == slider.getMinimum() - 1) {
0862                        return null;
0863                    }
0864                    return max;
0865                }
0866                return null;
0867            }
0868
0869            /**
0870             * Returns the smallest value that has an entry in the label table.
0871             *
0872             * @return smallest value that has an entry in the label table, or
0873             *         null.
0874             * @since 1.6
0875             */
0876            protected Integer getLowestValue() {
0877                Dictionary dictionary = slider.getLabelTable();
0878                if (dictionary != null) {
0879                    Enumeration keys = dictionary.keys();
0880                    int min = slider.getMaximum() + 1;
0881                    while (keys.hasMoreElements()) {
0882                        min = Math.min(min, ((Integer) keys.nextElement())
0883                                .intValue());
0884                    }
0885                    if (min == slider.getMaximum() + 1) {
0886                        return null;
0887                    }
0888                    return min;
0889                }
0890                return null;
0891            }
0892
0893            /**
0894             * Returns the label that corresponds to the highest slider value in the label table.
0895             * @see JSlider#setLabelTable
0896             */
0897            protected Component getLowestValueLabel() {
0898                Integer min = getLowestValue();
0899                if (min != null) {
0900                    return (Component) slider.getLabelTable().get(min);
0901                }
0902                return null;
0903            }
0904
0905            /**
0906             * Returns the label that corresponds to the lowest slider value in the label table.
0907             * @see JSlider#setLabelTable
0908             */
0909            protected Component getHighestValueLabel() {
0910                Integer max = getHighestValue();
0911                if (max != null) {
0912                    return (Component) slider.getLabelTable().get(max);
0913                }
0914                return null;
0915            }
0916
0917            public void paint(Graphics g, JComponent c) {
0918                recalculateIfInsetsChanged();
0919                recalculateIfOrientationChanged();
0920                Rectangle clip = g.getClipBounds();
0921
0922                if (!clip.intersects(trackRect) && slider.getPaintTrack())
0923                    calculateGeometry();
0924
0925                if (slider.getPaintTrack() && clip.intersects(trackRect)) {
0926                    paintTrack(g);
0927                }
0928                if (slider.getPaintTicks() && clip.intersects(tickRect)) {
0929                    paintTicks(g);
0930                }
0931                if (slider.getPaintLabels() && clip.intersects(labelRect)) {
0932                    paintLabels(g);
0933                }
0934                if (slider.hasFocus() && clip.intersects(focusRect)) {
0935                    paintFocus(g);
0936                }
0937                if (clip.intersects(thumbRect)) {
0938                    paintThumb(g);
0939                }
0940            }
0941
0942            protected void recalculateIfInsetsChanged() {
0943                Insets newInsets = slider.getInsets();
0944                if (!newInsets.equals(insetCache)) {
0945                    insetCache = newInsets;
0946                    calculateGeometry();
0947                }
0948            }
0949
0950            protected void recalculateIfOrientationChanged() {
0951                boolean ltr = BasicGraphicsUtils.isLeftToRight(slider);
0952                if (ltr != leftToRightCache) {
0953                    leftToRightCache = ltr;
0954                    calculateGeometry();
0955                }
0956            }
0957
0958            public void paintFocus(Graphics g) {
0959                g.setColor(getFocusColor());
0960
0961                BasicGraphicsUtils.drawDashedRect(g, focusRect.x, focusRect.y,
0962                        focusRect.width, focusRect.height);
0963            }
0964
0965            public void paintTrack(Graphics g) {
0966
0967                Rectangle trackBounds = trackRect;
0968
0969                if (slider.getOrientation() == JSlider.HORIZONTAL) {
0970                    int cy = (trackBounds.height / 2) - 2;
0971                    int cw = trackBounds.width;
0972
0973                    g.translate(trackBounds.x, trackBounds.y + cy);
0974
0975                    g.setColor(getShadowColor());
0976                    g.drawLine(0, 0, cw - 1, 0);
0977                    g.drawLine(0, 1, 0, 2);
0978                    g.setColor(getHighlightColor());
0979                    g.drawLine(0, 3, cw, 3);
0980                    g.drawLine(cw, 0, cw, 3);
0981                    g.setColor(Color.black);
0982                    g.drawLine(1, 1, cw - 2, 1);
0983
0984                    g.translate(-trackBounds.x, -(trackBounds.y + cy));
0985                } else {
0986                    int cx = (trackBounds.width / 2) - 2;
0987                    int ch = trackBounds.height;
0988
0989                    g.translate(trackBounds.x + cx, trackBounds.y);
0990
0991                    g.setColor(getShadowColor());
0992                    g.drawLine(0, 0, 0, ch - 1);
0993                    g.drawLine(1, 0, 2, 0);
0994                    g.setColor(getHighlightColor());
0995                    g.drawLine(3, 0, 3, ch);
0996                    g.drawLine(0, ch, 3, ch);
0997                    g.setColor(Color.black);
0998                    g.drawLine(1, 1, 1, ch - 2);
0999
1000                    g.translate(-(trackBounds.x + cx), -trackBounds.y);
1001                }
1002            }
1003
1004            public void paintTicks(Graphics g) {
1005                Rectangle tickBounds = tickRect;
1006                int i;
1007                int maj, min, max;
1008                int w = tickBounds.width;
1009                int h = tickBounds.height;
1010                int centerEffect, tickHeight;
1011
1012                g.setColor(DefaultLookup.getColor(slider, this ,
1013                        "Slider.tickColor", Color.black));
1014
1015                maj = slider.getMajorTickSpacing();
1016                min = slider.getMinorTickSpacing();
1017
1018                if (slider.getOrientation() == JSlider.HORIZONTAL) {
1019                    g.translate(0, tickBounds.y);
1020
1021                    int value = slider.getMinimum();
1022                    int xPos = 0;
1023
1024                    if (slider.getMinorTickSpacing() > 0) {
1025                        while (value <= slider.getMaximum()) {
1026                            xPos = xPositionForValue(value);
1027                            paintMinorTickForHorizSlider(g, tickBounds, xPos);
1028                            value += slider.getMinorTickSpacing();
1029                        }
1030                    }
1031
1032                    if (slider.getMajorTickSpacing() > 0) {
1033                        value = slider.getMinimum();
1034
1035                        while (value <= slider.getMaximum()) {
1036                            xPos = xPositionForValue(value);
1037                            paintMajorTickForHorizSlider(g, tickBounds, xPos);
1038                            value += slider.getMajorTickSpacing();
1039                        }
1040                    }
1041
1042                    g.translate(0, -tickBounds.y);
1043                } else {
1044                    g.translate(tickBounds.x, 0);
1045
1046                    int value = slider.getMinimum();
1047                    int yPos = 0;
1048
1049                    if (slider.getMinorTickSpacing() > 0) {
1050                        int offset = 0;
1051                        if (!BasicGraphicsUtils.isLeftToRight(slider)) {
1052                            offset = tickBounds.width - tickBounds.width / 2;
1053                            g.translate(offset, 0);
1054                        }
1055
1056                        while (value <= slider.getMaximum()) {
1057                            yPos = yPositionForValue(value);
1058                            paintMinorTickForVertSlider(g, tickBounds, yPos);
1059                            value += slider.getMinorTickSpacing();
1060                        }
1061
1062                        if (!BasicGraphicsUtils.isLeftToRight(slider)) {
1063                            g.translate(-offset, 0);
1064                        }
1065                    }
1066
1067                    if (slider.getMajorTickSpacing() > 0) {
1068                        value = slider.getMinimum();
1069                        if (!BasicGraphicsUtils.isLeftToRight(slider)) {
1070                            g.translate(2, 0);
1071                        }
1072
1073                        while (value <= slider.getMaximum()) {
1074                            yPos = yPositionForValue(value);
1075                            paintMajorTickForVertSlider(g, tickBounds, yPos);
1076                            value += slider.getMajorTickSpacing();
1077                        }
1078
1079                        if (!BasicGraphicsUtils.isLeftToRight(slider)) {
1080                            g.translate(-2, 0);
1081                        }
1082                    }
1083                    g.translate(-tickBounds.x, 0);
1084                }
1085            }
1086
1087            protected void paintMinorTickForHorizSlider(Graphics g,
1088                    Rectangle tickBounds, int x) {
1089                g.drawLine(x, 0, x, tickBounds.height / 2 - 1);
1090            }
1091
1092            protected void paintMajorTickForHorizSlider(Graphics g,
1093                    Rectangle tickBounds, int x) {
1094                g.drawLine(x, 0, x, tickBounds.height - 2);
1095            }
1096
1097            protected void paintMinorTickForVertSlider(Graphics g,
1098                    Rectangle tickBounds, int y) {
1099                g.drawLine(0, y, tickBounds.width / 2 - 1, y);
1100            }
1101
1102            protected void paintMajorTickForVertSlider(Graphics g,
1103                    Rectangle tickBounds, int y) {
1104                g.drawLine(0, y, tickBounds.width - 2, y);
1105            }
1106
1107            public void paintLabels(Graphics g) {
1108                Rectangle labelBounds = labelRect;
1109
1110                Dictionary dictionary = slider.getLabelTable();
1111                if (dictionary != null) {
1112                    Enumeration keys = dictionary.keys();
1113                    int minValue = slider.getMinimum();
1114                    int maxValue = slider.getMaximum();
1115                    boolean enabled = slider.isEnabled();
1116                    while (keys.hasMoreElements()) {
1117                        Integer key = (Integer) keys.nextElement();
1118                        int value = key.intValue();
1119                        if (value >= minValue && value <= maxValue) {
1120                            Component label = (Component) dictionary.get(key);
1121                            if (label instanceof  JComponent) {
1122                                ((JComponent) label).setEnabled(enabled);
1123                            }
1124                            if (slider.getOrientation() == JSlider.HORIZONTAL) {
1125                                g.translate(0, labelBounds.y);
1126                                paintHorizontalLabel(g, value, label);
1127                                g.translate(0, -labelBounds.y);
1128                            } else {
1129                                int offset = 0;
1130                                if (!BasicGraphicsUtils.isLeftToRight(slider)) {
1131                                    offset = labelBounds.width
1132                                            - label.getPreferredSize().width;
1133                                }
1134                                g.translate(labelBounds.x + offset, 0);
1135                                paintVerticalLabel(g, value, label);
1136                                g.translate(-labelBounds.x - offset, 0);
1137                            }
1138                        }
1139                    }
1140                }
1141
1142            }
1143
1144            /**
1145             * Called for every label in the label table.  Used to draw the labels for horizontal sliders.
1146             * The graphics have been translated to labelRect.y already.
1147             * @see JSlider#setLabelTable
1148             */
1149            protected void paintHorizontalLabel(Graphics g, int value,
1150                    Component label) {
1151                int labelCenter = xPositionForValue(value);
1152                int labelLeft = labelCenter
1153                        - (label.getPreferredSize().width / 2);
1154                g.translate(labelLeft, 0);
1155                label.paint(g);
1156                g.translate(-labelLeft, 0);
1157            }
1158
1159            /**
1160             * Called for every label in the label table.  Used to draw the labels for vertical sliders.
1161             * The graphics have been translated to labelRect.x already.
1162             * @see JSlider#setLabelTable
1163             */
1164            protected void paintVerticalLabel(Graphics g, int value,
1165                    Component label) {
1166                int labelCenter = yPositionForValue(value);
1167                int labelTop = labelCenter
1168                        - (label.getPreferredSize().height / 2);
1169                g.translate(0, labelTop);
1170                label.paint(g);
1171                g.translate(0, -labelTop);
1172            }
1173
1174            public void paintThumb(Graphics g) {
1175                Rectangle knobBounds = thumbRect;
1176                int w = knobBounds.width;
1177                int h = knobBounds.height;
1178
1179                g.translate(knobBounds.x, knobBounds.y);
1180
1181                if (slider.isEnabled()) {
1182                    g.setColor(slider.getBackground());
1183                } else {
1184                    g.setColor(slider.getBackground().darker());
1185                }
1186
1187                Boolean paintThumbArrowShape = (Boolean) slider
1188                        .getClientProperty("Slider.paintThumbArrowShape");
1189
1190                if ((!slider.getPaintTicks() && paintThumbArrowShape == null)
1191                        || paintThumbArrowShape == Boolean.FALSE) {
1192
1193                    // "plain" version
1194                    g.fillRect(0, 0, w, h);
1195
1196                    g.setColor(Color.black);
1197                    g.drawLine(0, h - 1, w - 1, h - 1);
1198                    g.drawLine(w - 1, 0, w - 1, h - 1);
1199
1200                    g.setColor(highlightColor);
1201                    g.drawLine(0, 0, 0, h - 2);
1202                    g.drawLine(1, 0, w - 2, 0);
1203
1204                    g.setColor(shadowColor);
1205                    g.drawLine(1, h - 2, w - 2, h - 2);
1206                    g.drawLine(w - 2, 1, w - 2, h - 3);
1207                } else if (slider.getOrientation() == JSlider.HORIZONTAL) {
1208                    int cw = w / 2;
1209                    g.fillRect(1, 1, w - 3, h - 1 - cw);
1210                    Polygon p = new Polygon();
1211                    p.addPoint(1, h - cw);
1212                    p.addPoint(cw - 1, h - 1);
1213                    p.addPoint(w - 2, h - 1 - cw);
1214                    g.fillPolygon(p);
1215
1216                    g.setColor(highlightColor);
1217                    g.drawLine(0, 0, w - 2, 0);
1218                    g.drawLine(0, 1, 0, h - 1 - cw);
1219                    g.drawLine(0, h - cw, cw - 1, h - 1);
1220
1221                    g.setColor(Color.black);
1222                    g.drawLine(w - 1, 0, w - 1, h - 2 - cw);
1223                    g.drawLine(w - 1, h - 1 - cw, w - 1 - cw, h - 1);
1224
1225                    g.setColor(shadowColor);
1226                    g.drawLine(w - 2, 1, w - 2, h - 2 - cw);
1227                    g.drawLine(w - 2, h - 1 - cw, w - 1 - cw, h - 2);
1228                } else { // vertical
1229                    int cw = h / 2;
1230                    if (BasicGraphicsUtils.isLeftToRight(slider)) {
1231                        g.fillRect(1, 1, w - 1 - cw, h - 3);
1232                        Polygon p = new Polygon();
1233                        p.addPoint(w - cw - 1, 0);
1234                        p.addPoint(w - 1, cw);
1235                        p.addPoint(w - 1 - cw, h - 2);
1236                        g.fillPolygon(p);
1237
1238                        g.setColor(highlightColor);
1239                        g.drawLine(0, 0, 0, h - 2); // left
1240                        g.drawLine(1, 0, w - 1 - cw, 0); // top
1241                        g.drawLine(w - cw - 1, 0, w - 1, cw); // top slant
1242
1243                        g.setColor(Color.black);
1244                        g.drawLine(0, h - 1, w - 2 - cw, h - 1); // bottom
1245                        g.drawLine(w - 1 - cw, h - 1, w - 1, h - 1 - cw); // bottom slant
1246
1247                        g.setColor(shadowColor);
1248                        g.drawLine(1, h - 2, w - 2 - cw, h - 2); // bottom
1249                        g.drawLine(w - 1 - cw, h - 2, w - 2, h - cw - 1); // bottom slant
1250                    } else {
1251                        g.fillRect(5, 1, w - 1 - cw, h - 3);
1252                        Polygon p = new Polygon();
1253                        p.addPoint(cw, 0);
1254                        p.addPoint(0, cw);
1255                        p.addPoint(cw, h - 2);
1256                        g.fillPolygon(p);
1257
1258                        g.setColor(highlightColor);
1259                        g.drawLine(cw - 1, 0, w - 2, 0); // top
1260                        g.drawLine(0, cw, cw, 0); // top slant
1261
1262                        g.setColor(Color.black);
1263                        g.drawLine(0, h - 1 - cw, cw, h - 1); // bottom slant
1264                        g.drawLine(cw, h - 1, w - 1, h - 1); // bottom
1265
1266                        g.setColor(shadowColor);
1267                        g.drawLine(cw, h - 2, w - 2, h - 2); // bottom
1268                        g.drawLine(w - 1, 1, w - 1, h - 2); // right
1269                    }
1270                }
1271
1272                g.translate(-knobBounds.x, -knobBounds.y);
1273            }
1274
1275            // Used exclusively by setThumbLocation()
1276            private static Rectangle unionRect = new Rectangle();
1277
1278            public void setThumbLocation(int x, int y) {
1279                unionRect.setBounds(thumbRect);
1280
1281                thumbRect.setLocation(x, y);
1282
1283                SwingUtilities.computeUnion(thumbRect.x, thumbRect.y,
1284                        thumbRect.width, thumbRect.height, unionRect);
1285                slider.repaint(unionRect.x, unionRect.y, unionRect.width,
1286                        unionRect.height);
1287            }
1288
1289            public void scrollByBlock(int direction) {
1290                synchronized (slider) {
1291
1292                    int oldValue = slider.getValue();
1293                    int blockIncrement = (slider.getMaximum() - slider
1294                            .getMinimum()) / 10;
1295                    if (blockIncrement <= 0
1296                            && slider.getMaximum() > slider.getMinimum()) {
1297
1298                        blockIncrement = 1;
1299                    }
1300
1301                    int delta = blockIncrement
1302                            * ((direction > 0) ? POSITIVE_SCROLL
1303                                    : NEGATIVE_SCROLL);
1304                    slider.setValue(oldValue + delta);
1305                }
1306            }
1307
1308            public void scrollByUnit(int direction) {
1309                synchronized (slider) {
1310
1311                    int oldValue = slider.getValue();
1312                    int delta = 1 * ((direction > 0) ? POSITIVE_SCROLL
1313                            : NEGATIVE_SCROLL);
1314
1315                    slider.setValue(oldValue + delta);
1316                }
1317            }
1318
1319            /**
1320             * This function is called when a mousePressed was detected in the track, not
1321             * in the thumb.  The default behavior is to scroll by block.  You can
1322             *  override this method to stop it from scrolling or to add additional behavior.
1323             */
1324            protected void scrollDueToClickInTrack(int dir) {
1325                scrollByBlock(dir);
1326            }
1327
1328            protected int xPositionForValue(int value) {
1329                int min = slider.getMinimum();
1330                int max = slider.getMaximum();
1331                int trackLength = trackRect.width;
1332                double valueRange = (double) max - (double) min;
1333                double pixelsPerValue = (double) trackLength / valueRange;
1334                int trackLeft = trackRect.x;
1335                int trackRight = trackRect.x + (trackRect.width - 1);
1336                int xPosition;
1337
1338                if (!drawInverted()) {
1339                    xPosition = trackLeft;
1340                    xPosition += Math.round(pixelsPerValue
1341                            * ((double) value - min));
1342                } else {
1343                    xPosition = trackRight;
1344                    xPosition -= Math.round(pixelsPerValue
1345                            * ((double) value - min));
1346                }
1347
1348                xPosition = Math.max(trackLeft, xPosition);
1349                xPosition = Math.min(trackRight, xPosition);
1350
1351                return xPosition;
1352            }
1353
1354            protected int yPositionForValue(int value) {
1355                return yPositionForValue(value, trackRect.y, trackRect.height);
1356            }
1357
1358            /**
1359             * Returns the y location for the specified value.  No checking is
1360             * done on the arguments.  In particular if <code>trackHeight</code> is
1361             * negative undefined results may occur.
1362             *
1363             * @param value the slider value to get the location for
1364             * @param trackY y-origin of the track
1365             * @param trackHeight the height of the track
1366             * @since 1.6
1367             */
1368            protected int yPositionForValue(int value, int trackY,
1369                    int trackHeight) {
1370                int min = slider.getMinimum();
1371                int max = slider.getMaximum();
1372                double valueRange = (double) max - (double) min;
1373                double pixelsPerValue = (double) trackHeight
1374                        / (double) valueRange;
1375                int trackBottom = trackY + (trackHeight - 1);
1376                int yPosition;
1377
1378                if (!drawInverted()) {
1379                    yPosition = trackY;
1380                    yPosition += Math.round(pixelsPerValue
1381                            * ((double) max - value));
1382                } else {
1383                    yPosition = trackY;
1384                    yPosition += Math.round(pixelsPerValue
1385                            * ((double) value - min));
1386                }
1387
1388                yPosition = Math.max(trackY, yPosition);
1389                yPosition = Math.min(trackBottom, yPosition);
1390
1391                return yPosition;
1392            }
1393
1394            /**
1395             * Returns a value give a y position.  If yPos is past the track at the top or the
1396             * bottom it will set the value to the min or max of the slider, depending if the
1397             * slider is inverted or not.
1398             */
1399            public int valueForYPosition(int yPos) {
1400                int value;
1401                final int minValue = slider.getMinimum();
1402                final int maxValue = slider.getMaximum();
1403                final int trackLength = trackRect.height;
1404                final int trackTop = trackRect.y;
1405                final int trackBottom = trackRect.y + (trackRect.height - 1);
1406
1407                if (yPos <= trackTop) {
1408                    value = drawInverted() ? minValue : maxValue;
1409                } else if (yPos >= trackBottom) {
1410                    value = drawInverted() ? maxValue : minValue;
1411                } else {
1412                    int distanceFromTrackTop = yPos - trackTop;
1413                    double valueRange = (double) maxValue - (double) minValue;
1414                    double valuePerPixel = valueRange / (double) trackLength;
1415                    int valueFromTrackTop = (int) Math
1416                            .round(distanceFromTrackTop * valuePerPixel);
1417
1418                    value = drawInverted() ? minValue + valueFromTrackTop
1419                            : maxValue - valueFromTrackTop;
1420                }
1421
1422                return value;
1423            }
1424
1425            /**
1426             * Returns a value give an x position.  If xPos is past the track at the left or the
1427             * right it will set the value to the min or max of the slider, depending if the
1428             * slider is inverted or not.
1429             */
1430            public int valueForXPosition(int xPos) {
1431                int value;
1432                final int minValue = slider.getMinimum();
1433                final int maxValue = slider.getMaximum();
1434                final int trackLength = trackRect.width;
1435                final int trackLeft = trackRect.x;
1436                final int trackRight = trackRect.x + (trackRect.width - 1);
1437
1438                if (xPos <= trackLeft) {
1439                    value = drawInverted() ? maxValue : minValue;
1440                } else if (xPos >= trackRight) {
1441                    value = drawInverted() ? minValue : maxValue;
1442                } else {
1443                    int distanceFromTrackLeft = xPos - trackLeft;
1444                    double valueRange = (double) maxValue - (double) minValue;
1445                    double valuePerPixel = valueRange / (double) trackLength;
1446                    int valueFromTrackLeft = (int) Math
1447                            .round(distanceFromTrackLeft * valuePerPixel);
1448
1449                    value = drawInverted() ? maxValue - valueFromTrackLeft
1450                            : minValue + valueFromTrackLeft;
1451                }
1452
1453                return value;
1454            }
1455
1456            private class Handler implements  ChangeListener, ComponentListener,
1457                    FocusListener, PropertyChangeListener {
1458                // Change Handler
1459                public void stateChanged(ChangeEvent e) {
1460                    if (!isDragging) {
1461                        calculateThumbLocation();
1462                        slider.repaint();
1463                    }
1464                    lastValue = slider.getValue();
1465                }
1466
1467                // Component Handler
1468                public void componentHidden(ComponentEvent e) {
1469                }
1470
1471                public void componentMoved(ComponentEvent e) {
1472                }
1473
1474                public void componentResized(ComponentEvent e) {
1475                    calculateGeometry();
1476                    slider.repaint();
1477                }
1478
1479                public void componentShown(ComponentEvent e) {
1480                }
1481
1482                // Focus Handler
1483                public void focusGained(FocusEvent e) {
1484                    slider.repaint();
1485                }
1486
1487                public void focusLost(FocusEvent e) {
1488                    slider.repaint();
1489                }
1490
1491                // Property Change Handler
1492                public void propertyChange(PropertyChangeEvent e) {
1493                    String propertyName = e.getPropertyName();
1494                    if (propertyName == "orientation"
1495                            || propertyName == "inverted"
1496                            || propertyName == "labelTable"
1497                            || propertyName == "majorTickSpacing"
1498                            || propertyName == "minorTickSpacing"
1499                            || propertyName == "paintTicks"
1500                            || propertyName == "paintTrack"
1501                            || propertyName == "font"
1502                            || propertyName == "paintLabels") {
1503                        checkedLabelBaselines = false;
1504                        calculateGeometry();
1505                        slider.repaint();
1506                    } else if (propertyName == "componentOrientation") {
1507                        calculateGeometry();
1508                        slider.repaint();
1509                        InputMap km = getInputMap(JComponent.WHEN_FOCUSED,
1510                                slider);
1511                        SwingUtilities.replaceUIInputMap(slider,
1512                                JComponent.WHEN_FOCUSED, km);
1513                    } else if (propertyName == "model") {
1514                        ((BoundedRangeModel) e.getOldValue())
1515                                .removeChangeListener(changeListener);
1516                        ((BoundedRangeModel) e.getNewValue())
1517                                .addChangeListener(changeListener);
1518                        calculateThumbLocation();
1519                        slider.repaint();
1520                    }
1521                }
1522            }
1523
1524            /////////////////////////////////////////////////////////////////////////
1525            /// Model Listener Class
1526            /////////////////////////////////////////////////////////////////////////        
1527            /**
1528             * Data model listener.
1529             *
1530             * This class should be treated as a &quot;protected&quot; inner class.
1531             * Instantiate it only within subclasses of <Foo>.
1532             */
1533            public class ChangeHandler implements  ChangeListener {
1534                // NOTE: This class exists only for backward compatability. All
1535                // its functionality has been moved into Handler. If you need to add
1536                // new functionality add it to the Handler, but make sure this      
1537                // class calls into the Handler.
1538                public void stateChanged(ChangeEvent e) {
1539                    getHandler().stateChanged(e);
1540                }
1541            }
1542
1543            /////////////////////////////////////////////////////////////////////////
1544            /// Track Listener Class
1545            /////////////////////////////////////////////////////////////////////////        
1546            /**
1547             * Track mouse movements.
1548             *
1549             * This class should be treated as a &quot;protected&quot; inner class.
1550             * Instantiate it only within subclasses of <Foo>.
1551             */
1552            public class TrackListener extends MouseInputAdapter {
1553                protected transient int offset;
1554                protected transient int currentMouseX, currentMouseY;
1555
1556                public void mouseReleased(MouseEvent e) {
1557                    if (!slider.isEnabled()) {
1558                        return;
1559                    }
1560
1561                    offset = 0;
1562                    scrollTimer.stop();
1563
1564                    // This is the way we have to determine snap-to-ticks.  It's
1565                    // hard to explain but since ChangeEvents don't give us any
1566                    // idea what has changed we don't have a way to stop the thumb
1567                    // bounds from being recalculated.  Recalculating the thumb
1568                    // bounds moves the thumb over the current value (i.e., snapping
1569                    // to the ticks).
1570                    if (slider.getSnapToTicks() /*|| slider.getSnapToValue()*/) {
1571                        isDragging = false;
1572                        slider.setValueIsAdjusting(false);
1573                    } else {
1574                        slider.setValueIsAdjusting(false);
1575                        isDragging = false;
1576                    }
1577                    slider.repaint();
1578                }
1579
1580                /**
1581                 * If the mouse is pressed above the "thumb" component
1582                 * then reduce the scrollbars value by one page ("page up"), 
1583                 * otherwise increase it by one page.  If there is no 
1584                 * thumb then page up if the mouse is in the upper half
1585                 * of the track.
1586                 */
1587                public void mousePressed(MouseEvent e) {
1588                    if (!slider.isEnabled()) {
1589                        return;
1590                    }
1591
1592                    // We should recalculate geometry just before
1593                    // calculation of the thumb movement direction.
1594                    // It is important for the case, when JSlider
1595                    // is a cell editor in JTable. See 6348946.
1596                    calculateGeometry();
1597
1598                    currentMouseX = e.getX();
1599                    currentMouseY = e.getY();
1600
1601                    if (slider.isRequestFocusEnabled()) {
1602                        slider.requestFocus();
1603                    }
1604
1605                    // Clicked in the Thumb area?
1606                    if (thumbRect.contains(currentMouseX, currentMouseY)) {
1607                        switch (slider.getOrientation()) {
1608                        case JSlider.VERTICAL:
1609                            offset = currentMouseY - thumbRect.y;
1610                            break;
1611                        case JSlider.HORIZONTAL:
1612                            offset = currentMouseX - thumbRect.x;
1613                            break;
1614                        }
1615                        isDragging = true;
1616                        return;
1617                    }
1618                    isDragging = false;
1619                    slider.setValueIsAdjusting(true);
1620
1621                    Dimension sbSize = slider.getSize();
1622                    int direction = POSITIVE_SCROLL;
1623
1624                    switch (slider.getOrientation()) {
1625                    case JSlider.VERTICAL:
1626                        if (thumbRect.isEmpty()) {
1627                            int scrollbarCenter = sbSize.height / 2;
1628                            if (!drawInverted()) {
1629                                direction = (currentMouseY < scrollbarCenter) ? POSITIVE_SCROLL
1630                                        : NEGATIVE_SCROLL;
1631                            } else {
1632                                direction = (currentMouseY < scrollbarCenter) ? NEGATIVE_SCROLL
1633                                        : POSITIVE_SCROLL;
1634                            }
1635                        } else {
1636                            int thumbY = thumbRect.y;
1637                            if (!drawInverted()) {
1638                                direction = (currentMouseY < thumbY) ? POSITIVE_SCROLL
1639                                        : NEGATIVE_SCROLL;
1640                            } else {
1641                                direction = (currentMouseY < thumbY) ? NEGATIVE_SCROLL
1642                                        : POSITIVE_SCROLL;
1643                            }
1644                        }
1645                        break;
1646                    case JSlider.HORIZONTAL:
1647                        if (thumbRect.isEmpty()) {
1648                            int scrollbarCenter = sbSize.width / 2;
1649                            if (!drawInverted()) {
1650                                direction = (currentMouseX < scrollbarCenter) ? NEGATIVE_SCROLL
1651                                        : POSITIVE_SCROLL;
1652                            } else {
1653                                direction = (currentMouseX < scrollbarCenter) ? POSITIVE_SCROLL
1654                                        : NEGATIVE_SCROLL;
1655                            }
1656                        } else {
1657                            int thumbX = thumbRect.x;
1658                            if (!drawInverted()) {
1659                                direction = (currentMouseX < thumbX) ? NEGATIVE_SCROLL
1660                                        : POSITIVE_SCROLL;
1661                            } else {
1662                                direction = (currentMouseX < thumbX) ? POSITIVE_SCROLL
1663                                        : NEGATIVE_SCROLL;
1664                            }
1665                        }
1666                        break;
1667                    }
1668
1669                    if (shouldScroll(direction)) {
1670                        scrollDueToClickInTrack(direction);
1671                    }
1672                    if (shouldScroll(direction)) {
1673                        scrollTimer.stop();
1674                        scrollListener.setDirection(direction);
1675                        scrollTimer.start();
1676                    }
1677                }
1678
1679                public boolean shouldScroll(int direction) {
1680                    Rectangle r = thumbRect;
1681                    if (slider.getOrientation() == JSlider.VERTICAL) {
1682                        if (drawInverted() ? direction < 0 : direction > 0) {
1683                            if (r.y <= currentMouseY) {
1684                                return false;
1685                            }
1686                        } else if (r.y + r.height >= currentMouseY) {
1687                            return false;
1688                        }
1689                    } else {
1690                        if (drawInverted() ? direction < 0 : direction > 0) {
1691                            if (r.x + r.width >= currentMouseX) {
1692                                return false;
1693                            }
1694                        } else if (r.x <= currentMouseX) {
1695                            return false;
1696                        }
1697                    }
1698
1699                    if (direction > 0
1700                            && slider.getValue() + slider.getExtent() >= slider
1701                                    .getMaximum()) {
1702                        return false;
1703                    } else if (direction < 0
1704                            && slider.getValue() <= slider.getMinimum()) {
1705                        return false;
1706                    }
1707
1708                    return true;
1709                }
1710
1711                /** 
1712                 * Set the models value to the position of the top/left
1713                 * of the thumb relative to the origin of the track.
1714                 */
1715                public void mouseDragged(MouseEvent e) {
1716                    int thumbMiddle = 0;
1717
1718                    if (!slider.isEnabled()) {
1719                        return;
1720                    }
1721
1722                    currentMouseX = e.getX();
1723                    currentMouseY = e.getY();
1724
1725                    if (!isDragging) {
1726                        return;
1727                    }
1728
1729                    slider.setValueIsAdjusting(true);
1730
1731                    switch (slider.getOrientation()) {
1732                    case JSlider.VERTICAL:
1733                        int halfThumbHeight = thumbRect.height / 2;
1734                        int thumbTop = e.getY() - offset;
1735                        int trackTop = trackRect.y;
1736                        int trackBottom = trackRect.y + (trackRect.height - 1);
1737                        int vMax = yPositionForValue(slider.getMaximum()
1738                                - slider.getExtent());
1739
1740                        if (drawInverted()) {
1741                            trackBottom = vMax;
1742                        } else {
1743                            trackTop = vMax;
1744                        }
1745                        thumbTop = Math.max(thumbTop, trackTop
1746                                - halfThumbHeight);
1747                        thumbTop = Math.min(thumbTop, trackBottom
1748                                - halfThumbHeight);
1749
1750                        setThumbLocation(thumbRect.x, thumbTop);
1751
1752                        thumbMiddle = thumbTop + halfThumbHeight;
1753                        slider.setValue(valueForYPosition(thumbMiddle));
1754                        break;
1755                    case JSlider.HORIZONTAL:
1756                        int halfThumbWidth = thumbRect.width / 2;
1757                        int thumbLeft = e.getX() - offset;
1758                        int trackLeft = trackRect.x;
1759                        int trackRight = trackRect.x + (trackRect.width - 1);
1760                        int hMax = xPositionForValue(slider.getMaximum()
1761                                - slider.getExtent());
1762
1763                        if (drawInverted()) {
1764                            trackLeft = hMax;
1765                        } else {
1766                            trackRight = hMax;
1767                        }
1768                        thumbLeft = Math.max(thumbLeft, trackLeft
1769                                - halfThumbWidth);
1770                        thumbLeft = Math.min(thumbLeft, trackRight
1771                                - halfThumbWidth);
1772
1773                        setThumbLocation(thumbLeft, thumbRect.y);
1774
1775                        thumbMiddle = thumbLeft + halfThumbWidth;
1776                        slider.setValue(valueForXPosition(thumbMiddle));
1777                        break;
1778                    default:
1779                        return;
1780                    }
1781                }
1782
1783                public void mouseMoved(MouseEvent e) {
1784                }
1785            }
1786
1787            /**
1788             * Scroll-event listener.
1789             *
1790             * This class should be treated as a &quot;protected&quot; inner class.
1791             * Instantiate it only within subclasses of <Foo>.
1792             */
1793            public class ScrollListener implements  ActionListener {
1794                // changed this class to public to avoid bogus IllegalAccessException
1795                // bug in InternetExplorer browser.  It was protected.  Work around
1796                // for 4109432
1797                int direction = POSITIVE_SCROLL;
1798                boolean useBlockIncrement;
1799
1800                public ScrollListener() {
1801                    direction = POSITIVE_SCROLL;
1802                    useBlockIncrement = true;
1803                }
1804
1805                public ScrollListener(int dir, boolean block) {
1806                    direction = dir;
1807                    useBlockIncrement = block;
1808                }
1809
1810                public void setDirection(int direction) {
1811                    this .direction = direction;
1812                }
1813
1814                public void setScrollByBlock(boolean block) {
1815                    this .useBlockIncrement = block;
1816                }
1817
1818                public void actionPerformed(ActionEvent e) {
1819                    if (useBlockIncrement) {
1820                        scrollByBlock(direction);
1821                    } else {
1822                        scrollByUnit(direction);
1823                    }
1824                    if (!trackListener.shouldScroll(direction)) {
1825                        ((Timer) e.getSource()).stop();
1826                    }
1827                }
1828            }
1829
1830            /**
1831             * Listener for resizing events.
1832             * <p>
1833             * This class should be treated as a &quot;protected&quot; inner class.
1834             * Instantiate it only within subclasses of <Foo>.
1835             */
1836            public class ComponentHandler extends ComponentAdapter {
1837                // NOTE: This class exists only for backward compatability. All
1838                // its functionality has been moved into Handler. If you need to add
1839                // new functionality add it to the Handler, but make sure this      
1840                // class calls into the Handler.
1841                public void componentResized(ComponentEvent e) {
1842                    getHandler().componentResized(e);
1843                }
1844            };
1845
1846            /**
1847             * Focus-change listener.
1848             * <p>
1849             * This class should be treated as a &quot;protected&quot; inner class.
1850             * Instantiate it only within subclasses of <Foo>.
1851             */
1852            public class FocusHandler implements  FocusListener {
1853                // NOTE: This class exists only for backward compatability. All
1854                // its functionality has been moved into Handler. If you need to add
1855                // new functionality add it to the Handler, but make sure this      
1856                // class calls into the Handler.
1857                public void focusGained(FocusEvent e) {
1858                    getHandler().focusGained(e);
1859                }
1860
1861                public void focusLost(FocusEvent e) {
1862                    getHandler().focusLost(e);
1863                }
1864            }
1865
1866            /**
1867             * As of Java 2 platform v1.3 this undocumented class is no longer used.
1868             * The recommended approach to creating bindings is to use a
1869             * combination of an <code>ActionMap</code>, to contain the action,
1870             * and an <code>InputMap</code> to contain the mapping from KeyStroke
1871             * to action description. The InputMap is is usually described in the
1872             * LookAndFeel tables.
1873             * <p>
1874             * Please refer to the key bindings specification for further details.
1875             * <p>
1876             * This class should be treated as a &quot;protected&quot; inner class.
1877             * Instantiate it only within subclasses of <Foo>.
1878             */
1879            public class ActionScroller extends AbstractAction {
1880                // NOTE: This class exists only for backward compatability. All
1881                // its functionality has been moved into Actions. If you need to add
1882                // new functionality add it to the Actions, but make sure this
1883                // class calls into the Actions.
1884                int dir;
1885                boolean block;
1886                JSlider slider;
1887
1888                public ActionScroller(JSlider slider, int dir, boolean block) {
1889                    this .dir = dir;
1890                    this .block = block;
1891                    this .slider = slider;
1892                }
1893
1894                public void actionPerformed(ActionEvent e) {
1895                    SHARED_ACTION
1896                            .scroll(slider, BasicSliderUI.this , dir, block);
1897                }
1898
1899                public boolean isEnabled() {
1900                    boolean b = true;
1901                    if (slider != null) {
1902                        b = slider.isEnabled();
1903                    }
1904                    return b;
1905                }
1906
1907            };
1908
1909            /**
1910             * A static version of the above.
1911             */
1912            static class SharedActionScroller extends AbstractAction {
1913                // NOTE: This class exists only for backward compatability. All
1914                // its functionality has been moved into Actions. If you need to add
1915                // new functionality add it to the Actions, but make sure this
1916                // class calls into the Actions.
1917                int dir;
1918                boolean block;
1919
1920                public SharedActionScroller(int dir, boolean block) {
1921                    this .dir = dir;
1922                    this .block = block;
1923                }
1924
1925                public void actionPerformed(ActionEvent evt) {
1926                    JSlider slider = (JSlider) evt.getSource();
1927                    BasicSliderUI ui = (BasicSliderUI) BasicLookAndFeel
1928                            .getUIOfType(slider.getUI(), BasicSliderUI.class);
1929                    if (ui == null) {
1930                        return;
1931                    }
1932                    SHARED_ACTION.scroll(slider, ui, dir, block);
1933                }
1934            }
1935
1936            private static class Actions extends UIAction {
1937                public static final String POSITIVE_UNIT_INCREMENT = "positiveUnitIncrement";
1938                public static final String POSITIVE_BLOCK_INCREMENT = "positiveBlockIncrement";
1939                public static final String NEGATIVE_UNIT_INCREMENT = "negativeUnitIncrement";
1940                public static final String NEGATIVE_BLOCK_INCREMENT = "negativeBlockIncrement";
1941                public static final String MIN_SCROLL_INCREMENT = "minScroll";
1942                public static final String MAX_SCROLL_INCREMENT = "maxScroll";
1943
1944                Actions() {
1945                    super (null);
1946                }
1947
1948                public Actions(String name) {
1949                    super (name);
1950                }
1951
1952                public void actionPerformed(ActionEvent evt) {
1953                    JSlider slider = (JSlider) evt.getSource();
1954                    BasicSliderUI ui = (BasicSliderUI) BasicLookAndFeel
1955                            .getUIOfType(slider.getUI(), BasicSliderUI.class);
1956                    String name = getName();
1957
1958                    if (ui == null) {
1959                        return;
1960                    }
1961                    if (POSITIVE_UNIT_INCREMENT == name) {
1962                        scroll(slider, ui, POSITIVE_SCROLL, false);
1963                    } else if (NEGATIVE_UNIT_INCREMENT == name) {
1964                        scroll(slider, ui, NEGATIVE_SCROLL, false);
1965                    } else if (POSITIVE_BLOCK_INCREMENT == name) {
1966                        scroll(slider, ui, POSITIVE_SCROLL, true);
1967                    } else if (NEGATIVE_BLOCK_INCREMENT == name) {
1968                        scroll(slider, ui, NEGATIVE_SCROLL, true);
1969                    } else if (MIN_SCROLL_INCREMENT == name) {
1970                        scroll(slider, ui, MIN_SCROLL, false);
1971                    } else if (MAX_SCROLL_INCREMENT == name) {
1972                        scroll(slider, ui, MAX_SCROLL, false);
1973                    }
1974                }
1975
1976                private void scroll(JSlider slider, BasicSliderUI ui,
1977                        int direction, boolean isBlock) {
1978                    boolean invert = slider.getInverted();
1979
1980                    if (direction == NEGATIVE_SCROLL
1981                            || direction == POSITIVE_SCROLL) {
1982                        if (invert) {
1983                            direction = (direction == POSITIVE_SCROLL) ? NEGATIVE_SCROLL
1984                                    : POSITIVE_SCROLL;
1985                        }
1986
1987                        if (isBlock) {
1988                            ui.scrollByBlock(direction);
1989                        } else {
1990                            ui.scrollByUnit(direction);
1991                        }
1992                    } else { // MIN or MAX
1993                        if (invert) {
1994                            direction = (direction == MIN_SCROLL) ? MAX_SCROLL
1995                                    : MIN_SCROLL;
1996                        }
1997
1998                        slider.setValue((direction == MIN_SCROLL) ? slider
1999                                .getMinimum() : slider.getMaximum());
2000                    }
2001                }
2002            }
2003        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.