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:
77:
137: public class BasicSliderUI extends SliderUI
138: {
139:
146: public class ChangeHandler implements ChangeListener
147: {
148:
155: public void stateChanged(ChangeEvent e)
156: {
157:
158:
159:
160: calculateThumbLocation();
161: slider.repaint();
162: }
163: }
164:
165:
172: public class ComponentHandler extends ComponentAdapter
173: {
174:
181: public void componentResized(ComponentEvent e)
182: {
183: calculateGeometry();
184:
185: slider.revalidate();
186: slider.repaint();
187: }
188: }
189:
190:
197: public class FocusHandler implements FocusListener
198: {
199:
205: public void focusGained(FocusEvent e)
206: {
207:
208: }
209:
210:
216: public void focusLost(FocusEvent e)
217: {
218:
219: }
220: }
221:
222:
226: public class PropertyChangeHandler implements PropertyChangeListener
227: {
228:
234: public void propertyChange(PropertyChangeEvent e)
235: {
236:
237: if (e.getPropertyName().equals("orientation"))
238: recalculateIfOrientationChanged();
239: else if (e.getPropertyName().equals("model"))
240: {
241: BoundedRangeModel oldModel = (BoundedRangeModel) e.getOldValue();
242: oldModel.removeChangeListener(changeListener);
243: slider.getModel().addChangeListener(changeListener);
244: calculateThumbLocation();
245: }
246:
247:
248:
249:
250:
251:
252:
253: slider.repaint();
254: }
255: }
256:
257:
266: public class ScrollListener implements ActionListener
267: {
268:
269: private transient int direction;
270:
271:
272: private transient boolean block;
273:
274:
277: public ScrollListener()
278: {
279: direction = POSITIVE_SCROLL;
280: block = false;
281: }
282:
283:
289: public ScrollListener(int dir, boolean block)
290: {
291: direction = dir;
292: this.block = block;
293: }
294:
295:
302: public void actionPerformed(ActionEvent e)
303: {
304: if (! trackListener.shouldScroll(direction))
305: {
306: scrollTimer.stop();
307: return;
308: }
309:
310: if (block)
311: scrollByBlock(direction);
312: else
313: scrollByUnit(direction);
314: }
315:
316:
321: public void setDirection(int direction)
322: {
323: this.direction = direction;
324: }
325:
326:
331: public void setScrollByBlock(boolean block)
332: {
333: this.block = block;
334: }
335: }
336:
337:
344: public class TrackListener extends MouseInputAdapter
345: {
346:
347: protected int currentMouseX;
348:
349:
350: protected int currentMouseY;
351:
352:
355: protected int offset;
356:
357:
364: public void mouseDragged(MouseEvent e)
365: {
366: currentMouseX = e.getX();
367: currentMouseY = e.getY();
368: if (slider.getValueIsAdjusting())
369: {
370: int value;
371: if (slider.getOrientation() == JSlider.HORIZONTAL)
372: value = valueForXPosition(currentMouseX) - offset;
373: else
374: value = valueForYPosition(currentMouseY) - offset;
375:
376: slider.setValue(value);
377: }
378: }
379:
380:
386: public void mouseMoved(MouseEvent e)
387: {
388:
389: }
390:
391:
399: public void mousePressed(MouseEvent e)
400: {
401: currentMouseX = e.getX();
402: currentMouseY = e.getY();
403:
404: int value;
405: if (slider.getOrientation() == JSlider.HORIZONTAL)
406: value = valueForXPosition(currentMouseX);
407: else
408: value = valueForYPosition(currentMouseY);
409:
410: if (slider.getSnapToTicks())
411: value = findClosestTick(value);
412:
413:
414: if (! thumbRect.contains(e.getPoint()))
415: {
416:
417:
418: if (value > slider.getValue())
419: scrollDueToClickInTrack(POSITIVE_SCROLL);
420: else
421: scrollDueToClickInTrack(NEGATIVE_SCROLL);
422: }
423: else
424: {
425: slider.setValueIsAdjusting(true);
426: offset = value - slider.getValue();
427: }
428: }
429:
430:
436: public void mouseReleased(MouseEvent e)
437: {
438: currentMouseX = e.getX();
439: currentMouseY = e.getY();
440:
441: if (slider.getValueIsAdjusting())
442: {
443: slider.setValueIsAdjusting(false);
444: if (slider.getSnapToTicks())
445: slider.setValue(findClosestTick(slider.getValue()));
446: }
447: if (scrollTimer != null)
448: scrollTimer.stop();
449: }
450:
451:
458: public boolean shouldScroll(int direction)
459: {
460: int value;
461: if (slider.getOrientation() == JSlider.HORIZONTAL)
462: value = valueForXPosition(currentMouseX);
463: else
464: value = valueForYPosition(currentMouseY);
465:
466: if (direction == POSITIVE_SCROLL)
467: return (value > slider.getValue());
468: else
469: return (value < slider.getValue());
470: }
471: }
472:
473:
474: protected ChangeListener changeListener;
475:
476:
477: protected PropertyChangeListener propertyChangeListener;
478:
479:
480: protected ScrollListener scrollListener;
481:
482:
483: protected ComponentListener componentListener;
484:
485:
486: protected FocusListener focusListener;
487:
488:
489: protected TrackListener trackListener;
490:
491:
492: protected Insets focusInsets;
493:
494:
495: protected Insets insetCache;
496:
497:
498: protected Rectangle contentRect;
499:
500:
501: protected Rectangle focusRect;
502:
503:
504: protected Rectangle thumbRect;
505:
506:
507: protected Rectangle tickRect;
508:
509:
510: protected Rectangle labelRect;
511:
512:
513: protected Rectangle trackRect;
514:
515:
516: public static final int MAX_SCROLL = 2;
517:
518:
519: public static final int MIN_SCROLL = -2;
520:
521:
522: public static final int NEGATIVE_SCROLL = -1;
523:
524:
525: public static final int POSITIVE_SCROLL = 1;
526:
527:
528: protected int trackBuffer;
529:
530:
531: protected boolean leftToRightCache;
532:
533:
534: protected Timer scrollTimer;
535:
536:
537: protected JSlider slider;
538:
539:
540: private transient Color shadowColor;
541:
542:
543: private transient Color highlightColor;
544:
545:
546: private transient Color focusColor;
547:
548:
553: public BasicSliderUI(JSlider b)
554: {
555: super();
556: }
557:
558:
564: protected Color getShadowColor()
565: {
566: return shadowColor;
567: }
568:
569:
575: protected Color getHighlightColor()
576: {
577: return highlightColor;
578: }
579:
580:
587: protected Color getFocusColor()
588: {
589: return focusColor;
590: }
591:
592:
600: public static ComponentUI createUI(JComponent b)
601: {
602: return new BasicSliderUI((JSlider) b);
603: }
604:
605:
612: public void installUI(JComponent c)
613: {
614: super.installUI(c);
615: if (c instanceof JSlider)
616: {
617: slider = (JSlider) c;
618:
619: focusRect = new Rectangle();
620: contentRect = new Rectangle();
621: thumbRect = new Rectangle();
622: trackRect = new Rectangle();
623: tickRect = new Rectangle();
624: labelRect = new Rectangle();
625:
626: insetCache = slider.getInsets();
627: leftToRightCache = ! slider.getInverted();
628:
629: scrollTimer = new Timer(200, null);
630: scrollTimer.setRepeats(true);
631:
632: installDefaults(slider);
633: installListeners(slider);
634: installKeyboardActions(slider);
635:
636: calculateFocusRect();
637:
638: calculateContentRect();
639: calculateThumbSize();
640: calculateTrackBuffer();
641: calculateTrackRect();
642: calculateThumbLocation();
643:
644: calculateTickRect();
645: calculateLabelRect();
646: }
647: }
648:
649:
656: public void uninstallUI(JComponent c)
657: {
658: super.uninstallUI(c);
659:
660: uninstallKeyboardActions(slider);
661: uninstallListeners(slider);
662:
663: scrollTimer = null;
664:
665: focusRect = null;
666: contentRect = null;
667: thumbRect = null;
668: trackRect = null;
669: tickRect = null;
670: labelRect = null;
671:
672: focusInsets = null;
673: }
674:
675:
681: protected void installDefaults(JSlider slider)
682: {
683: UIDefaults defaults = UIManager.getLookAndFeelDefaults();
684:
685: slider.setForeground(defaults.getColor("Slider.foreground"));
686: slider.setBackground(defaults.getColor("Slider.background"));
687: shadowColor = defaults.getColor("Slider.shadow");
688: highlightColor = defaults.getColor("Slider.highlight");
689: focusColor = defaults.getColor("Slider.focus");
690: slider.setBorder(defaults.getBorder("Slider.border"));
691: slider.setOpaque(true);
692: focusInsets = defaults.getInsets("Slider.focusInsets");
693: }
694:
695:
703: protected TrackListener createTrackListener(JSlider slider)
704: {
705: return new TrackListener();
706: }
707:
708:
716: protected ChangeListener createChangeListener(JSlider slider)
717: {
718: return new ChangeHandler();
719: }
720:
721:
729: protected ComponentListener createComponentListener(JSlider slider)
730: {
731: return new ComponentHandler();
732: }
733:
734:
742: protected FocusListener createFocusListener(JSlider slider)
743: {
744: return new FocusHandler();
745: }
746:
747:
755: protected ScrollListener createScrollListener(JSlider slider)
756: {
757: return new ScrollListener();
758: }
759:
760:
768: protected PropertyChangeListener createPropertyChangeListener(JSlider slider)
769: {
770: return new PropertyChangeHandler();
771: }
772:
773:
779: protected void installListeners(JSlider slider)
780: {
781: propertyChangeListener = createPropertyChangeListener(slider);
782: componentListener = createComponentListener(slider);
783: trackListener = createTrackListener(slider);
784: focusListener = createFocusListener(slider);
785: changeListener = createChangeListener(slider);
786: scrollListener = createScrollListener(slider);
787:
788: slider.addPropertyChangeListener(propertyChangeListener);
789: slider.addComponentListener(componentListener);
790: slider.addMouseListener(trackListener);
791: slider.addMouseMotionListener(trackListener);
792: slider.addFocusListener(focusListener);
793: slider.getModel().addChangeListener(changeListener);
794:
795: scrollTimer.addActionListener(scrollListener);
796: }
797:
798:
804: protected void uninstallListeners(JSlider slider)
805: {
806: slider.removePropertyChangeListener(propertyChangeListener);
807: slider.removeComponentListener(componentListener);
808: slider.removeMouseListener(trackListener);
809: slider.removeMouseMotionListener(trackListener);
810: slider.removeFocusListener(focusListener);
811: slider.getModel().removeChangeListener(changeListener);
812:
813: scrollTimer.removeActionListener(scrollListener);
814:
815: propertyChangeListener = null;
816: componentListener = null;
817: trackListener = null;
818: focusListener = null;
819: changeListener = null;
820: scrollListener = null;
821: }
822:
823:
830: protected void installKeyboardActions(JSlider slider)
831: {
832:
833: }
834:
835:
842: protected void uninstallKeyboardActions(JSlider slider)
843: {
844:
845: }
846:
847:
861:
862:
868: public Dimension getPreferredHorizontalSize()
869: {
870: Insets insets = slider.getInsets();
871:
872:
873:
874: int width = getWidthOfWidestLabel() * (slider.getLabelTable() == null ? 0
875: : slider.getLabelTable()
876: .size());
877:
878:
879:
880: if (width < 200)
881: width = 200;
882:
883:
884:
885: width += insets.left + insets.right + focusInsets.left + focusInsets.right;
886:
887:
888: int height = getThumbSize().height;
889:
890: if (slider.getPaintTicks() && slider.getMajorTickSpacing() > 0
891: || slider.getMinorTickSpacing() > 0)
892: height += getTickLength();
893:
894: if (slider.getPaintLabels())
895: height += getHeightOfTallestLabel();
896:
897: height += insets.top + insets.bottom + focusInsets.top
898: + focusInsets.bottom;
899:
900: return new Dimension(width, height);
901: }
902:
903:
909: public Dimension getPreferredVerticalSize()
910: {
911: Insets insets = slider.getInsets();
912:
913: int height = getHeightOfTallestLabel() * (slider.getLabelTable() == null
914: ? 0 : slider.getLabelTable()
915: .size());
916:
917: if (height < 200)
918: height = 200;
919:
920: height += insets.top + insets.bottom + focusInsets.top
921: + focusInsets.bottom;
922:
923: int width = getThumbSize().width;
924:
925: if (slider.getPaintTicks() && slider.getMajorTickSpacing() > 0
926: || slider.getMinorTickSpacing() > 0)
927: width += getTickLength();
928:
929: if (slider.getPaintLabels())
930: width += getWidthOfWidestLabel();
931:
932: width += insets.left + insets.right + focusInsets.left + focusInsets.right;
933:
934: return new Dimension(width, height);
935: }
936:
937:
943: public Dimension getMinimumHorizontalSize()
944: {
945: Insets insets = slider.getInsets();
946:
947: int height = getThumbSize().height;
948:
949: if (slider.getPaintTicks() && slider.getMajorTickSpacing() > 0
950: || slider.getMinorTickSpacing() > 0)
951: height += getTickLength();
952:
953: if (slider.getPaintLabels())
954: height += getHeightOfTallestLabel();
955:
956: height += insets.top + insets.bottom + focusInsets.top
957: + focusInsets.bottom;
958:
959: return new Dimension(36, height);
960: }
961:
962:
968: public Dimension getMinimumVerticalSize()
969: {
970: Insets insets = slider.getInsets();
971: int width = getThumbSize().width;
972:
973: if (slider.getPaintTicks() && slider.getMajorTickSpacing() > 0
974: || slider.getMinorTickSpacing() > 0)
975: width += getTickLength();
976:
977: if (slider.getPaintLabels())
978: width += getWidthOfWidestLabel();
979:
980: width += insets.left + insets.right + focusInsets.left + focusInsets.right;
981:
982: return new Dimension(width, 36);
983: }
984:
985:
994: public Dimension getPreferredSize(JComponent c)
995: {
996: if (slider.getOrientation() == JSlider.HORIZONTAL)
997: return getPreferredHorizontalSize();
998: else
999: return getPreferredVerticalSize();
1000: }
1001:
1002:
1011: public Dimension getMinimumSize(JComponent c)
1012: {
1013: if (slider.getOrientation() == JSlider.HORIZONTAL)
1014: return getMinimumHorizontalSize();
1015: else
1016: return getMinimumVerticalSize();
1017: }
1018:
1019:
1027: public Dimension getMaximumSize(JComponent c)
1028: {
1029: Insets insets = slider.getInsets();
1030: if (slider.getOrientation() == JSlider.HORIZONTAL)
1031: {
1032:
1033: int height = getThumbSize().height;
1034:
1035: if (slider.getPaintTicks() && slider.getMajorTickSpacing() > 0
1036: || slider.getMinorTickSpacing() > 0)
1037: height += getTickLength();
1038:
1039: if (slider.getPaintLabels())
1040: height += getHeightOfTallestLabel();
1041:
1042: height += insets.top + insets.bottom + focusInsets.top
1043: + focusInsets.bottom;
1044:
1045: return new Dimension(32767, height);
1046: }
1047: else
1048: {
1049: int width = getThumbSize().width;
1050:
1051: if (slider.getPaintTicks() && slider.getMajorTickSpacing() > 0
1052: || slider.getMinorTickSpacing() > 0)
1053: width += getTickLength();
1054:
1055: if (slider.getPaintLabels())
1056: width += getWidthOfWidestLabel();
1057:
1058: width += insets.left + insets.right + focusInsets.left
1059: + focusInsets.right;
1060:
1061: return new Dimension(width, 32767);
1062: }
1063: }
1064:
1065:
1069: protected void calculateGeometry()
1070: {
1071: calculateFocusRect();
1072: calculateContentRect();
1073: calculateThumbSize();
1074: calculateTrackBuffer();
1075: calculateTrackRect();
1076: calculateTickRect();
1077: calculateLabelRect();
1078: calculateThumbLocation();
1079: }
1080:
1081:
1085: protected void calculateFocusRect()
1086: {
1087: insetCache = slider.getInsets();
1088: focusRect = SwingUtilities.calculateInnerArea(slider, focusRect);
1089: if (focusRect.width < 0)
1090: focusRect.width = 0;
1091: if (focusRect.height < 0)
1092: focusRect.height = 0;
1093: }
1094:
1095:
1099: protected void calculateThumbSize()
1100: {
1101: Dimension d = getThumbSize();
1102: thumbRect.width = d.width;
1103: thumbRect.height = d.height;
1104: if (slider.getOrientation() == JSlider.HORIZONTAL)
1105: thumbRect.y = trackRect.y;
1106: else
1107: thumbRect.x = trackRect.x;
1108: }
1109:
1110:
1114: protected void calculateContentRect()
1115: {
1116: contentRect.x = focusRect.x + focusInsets.left;
1117: contentRect.y = focusRect.y + focusInsets.top;
1118:
1119: contentRect.width = focusRect.width - focusInsets.left - focusInsets.right;
1120: contentRect.height = focusRect.height - focusInsets.top
1121: - focusInsets.bottom;
1122:
1123: if (contentRect.width < 0)
1124: contentRect.width = 0;
1125: if (contentRect.height < 0)
1126: contentRect.height = 0;
1127: }
1128:
1129:
1133: protected void calculateThumbLocation()
1134: {
1135: int value = slider.getValue();
1136:
1137: if (slider.getOrientation() == JSlider.HORIZONTAL)
1138: {
1139: thumbRect.x = xPositionForValue(value) - thumbRect.width / 2;
1140: thumbRect.y = trackRect.y;
1141: }
1142: else
1143: {
1144: thumbRect.x = trackRect.x;
1145: thumbRect.y = yPositionForValue(value) - thumbRect.height / 2;
1146: }
1147: }
1148:
1149:
1153: protected void calculateTrackBuffer()
1154: {
1155: if (slider.getOrientation() == JSlider.HORIZONTAL)
1156: trackBuffer = thumbRect.width / 2;
1157: else
1158: trackBuffer = thumbRect.height / 2;
1159: }
1160:
1161:
1166: protected Dimension getThumbSize()
1167: {
1168:
1169: if (slider.getOrientation() == JSlider.HORIZONTAL)
1170: return new Dimension(11, 20);
1171: else
1172: return new Dimension(20, 11);
1173: }
1174:
1175:
1179: protected void calculateTrackRect()
1180: {
1181: if (slider.getOrientation() == JSlider.HORIZONTAL)
1182: {
1183: trackRect.x = contentRect.x + trackBuffer;
1184: int h = getThumbSize().height;
1185: if (slider.getPaintTicks() && (slider.getMajorTickSpacing() > 0
1186: || slider.getMinorTickSpacing() > 0))
1187: h += getTickLength();
1188: trackRect.y = contentRect.y + (contentRect.height - h) / 2 - 1;
1189: trackRect.width = contentRect.width - 2 * trackBuffer;
1190: trackRect.height = thumbRect.height;
1191: }
1192: else
1193: {
1194: int w = getThumbSize().width;
1195: if (slider.getPaintTicks() && (slider.getMajorTickSpacing() > 0
1196: || slider.getMinorTickSpacing() > 0))
1197: w += getTickLength();
1198: trackRect.x = contentRect.x + (contentRect.width - w) / 2 - 1;
1199: trackRect.y = contentRect.y + trackBuffer;
1200: trackRect.width = thumbRect.width;
1201: trackRect.height = contentRect.height - 2 * trackBuffer;
1202: }
1203: }
1204:
1205:
1215: protected int getTickLength()
1216: {
1217: return 8;
1218: }
1219:
1220:
1224: protected void calculateTickRect()
1225: {
1226: if (slider.getOrientation() == JSlider.HORIZONTAL)
1227: {
1228: tickRect.x = trackRect.x;
1229: tickRect.y = trackRect.y + trackRect.height;
1230: tickRect.width = trackRect.width;
1231: tickRect.height = getTickLength();
1232:
1233: if (tickRect.y + tickRect.height > contentRect.y + contentRect.height)
1234: tickRect.height = contentRect.y + contentRect.height - tickRect.y;
1235: }
1236: else
1237: {
1238: tickRect.x = trackRect.x + trackRect.width;
1239: tickRect.y = trackRect.y;
1240: tickRect.width = getTickLength();
1241: tickRect.height = trackRect.height;
1242:
1243: if (tickRect.x + tickRect.width > contentRect.x + contentRect.width)
1244: tickRect.width = contentRect.x + contentRect.width - tickRect.x;
1245: }
1246: }
1247:
1248:
1252: protected void calculateLabelRect()
1253: {
1254: if (slider.getOrientation() == JSlider.HORIZONTAL)
1255: {
1256: labelRect.x = contentRect.x;
1257: labelRect.y = tickRect.y + tickRect.height;
1258: labelRect.width = contentRect.width;
1259: labelRect.height = contentRect.height - labelRect.y;
1260: }
1261: else
1262: {
1263: labelRect.x = tickRect.x + tickRect.width;
1264: labelRect.y = contentRect.y;
1265: labelRect.width = contentRect.width - labelRect.x;
1266: labelRect.height = contentRect.height;
1267: }
1268: }
1269:
1270:
1276: protected int getWidthOfWidestLabel()
1277: {
1278: int widest = 0;
1279: Component label;
1280:
1281: if (slider.getLabelTable() == null)
1282: return 0;
1283:
1284: Dimension pref;
1285: for (Enumeration list = slider.getLabelTable().elements();
1286: list.hasMoreElements();)
1287: {
1288: Object comp = list.nextElement();
1289: if (! (comp instanceof Component))
1290: continue;
1291: label = (Component) comp;
1292: pref = label.getPreferredSize();
1293: if (pref != null && pref.width > widest)
1294: widest = pref.width;
1295: }
1296: return widest;
1297: }
1298:
1299:
1305: protected int getHeightOfTallestLabel()
1306: {
1307: int tallest = 0;
1308: Component label;
1309:
1310: if (slider.getLabelTable() == null)
1311: return 0;
1312: Dimension pref;
1313: for (Enumeration list = slider.getLabelTable().elements();
1314: list.hasMoreElements();)
1315: {
1316: Object comp = list.nextElement();
1317: if (! (comp instanceof Component))
1318: continue;
1319: label = (Component) comp;
1320: pref = label.getPreferredSize();
1321: if (pref != null && pref.height > tallest)
1322: tallest = pref.height;
1323: }
1324: return tallest;
1325: }
1326:
1327:
1333: protected int getWidthOfHighValueLabel()
1334: {
1335: Component highValueLabel = getHighestValueLabel();
1336: if (highValueLabel != null)
1337: return highValueLabel.getWidth();
1338: else
1339: return 0;
1340: }
1341:
1342:
1348: protected int getWidthOfLowValueLabel()
1349: {
1350: Component lowValueLabel = getLowestValueLabel();
1351: if (lowValueLabel != null)
1352: return lowValueLabel.getWidth();
1353: else
1354: return 0;
1355: }
1356:
1357:
1363: protected int getHeightOfHighValueLabel()
1364: {
1365: Component highValueLabel = getHighestValueLabel();
1366: if (highValueLabel != null)
1367: return highValueLabel.getHeight();
1368: else
1369: return 0;
1370: }
1371:
1372:
1378: protected int getHeightOfLowValueLabel()
1379: {
1380: Component lowValueLabel = getLowestValueLabel();
1381: if (lowValueLabel != null)
1382: return lowValueLabel.getHeight();
1383: else
1384: return 0;
1385: }
1386:
1387:
1392: protected boolean drawInverted()
1393: {
1394: return ! (slider.getInverted() ^ leftToRightCache);
1395: }
1396:
1397:
1402: protected Component getLowestValueLabel()
1403: {
1404: Integer key = new Integer(Integer.MAX_VALUE);
1405: Integer tmpKey;
1406: Dictionary labelTable = slider.getLabelTable();
1407:
1408: if (labelTable == null)
1409: return null;
1410:
1411: for (Enumeration list = labelTable.keys(); list.hasMoreElements();)
1412: {
1413: Object value = list.nextElement();
1414: if (! (value instanceof Integer))
1415: continue;
1416: tmpKey = (Integer) value;
1417: if (tmpKey.intValue() < key.intValue())
1418: key = tmpKey;
1419: }
1420: Object comp = labelTable.get(key);
1421: if (! (comp instanceof Component))
1422: return null;
1423: return (Component) comp;
1424: }
1425:
1426:
1431: protected Component getHighestValueLabel()
1432: {
1433: Integer key = new Integer(Integer.MIN_VALUE);
1434: Integer tmpKey;
1435: Dictionary labelTable = slider.getLabelTable();
1436:
1437: if (labelTable == null)
1438: return null;
1439:
1440: for (Enumeration list = labelTable.keys(); list.hasMoreElements();)
1441: {
1442: Object value = list.nextElement();
1443: if (! (value instanceof Integer))
1444: continue;
1445: tmpKey = (Integer) value;
1446: if (tmpKey.intValue() > key.intValue())
1447: key = tmpKey;
1448: }
1449: Object comp = labelTable.get(key);
1450: if (! (comp instanceof Component))
1451: return null;
1452: return (Component) comp;
1453: }
1454:
1455:
1463: public void paint(Graphics g, JComponent c)
1464: {
1465:
1466: leftToRightCache = slider.getComponentOrientation() != ComponentOrientation.RIGHT_TO_LEFT;
1467:
1468: calculateThumbLocation();
1469:
1470: if (slider.getPaintTrack())
1471: paintTrack(g);
1472: if (slider.getPaintTicks())
1473: paintTicks(g);
1474: if (slider.getPaintLabels())
1475: paintLabels(g);
1476:
1477:
1478: paintThumb(g);
1479: }
1480:
1481:
1485: protected void recalculateIfInsetsChanged()
1486: {
1487:
1488:
1489: calculateFocusRect();
1490:
1491: calculateContentRect();
1492: calculateThumbSize();
1493: calculateTrackBuffer();
1494: calculateTrackRect();
1495: calculateThumbLocation();
1496:
1497: calculateTickRect();
1498: calculateLabelRect();
1499: }
1500:
1501:
1505: protected void recalculateIfOrientationChanged()
1506: {
1507:
1508:
1509: calculateThumbSize();
1510: calculateTrackBuffer();
1511: calculateTrackRect();
1512: calculateThumbLocation();
1513:
1514: calculateTickRect();
1515: calculateLabelRect();
1516: }
1517:
1518:
1525: public void paintFocus(Graphics g)
1526: {
1527: Color saved_color = g.getColor();
1528:
1529: g.setColor(getFocusColor());
1530:
1531: g.drawRect(focusRect.x, focusRect.y, focusRect.width, focusRect.height);
1532:
1533: g.setColor(saved_color);
1534: }
1535:
1536:
1562: public void paintTrack(Graphics g)
1563: {
1564: Color saved_color = g.getColor();
1565: int width;
1566: int height;
1567:
1568: Point a = new Point(trackRect.x, trackRect.y);
1569: Point b = new Point(a);
1570: Point c = new Point(a);
1571: Point d = new Point(a);
1572:
1573: if (slider.getOrientation() == JSlider.HORIZONTAL)
1574: {
1575: width = trackRect.width;
1576: height = (thumbRect.height / 4 == 0) ? 1 : thumbRect.height / 4;
1577:
1578: a.translate(0, (trackRect.height / 2) - (height / 2));
1579: b.translate(0, (trackRect.height / 2) + (height / 2));
1580: c.translate(trackRect.width, (trackRect.height / 2) + (height / 2));
1581: d.translate(trackRect.width, (trackRect.height / 2) - (height / 2));
1582: }
1583: else
1584: {
1585: width = (thumbRect.width / 4 == 0) ? 1 : thumbRect.width / 4;
1586: height = trackRect.height;
1587:
1588: a.translate((trackRect.width / 2) - (width / 2), 0);
1589: b.translate((trackRect.width / 2) - (width / 2), trackRect.height);
1590: c.translate((trackRect.width / 2) + (width / 2), trackRect.height);
1591: d.translate((trackRect.width / 2) + (width / 2), 0);
1592: }
1593: g.setColor(Color.GRAY);
1594: g.fillRect(a.x, a.y, width, height);
1595:
1596: g.setColor(getHighlightColor());
1597: g.drawLine(b.x, b.y, c.x, c.y);
1598: g.drawLine(c.x, c.y, d.x, d.y);
1599:
1600: g.setColor(getShadowColor());
1601: g.drawLine(b.x, b.y, a.x, a.y);
1602: g.drawLine(a.x, a.y, d.x, d.y);
1603:
1604: g.setColor(saved_color);
1605: }
1606:
1607:
1614: public void paintTicks(Graphics g)
1615: {
1616: int max = slider.getMaximum();
1617: int min = slider.getMinimum();
1618: int majorSpace = slider.getMajorTickSpacing();
1619: int minorSpace = slider.getMinorTickSpacing();
1620:
1621: if (majorSpace > 0)
1622: {
1623: if (slider.getOrientation() == JSlider.HORIZONTAL)
1624: {
1625: double loc = tickRect.x + 0.5;
1626: double increment = (max == min) ? 0
1627: : majorSpace * (double) (tickRect.width - 1) / (max - min);
1628: if (drawInverted())
1629: {
1630: loc += tickRect.width;
1631: increment *= -1;
1632: }
1633: g.translate(0, tickRect.y);
1634: for (int i = min; i <= max; i += majorSpace)
1635: {
1636: paintMajorTickForHorizSlider(g, tickRect, (int) loc);
1637: loc += increment;
1638: }
1639: g.translate(0, -tickRect.y);
1640: }
1641: else
1642: {
1643: double loc = tickRect.height + tickRect.y + 0.5;
1644: double increment = (max == min) ? 0
1645: : -majorSpace * (double) (tickRect.height - 1) / (max - min);
1646: if (drawInverted())
1647: {
1648: loc = tickRect.y + 0.5;
1649: increment *= -1;
1650: }
1651: g.translate(tickRect.x, 0);
1652: for (int i = min; i <= max; i += majorSpace)
1653: {
1654: paintMajorTickForVertSlider(g, tickRect, (int) loc);
1655: loc += increment;
1656: }
1657: g.translate(-tickRect.x, 0);
1658: }
1659: }
1660: if (minorSpace > 0)
1661: {
1662: if (slider.getOrientation() == JSlider.HORIZONTAL)
1663: {
1664: double loc = tickRect.x + 0.5;
1665: double increment = (max == min) ? 0
1666: : minorSpace * (double) (tickRect.width - 1) / (max - min);
1667: if (drawInverted())
1668: {
1669: loc += tickRect.width;
1670: increment *= -1;
1671: }
1672: g.translate(0, tickRect.y);
1673: for (int i = min; i <= max; i += minorSpace)
1674: {
1675: paintMinorTickForHorizSlider(g, tickRect, (int) loc);
1676: loc += increment;
1677: }
1678: g.translate(0, -tickRect.y);
1679: }
1680: else
1681: {
1682: double loc = tickRect.height + tickRect.y + 0.5;
1683: double increment = (max == min) ? 0
1684: : -minorSpace * (double) (tickRect.height - 1) / (max - min);
1685: if (drawInverted())
1686: {
1687: loc = tickRect.y + 0.5;
1688: increment *= -1;
1689: }
1690: g.translate(tickRect.x, 0);
1691: for (int i = min; i <= max; i += minorSpace)
1692: {
1693: paintMinorTickForVertSlider(g, tickRect, (int) loc);
1694: loc += increment;
1695: }
1696: g.translate(-tickRect.x, 0);
1697: }
1698: }
1699: }
1700:
1701:
1706:
1707:
1715: protected void paintMinorTickForHorizSlider(Graphics g,
1716: Rectangle tickBounds, int x)
1717: {
1718: int y = tickRect.height / 4;
1719: Color saved = g.getColor();
1720: g.setColor(Color.BLACK);
1721:
1722: g.drawLine(x, y, x, y + tickRect.height / 4);
1723: g.setColor(saved);
1724: }
1725:
1726:
1734: protected void paintMajorTickForHorizSlider(Graphics g,
1735: Rectangle tickBounds, int x)
1736: {
1737: int y = tickRect.height / 4;
1738: Color saved = g.getColor();
1739: g.setColor(Color.BLACK);
1740:
1741: g.drawLine(x, y, x, y + tickRect.height / 2);
1742: g.setColor(saved);
1743: }
1744:
1745:
1753: protected void paintMinorTickForVertSlider(Graphics g, Rectangle tickBounds,
1754: int y)
1755: {
1756: int x = tickRect.width / 4;
1757: Color saved = g.getColor();
1758: g.setColor(Color.BLACK);
1759:
1760: g.drawLine(x, y, x + tickRect.width / 4, y);
1761: g.setColor(saved);
1762: }
1763:
1764:
1772: protected void paintMajorTickForVertSlider(Graphics g, Rectangle tickBounds,
1773: int y)
1774: {
1775: int x = tickRect.width / 4;
1776: Color saved = g.getColor();
1777: g.setColor(Color.BLACK);
1778:
1779: g.drawLine(x, y, x + tickRect.width / 2, y);
1780: g.setColor(saved);
1781: }
1782:
1783:
1791: public void paintLabels(Graphics g)
1792: {
1793: if (slider.getLabelTable() != null)
1794: {
1795: Dictionary table = slider.getLabelTable();
1796: Integer tmpKey;
1797: Object key;
1798: Object element;
1799: Component label;
1800: if (slider.getOrientation() == JSlider.HORIZONTAL)
1801: {
1802: for (Enumeration list = table.keys(); list.hasMoreElements();)
1803: {
1804: key = list.nextElement();
1805: if (! (key instanceof Integer))
1806: continue;
1807: tmpKey = (Integer) key;
1808: element = table.get(tmpKey);
1809:
1810:
1811: if (! (element instanceof JLabel))
1812: continue;
1813: label = (Component) element;
1814: paintHorizontalLabel(g, tmpKey.intValue(), label);
1815: }
1816: }
1817: else
1818: {
1819: for (Enumeration list = table.keys(); list.hasMoreElements();)
1820: {
1821: key = list.nextElement();
1822: if (! (key instanceof Integer))
1823: continue;
1824: tmpKey = (Integer) key;
1825: element = table.get(tmpKey);
1826:
1827:
1828: if (! (element instanceof JLabel))
1829: continue;
1830: label = (Component) element;
1831: paintVerticalLabel(g, tmpKey.intValue(), label);
1832: }
1833: }
1834: }
1835: }
1836:
1837:
1848: protected void paintHorizontalLabel(Graphics g, int value, Component label)
1849: {
1850:
1851:
1852:
1853:
1854:
1855: Dimension dim = label.getPreferredSize();
1856: int w = (int) dim.getWidth();
1857: int h = (int) dim.getHeight();
1858:
1859: int max = slider.getMaximum();
1860: int min = slider.getMinimum();
1861:
1862: if (value > max || value < min)
1863: return;
1864:
1865:
1866:
1867:
1868:
1869:
1870:
1871:
1872: int xpos = xPositionForValue(value) - w / 2;
1873: int ypos = labelRect.y;
1874:
1875:
1876:
1877:
1878:
1879: if (xpos < 0)
1880: xpos = 0;
1881:
1882:
1883:
1884:
1885: if (xpos + w > labelRect.x + labelRect.width)
1886: w = labelRect.x + labelRect.width - xpos;
1887:
1888:
1889:
1890: if (h > labelRect.height)
1891: h = labelRect.height;
1892:
1893: label.setBounds(xpos, ypos, w, h);
1894: javax.swing.SwingUtilities.paintComponent(g, label, null, label.getBounds());
1895: }
1896:
1897:
1908: protected void paintVerticalLabel(Graphics g, int value, Component label)
1909: {
1910: Dimension dim = label.getPreferredSize();
1911: int w = (int) dim.getWidth();
1912: int h = (int) dim.getHeight();
1913:
1914: int max = slider.getMaximum();
1915: int min = slider.getMinimum();
1916:
1917: if (value > max || value < min)
1918: return;
1919:
1920: int xpos = labelRect.x;
1921: int ypos = yPositionForValue(value) - h / 2;
1922:
1923: if (ypos < 0)
1924: ypos = 0;
1925:
1926: if (ypos + h > labelRect.y + labelRect.height)
1927: h = labelRect.y + labelRect.height - ypos;
1928:
1929: if (w > labelRect.width)
1930: w = labelRect.width;
1931:
1932: label.setBounds(xpos, ypos, w, h);
1933: javax.swing.SwingUtilities.paintComponent(g, label, null, label.getBounds());
1934: }
1935:
1936:
1958: public void paintThumb(Graphics g)
1959: {
1960: Color saved_color = g.getColor();
1961:
1962: Point a = new Point(thumbRect.x, thumbRect.y);
1963: Point b = new Point(a);
1964: Point c = new Point(a);
1965: Point d = new Point(a);
1966: Point e = new Point(a);
1967:
1968: Polygon bright;
1969: Polygon light;
1970: Polygon dark;
1971: Polygon all;
1972:
1973:
1974: int turnPoint;
1975:
1976: if (slider.getOrientation() == JSlider.HORIZONTAL)
1977: {
1978: turnPoint = thumbRect.height * 3 / 4;
1979:
1980: b.translate(thumbRect.width - 1, 0);
1981: c.translate(thumbRect.width - 1, turnPoint);
1982: d.translate(thumbRect.width / 2 - 1, thumbRect.height - 1);
1983: e.translate(0, turnPoint);
1984:
1985: bright = new Polygon(new int[] { b.x - 1, a.x, e.x, d.x },
1986: new int[] { b.y, a.y, e.y, d.y }, 4);
1987:
1988: dark = new Polygon(new int[] { b.x, c.x, d.x + 1 },
1989: new int[] { b.y, c.y - 1, d.y }, 3);
1990:
1991: light = new Polygon(new int[] { b.x - 1, c.x - 1, d.x + 1 },
1992: new int[] { b.y + 1, c.y - 1, d.y - 1 }, 3);
1993:
1994: all = new Polygon(new int[] { a.x + 1, b.x - 2, c.x - 2, d.x, e.x + 1 },
1995: new int[] { a.y + 1, b.y + 1, c.y - 1, d.y - 1, e.y }, 5);
1996: }
1997: else
1998: {
1999: turnPoint = thumbRect.width * 3 / 4 - 1;
2000:
2001: b.translate(turnPoint, 0);
2002: c.translate(thumbRect.width - 1, thumbRect.height / 2);
2003: d.translate(turnPoint, thumbRect.height - 1);
2004: e.translate(0, thumbRect.height - 1);
2005:
2006: bright = new Polygon(new int[] { c.x - 1, b.x, a.x, e.x },
2007: new int[] { c.y - 1, b.y, a.y, e.y - 1 }, 4);
2008:
2009: dark = new Polygon(new int[] { c.x, d.x, e.x },
2010: new int[] { c.y, d.y, e.y }, 3);
2011:
2012: light = new Polygon(new int[] { c.x - 1, d.x, e.x + 1},
2013: new int[] { c.y, d.y - 1, e.y - 1}, 3);
2014: all = new Polygon(new int[] { a.x + 1, b.x, c.x - 2, c.x - 2, d.x, e.x + 1 },
2015: new int[] { a.y + 1, b.y + 1, c.y - 1, c.y, d.y - 2, e.y - 2 }, 6);
2016: }
2017:
2018: g.setColor(Color.WHITE);
2019: g.drawPolyline(bright.xpoints, bright.ypoints, bright.npoints);
2020:
2021: g.setColor(Color.BLACK);
2022: g.drawPolyline(dark.xpoints, dark.ypoints, dark.npoints);
2023:
2024: g.setColor(Color.GRAY);
2025: g.drawPolyline(light.xpoints, light.ypoints, light.npoints);
2026:
2027: g.setColor(Color.LIGHT_GRAY);
2028: g.drawPolyline(all.xpoints, all.ypoints, all.npoints);
2029: g.fillPolygon(all);
2030:
2031: g.setColor(saved_color);
2032: }
2033:
2034:
2040: public void setThumbLocation(int x, int y)
2041: {
2042: thumbRect.x = x;
2043: thumbRect.y = y;
2044: }
2045:
2046:
2053: public void scrollByBlock(int direction)
2054: {
2055:
2056: int unit = direction * (slider.getMaximum() - slider.getMinimum()) / 10;
2057:
2058: int moveTo = slider.getValue() + unit;
2059:
2060: if (slider.getSnapToTicks())
2061: moveTo = findClosestTick(moveTo);
2062:
2063: slider.setValue(moveTo);
2064: }
2065:
2066:
2073: public void scrollByUnit(int direction)
2074: {
2075:
2076: int moveTo = slider.getValue() + direction;
2077:
2078: if (slider.getSnapToTicks())
2079: moveTo = findClosestTick(moveTo);
2080:
2081: slider.setValue(moveTo);
2082: }
2083:
2084:
2091: protected void scrollDueToClickInTrack(int dir)
2092: {
2093: scrollTimer.stop();
2094:
2095: scrollListener.setDirection(dir);
2096: scrollListener.setScrollByBlock(true);
2097:
2098: scrollTimer.start();
2099: }
2100:
2101:
2108: protected int xPositionForValue(int value)
2109: {
2110: int min = slider.getMinimum();
2111: int max = slider.getMaximum();
2112: int len = trackRect.width - 1;
2113:
2114: int xPos = (max == min) ? 0 : (value - min) * len / (max - min);
2115:
2116: if (! drawInverted())
2117: xPos += trackRect.x;
2118: else
2119: {
2120: xPos = len - xPos;
2121: xPos += trackRect.x;
2122: }
2123: return xPos;
2124: }
2125:
2126:
2133: protected int yPositionForValue(int value)
2134: {
2135: int min = slider.getMinimum();
2136: int max = slider.getMaximum();
2137: int len = trackRect.height - 1;
2138:
2139: int yPos = (max == min) ? 0 : (value - min) * len / (max - min);
2140:
2141: if (! drawInverted())
2142: {
2143: yPos = len - yPos;
2144: yPos += trackRect.y;
2145: }
2146: else
2147: yPos += trackRect.y;
2148: return yPos;
2149: }
2150:
2151:
2160: public int valueForYPosition(int yPos)
2161: {
2162: int min = slider.getMinimum();
2163: int max = slider.getMaximum();
2164: int len = trackRect.height;
2165:
2166: int value;
2167:
2168:
2169:
2170:
2171: if (len == 0)
2172: return ((max - min) / 2);
2173:
2174: if (! drawInverted())
2175: value = ((len - (yPos - trackRect.y)) * (max - min) / len + min);
2176: else
2177: value = ((yPos - trackRect.y) * (max - min) / len + min);
2178:
2179:
2180: if (value > max)
2181: value = max;
2182: else if (value < min)
2183: value = min;
2184: return value;
2185: }
2186:
2187:
2196: public int valueForXPosition(int xPos)
2197: {
2198: int min = slider.getMinimum();
2199: int max = slider.getMaximum();
2200: int len = trackRect.width;
2201:
2202: int value;
2203:
2204:
2205:
2206:
2207: if (len == 0)
2208: return ((max - min) / 2);
2209:
2210: if (! drawInverted())
2211: value = ((xPos - trackRect.x) * (max - min) / len + min);
2212: else
2213: value = ((len - (xPos - trackRect.x)) * (max - min) / len + min);
2214:
2215:
2216: if (value > max)
2217: value = max;
2218: else if (value < min)
2219: value = min;
2220: return value;
2221: }
2222:
2223:
2231: int findClosestTick(int value)
2232: {
2233: int min = slider.getMinimum();
2234: int max = slider.getMaximum();
2235: int majorSpace = slider.getMajorTickSpacing();
2236: int minorSpace = slider.getMinorTickSpacing();
2237:
2238:
2239:
2240:
2241:
2242:
2243: int minor = min - value;
2244: int major = min - value;
2245:
2246:
2247:
2248:
2249: if (majorSpace <= 0 && minorSpace <= 0)
2250: return value;
2251:
2252:
2253: if (majorSpace > 0)
2254: {
2255: int lowerBound = (value - min) / majorSpace;
2256: int majLower = majorSpace * lowerBound + min;
2257: int majHigher = majorSpace * (lowerBound + 1) + min;
2258:
2259: if (majHigher <= max && majHigher - value <= value - majLower)
2260: major = majHigher - value;
2261: else
2262: major = majLower - value;
2263: }
2264:
2265: if (minorSpace > 0)
2266: {
2267: int lowerBound = value / minorSpace;
2268: int minLower = minorSpace * lowerBound;
2269: int minHigher = minorSpace * (lowerBound + 1);
2270:
2271: if (minHigher <= max && minHigher - value <= value - minLower)
2272: minor = minHigher - value;
2273: else
2274: minor = minLower - value;
2275: }
2276:
2277:
2278: if (Math.abs(minor) > Math.abs(major))
2279: return value + major;
2280: else
2281: return value + minor;
2282: }
2283: }