KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > swing > plaf > basic > BasicSliderUI


1 /*
2  * @(#)BasicSliderUI.java 1.100 03/12/19
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package javax.swing.plaf.basic;
9
10 import java.awt.Component JavaDoc;
11 import java.awt.Container JavaDoc;
12 import java.awt.Adjustable JavaDoc;
13 import java.awt.event.*;
14 import java.awt.Graphics JavaDoc;
15 import java.awt.Dimension JavaDoc;
16 import java.awt.Rectangle JavaDoc;
17 import java.awt.Point JavaDoc;
18 import java.awt.Insets JavaDoc;
19 import java.awt.Color JavaDoc;
20 import java.awt.IllegalComponentStateException JavaDoc;
21 import java.awt.Polygon JavaDoc;
22 import java.beans.*;
23 import java.util.Dictionary JavaDoc;
24 import java.util.Enumeration JavaDoc;
25
26 import javax.swing.border.AbstractBorder JavaDoc;
27
28 import javax.swing.*;
29 import javax.swing.event.*;
30 import javax.swing.plaf.*;
31 import sun.swing.DefaultLookup;
32 import sun.swing.UIAction;
33
34
35 /**
36  * A Basic L&F implementation of SliderUI.
37  *
38  * @version 1.100 12/19/03
39  * @author Tom Santos
40  */

