1:
37:
38:
39: package ;
40:
41: import ;
42: import ;
43: import ;
44: import ;
45: import ;
46: import ;
47: import ;
48: import ;
49: import ;
50: import ;
51: import ;
52: import ;
53: import ;
54: import ;
55: import ;
56: import ;
57: import ;
58: import ;
59: import ;
60: import ;
61: import ;
62:
63: import ;
64: import ;
65: import ;
66: import ;
67: import ;
68: import ;
69: import ;
70: import ;
71: import ;
72: import ;
73: import ;
74: import ;
75: import ;
76: import ;
77:
78:
138: public class BasicSliderUI extends SliderUI
139: {
140:
147: public class ChangeHandler implements ChangeListener
148: {
149:
156: public void stateChanged(ChangeEvent e)
157: {
158:
159:
160:
161: calculateThumbLocation();
162: slider.repaint();
163: }
164: }
165:
166:
173: public class ComponentHandler extends ComponentAdapter
174: {
175:
182: public void componentResized(ComponentEvent e)
183: {
184: calculateGeometry();
185:
186: slider.revalidate();
187: slider.repaint();
188: }
189: }
190:
191:
198: public class FocusHandler implements FocusListener
199: {
200:
206: public void focusGained(FocusEvent e)
207: {
208:
209: }
210:
211:
217: public void focusLost(FocusEvent e)
218: {
219:
220: }
221: }
222:
223:
227: public class PropertyChangeHandler implements PropertyChangeListener
228: {
229:
235: public void propertyChange(PropertyChangeEvent e)
236: {
237:
238: if (e.getPropertyName().equals("orientation"))
239: recalculateIfOrientationChanged();
240: else if (e.getPropertyName().equals("model"))
241: {
242: BoundedRangeModel oldModel = (BoundedRangeModel) e.getOldValue();
243: oldModel.removeChangeListener(changeListener);
244: slider.getModel().addChangeListener(changeListener);
245: calculateThumbLocation();
246: }
247:
248:
249:
250:
251:
252:
253:
254: slider.repaint();
255: }
256: }
257:
258:
267: public class ScrollListener implements ActionListener
268: {
269:
270: private transient int direction;
271:
272:
273: private transient boolean block;
274:
275:
278: public ScrollListener()
279: {
280: direction = POSITIVE_SCROLL;
281: block = false;
282: }
283:
284:
290: public ScrollListener(int dir, boolean block)
291: {
292: direction = dir;
293: this.block = block;
294: }
295:
296:
303: public void actionPerformed(ActionEvent e)
304: {
305: if (! trackListener.shouldScroll(direction))
306: {
307: scrollTimer.stop();
308: return;
309: }
310:
311: if (block)
312: scrollByBlock(direction);
313: else
314: scrollByUnit(direction);
315: }
316:
317:
322: public void setDirection(int direction)
323: {
324: this.direction = direction;
325: }
326:
327:
332: public void setScrollByBlock(boolean block)
333: {
334: this.block = block;
335: }
336: }
337:
338:
345: public class TrackListener extends MouseInputAdapter
346: {
347:
348: protected int currentMouseX;
349:
350:
351: protected int currentMouseY;
352:
353:
356: protected int offset;
357:
358:
365: public void mouseDragged(MouseEvent e)
366: {
367: currentMouseX = e.getX();
368: currentMouseY = e.getY();
369: if (slider.getValueIsAdjusting())
370: {
371: int value;
372: if (slider.getOrientation() == JSlider.HORIZONTAL)
373: value = valueForXPosition(currentMouseX) - offset;
374: else
375: value = valueForYPosition(currentMouseY) - offset;
376:
377: slider.setValue(value);
378: }
379: }
380:
381:
387: public void mouseMoved(MouseEvent e)
388: {
389:
390: }
391:
392:
400: public void mousePressed(MouseEvent e)
401: {
402: currentMouseX = e.getX();
403: currentMouseY = e.getY();
404:
405: int value;
406: if (slider.getOrientation() == JSlider.HORIZONTAL)
407: value = valueForXPosition(currentMouseX);
408: else
409: value = valueForYPosition(currentMouseY);
410:
411: if (slider.getSnapToTicks())
412: value = findClosestTick(value);
413:
414:
415: if (! thumbRect.contains(e.getPoint()))
416: {
417:
418:
419: if (value > slider.getValue())
420: scrollDueToClickInTrack(POSITIVE_SCROLL);
421: else
422: scrollDueToClickInTrack(NEGATIVE_SCROLL);
423: }
424: else
425: {
426: slider.setValueIsAdjusting(true);
427: offset = value - slider.getValue();
428: }
429: }
430:
431:
437: public void mouseReleased(MouseEvent e)
438: {
439: currentMouseX = e.getX();
440: currentMouseY = e.getY();
441:
442: if (slider.getValueIsAdjusting())
443: {
444: slider.setValueIsAdjusting(false);
445: if (slider.getSnapToTicks())
446: slider.setValue(findClosestTick(slider.getValue()));
447: }
448: if (scrollTimer != null)
449: scrollTimer.stop();
450: }
451:
452:
459: public boolean shouldScroll(int direction)
460: {
461: int value;
462: if (slider.getOrientation() == JSlider.HORIZONTAL)
463: value = valueForXPosition(currentMouseX);
464: else
465: value = valueForYPosition(currentMouseY);
466:
467: if (direction == POSITIVE_SCROLL)
468: return (value > slider.getValue());
469: else
470: return (value < slider.getValue());
471: }
472: }
473:
474:
477: public class ActionScroller extends AbstractAction
478: {
479:
486: public ActionScroller(JSlider slider, int dir, boolean block)
487: {
488:
489: }
490:
491:
496: public void actionPerformed(ActionEvent event)
497: {
498:
499: }
500: }
501:
502:
503: protected ChangeListener changeListener;
504:
505:
506: protected PropertyChangeListener propertyChangeListener;
507:
508:
509: protected ScrollListener scrollListener;
510:
511:
512: protected ComponentListener componentListener;
513:
514:
515: protected FocusListener focusListener;
516:
517:
518: protected TrackListener trackListener;
519:
520:
521: protected Insets focusInsets;
522:
523:
524: protected Insets insetCache;
525:
526:
527: protected Rectangle contentRect;
528:
529:
530: protected Rectangle focusRect;
531:
532:
533: protected Rectangle thumbRect;
534:
535:
536: protected Rectangle tickRect;
537:
538:
539: protected Rectangle labelRect;
540:
541:
542: protected Rectangle trackRect;
543:
544:
545: public static final int MAX_SCROLL = 2;
546:
547:
548: public static final int MIN_SCROLL = -2;
549:
550:
551: public static final int NEGATIVE_SCROLL = -1;
552:
553:
554: public static final int POSITIVE_SCROLL = 1;
555:
556:
557: protected int trackBuffer;
558:
559:
560: protected boolean leftToRightCache;
561:
562:
563: protected Timer scrollTimer;
564:
565:
566: protected JSlider slider;
567:
568:
569: private transient Color shadowColor;
570:
571:
572: private transient Color highlightColor;
573:
574:
575: private transient Color focusColor;
576:
577:
582: public BasicSliderUI(JSlider b)
583: {
584: super();
585: }
586:
587:
593: protected Color getShadowColor()
594: {
595: return shadowColor;
596: }
597:
598:
604: protected Color getHighlightColor()
605: {
606: return highlightColor;
607: }
608:
609:
616: protected Color getFocusColor()
617: {
618: return focusColor;
619: }
620:
621:
629: public static ComponentUI createUI(JComponent b)
630: {
631: return new BasicSliderUI((JSlider) b);
632: }
633:
634:
641: public void installUI(JComponent c)
642: {
643: super.installUI(c);
644: if (c instanceof JSlider)
645: {
646: slider = (JSlider) c;
647:
648: focusRect = new Rectangle();
649: contentRect = new Rectangle();
650: thumbRect = new Rectangle();
651: trackRect = new Rectangle();
652: tickRect = new Rectangle();
653: labelRect = new Rectangle();
654:
655: insetCache = slider.getInsets();
656: leftToRightCache = ! slider.getInverted();
657:
658: scrollTimer = new Timer(200, null);
659: scrollTimer.setRepeats(true);
660:
661: installDefaults(slider);
662: installListeners(slider);
663: installKeyboardActions(slider);
664:
665: calculateFocusRect();
666:
667: calculateContentRect();
668: calculateThumbSize();
669: calculateTrackBuffer();
670: calculateTrackRect();
671: calculateThumbLocation();
672:
673: calculateTickRect();
674: calculateLabelRect();
675: }
676: }
677:
678:
685: public void uninstallUI(JComponent c)
686: {
687: super.uninstallUI(c);
688:
689: uninstallKeyboardActions(slider);
690: uninstallListeners(slider);
691:
692: scrollTimer = null;
693:
694: focusRect = null;
695: contentRect = null;
696: thumbRect = null;
697: trackRect = null;
698: tickRect = null;
699: labelRect = null;
700:
701: focusInsets = null;
702: }
703:
704:
710: protected void installDefaults(JSlider slider)
711: {
712: LookAndFeel.installColors(slider, "Slider.background",
713: "Slider.foreground");
714: LookAndFeel.installBorder(slider, "Slider.border");
715: shadowColor = UIManager.getColor("Slider.shadow");
716: highlightColor = UIManager.getColor("Slider.highlight");
717: focusColor = UIManager.getColor("Slider.focus");
718: focusInsets = UIManager.getInsets("Slider.focusInsets");
719: slider.setOpaque(true);
720: }
721:
722:
730: protected TrackListener createTrackListener(JSlider slider)
731: {
732: return new TrackListener();
733: }
734:
735:
743: protected ChangeListener createChangeListener(JSlider slider)
744: {
745: return new ChangeHandler();
746: }
747:
748:
756: protected ComponentListener createComponentListener(JSlider slider)
757: {
758: return new ComponentHandler();
759: }
760:
761:
769: protected FocusListener createFocusListener(JSlider slider)
770: {
771: return new FocusHandler();
772: }
773:
774:
782: protected ScrollListener createScrollListener(JSlider slider)
783: {
784: return new ScrollListener();
785: }
786:
787:
795: protected PropertyChangeListener createPropertyChangeListener(JSlider slider)
796: {
797: return new PropertyChangeHandler();
798: }
799:
800:
806: protected void installListeners(JSlider slider)
807: {
808: propertyChangeListener = createPropertyChangeListener(slider);
809: componentListener = createComponentListener(slider);
810: trackListener = createTrackListener(slider);
811: focusListener = createFocusListener(slider);
812: changeListener = createChangeListener(slider);
813: scrollListener = createScrollListener(slider);
814:
815: slider.addPropertyChangeListener(propertyChangeListener);
816: slider.addComponentListener(componentListener);
817: slider.addMouseListener(trackListener);
818: slider.addMouseMotionListener(trackListener);
819: slider.addFocusListener(focusListener);
820: slider.getModel().addChangeListener(changeListener);
821:
822: scrollTimer.addActionListener(scrollListener);
823: }
824:
825:
831: protected void uninstallListeners(JSlider slider)
832: {
833: slider.removePropertyChangeListener(propertyChangeListener);
834: slider.removeComponentListener(componentListener);
835: slider.removeMouseListener(trackListener);
836: slider.removeMouseMotionListener(trackListener);
837: slider.removeFocusListener(focusListener);
838: slider.getModel().removeChangeListener(changeListener);
839:
840: scrollTimer.removeActionListener(scrollListener);
841:
842: propertyChangeListener = null;
843: componentListener = null;
844: trackListener = null;
845: focusListener = null;
846: changeListener = null;
847: scrollListener = null;
848: }
849:
850:
857: protected void installKeyboardActions(JSlider slider)
858: {
859:
860: }
861:
862:
869: protected void uninstallKeyboardActions(JSlider slider)
870: {
871:
872: }
873:
874:
888:
889:
895: public Dimension getPreferredHorizontalSize()
896: {
897: Insets insets = slider.getInsets();
898:
899:
900:
901: int width = getWidthOfWidestLabel() * (slider.getLabelTable() == null ? 0
902: : slider.getLabelTable()
903: .size());
904:
905:
906:
907: if (width < 200)
908: width = 200;
909:
910:
911:
912: width += insets.left + insets.right + focusInsets.left + focusInsets.right;
913:
914:
915: int height = getThumbSize().height;
916:
917: if (slider.getPaintTicks() && slider.getMajorTickSpacing() > 0
918: || slider.getMinorTickSpacing() > 0)
919: height += getTickLength();
920:
921: if (slider.getPaintLabels())
922: height += getHeightOfTallestLabel();
923:
924: height += insets.top + insets.bottom + focusInsets.top
925: + focusInsets.bottom;
926:
927: return new Dimension(width, height);
928: }
929:
930:
936: public Dimension getPreferredVerticalSize()
937: {
938: Insets insets = slider.getInsets();
939:
940: int height = getHeightOfTallestLabel() * (slider.getLabelTable() == null
941: ? 0 : slider.getLabelTable()
942: .size());
943:
944: if (height < 200)
945: height = 200;
946:
947: height += insets.top + insets.bottom + focusInsets.top
948: + focusInsets.bottom;
949:
950: int width = getThumbSize().width;
951:
952: if (slider.getPaintTicks() && slider.getMajorTickSpacing() > 0
953: || slider.getMinorTickSpacing() > 0)
954: width += getTickLength();
955:
956: if (slider.getPaintLabels())
957: width += getWidthOfWidestLabel();
958:
959: width += insets.left + insets.right + focusInsets.left + focusInsets.right;
960:
961: return new Dimension(width, height);
962: }
963:
964:
970: public Dimension getMinimumHorizontalSize()
971: {
972: Insets insets = slider.getInsets();
973:
974: int height = getThumbSize().height;
975:
976: if (slider.getPaintTicks() && slider.getMajorTickSpacing() > 0
977: || slider.getMinorTickSpacing() > 0)
978: height += getTickLength();
979:
980: if (slider.getPaintLabels())
981: height += getHeightOfTallestLabel();
982:
983: height += insets.top + insets.bottom + focusInsets.top
984: + focusInsets.bottom;
985:
986: return new Dimension(36, height);
987: }
988:
989:
995: public Dimension getMinimumVerticalSize()
996: {
997: Insets insets = slider.getInsets();
998: int width = getThumbSize().width;
999:
1000: if (slider.getPaintTicks() && slider.getMajorTickSpacing() > 0
1001: || slider.getMinorTickSpacing() > 0)
1002: width += getTickLength();
1003:
1004: if (slider.getPaintLabels())
1005: width += getWidthOfWidestLabel();
1006:
1007: width += insets.left + insets.right + focusInsets.left + focusInsets.right;
1008:
1009: return new Dimension(width, 36);
1010: }
1011:
1012:
1021: public Dimension getPreferredSize(JComponent c)
1022: {
1023: if (slider.getOrientation() == JSlider.HORIZONTAL)
1024: return getPreferredHorizontalSize();
1025: else
1026: return getPreferredVerticalSize();
1027: }
1028:
1029:
1038: public Dimension getMinimumSize(JComponent c)
1039: {
1040: if (slider.getOrientation() == JSlider.HORIZONTAL)
1041: return getMinimumHorizontalSize();
1042: else
1043: return getMinimumVerticalSize();
1044: }
1045:
1046:
1054: public Dimension getMaximumSize(JComponent c)
1055: {
1056: Insets insets = slider.getInsets();
1057: if (slider.getOrientation() == JSlider.HORIZONTAL)
1058: {
1059:
1060: int height = getThumbSize().height;
1061:
1062: if (slider.getPaintTicks() && slider.getMajorTickSpacing() > 0
1063: || slider.getMinorTickSpacing() > 0)
1064: height += getTickLength();
1065:
1066: if (slider.getPaintLabels())
1067: height += getHeightOfTallestLabel();
1068:
1069: height += insets.top + insets.bottom + focusInsets.top
1070: + focusInsets.bottom;
1071:
1072: return new Dimension(32767, height);
1073: }
1074: else
1075: {
1076: int width = getThumbSize().width;
1077:
1078: if (slider.getPaintTicks() && slider.getMajorTickSpacing() > 0
1079: || slider.getMinorTickSpacing() > 0)
1080: width += getTickLength();
1081:
1082: if (slider.getPaintLabels())
1083: width += getWidthOfWidestLabel();
1084:
1085: width += insets.left + insets.right + focusInsets.left
1086: + focusInsets.right;
1087:
1088: return new Dimension(width, 32767);
1089: }
1090: }
1091:
1092:
1096: protected void calculateGeometry()
1097: {
1098: calculateFocusRect();
1099: calculateContentRect();
1100: calculateThumbSize();
1101: calculateTrackBuffer();
1102: calculateTrackRect();
1103: calculateTickRect();
1104: calculateLabelRect();
1105: calculateThumbLocation();
1106: }
1107:
1108:
1112: protected void calculateFocusRect()
1113: {
1114: insetCache = slider.getInsets();
1115: focusRect = SwingUtilities.calculateInnerArea(slider, focusRect);
1116: if (focusRect.width < 0)
1117: focusRect.width = 0;
1118: if (focusRect.height < 0)
1119: focusRect.height = 0;
1120: }
1121:
1122:
1126: protected void calculateThumbSize()
1127: {
1128: Dimension d = getThumbSize();
1129: thumbRect.width = d.width;
1130: thumbRect.height = d.height;
1131: if (slider.getOrientation() == JSlider.HORIZONTAL)
1132: thumbRect.y = trackRect.y;
1133: else
1134: thumbRect.x = trackRect.x;
1135: }
1136:
1137:
1141: protected void calculateContentRect()
1142: {
1143: contentRect.x = focusRect.x + focusInsets.left;
1144: contentRect.y = focusRect.y + focusInsets.top;
1145:
1146: contentRect.width = focusRect.width - focusInsets.left - focusInsets.right;
1147: contentRect.height = focusRect.height - focusInsets.top
1148: - focusInsets.bottom;
1149:
1150: if (contentRect.width < 0)
1151: contentRect.width = 0;
1152: if (contentRect.height < 0)
1153: contentRect.height = 0;
1154: }
1155:
1156:
1160: protected void calculateThumbLocation()
1161: {
1162: int value = slider.getValue();
1163:
1164: if (slider.getOrientation() == JSlider.HORIZONTAL)
1165: {
1166: thumbRect.x = xPositionForValue(value) - thumbRect.width / 2;
1167: thumbRect.y = trackRect.y;
1168: }
1169: else
1170: {
1171: thumbRect.x = trackRect.x;
1172: thumbRect.y = yPositionForValue(value) - thumbRect.height / 2;
1173: }
1174: }
1175:
1176:
1180: protected void calculateTrackBuffer()
1181: {
1182: if (slider.getOrientation() == JSlider.HORIZONTAL)
1183: trackBuffer = thumbRect.width / 2;
1184: else
1185: trackBuffer = thumbRect.height / 2;
1186: }
1187:
1188:
1193: protected Dimension getThumbSize()
1194: {
1195:
1196: if (slider.getOrientation() == JSlider.HORIZONTAL)
1197: return new Dimension(11, 20);
1198: else
1199: return new Dimension(20, 11);
1200: }
1201:
1202:
1206: protected void calculateTrackRect()
1207: {
1208: if (slider.getOrientation() == JSlider.HORIZONTAL)
1209: {
1210: trackRect.x = contentRect.x + trackBuffer;
1211: int h = getThumbSize().height;
1212: if (slider.getPaintTicks() && (slider.getMajorTickSpacing() > 0
1213: || slider.getMinorTickSpacing() > 0))
1214: h += getTickLength();
1215: trackRect.y = contentRect.y + (contentRect.height - h) / 2 - 1;
1216: trackRect.width = contentRect.width - 2 * trackBuffer;
1217: trackRect.height = thumbRect.height;
1218: }
1219: else
1220: {
1221: int w = getThumbSize().width;
1222: if (slider.getPaintTicks() && (slider.getMajorTickSpacing() > 0
1223: || slider.getMinorTickSpacing() > 0))
1224: w += getTickLength();
1225: trackRect.x = contentRect.x + (contentRect.width - w) / 2 - 1;
1226: trackRect.y = contentRect.y + trackBuffer;
1227: trackRect.width = thumbRect.width;
1228: trackRect.height = contentRect.height - 2 * trackBuffer;
1229: }
1230: }
1231:
1232:
1242: protected int getTickLength()
1243: {
1244: return 8;
1245: }
1246:
1247:
1251: protected void calculateTickRect()
1252: {
1253: if (slider.getOrientation() == JSlider.HORIZONTAL)
1254: {
1255: tickRect.x = trackRect.x;
1256: tickRect.y = trackRect.y + trackRect.height;
1257: tickRect.width = trackRect.width;
1258: tickRect.height = getTickLength();
1259:
1260: if (tickRect.y + tickRect.height > contentRect.y + contentRect.height)
1261: tickRect.height = contentRect.y + contentRect.height - tickRect.y;
1262: }
1263: else
1264: {
1265: tickRect.x = trackRect.x + trackRect.width;
1266: tickRect.y = trackRect.y;
1267: tickRect.width = getTickLength();
1268: tickRect.height = trackRect.height;
1269:
1270: if (tickRect.x + tickRect.width > contentRect.x + contentRect.width)
1271: tickRect.width = contentRect.x + contentRect.width - tickRect.x;
1272: }
1273: }
1274:
1275:
1279: protected void calculateLabelRect()
1280: {
1281: if (slider.getOrientation() == JSlider.HORIZONTAL)
1282: {
1283: labelRect.x = contentRect.x;
1284: labelRect.y = tickRect.y + tickRect.height;
1285: labelRect.width = contentRect.width;
1286: labelRect.height = contentRect.height - labelRect.y;
1287: }
1288: else
1289: {
1290: labelRect.x = tickRect.x + tickRect.width;
1291: labelRect.y = contentRect.y;
1292: labelRect.width = contentRect.width - labelRect.x;
1293: labelRect.height = contentRect.height;
1294: }
1295: }
1296:
1297:
1303: protected int getWidthOfWidestLabel()
1304: {
1305: int widest = 0;
1306: Component label;
1307:
1308: if (slider.getLabelTable() == null)
1309: return 0;
1310:
1311: Dimension pref;
1312: for (Enumeration list = slider.getLabelTable().elements();
1313: list.hasMoreElements();)
1314: {
1315: Object comp = list.nextElement();
1316: if (! (comp instanceof Component))
1317: continue;
1318: label = (Component) comp;
1319: pref = label.getPreferredSize();
1320: if (pref != null && pref.width > widest)
1321: widest = pref.width;
1322: }
1323: return widest;
1324: }
1325:
1326:
1332: protected int getHeightOfTallestLabel()
1333: {
1334: int tallest = 0;
1335: Component label;
1336:
1337: if (slider.getLabelTable() == null)
1338: return 0;
1339: Dimension pref;
1340: for (Enumeration list = slider.getLabelTable().elements();
1341: list.hasMoreElements();)
1342: {
1343: Object comp = list.nextElement();
1344: if (! (comp instanceof Component))
1345: continue;
1346: label = (Component) comp;
1347: pref = label.getPreferredSize();
1348: if (pref != null && pref.height > tallest)
1349: tallest = pref.height;
1350: }
1351: return tallest;
1352: }
1353:
1354:
1360: protected int getWidthOfHighValueLabel()
1361: {
1362: Component highValueLabel = getHighestValueLabel();
1363: if (highValueLabel != null)
1364: return highValueLabel.getWidth();
1365: else
1366: return 0;
1367: }
1368:
1369:
1375: protected int getWidthOfLowValueLabel()
1376: {
1377: Component lowValueLabel = getLowestValueLabel();
1378: if (lowValueLabel != null)
1379: return lowValueLabel.getWidth();
1380: else
1381: return 0;
1382: }
1383:
1384:
1390: protected int getHeightOfHighValueLabel()
1391: {
1392: Component highValueLabel = getHighestValueLabel();
1393: if (highValueLabel != null)
1394: return highValueLabel.getHeight();
1395: else
1396: return 0;
1397: }
1398:
1399:
1405: protected int getHeightOfLowValueLabel()
1406: {
1407: Component lowValueLabel = getLowestValueLabel();
1408: if (lowValueLabel != null)
1409: return lowValueLabel.getHeight();
1410: else
1411: return 0;
1412: }
1413:
1414:
1419: protected boolean drawInverted()
1420: {
1421: return ! (slider.getInverted() ^ leftToRightCache);
1422: }
1423:
1424:
1429: protected Component getLowestValueLabel()
1430: {
1431: Integer key = new Integer(Integer.MAX_VALUE);
1432: Integer tmpKey;
1433: Dictionary labelTable = slider.getLabelTable();
1434:
1435: if (labelTable == null)
1436: return null;
1437:
1438: for (Enumeration list = labelTable.keys(); list.hasMoreElements();)
1439: {
1440: Object value = list.nextElement();
1441: if (! (value instanceof Integer))
1442: continue;
1443: tmpKey = (Integer) value;
1444: if (tmpKey.intValue() < key.intValue())
1445: key = tmpKey;
1446: }
1447: Object comp = labelTable.get(key);
1448: if (! (comp instanceof Component))
1449: return null;
1450: return (Component) comp;
1451: }
1452:
1453:
1458: protected Component getHighestValueLabel()
1459: {
1460: Integer key = new Integer(Integer.MIN_VALUE);
1461: Integer tmpKey;
1462: Dictionary labelTable = slider.getLabelTable();
1463:
1464: if (labelTable == null)
1465: return null;
1466:
1467: for (Enumeration list = labelTable.keys(); list.hasMoreElements();)
1468: {
1469: Object value = list.nextElement();
1470: if (! (value instanceof Integer))
1471: continue;
1472: tmpKey = (Integer) value;
1473: if (tmpKey.intValue() > key.intValue())
1474: key = tmpKey;
1475: }
1476: Object comp = labelTable.get(key);
1477: if (! (comp instanceof Component))
1478: return null;
1479: return (Component) comp;
1480: }
1481:
1482:
1490: public void paint(Graphics g, JComponent c)
1491: {
1492:
1493: leftToRightCache = slider.getComponentOrientation() != ComponentOrientation.RIGHT_TO_LEFT;
1494:
1495: calculateGeometry();
1496:
1497: if (slider.getPaintTrack())
1498: paintTrack(g);
1499: if (slider.getPaintTicks())
1500: paintTicks(g);
1501: if (slider.getPaintLabels())
1502: paintLabels(g);
1503:
1504:
1505: paintThumb(g);
1506: }
1507:
1508:
1512: protected void recalculateIfInsetsChanged()
1513: {
1514:
1515:
1516: calculateFocusRect();
1517:
1518: calculateContentRect();
1519: calculateThumbSize();
1520: calculateTrackBuffer();
1521: calculateTrackRect();
1522: calculateThumbLocation();
1523:
1524: calculateTickRect();
1525: calculateLabelRect();
1526: }
1527:
1528:
1532: protected void recalculateIfOrientationChanged()
1533: {
1534:
1535:
1536: calculateThumbSize();
1537: calculateTrackBuffer();
1538: calculateTrackRect();
1539: calculateThumbLocation();
1540:
1541: calculateTickRect();
1542: calculateLabelRect();
1543: }
1544:
1545:
1552: public void paintFocus(Graphics g)
1553: {
1554: Color saved_color = g.getColor();
1555:
1556: g.setColor(getFocusColor());
1557:
1558: g.drawRect(focusRect.x, focusRect.y, focusRect.width, focusRect.height);
1559:
1560: g.setColor(saved_color);
1561: }
1562:
1563:
1589: public void paintTrack(Graphics g)
1590: {
1591: Color saved_color = g.getColor();
1592: int width;
1593: int height;
1594:
1595: Point a = new Point(trackRect.x, trackRect.y);
1596: Point b = new Point(a);
1597: Point c = new Point(a);
1598: Point d = new Point(a);
1599:
1600: if (slider.getOrientation() == JSlider.HORIZONTAL)
1601: {
1602: width = trackRect.width;
1603: height = (thumbRect.height / 4 == 0) ? 1 : thumbRect.height / 4;
1604:
1605: a.translate(0, (trackRect.height / 2) - (height / 2));
1606: b.translate(0, (trackRect.height / 2) + (height / 2));
1607: c.translate(trackRect.width, (trackRect.height / 2) + (height / 2));
1608: d.translate(trackRect.width, (trackRect.height / 2) - (height / 2));
1609: }
1610: else
1611: {
1612: width = (thumbRect.width / 4 == 0) ? 1 : thumbRect.width / 4;
1613: height = trackRect.height;
1614:
1615: a.translate((trackRect.width / 2) - (width / 2), 0);
1616: b.translate((trackRect.width / 2) - (width / 2), trackRect.height);
1617: c.translate((trackRect.width / 2) + (width / 2), trackRect.height);
1618: d.translate((trackRect.width / 2) + (width / 2), 0);
1619: }
1620: g.setColor(Color.GRAY);
1621: g.fillRect(a.x, a.y, width, height);
1622:
1623: g.setColor(getHighlightColor());
1624: g.drawLine(b.x, b.y, c.x, c.y);
1625: g.drawLine(c.x, c.y, d.x, d.y);
1626:
1627: g.setColor(getShadowColor());
1628: g.drawLine(b.x, b.y, a.x, a.y);
1629: g.drawLine(a.x, a.y, d.x, d.y);
1630:
1631: g.setColor(saved_color);
1632: }
1633:
1634:
1641: public void paintTicks(Graphics g)
1642: {
1643: int max = slider.getMaximum();
1644: int min = slider.getMinimum();
1645: int majorSpace = slider.getMajorTickSpacing();
1646: int minorSpace = slider.getMinorTickSpacing();
1647:
1648: if (majorSpace > 0)
1649: {
1650: if (slider.getOrientation() == JSlider.HORIZONTAL)
1651: {
1652: double loc = tickRect.x + 0.5;
1653: double increment = (max == min) ? 0
1654: : majorSpace * (double) (tickRect.width - 1) / (max - min);
1655: if (drawInverted())
1656: {
1657: loc += tickRect.width;
1658: increment *= -1;
1659: }
1660: g.translate(0, tickRect.y);
1661: for (int i = min; i <= max; i += majorSpace)
1662: {
1663: paintMajorTickForHorizSlider(g, tickRect, (int) loc);
1664: loc += increment;
1665: }
1666: g.translate(0, -tickRect.y);
1667: }
1668: else
1669: {
1670: double loc = tickRect.height + tickRect.y + 0.5;
1671: double increment = (max == min) ? 0
1672: : -majorSpace * (double) (tickRect.height - 1) / (max - min);
1673: if (drawInverted())
1674: {
1675: loc = tickRect.y + 0.5;
1676: increment *= -1;
1677: }
1678: g.translate(tickRect.x, 0);
1679: for (int i = min; i <= max; i += majorSpace)
1680: {
1681: paintMajorTickForVertSlider(g, tickRect, (int) loc);
1682: loc += increment;
1683: }
1684: g.translate(-tickRect.x, 0);
1685: }
1686: }
1687: if (minorSpace > 0)
1688: {
1689: if (slider.getOrientation() == JSlider.HORIZONTAL)
1690: {
1691: double loc = tickRect.x + 0.5;
1692: double increment = (max == min) ? 0
1693: : minorSpace * (double) (tickRect.width - 1) / (max - min);
1694: if (drawInverted())
1695: {
1696: loc += tickRect.width;
1697: increment *= -1;
1698: }
1699: g.translate(0, tickRect.y);
1700: for (int i = min; i <= max; i += minorSpace)
1701: {
1702: paintMinorTickForHorizSlider(g, tickRect, (int) loc);
1703: loc += increment;
1704: }
1705: g.translate(0, -tickRect.y);
1706: }
1707: else
1708: {
1709: double loc = tickRect.height + tickRect.y + 0.5;
1710: double increment = (max == min) ? 0
1711: : -minorSpace * (double) (tickRect.height - 1) / (max - min);
1712: if (drawInverted())
1713: {
1714: loc = tickRect.y + 0.5;
1715: increment *= -1;
1716: }
1717: g.translate(tickRect.x, 0);
1718: for (int i = min; i <= max; i += minorSpace)
1719: {
1720: paintMinorTickForVertSlider(g, tickRect, (int) loc);
1721: loc += increment;
1722: }
1723: g.translate(-tickRect.x, 0);
1724: }
1725: }
1726: }
1727:
1728:
1733:
1734:
1742: protected void paintMinorTickForHorizSlider(Graphics g,
1743: Rectangle tickBounds, int x)
1744: {
1745: int y = tickRect.height / 4;
1746: Color saved = g.getColor();
1747: g.setColor(Color.BLACK);
1748:
1749: g.drawLine(x, y, x, y + tickRect.height / 4);
1750: g.setColor(saved);
1751: }
1752:
1753:
1761: protected void paintMajorTickForHorizSlider(Graphics g,
1762: Rectangle tickBounds, int x)
1763: {
1764: int y = tickRect.height / 4;
1765: Color saved = g.getColor();
1766: g.setColor(Color.BLACK);
1767:
1768: g.drawLine(x, y, x, y + tickRect.height / 2);
1769: g.setColor(saved);
1770: }
1771:
1772:
1780: protected void paintMinorTickForVertSlider(Graphics g, Rectangle tickBounds,
1781: int y)
1782: {
1783: int x = tickRect.width / 4;
1784: Color saved = g.getColor();
1785: g.setColor(Color.BLACK);
1786:
1787: g.drawLine(x, y, x + tickRect.width / 4, y);
1788: g.setColor(saved);
1789: }
1790:
1791:
1799: protected void paintMajorTickForVertSlider(Graphics g, Rectangle tickBounds,
1800: int y)
1801: {
1802: int x = tickRect.width / 4;
1803: Color saved = g.getColor();
1804: g.setColor(Color.BLACK);
1805:
1806: g.drawLine(x, y, x + tickRect.width / 2, y);
1807: g.setColor(saved);
1808: }
1809:
1810:
1818: public void paintLabels(Graphics g)
1819: {
1820: if (slider.getLabelTable() != null)
1821: {
1822: Dictionary table = slider.getLabelTable();
1823: Integer tmpKey;
1824: Object key;
1825: Object element;
1826: Component label;
1827: if (slider.getOrientation() == JSlider.HORIZONTAL)
1828: {
1829: for (Enumeration list = table.keys(); list.hasMoreElements();)
1830: {
1831: key = list.nextElement();
1832: if (! (key instanceof Integer))
1833: continue;
1834: tmpKey = (Integer) key;
1835: element = table.get(tmpKey);
1836:
1837:
1838: if (! (element instanceof JLabel))
1839: continue;
1840: label = (Component) element;
1841: paintHorizontalLabel(g, tmpKey.intValue(), label);
1842: }
1843: }
1844: else
1845: {
1846: for (Enumeration list = table.keys(); list.hasMoreElements();)
1847: {
1848: key = list.nextElement();
1849: if (! (key instanceof Integer))
1850: continue;
1851: tmpKey = (Integer) key;
1852: element = table.get(tmpKey);
1853:
1854:
1855: if (! (element instanceof JLabel))
1856: continue;
1857: label = (Component) element;
1858: paintVerticalLabel(g, tmpKey.intValue(), label);
1859: }
1860: }
1861: }
1862: }
1863:
1864:
1875: protected void paintHorizontalLabel(Graphics g, int value, Component label)
1876: {
1877:
1878:
1879:
1880:
1881:
1882: Dimension dim = label.getPreferredSize();
1883: int w = (int) dim.getWidth();
1884: int h = (int) dim.getHeight();
1885:
1886: int max = slider.getMaximum();
1887: int min = slider.getMinimum();
1888:
1889: if (value > max || value < min)
1890: return;
1891:
1892:
1893:
1894:
1895:
1896:
1897:
1898:
1899: int xpos = xPositionForValue(value) - w / 2;
1900: int ypos = labelRect.y;
1901:
1902:
1903:
1904:
1905:
1906: if (xpos < 0)
1907: xpos = 0;
1908:
1909:
1910:
1911:
1912: if (xpos + w > labelRect.x + labelRect.width)
1913: w = labelRect.x + labelRect.width - xpos;
1914:
1915:
1916:
1917: if (h > labelRect.height)
1918: h = labelRect.height;
1919:
1920: label.setBounds(xpos, ypos, w, h);
1921: javax.swing.SwingUtilities.paintComponent(g, label, null, label.getBounds());
1922: }
1923:
1924:
1935: protected void paintVerticalLabel(Graphics g, int value, Component label)
1936: {
1937: Dimension dim = label.getPreferredSize();
1938: int w = (int) dim.getWidth();
1939: int h = (int) dim.getHeight();
1940:
1941: int max = slider.getMaximum();
1942: int min = slider.getMinimum();
1943:
1944: if (value > max || value < min)
1945: return;
1946:
1947: int xpos = labelRect.x;
1948: int ypos = yPositionForValue(value) - h / 2;
1949:
1950: if (ypos < 0)
1951: ypos = 0;
1952:
1953: if (ypos + h > labelRect.y + labelRect.height)
1954: h = labelRect.y + labelRect.height - ypos;
1955:
1956: if (w > labelRect.width)
1957: w = labelRect.width;
1958:
1959: label.setBounds(xpos, ypos, w, h);
1960: javax.swing.SwingUtilities.paintComponent(g, label, null, label.getBounds());
1961: }
1962:
1963:
1985: public void paintThumb(Graphics g)
1986: {
1987: Color saved_color = g.getColor();
1988:
1989: Point a = new Point(thumbRect.x, thumbRect.y);
1990: Point b = new Point(a);
1991: Point c = new Point(a);
1992: Point d = new Point(a);
1993: Point e = new Point(a);
1994:
1995: Polygon bright;
1996: Polygon light;
1997: Polygon dark;
1998: Polygon all;
1999:
2000:
2001: int turnPoint;
2002:
2003: if (slider.getOrientation() == JSlider.HORIZONTAL)
2004: {
2005: turnPoint = thumbRect.height * 3 / 4;
2006:
2007: b.translate(thumbRect.width - 1, 0);
2008: c.translate(thumbRect.width - 1, turnPoint);
2009: d.translate(thumbRect.width / 2 - 1, thumbRect.height - 1);
2010: e.translate(0, turnPoint);
2011:
2012: bright = new Polygon(new int[] { b.x - 1, a.x, e.x, d.x },
2013: new int[] { b.y, a.y, e.y, d.y }, 4);
2014:
2015: dark = new Polygon(new int[] { b.x, c.x, d.x + 1 },
2016: new int[] { b.y, c.y - 1, d.y }, 3);
2017:
2018: light = new Polygon(new int[] { b.x - 1, c.x - 1, d.x + 1 },
2019: new int[] { b.y + 1, c.y - 1, d.y - 1 }, 3);
2020:
2021: all = new Polygon(new int[] { a.x + 1, b.x - 2, c.x - 2, d.x, e.x + 1 },
2022: new int[] { a.y + 1, b.y + 1, c.y - 1, d.y - 1, e.y }, 5);
2023: }
2024: else
2025: {
2026: turnPoint = thumbRect.width * 3 / 4 - 1;
2027:
2028: b.translate(turnPoint, 0);
2029: c.translate(thumbRect.width - 1, thumbRect.height / 2);
2030: d.translate(turnPoint, thumbRect.height - 1);
2031: e.translate(0, thumbRect.height - 1);
2032:
2033: bright = new Polygon(new int[] { c.x - 1, b.x, a.x, e.x },
2034: new int[] { c.y - 1, b.y, a.y, e.y - 1 }, 4);
2035:
2036: dark = new Polygon(new int[] { c.x, d.x, e.x },
2037: new int[] { c.y, d.y, e.y }, 3);
2038:
2039: light = new Polygon(new int[] { c.x - 1, d.x, e.x + 1},
2040: new int[] { c.y, d.y - 1, e.y - 1}, 3);
2041: all = new Polygon(new int[] { a.x + 1, b.x, c.x - 2, c.x - 2, d.x, e.x + 1 },
2042: new int[] { a.y + 1, b.y + 1, c.y - 1, c.y, d.y - 2, e.y - 2 }, 6);
2043: }
2044:
2045: g.setColor(Color.WHITE);
2046: g.drawPolyline(bright.xpoints, bright.ypoints, bright.npoints);
2047:
2048: g.setColor(Color.BLACK);
2049: g.drawPolyline(dark.xpoints, dark.ypoints, dark.npoints);
2050:
2051: g.setColor(Color.GRAY);
2052: g.drawPolyline(light.xpoints, light.ypoints, light.npoints);
2053:
2054: g.setColor(Color.LIGHT_GRAY);
2055: g.drawPolyline(all.xpoints, all.ypoints, all.npoints);
2056: g.fillPolygon(all);
2057:
2058: g.setColor(saved_color);
2059: }
2060:
2061:
2067: public void setThumbLocation(int x, int y)
2068: {
2069: thumbRect.x = x;
2070: thumbRect.y = y;
2071: }
2072:
2073:
2080: public void scrollByBlock(int direction)
2081: {
2082:
2083: int unit = direction * (slider.getMaximum() - slider.getMinimum()) / 10;
2084:
2085: int moveTo = slider.getValue() + unit;
2086:
2087: if (slider.getSnapToTicks())
2088: moveTo = findClosestTick(moveTo);
2089:
2090: slider.setValue(moveTo);
2091: }
2092:
2093:
2100: public void scrollByUnit(int direction)
2101: {
2102:
2103: int moveTo = slider.getValue() + direction;
2104:
2105: if (slider.getSnapToTicks())
2106: moveTo = findClosestTick(moveTo);
2107:
2108: slider.setValue(moveTo);
2109: }
2110:
2111:
2118: protected void scrollDueToClickInTrack(int dir)
2119: {
2120: scrollTimer.stop();
2121:
2122: scrollListener.setDirection(dir);
2123: scrollListener.setScrollByBlock(true);
2124:
2125: scrollTimer.start();
2126: }
2127:
2128:
2135: protected int xPositionForValue(int value)
2136: {
2137: int min = slider.getMinimum();
2138: int max = slider.getMaximum();
2139: int len = trackRect.width - 1;
2140:
2141: int xPos = (max == min) ? 0 : (value - min) * len / (max - min);
2142:
2143: if (! drawInverted())
2144: xPos += trackRect.x;
2145: else
2146: {
2147: xPos = len - xPos;
2148: xPos += trackRect.x;
2149: }
2150: return xPos;
2151: }
2152:
2153:
2160: protected int yPositionForValue(int value)
2161: {
2162: int min = slider.getMinimum();
2163: int max = slider.getMaximum();
2164: int len = trackRect.height - 1;
2165:
2166: int yPos = (max == min) ? 0 : (value - min) * len / (max - min);
2167:
2168: if (! drawInverted())
2169: {
2170: yPos = len - yPos;
2171: yPos += trackRect.y;
2172: }
2173: else
2174: yPos += trackRect.y;
2175: return yPos;
2176: }
2177:
2178:
2187: public int valueForYPosition(int yPos)
2188: {
2189: int min = slider.getMinimum();
2190: int max = slider.getMaximum();
2191: int len = trackRect.height;
2192:
2193: int value;
2194:
2195:
2196:
2197:
2198: if (len == 0)
2199: return ((max - min) / 2);
2200:
2201: if (! drawInverted())
2202: value = ((len - (yPos - trackRect.y)) * (max - min) / len + min);
2203: else
2204: value = ((yPos - trackRect.y) * (max - min) / len + min);
2205:
2206:
2207: if (value > max)
2208: value = max;
2209: else if (value < min)
2210: value = min;
2211: return value;
2212: }
2213:
2214:
2223: public int valueForXPosition(int xPos)
2224: {
2225: int min = slider.getMinimum();
2226: int max = slider.getMaximum();
2227: int len = trackRect.width;
2228:
2229: int value;
2230:
2231:
2232:
2233:
2234: if (len == 0)
2235: return ((max - min) / 2);
2236:
2237: if (! drawInverted())
2238: value = ((xPos - trackRect.x) * (max - min) / len + min);
2239: else
2240: value = ((len - (xPos - trackRect.x)) * (max - min) / len + min);
2241:
2242:
2243: if (value > max)
2244: value = max;
2245: else if (value < min)
2246: value = min;
2247: return value;
2248: }
2249:
2250:
2258: int findClosestTick(int value)
2259: {
2260: int min = slider.getMinimum();
2261: int max = slider.getMaximum();
2262: int majorSpace = slider.getMajorTickSpacing();
2263: int minorSpace = slider.getMinorTickSpacing();
2264:
2265:
2266:
2267:
2268:
2269:
2270: int minor = min - value;
2271: int major = min - value;
2272:
2273:
2274:
2275:
2276: if (majorSpace <= 0 && minorSpace <= 0)
2277: return value;
2278:
2279:
2280: if (majorSpace > 0)
2281: {
2282: int lowerBound = (value - min) / majorSpace;
2283: int majLower = majorSpace * lowerBound + min;
2284: int majHigher = majorSpace * (lowerBound + 1) + min;
2285:
2286: if (majHigher <= max && majHigher - value <= value - majLower)
2287: major = majHigher - value;
2288: else
2289: major = majLower - value;
2290: }
2291:
2292: if (minorSpace > 0)
2293: {
2294: int lowerBound = value / minorSpace;
2295: int minLower = minorSpace * lowerBound;
2296: int minHigher = minorSpace * (lowerBound + 1);
2297:
2298: if (minHigher <= max && minHigher - value <= value - minLower)
2299: minor = minHigher - value;
2300: else
2301: minor = minLower - value;
2302: }
2303:
2304:
2305: if (Math.abs(minor) > Math.abs(major))
2306: return value + major;
2307: else
2308: return value + minor;
2309: }
2310: }