41 public class BasicSliderUI extends SliderUI{
42     // Old actions forward to an instance of this.
43
private static final Actions SHARED_ACTION = new Actions();
44
45     public static final int POSITIVE_SCROLL = +1;
46     public static final int NEGATIVE_SCROLL = -1;
47     public static final int MIN_SCROLL = -2;
48     public static final int MAX_SCROLL = +2;
49
50     protected Timer scrollTimer;
51     protected JSlider slider;
52
53     protected Insets JavaDoc focusInsets = null;
54     protected Insets JavaDoc insetCache = null;
55     protected boolean leftToRightCache = true;
56     protected Rectangle JavaDoc focusRect = null;
57     protected Rectangle JavaDoc contentRect = null;
58     protected Rectangle JavaDoc labelRect = null;
59     protected Rectangle JavaDoc tickRect = null;
60     protected Rectangle JavaDoc trackRect = null;
61     protected Rectangle JavaDoc thumbRect = null;
62
63     protected int trackBuffer = 0; // The distance that the track is from the side of the control
64

65     private transient boolean isDragging;
66
67     protected TrackListener trackListener;
68     protected ChangeListener changeListener;
69     protected ComponentListener componentListener;
70     protected FocusListener focusListener;
71     protected ScrollListener scrollListener;
72     protected PropertyChangeListener propertyChangeListener;
73     private Handler handler;
74
75     // Colors
76
private Color JavaDoc shadowColor;
77     private Color JavaDoc highlightColor;
78     private Color JavaDoc focusColor;
79
80
81     protected Color JavaDoc getShadowColor() {
82         return shadowColor;
83     }
84
85     protected Color JavaDoc getHighlightColor() {
86         return highlightColor;
87     }
88
89     protected Color JavaDoc getFocusColor() {
90         return focusColor;
91     }
92
93     /**
94      * Returns true if the user is dragging the slider.
95      *
96      * @return true if the user is dragging the slider
97      * @since 1.5
98      */

99     protected boolean isDragging() {
100         return isDragging;
101     }
102
103     /////////////////////////////////////////////////////////////////////////////
104
// ComponentUI Interface Implementation methods
105
/////////////////////////////////////////////////////////////////////////////
106
public static ComponentUI createUI(JComponent b) {
107         return new BasicSliderUI JavaDoc((JSlider)b);
108     }
109
110     public BasicSliderUI(JSlider b) {
111     }
112
113     public void installUI(JComponent c) {
114         slider = (JSlider) c;
115
116         slider.setEnabled(slider.isEnabled());
117         LookAndFeel.installProperty(slider, "opaque", Boolean.TRUE);
118
119         isDragging = false;
120         trackListener = createTrackListener( slider );
121         changeListener = createChangeListener( slider );
122         componentListener = createComponentListener( slider );
123         focusListener = createFocusListener( slider );
124         scrollListener = createScrollListener( slider );
125     propertyChangeListener = createPropertyChangeListener( slider );
126
127     installDefaults( slider );
128     installListeners( slider );
129     installKeyboardActions( slider );
130
131         scrollTimer = new Timer( 100, scrollListener );
132         scrollTimer.setInitialDelay( 300 );
133
134     insetCache = slider.getInsets();
135     leftToRightCache = BasicGraphicsUtils.isLeftToRight(slider);
136     focusRect = new Rectangle JavaDoc();
137     contentRect = new Rectangle JavaDoc();
138     labelRect = new Rectangle JavaDoc();
139     tickRect = new Rectangle JavaDoc();
140     trackRect = new Rectangle JavaDoc();
141     thumbRect = new Rectangle JavaDoc();
142
143     calculateGeometry(); // This figures out where the labels, ticks, track, and thumb are.
144
}
145
146     public void uninstallUI(JComponent c) {
147         if ( c != slider )
148             throw new IllegalComponentStateException JavaDoc(
149                                                     this + " was asked to deinstall() "
150                                                     + c + " when it only knows about "
151                                                     + slider + ".");
152
153         LookAndFeel.uninstallBorder(slider);
154
155         scrollTimer.stop();
156         scrollTimer = null;
157
158     uninstallListeners( slider );
159     uninstallKeyboardActions(slider);
160
161     focusInsets = null;
162     insetCache = null;
163     leftToRightCache = true;
164     focusRect = null;
165     contentRect = null;
166     labelRect = null;
167     tickRect = null;
168     trackRect = null;
169         thumbRect = null;
170         trackListener = null;
171         changeListener = null;
172         componentListener = null;
173         focusListener = null;
174         scrollListener = null;
175     propertyChangeListener = null;
176         slider = null;
177     }
178
179     protected void installDefaults( JSlider slider ) {
180         LookAndFeel.installBorder(slider, "Slider.border");
181         LookAndFeel.installColors(slider, "Slider.background", "Slider.foreground");
182         highlightColor = UIManager.getColor("Slider.highlight");
183
184         shadowColor = UIManager.getColor("Slider.shadow");
185         focusColor = UIManager.getColor("Slider.focus");
186
187     focusInsets = (Insets JavaDoc)UIManager.get( "Slider.focusInsets" );
188     }
189
190     protected TrackListener createTrackListener(JSlider slider) {
191         return new TrackListener();
192     }
193
194     protected ChangeListener createChangeListener(JSlider slider) {
195         return getHandler();
196     }
197
198     protected ComponentListener createComponentListener(JSlider slider) {
199         return getHandler();
200     }
201
202     protected FocusListener createFocusListener(JSlider slider) {
203         return getHandler();
204     }
205
206     protected ScrollListener createScrollListener( JSlider slider ) {
207         return new ScrollListener();
208     }
209
210     protected PropertyChangeListener createPropertyChangeListener(
211             JSlider slider) {
212         return getHandler();
213     }
214
215     private Handler getHandler() {
216         if (handler == null) {
217             handler = new Handler();
218         }
219         return handler;
220     }
221
222     protected void installListeners( JSlider slider ) {
223         slider.addMouseListener(trackListener);
224         slider.addMouseMotionListener(trackListener);
225         slider.addFocusListener(focusListener);
226         slider.addComponentListener(componentListener);
227         slider.addPropertyChangeListener( propertyChangeListener );
228         slider.getModel().addChangeListener(changeListener);
229     }
230
231     protected void uninstallListeners( JSlider slider ) {
232         slider.removeMouseListener(trackListener);
233         slider.removeMouseMotionListener(trackListener);
234         slider.removeFocusListener(focusListener);
235         slider.removeComponentListener(componentListener);
236         slider.removePropertyChangeListener( propertyChangeListener );
237         slider.getModel().removeChangeListener(changeListener);
238         handler = null;
239     }
240
241     protected void installKeyboardActions( JSlider slider ) {
242     InputMap km = getInputMap(JComponent.WHEN_FOCUSED, slider);
243     SwingUtilities.replaceUIInputMap(slider, JComponent.WHEN_FOCUSED, km);
244         LazyActionMap.installLazyActionMap(slider, BasicSliderUI JavaDoc.class,
245                 "Slider.actionMap");
246     }
247
248     InputMap getInputMap(int condition, JSlider slider) {
249         if (condition == JComponent.WHEN_FOCUSED) {
250             InputMap keyMap = (InputMap)DefaultLookup.get(slider, this,
251                   "Slider.focusInputMap");
252             InputMap rtlKeyMap;
253
254             if (slider.getComponentOrientation().isLeftToRight() ||
255                 ((rtlKeyMap = (InputMap)DefaultLookup.get(slider, this,
256                           "Slider.focusInputMap.RightToLeft")) == null)) {
257                 return keyMap;
258             } else {
259                 rtlKeyMap.setParent(keyMap);
260                 return rtlKeyMap;
261             }
262         }
263         return null;
264     }
265
266     /**
267      * Populates ComboBox's actions.
268      */

269     static void loadActionMap(LazyActionMap JavaDoc map) {
270         map.put(new Actions(Actions.POSITIVE_UNIT_INCREMENT));
271         map.put(new Actions(Actions.POSITIVE_BLOCK_INCREMENT));
272         map.put(new Actions(Actions.NEGATIVE_UNIT_INCREMENT));
273         map.put(new Actions(Actions.NEGATIVE_BLOCK_INCREMENT));
274         map.put(new Actions(Actions.MIN_SCROLL_INCREMENT));
275         map.put(new Actions(Actions.MAX_SCROLL_INCREMENT));
276     }
277
278     protected void uninstallKeyboardActions( JSlider slider ) {
279     SwingUtilities.replaceUIActionMap(slider, null);
280     SwingUtilities.replaceUIInputMap(slider, JComponent.WHEN_FOCUSED,
281                      null);
282     }
283
284     public Dimension JavaDoc getPreferredHorizontalSize() {
285         Dimension JavaDoc horizDim = (Dimension JavaDoc)DefaultLookup.get(slider,
286                 this, "Slider.horizontalSize");
287         if (horizDim == null) {
288             horizDim = new Dimension JavaDoc(200, 21);
289         }
290         return horizDim;
291     }
292
293     public Dimension JavaDoc getPreferredVerticalSize() {
294         Dimension JavaDoc vertDim = (Dimension JavaDoc)DefaultLookup.get(slider,
295                 this, "Slider.verticalSize");
296         if (vertDim == null) {
297             vertDim = new Dimension JavaDoc(21, 200);
298         }
299         return vertDim;
300     }
301
302     public Dimension JavaDoc getMinimumHorizontalSize() {
303         Dimension JavaDoc minHorizDim = (Dimension JavaDoc)DefaultLookup.get(slider,
304                 this, "Slider.minimumHorizontalSize");
305         if (minHorizDim == null) {
306             minHorizDim = new Dimension JavaDoc(36, 21);
307         }
308         return minHorizDim;
309     }
310
311     public Dimension JavaDoc getMinimumVerticalSize() {
312         Dimension JavaDoc minVertDim = (Dimension JavaDoc)DefaultLookup.get(slider,
313                 this, "Slider.minimumVerticalSize");
314         if (minVertDim == null) {
315             minVertDim = new Dimension JavaDoc(21, 36);
316         }
317         return minVertDim;
318     }
319
320     public Dimension JavaDoc getPreferredSize(JComponent c) {
321         recalculateIfInsetsChanged();
322         Dimension JavaDoc d;
323         if ( slider.getOrientation() == JSlider.VERTICAL ) {
324             d = new Dimension JavaDoc(getPreferredVerticalSize());
325         d.width = insetCache.left + insetCache.right;
326         d.width += focusInsets.left + focusInsets.right;
327         d.width += trackRect.width + tickRect.width + labelRect.width;
328         }
329         else {
330             d = new Dimension JavaDoc(getPreferredHorizontalSize());
331         d.height = insetCache.top + insetCache.bottom;
332         d.height += focusInsets.top + focusInsets.bottom;
333         d.height += trackRect.height + tickRect.height + labelRect.height;
334         }
335
336         return d;
337     }
338
339     public Dimension JavaDoc getMinimumSize(JComponent c) {
340         recalculateIfInsetsChanged();
341         Dimension JavaDoc d;
342
343         if ( slider.getOrientation() == JSlider.VERTICAL ) {
344             d = new Dimension JavaDoc(getMinimumVerticalSize());
345         d.width = insetCache.left + insetCache.right;
346         d.width += focusInsets.left + focusInsets.right;
347         d.width += trackRect.width + tickRect.width + labelRect.width;
348         }
349         else {
350             d = new Dimension JavaDoc(getMinimumHorizontalSize());
351         d.height = insetCache.top + insetCache.bottom;
352         d.height += focusInsets.top + focusInsets.bottom;
353         d.height += trackRect.height + tickRect.height + labelRect.height;
354         }
355
356         return d;
357     }
358
359     public Dimension JavaDoc getMaximumSize(JComponent c) {
360         Dimension JavaDoc d = getPreferredSize(c);
361         if ( slider.getOrientation() == JSlider.VERTICAL ) {
362             d.height = Short.MAX_VALUE;
363         }
364         else {
365             d.width = Short.MAX_VALUE;
366         }
367
368         return d;
369     }
370
371     protected void calculateGeometry() {
372         calculateFocusRect();
373         calculateContentRect();
374     calculateThumbSize();
375     calculateTrackBuffer();
376     calculateTrackRect();
377     calculateTickRect();
378     calculateLabelRect();
379     calculateThumbLocation();
380     }
381   
382     protected void calculateFocusRect() {
383         focusRect.x = insetCache.left;
384     focusRect.y = insetCache.top;
385     focusRect.width = slider.getWidth() - (insetCache.left + insetCache.right);
386     focusRect.height = slider.getHeight() - (insetCache.top + insetCache.bottom);
387     }
388   
389     protected void calculateThumbSize() {
390     Dimension JavaDoc size = getThumbSize();
391     thumbRect.setSize( size.width, size.height );
392     }
393   
394     protected void calculateContentRect() {
395         contentRect.x = focusRect.x + focusInsets.left;
396         contentRect.y = focusRect.y + focusInsets.top;
397         contentRect.width = focusRect.width - (focusInsets.left + focusInsets.right);
398         contentRect.height = focusRect.height - (focusInsets.top + focusInsets.bottom);
399     }
400
401     protected void calculateThumbLocation() {
402         if ( slider.getSnapToTicks() ) {
403         int sliderValue = slider.getValue();
404         int snappedValue = sliderValue;
405         int majorTickSpacing = slider.getMajorTickSpacing();
406         int minorTickSpacing = slider.getMinorTickSpacing();
407         int tickSpacing = 0;
408         
409         if ( minorTickSpacing > 0 ) {
410             tickSpacing = minorTickSpacing;
411         }
412         else if ( majorTickSpacing > 0 ) {
413             tickSpacing = majorTickSpacing;
414         }
415
416         if ( tickSpacing != 0 ) {
417             // If it's not on a tick, change the value
418
if ( (sliderValue - slider.getMinimum()) % tickSpacing != 0 ) {
419             float temp = (float)(sliderValue - slider.getMinimum()) / (float)tickSpacing;
420             int whichTick = Math.round( temp );
421             snappedValue = slider.getMinimum() + (whichTick * tickSpacing);
422         }
423         
424         if( snappedValue != sliderValue ) {
425             slider.setValue( snappedValue );
426         }
427         }
428     }
429     
430         if ( slider.getOrientation() == JSlider.HORIZONTAL ) {
431             int valuePosition = xPositionForValue(slider.getValue());
432
433         thumbRect.x = valuePosition - (thumbRect.width / 2);
434         thumbRect.y = trackRect.y;
435         }
436         else {
437             int valuePosition = yPositionForValue(slider.getValue());
438         
439         thumbRect.x = trackRect.x;
440         thumbRect.y = valuePosition - (thumbRect.height / 2);
441         }
442     }
443
444     protected void calculateTrackBuffer() {
445         if ( slider.getPaintLabels() && slider.getLabelTable() != null ) {
446             Component JavaDoc highLabel = getHighestValueLabel();
447             Component JavaDoc lowLabel = getLowestValueLabel();
448
449             if ( slider.getOrientation() == JSlider.HORIZONTAL ) {
450                 trackBuffer = Math.max( highLabel.getBounds().width, lowLabel.getBounds().width ) / 2;
451                 trackBuffer = Math.max( trackBuffer, thumbRect.width / 2 );
452             }
453             else {
454                 trackBuffer = Math.max( highLabel.getBounds().height, lowLabel.getBounds().height ) / 2;
455                 trackBuffer = Math.max( trackBuffer, thumbRect.height / 2 );
456             }
457         }
458         else {
459             if ( slider.getOrientation() == JSlider.HORIZONTAL ) {
460                 trackBuffer = thumbRect.width / 2;
461             }
462             else {
463                 trackBuffer = thumbRect.height / 2;
464             }
465         }
466     }
467
468   
469     protected void calculateTrackRect() {
470     int centerSpacing = 0; // used to center sliders added using BorderLayout.CENTER (bug 4275631)
471
if ( slider.getOrientation() == JSlider.HORIZONTAL ) {
472         centerSpacing = thumbRect.height;
473         if ( slider.getPaintTicks() ) centerSpacing += getTickLength();
474         if ( slider.getPaintLabels() ) centerSpacing += getHeightOfTallestLabel();
475         trackRect.x = contentRect.x + trackBuffer;
476         trackRect.y = contentRect.y + (contentRect.height - centerSpacing - 1)/2;
477         trackRect.width = contentRect.width - (trackBuffer * 2);
478         trackRect.height = thumbRect.height;
479     }
480     else {
481         centerSpacing = thumbRect.width;
482         if (BasicGraphicsUtils.isLeftToRight(slider)) {
483         if ( slider.getPaintTicks() ) centerSpacing += getTickLength();
484             if ( slider.getPaintLabels() ) centerSpacing += getWidthOfWidestLabel();
485         } else {
486             if ( slider.getPaintTicks() ) centerSpacing -= getTickLength();
487             if ( slider.getPaintLabels() ) centerSpacing -= getWidthOfWidestLabel();
488         }
489         trackRect.x = contentRect.x + (contentRect.width - centerSpacing - 1)/2;
490         trackRect.y = contentRect.y + trackBuffer;
491         trackRect.width = thumbRect.width;
492         trackRect.height = contentRect.height - (trackBuffer * 2);
493     }
494
495     }
496
497     /**
498      * Gets the height of the tick area for horizontal sliders and the width of the
499      * tick area for vertical sliders. BasicSliderUI uses the returned value to
500      * determine the tick area rectangle. If you want to give your ticks some room,
501      * make this larger than you need and paint your ticks away from the sides in paintTicks().
502      */

503     protected int getTickLength() {
504         return 8;
505     }
506
507     protected void calculateTickRect() {
508     if ( slider.getOrientation() == JSlider.HORIZONTAL ) {
509         tickRect.x = trackRect.x;
510         tickRect.y = trackRect.y + trackRect.height;
511         tickRect.width = trackRect.width;
512         tickRect.height = getTickLength();
513         
514         if ( !slider.getPaintTicks() ) {
515             --tickRect.y;
516         tickRect.height = 0;
517         }
518     }
519     else {
520         if(BasicGraphicsUtils.isLeftToRight(slider)) {
521             tickRect.x = trackRect.x + trackRect.width;
522         tickRect.width = getTickLength();
523         }
524         else {
525             tickRect.width = getTickLength();
526             tickRect.x = trackRect.x - tickRect.width;
527         }
528         tickRect.y = trackRect.y;
529         tickRect.height = trackRect.height;
530
531         if ( !slider.getPaintTicks() ) {
532             --tickRect.x;
533         tickRect.width = 0;
534         }
535     }
536     }
537
538     protected void calculateLabelRect() {
539         if ( slider.getPaintLabels() ) {
540         if ( slider.getOrientation() == JSlider.HORIZONTAL ) {
541             labelRect.x = tickRect.x - trackBuffer;
542         labelRect.y = tickRect.y + tickRect.height;
543         labelRect.width = tickRect.width + (trackBuffer * 2);
544                 labelRect.height = getHeightOfTallestLabel();
545             }
546             else {
547             if(BasicGraphicsUtils.isLeftToRight(slider)) {
548             labelRect.x = tickRect.x + tickRect.width;
549             labelRect.width = getWidthOfWidestLabel();
550         }
551         else {
552             labelRect.width = getWidthOfWidestLabel();
553             labelRect.x = tickRect.x - labelRect.width;
554         }
555         labelRect.y = tickRect.y - trackBuffer;
556         labelRect.height = tickRect.height + (trackBuffer * 2);
557             }
558         }
559         else {
560             if ( slider.getOrientation() == JSlider.HORIZONTAL ) {
561             labelRect.x = tickRect.x;
562         labelRect.y = tickRect.y + tickRect.height;
563         labelRect.width = tickRect.width;
564         labelRect.height = 0;
565             }
566             else {
567             if(BasicGraphicsUtils.isLeftToRight(slider)) {
568             labelRect.x = tickRect.x + tickRect.width;
569         }
570         else {
571             labelRect.x = tickRect.x;
572         }
573         labelRect.y = tickRect.y;
574         labelRect.width = 0;
575         labelRect.height = tickRect.height;
576             }
577         }
578     }
579
580     protected Dimension JavaDoc getThumbSize() {
581         Dimension JavaDoc size = new Dimension JavaDoc();
582
583         if ( slider.getOrientation() == JSlider.VERTICAL ) {
584         size.width = 20;
585         size.height = 11;
586     }
587     else {
588         size.width = 11;
589         size.height = 20;
590     }
591
592     return size;
593     }
594
595     public class PropertyChangeHandler implements PropertyChangeListener {
596         // NOTE: This class exists only for backward compatability. All
597
// its functionality has been moved into Handler. If you need to add
598
// new functionality add it to the Handler, but make sure this
599
// class calls into the Handler.
600
public void propertyChange( PropertyChangeEvent e ) {
601             getHandler().propertyChange(e);
602         }
603     }
604
605     protected int getWidthOfWidestLabel() {
606         Dictionary JavaDoc dictionary = slider.getLabelTable();
607         int widest = 0;
608         if ( dictionary != null ) {
609             Enumeration JavaDoc keys = dictionary.keys();
610             while ( keys.hasMoreElements() ) {
611                 Component JavaDoc label = (Component JavaDoc)dictionary.get( keys.nextElement() );
612                 widest = Math.max( label.getPreferredSize().width, widest );
613             }
614         }
615         return widest;
616     }
617
618     protected int getHeightOfTallestLabel() {
619         Dictionary JavaDoc dictionary = slider.getLabelTable();
620         int tallest = 0;
621         if ( dictionary != null ) {
622             Enumeration JavaDoc keys = dictionary.keys();
623             while ( keys.hasMoreElements() ) {
624                 Component JavaDoc label = (Component JavaDoc)dictionary.get( keys.nextElement() );
625                 tallest = Math.max( label.getPreferredSize().height, tallest );
626             }
627         }
628         return tallest;
629     }
630
631     protected int getWidthOfHighValueLabel() {
632         Component JavaDoc label = getHighestValueLabel();
633         int width = 0;
634
635         if ( label != null ) {
636             width = label.getPreferredSize().width;
637         }
638
639         return width;
640     }
641
642     protected int getWidthOfLowValueLabel() {
643         Component JavaDoc label = getLowestValueLabel();
644         int width = 0;
645
646         if ( label != null ) {
647             width = label.getPreferredSize().width;
648         }
649
650         return width;
651     }
652
653     protected int getHeightOfHighValueLabel() {
654         Component JavaDoc label = getHighestValueLabel();
655         int height = 0;
656
657         if ( label != null ) {
658             height = label.getPreferredSize().height;
659         }
660
661         return height;
662     }
663
664     protected int getHeightOfLowValueLabel() {
665         Component JavaDoc label = getLowestValueLabel();
666         int height = 0;
667
668         if ( label != null ) {
669             height = label.getPreferredSize().height;
670         }
671
672         return height;
673     }
674
675     protected boolean drawInverted() {
676         if (slider.getOrientation()==JSlider.HORIZONTAL) {
677         if(BasicGraphicsUtils.isLeftToRight(slider)) {
678             return slider.getInverted();
679         } else {
680             return !slider.getInverted();
681         }
682     } else {
683         return slider.getInverted();
684     }
685     }
686
687     /**
688      * Returns the label that corresponds to the highest slider value in the label table.
689      * @see JSlider#setLabelTable
690      */

691     protected Component JavaDoc getLowestValueLabel() {
692         Dictionary JavaDoc dictionary = slider.getLabelTable();
693         Component JavaDoc label = null;
694
695         if ( dictionary != null ) {
696             Enumeration JavaDoc keys = dictionary.keys();
697             if ( keys.hasMoreElements() ) {
698                 int lowestValue = ((Integer JavaDoc)keys.nextElement()).intValue();
699
700                 while ( keys.hasMoreElements() ) {
701                     int value = ((Integer JavaDoc)keys.nextElement()).intValue();
702                     lowestValue = Math.min( value, lowestValue );
703                 }
704
705                 label = (Component JavaDoc)dictionary.get( new Integer JavaDoc( lowestValue ) );
706             }
707         }
708
709         return label;
710     }
711
712     /**
713      * Returns the label that corresponds to the lowest slider value in the label table.
714      * @see JSlider#setLabelTable
715      */

716     protected Component JavaDoc getHighestValueLabel() {
717         Dictionary JavaDoc dictionary = slider.getLabelTable();
718         Component JavaDoc label = null;
719
720         if ( dictionary != null ) {
721             Enumeration JavaDoc keys = dictionary.keys();
722             if ( keys.hasMoreElements() ) {
723                 int highestValue = ((Integer JavaDoc)keys.nextElement()).intValue();
724
725                 while ( keys.hasMoreElements() ) {
726                     int value = ((Integer JavaDoc)keys.nextElement()).intValue();
727                     highestValue = Math.max( value, highestValue );
728                 }
729
730                 label = (Component JavaDoc)dictionary.get( new Integer JavaDoc( highestValue ) );
731             }
732         }
733
734         return label;
735     }
736
737     public void paint( Graphics JavaDoc g, JComponent c ) {
738         recalculateIfInsetsChanged();
739     recalculateIfOrientationChanged();
740     Rectangle JavaDoc clip = g.getClipBounds();
741
742     if ( !clip.intersects(trackRect) && slider.getPaintTrack())
743         calculateGeometry();
744
745     if ( slider.getPaintTrack() && clip.intersects( trackRect ) ) {
746         paintTrack( g );
747     }
748         if ( slider.getPaintTicks() && clip.intersects( tickRect ) ) {
749             paintTicks( g );
750         }
751         if ( slider.getPaintLabels() && clip.intersects( labelRect ) ) {
752             paintLabels( g );
753         }
754     if ( slider.hasFocus() && clip.intersects( focusRect ) ) {
755         paintFocus( g );
756     }
757     if ( clip.intersects( thumbRect ) ) {
758         paintThumb( g );
759     }
760     }
761
762     protected void recalculateIfInsetsChanged() {
763         Insets JavaDoc newInsets = slider.getInsets();
764         if ( !newInsets.equals( insetCache ) ) {
765         insetCache = newInsets;
766         calculateGeometry();
767     }
768     }
769
770     protected void recalculateIfOrientationChanged() {
771         boolean ltr = BasicGraphicsUtils.isLeftToRight(slider);
772         if ( ltr!=leftToRightCache ) {
773         leftToRightCache = ltr;
774         calculateGeometry();
775     }
776     }
777
778     public void paintFocus(Graphics JavaDoc g) {
779     g.setColor( getFocusColor() );
780
781     BasicGraphicsUtils.drawDashedRect( g, focusRect.x, focusRect.y,
782                        focusRect.width, focusRect.height );
783     }
784
785     public void paintTrack(Graphics JavaDoc g) {
786         int cx, cy, cw, ch;
787         int pad;
788
789         Rectangle JavaDoc trackBounds = trackRect;
790
791         if ( slider.getOrientation() == JSlider.HORIZONTAL ) {
792             pad = trackBuffer;
793             cx = pad;
794             cy = (trackBounds.height / 2) - 2;
795             cw = trackBounds.width;
796
797             g.translate(trackBounds.x, trackBounds.y + cy);
798
799             g.setColor(getShadowColor());
800             g.drawLine(0, 0, cw - 1, 0);
801             g.drawLine(0, 1, 0, 2);
802             g.setColor(getHighlightColor());
803             g.drawLine(0, 3, cw, 3);
804             g.drawLine(cw, 0, cw, 3);
805             g.setColor(Color.black);
806             g.drawLine(1, 1, cw-2, 1);
807
808             g.translate(-trackBounds.x, -(trackBounds.y + cy));
809         }
810         else {
811             pad = trackBuffer;
812             cx = (trackBounds.width / 2) - 2;
813             cy = pad;
814             ch = trackBounds.height;
815
816             g.translate(trackBounds.x + cx, trackBounds.y);
817
818             g.setColor(getShadowColor());
819             g.drawLine(0, 0, 0, ch - 1);
820             g.drawLine(1, 0, 2, 0);
821             g.setColor(getHighlightColor());
822             g.drawLine(3, 0, 3, ch);
823             g.drawLine(0, ch, 3, ch);
824             g.setColor(Color.black);
825             g.drawLine(1, 1, 1, ch-2);
826
827             g.translate(-(trackBounds.x + cx), -trackBounds.y);
828         }
829     }
830
831     public void paintTicks(Graphics JavaDoc g) {
832         Rectangle JavaDoc tickBounds = tickRect;
833         int i;
834         int maj, min, max;
835         int w = tickBounds.width;
836         int h = tickBounds.height;
837         int centerEffect, tickHeight;
838
839         g.setColor(DefaultLookup.getColor(slider, this, "Slider.tickColor", Color.black));
840
841         maj = slider.getMajorTickSpacing();
842         min = slider.getMinorTickSpacing();
843
844         if ( slider.getOrientation() == JSlider.HORIZONTAL ) {
845            g.translate( 0, tickBounds.y);
846
847             int value = slider.getMinimum();
848             int xPos = 0;
849
850             if ( slider.getMinorTickSpacing() > 0 ) {
851                 while ( value <= slider.getMaximum() ) {
852                     xPos = xPositionForValue( value );
853                     paintMinorTickForHorizSlider( g, tickBounds, xPos );
854                     value += slider.getMinorTickSpacing();
855                 }
856             }
857
858             if ( slider.getMajorTickSpacing() > 0 ) {
859                 value = slider.getMinimum();
860
861                 while ( value <= slider.getMaximum() ) {
862                     xPos = xPositionForValue( value );
863                     paintMajorTickForHorizSlider( g, tickBounds, xPos );
864                     value += slider.getMajorTick