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:
62: import ;
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: import ;
78:
79:
139: public class BasicSliderUI extends SliderUI
140: {
141:
148: public class ChangeHandler implements ChangeListener
149: {
150:
157: public void stateChanged(ChangeEvent e)
158: {
159:
160:
161:
162: calculateThumbLocation();
163: slider.repaint();
164: }
165: }
166:
167:
174: public class ComponentHandler extends ComponentAdapter
175: {
176:
183: public void componentResized(ComponentEvent e)
184: {
185: calculateGeometry();
186: slider.repaint();
187: }
188: }
189:
190:
197: public class FocusHandler implements FocusListener
198: {
199:
205: public void focusGained(FocusEvent e)
206: {
207: slider.repaint();
208: }
209:
210:
216: public void focusLost(FocusEvent e)
217: {
218: slider.repaint();
219: }
220: }
221:
222:
226: public class PropertyChangeHandler implements PropertyChangeListener
227: {
228:
234: public void propertyChange(PropertyChangeEvent e)
235: {
236:
237: String prop = e.getPropertyName();
238: if (prop.equals("orientation")
239: || prop.equals("inverted")
240: || prop.equals("labelTable")
241: || prop.equals("majorTickSpacing")
242: || prop.equals("minorTickSpacing")
243: || prop.equals("paintTicks")
244: || prop.equals("paintTrack")
245: || prop.equals("paintLabels"))
246: {
247: calculateGeometry();
248: slider.repaint();
249: }
250: else if (e.getPropertyName().equals("model"))
251: {
252: BoundedRangeModel oldModel = (BoundedRangeModel) e.getOldValue();
253: oldModel.removeChangeListener(changeListener);
254: slider.getModel().addChangeListener(changeListener);
255: calculateThumbLocation();
256: slider.repaint();
257: }
258: }
259: }
260:
261:
270: public class ScrollListener implements ActionListener
271: {
272:
273: private transient int direction;
274:
275:
276: private transient boolean block;
277:
278:
281: public ScrollListener()
282: {
283: direction = POSITIVE_SCROLL;
284: block = false;
285: }
286:
287:
293: public ScrollListener(int dir, boolean block)
294: {
295: direction = dir;
296: this.block = block;
297: }
298:
299:
306: public void actionPerformed(ActionEvent e)
307: {
308: if (! trackListener.shouldScroll(direction))
309: {
310: scrollTimer.stop();
311: return;
312: }
313:
314: if (block)
315: scrollByBlock(direction);
316: else
317: scrollByUnit(direction);
318: }
319:
320:
325: public void setDirection(int direction)
326: {
327: this.direction = direction;
328: }
329:
330:
335: public void setScrollByBlock(boolean block)
336: {
337: this.block = block;
338: }
339: }
340:
341:
348: public class TrackListener extends MouseInputAdapter
349: {
350:
351: protected int currentMouseX;
352:
353:
354: protected int currentMouseY;
355:
356:
359: protected int offset;
360:
361:
368: public void mouseDragged(MouseEvent e)
369: {
370: dragging = true;
371: if (slider.isEnabled())
372: {
373: currentMouseX = e.getX();
374: currentMouseY = e.getY();
375: if (slider.getValueIsAdjusting())
376: {
377: int value;
378: if (slider.getOrientation() == JSlider.HORIZONTAL)
379: value = valueForXPosition(currentMouseX) - offset;
380: else
381: value = valueForYPosition(currentMouseY) - offset;
382:
383: slider.setValue(value);
384: }
385: }
386: }
387:
388:
394: public void mouseMoved(MouseEvent e)
395: {
396:
397: }
398:
399:
407: public void mousePressed(MouseEvent e)
408: {
409: if (slider.isEnabled())
410: {
411: currentMouseX = e.getX();
412: currentMouseY = e.getY();
413:
414: int value;
415: if (slider.getOrientation() == JSlider.HORIZONTAL)
416: value = valueForXPosition(currentMouseX);
417: else
418: value = valueForYPosition(currentMouseY);
419:
420: if (slider.getSnapToTicks())
421: value = findClosestTick(value);
422:
423:
424:
425: if (! thumbRect.contains(e.getPoint()))
426: {
427:
428:
429: if (value > slider.getValue())
430: scrollDueToClickInTrack(POSITIVE_SCROLL);
431: else
432: scrollDueToClickInTrack(NEGATIVE_SCROLL);
433: }
434: else
435: {
436: slider.setValueIsAdjusting(true);
437: offset = value - slider.getValue();
438: }
439: }
440: }
441:
442:
448: public void mouseReleased(MouseEvent e)
449: {
450: dragging = false;
451: if (slider.isEnabled())
452: {
453: currentMouseX = e.getX();
454: currentMouseY = e.getY();
455:
456: if (slider.getValueIsAdjusting())
457: {
458: slider.setValueIsAdjusting(false);
459: if (slider.getSnapToTicks())
460: slider.setValue(findClosestTick(slider.getValue()));
461: }
462: if (scrollTimer != null)
463: scrollTimer.stop();
464: }
465: slider.repaint();
466: }
467:
468:
475: public boolean shouldScroll(int direction)
476: {
477: int value;
478: if (slider.getOrientation() == JSlider.HORIZONTAL)
479: value = valueForXPosition(currentMouseX);
480: else
481: value = valueForYPosition(currentMouseY);
482:
483: if (direction == POSITIVE_SCROLL)
484: return value > slider.getValue();
485: else
486: return value < slider.getValue();
487: }
488: }
489:
490:
493: public class ActionScroller extends AbstractAction
494: {
495:
502: public ActionScroller(JSlider slider, int dir, boolean block)
503: {
504:
505: }
506:
507:
512: public void actionPerformed(ActionEvent event)
513: {
514:
515: }
516: }
517:
518:
519: protected ChangeListener changeListener;
520:
521:
522: protected PropertyChangeListener propertyChangeListener;
523:
524:
525: protected ScrollListener scrollListener;
526:
527:
528: protected ComponentListener componentListener;
529:
530:
531: protected FocusListener focusListener;
532:
533:
534: protected TrackListener trackListener;
535:
536:
537: protected Insets focusInsets;
538:
539:
540: protected Insets insetCache;
541:
542:
543: protected Rectangle contentRect;
544:
545:
546: protected Rectangle focusRect;
547:
548:
549: protected Rectangle thumbRect;
550:
551:
552: protected Rectangle tickRect;
553:
554:
555: protected Rectangle labelRect;
556:
557:
558: protected Rectangle trackRect;
559:
560:
561: public static final int MAX_SCROLL = 2;
562:
563:
564: public static final int MIN_SCROLL = -2;
565:
566:
567: public static final int NEGATIVE_SCROLL = -1;
568:
569:
570: public static final int POSITIVE_SCROLL = 1;
571:
572:
573: protected int trackBuffer;
574:
575:
576: protected boolean leftToRightCache;
577:
578:
579: protected Timer scrollTimer;
580:
581:
582: protected JSlider slider;
583:
584:
585: private transient Color shadowColor;
586:
587:
588: private transient Color highlightColor;
589:
590:
591: private transient Color focusColor;
592:
593:
594: boolean dragging;
595:
596:
601: public BasicSliderUI(JSlider b)
602: {
603: super();
604: }
605:
606:
613: protected boolean isDragging()
614: {
615: return dragging;
616: }
617:
618:
624: protected Color getShadowColor()
625: {
626: return shadowColor;
627: }
628:
629:
635: protected Color getHighlightColor()
636: {
637: return highlightColor;
638: }
639:
640:
647: protected Color getFocusColor()
648: {
649: return focusColor;
650: }
651:
652:
660: public static ComponentUI createUI(JComponent b)
661: {
662: return new BasicSliderUI((JSlider) b);
663: }
664:
665:
672: public void installUI(JComponent c)
673: {
674: super.installUI(c);
675: if (c instanceof JSlider)
676: {
677: slider = (JSlider) c;
678:
679: focusRect = new Rectangle();
680: contentRect = new Rectangle();
681: thumbRect = new Rectangle();
682: trackRect = new Rectangle();
683: tickRect = new Rectangle();
684: labelRect = new Rectangle();
685:
686: insetCache = slider.getInsets();
687: leftToRightCache = ! slider.getInverted();
688:
689: scrollTimer = new Timer(200, null);
690: scrollTimer.setRepeats(true);
691:
692: installDefaults(slider);
693: installListeners(slider);
694: installKeyboardActions(slider);
695:
696: calculateFocusRect();
697:
698: calculateContentRect();
699: calculateThumbSize();
700: calculateTrackBuffer();
701: calculateTrackRect();
702: calculateThumbLocation();
703:
704: calculateTickRect();
705: calculateLabelRect();
706: }
707: }
708:
709:
716: public void uninstallUI(JComponent c)
717: {
718: super.uninstallUI(c);
719:
720: uninstallKeyboardActions(slider);
721: uninstallListeners(slider);
722:
723: scrollTimer = null;
724:
725: focusRect = null;
726: contentRect = null;
727: thumbRect = null;
728: trackRect = null;
729: tickRect = null;
730: labelRect = null;
731:
732: focusInsets = null;
733: }
734:
735:
741: protected void installDefaults(JSlider slider)
742: {
743: LookAndFeel.installColors(slider, "Slider.background",
744: "Slider.foreground");
745: LookAndFeel.installBorder(slider, "Slider.border");
746: shadowColor = UIManager.getColor("Slider.shadow");
747: highlightColor = UIManager.getColor("Slider.highlight");
748: focusColor = UIManager.getColor("Slider.focus");
749: focusInsets = UIManager.getInsets("Slider.focusInsets");
750: slider.setOpaque(true);
751: }
752:
753:
761: protected TrackListener createTrackListener(JSlider slider)
762: {
763: return new TrackListener();
764: }
765:
766:
774: protected ChangeListener createChangeListener(JSlider slider)
775: {
776: return new ChangeHandler();
777: }
778:
779:
787: protected ComponentListener createComponentListener(JSlider slider)
788: {
789: return new ComponentHandler();
790: }
791:
792:
800: protected FocusListener createFocusListener(JSlider slider)
801: {
802: return new FocusHandler();
803: }
804:
805:
813: protected ScrollListener createScrollListener(JSlider slider)
814: {
815: return new ScrollListener();
816: }
817:
818:
826: protected PropertyChangeListener createPropertyChangeListener(JSlider slider)
827: {
828: return new PropertyChangeHandler();
829: }
830:
831:
837: protected void installListeners(JSlider slider)
838: {
839: propertyChangeListener = createPropertyChangeListener(slider);
840: componentListener = createComponentListener(slider);
841: trackListener = createTrackListener(slider);
842: focusListener = createFocusListener(slider);
843: changeListener = createChangeListener(slider);
844: scrollListener = createScrollListener(slider);
845:
846: slider.addPropertyChangeListener(propertyChangeListener);
847: slider.addComponentListener(componentListener);
848: slider.addMouseListener(trackListener);
849: slider.addMouseMotionListener(trackListener);
850: slider.addFocusListener(focusListener);
851: slider.getModel().addChangeListener(changeListener);
852:
853: scrollTimer.addActionListener(scrollListener);
854: }
855:
856:
862: protected void uninstallListeners(JSlider slider)
863: {
864: slider.removePropertyChangeListener(propertyChangeListener);
865: slider.removeComponentListener(componentListener);
866: slider.removeMouseListener(trackListener);
867: slider.removeMouseMotionListener(trackListener);
868: slider.removeFocusListener(focusListener);
869: slider.getModel().removeChangeListener(changeListener);
870:
871: scrollTimer.removeActionListener(scrollListener);
872:
873: propertyChangeListener = null;
874: componentListener = null;
875: trackListener = null;
876: focusListener = null;
877: changeListener = null;
878: scrollListener = null;
879: }
880:
881:
888: protected void installKeyboardActions(JSlider slider)
889: {
890: InputMap keyMap = getInputMap(JComponent.WHEN_FOCUSED);
891: SwingUtilities.replaceUIInputMap(slider, JComponent.WHEN_FOCUSED, keyMap);
892: ActionMap map = getActionMap();
893: SwingUtilities.replaceUIActionMap(slider, map);
894: }
895:
896:
903: protected void uninstallKeyboardActions(JSlider slider)
904: {
905: SwingUtilities.replaceUIActionMap(slider, null);
906: SwingUtilities.replaceUIInputMap(slider, JComponent.WHEN_FOCUSED, null);
907: }
908:
909:
923:
924:
930: public Dimension getPreferredHorizontalSize()
931: {
932: Dimension dim = UIManager.getDimension("Slider.horizontalSize");
933: if (dim == null)
934: dim = new Dimension(200, 21);
935: return dim;
936: }
937:
938:
944: public Dimension getPreferredVerticalSize()
945: {
946: Dimension dim = UIManager.getDimension("Slider.verticalSize");
947: if (dim == null)
948: dim = new Dimension(21, 200);
949: return dim;
950: }
951:
952:
958: public Dimension getMinimumHorizontalSize()
959: {
960: Dimension dim = UIManager.getDimension("Slider.minimumHorizontalSize");
961: if (dim == null)
962: dim = new Dimension(36, 21);
963: return dim;
964: }
965:
966:
972: public Dimension getMinimumVerticalSize()
973: {
974: Dimension dim = UIManager.getDimension("Slider.minimumVerticalSize");
975: if (dim == null)
976: dim = new Dimension(21, 36);
977: return dim;
978: }
979:
980:
989: public Dimension getPreferredSize(JComponent c)
990: {
991: recalculateIfInsetsChanged();
992: Dimension dim;
993: if (slider.getOrientation() == JSlider.HORIZONTAL)
994: {
995:
996: dim = new Dimension(getPreferredHorizontalSize());
997: dim.height = insetCache.top + insetCache.bottom;
998: dim.height += focusInsets.top + focusInsets.bottom;
999: dim.height += trackRect.height + tickRect.height + labelRect.height;
1000: }
1001: else
1002: {
1003:
1004: dim = new Dimension(getPreferredVerticalSize());
1005: dim.width = insetCache.left + insetCache.right;
1006: dim.width += focusInsets.left + focusInsets.right;
1007: dim.width += trackRect.width + tickRect.width + labelRect.width;
1008: }
1009: return dim;
1010: }
1011:
1012:
1021: public Dimension getMinimumSize(JComponent c)
1022: {
1023: recalculateIfInsetsChanged();
1024: Dimension dim;
1025: if (slider.getOrientation() == JSlider.HORIZONTAL)
1026: {
1027:
1028: dim = new Dimension(getMinimumHorizontalSize());
1029: dim.height = insetCache.top + insetCache.bottom;
1030: dim.height += focusInsets.top + focusInsets.bottom;
1031: dim.height += trackRect.height + tickRect.height + labelRect.height;
1032: }
1033: else
1034: {
1035:
1036: dim = new Dimension(getMinimumVerticalSize());
1037: dim.width = insetCache.left + insetCache.right;
1038: dim.width += focusInsets.left + focusInsets.right;
1039: dim.width += trackRect.width + tickRect.width + labelRect.width;
1040: }
1041: return dim;
1042: }
1043:
1044:
1052: public Dimension getMaximumSize(JComponent c)
1053: {
1054: Dimension dim = getPreferredSize(c);
1055: if (slider.getOrientation() == JSlider.HORIZONTAL)
1056: dim.width = Short.MAX_VALUE;
1057: else
1058: dim.height = Short.MAX_VALUE;
1059: return dim;
1060: }
1061:
1062:
1066: protected void calculateGeometry()
1067: {
1068: calculateFocusRect();
1069: calculateContentRect();
1070: calculateThumbSize();
1071: calculateTrackBuffer();
1072: calculateTrackRect();
1073: calculateTickRect();
1074: calculateLabelRect();
1075: calculateThumbLocation();
1076: }
1077:
1078:
1082: protected void calculateFocusRect()
1083: {
1084: focusRect.x = insetCache.left;
1085: focusRect.y = insetCache.top;
1086: focusRect.width = slider.getWidth() - insetCache.left - insetCache.right;
1087: focusRect.height = slider.getHeight() - insetCache.top - insetCache.bottom;
1088: }
1089:
1090:
1094: protected void calculateThumbSize()
1095: {
1096: Dimension d = getThumbSize();
1097: thumbRect.width = d.width;
1098: thumbRect.height = d.height;
1099: }
1100:
1101:
1106: protected void calculateContentRect()
1107: {
1108: contentRect.x = focusRect.x + focusInsets.left;
1109: contentRect.y = focusRect.y + focusInsets.top;
1110:
1111: contentRect.width = focusRect.width - focusInsets.left - focusInsets.right;
1112: contentRect.height = focusRect.height - focusInsets.top
1113: - focusInsets.bottom;
1114: }
1115:
1116:
1120: protected void calculateThumbLocation()
1121: {
1122: int value = slider.getValue();
1123:
1124: if (slider.getOrientation() == JSlider.HORIZONTAL)
1125: {
1126: thumbRect.x = xPositionForValue(value) - thumbRect.width / 2;
1127: thumbRect.y = trackRect.y + 1;
1128: }
1129: else
1130: {
1131: thumbRect.x = trackRect.x + 1;
1132: thumbRect.y = yPositionForValue(value) - thumbRect.height / 2;
1133: }
1134: }
1135:
1136:
1142: protected void calculateTrackBuffer()
1143: {
1144: if (slider.getOrientation() == JSlider.HORIZONTAL)
1145: {
1146: int w = Math.max(getWidthOfLowValueLabel(), getWidthOfHighValueLabel());
1147: trackBuffer = Math.max(thumbRect.width / 2, w / 2);
1148:
1149: }
1150: else
1151: {
1152: int h = Math.max(getHeightOfLowValueLabel(),
1153: getHeightOfHighValueLabel());
1154: trackBuffer = Math.max(thumbRect.height / 2, h / 2);
1155: }
1156: }
1157:
1158:
1168: protected Dimension getThumbSize()
1169: {
1170: if (slider.getOrientation() == JSlider.HORIZONTAL)
1171: return new Dimension(11, 20);
1172: else
1173: return new Dimension(20, 11);
1174: }
1175:
1176:
1180: protected void calculateTrackRect()
1181: {
1182: if (slider.getOrientation() == JSlider.HORIZONTAL)
1183: {
1184: int center = thumbRect.height;
1185: if (slider.getPaintTicks())
1186: center += getTickLength();
1187: if (slider.getPaintLabels())
1188: center += getHeightOfTallestLabel();
1189: trackRect.x = contentRect.x + trackBuffer;
1190: trackRect.y = contentRect.y + (contentRect.height - center - 1) / 2;
1191: trackRect.width = contentRect.width - 2 * trackBuffer;
1192: trackRect.height = thumbRect.height;
1193: }
1194: else
1195: {
1196: int center = thumbRect.width;
1197: if (slider.getPaintTicks())
1198: center += getTickLength();
1199: if (slider.getPaintLabels())
1200: center += getWidthOfWidestLabel();
1201: trackRect.x = contentRect.x + (contentRect.width - center - 1) / 2;
1202: trackRect.y = contentRect.y + trackBuffer;
1203: trackRect.width = thumbRect.width;
1204: trackRect.height = contentRect.height - 2 * trackBuffer;
1205: }
1206: }
1207:
1208:
1218: protected int getTickLength()
1219: {
1220: return 8;
1221: }
1222:
1223:
1227: protected void calculateTickRect()
1228: {
1229: if (slider.getOrientation() == JSlider.HORIZONTAL)
1230: {
1231: tickRect.x = trackRect.x;
1232: tickRect.y = trackRect.y + trackRect.height;
1233: tickRect.width = trackRect.width;
1234: tickRect.height = getTickLength();
1235:
1236:
1237: if (!slider.getPaintTicks())
1238: {
1239: tickRect.y--;
1240: tickRect.height = 0;
1241: }
1242: }
1243: else
1244: {
1245: tickRect.x = trackRect.x + trackRect.width;
1246: tickRect.y = trackRect.y;
1247: tickRect.width = getTickLength();
1248: tickRect.height = trackRect.height;
1249:
1250:
1251: if (!slider.getPaintTicks())
1252: {
1253: tickRect.x--;
1254: tickRect.width = 0;
1255: }
1256: }
1257: }
1258:
1259:
1263: protected void calculateLabelRect()
1264: {
1265: if (slider.getOrientation() == JSlider.HORIZONTAL)
1266: {
1267: if (slider.getPaintLabels())
1268: {
1269: labelRect.x = tickRect.x - trackBuffer;
1270: labelRect.y = tickRect.y + tickRect.height;
1271: labelRect.width = tickRect.width + trackBuffer * 2;
1272: labelRect.height = getHeightOfTallestLabel();
1273: }
1274: else
1275: {
1276: labelRect.x = tickRect.x;
1277: labelRect.y = tickRect.y + tickRect.height;
1278: labelRect.width = tickRect.width;
1279: labelRect.height = 0;
1280: }
1281: }
1282: else
1283: {
1284: if (slider.getPaintLabels())
1285: {
1286: labelRect.x = tickRect.x + tickRect.width;
1287: labelRect.y = tickRect.y - trackBuffer;
1288: labelRect.width = getWidthOfWidestLabel();
1289: labelRect.height = tickRect.height + trackBuffer * 2;
1290: }
1291: else
1292: {
1293: labelRect.x = tickRect.x + tickRect.width;
1294: labelRect.y = tickRect.y;
1295: labelRect.width = 0;
1296: labelRect.height = tickRect.height;
1297: }
1298: }
1299: }
1300:
1301:
1307: protected int getWidthOfWidestLabel()
1308: {
1309: int widest = 0;
1310: Dictionary table = slider.getLabelTable();
1311: if (table != null)
1312: {
1313: for (Enumeration list = slider.getLabelTable().elements();
1314: list.hasMoreElements();)
1315: {
1316: Component label = (Component) list.nextElement();
1317: widest = Math.max(label.getPreferredSize().width, widest);
1318: }
1319: }
1320: return widest;
1321: }
1322:
1323:
1329: protected int getHeightOfTallestLabel()
1330: {
1331: int tallest = 0;
1332: Component label;
1333:
1334: if (slider.getLabelTable() == null)
1335: return 0;
1336: Dimension pref;
1337: for (Enumeration list = slider.getLabelTable().elements();
1338: list.hasMoreElements();)
1339: {
1340: Object comp = list.nextElement();
1341: if (! (comp instanceof Component))
1342: continue;
1343: label = (Component) comp;
1344: pref = label.getPreferredSize();
1345: if (pref != null && pref.height > tallest)
1346: tallest = pref.height;
1347: }
1348: return tallest;
1349: }
1350:
1351:
1359: protected int getWidthOfHighValueLabel()
1360: {
1361: Component highValueLabel = getHighestValueLabel();
1362: if (highValueLabel != null)
1363: return highValueLabel.getPreferredSize().width;
1364: else
1365: return 0;
1366: }
1367:
1368:
1376: protected int getWidthOfLowValueLabel()
1377: {
1378: Component lowValueLabel = getLowestValueLabel();
1379: if (lowValueLabel != null)
1380: return lowValueLabel.getPreferredSize().width;
1381: else
1382: return 0;
1383: }
1384:
1385:
1391: protected int getHeightOfHighValueLabel()
1392: {
1393: Component highValueLabel = getHighestValueLabel();
1394: if (highValueLabel != null)
1395: return highValueLabel.getPreferredSize().height;
1396: else
1397: return 0;
1398: }
1399:
1400:
1406: protected int getHeightOfLowValueLabel()
1407: {
1408: Component lowValueLabel = getLowestValueLabel();
1409: if (lowValueLabel != null)
1410: return lowValueLabel.getPreferredSize().height;
1411: else
1412: return 0;
1413: }
1414:
1415:
1421: protected boolean drawInverted()
1422: {
1423: return slider.getInverted();
1424: }
1425:
1426:
1431: protected Component getLowestValueLabel()
1432: {
1433: Integer key = new Integer(Integer.MAX_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:
1461: protected Component getHighestValueLabel()
1462: {
1463: Integer key = new Integer(Integer.MIN_VALUE);
1464: Integer tmpKey;
1465: Dictionary labelTable = slider.getLabelTable();
1466:
1467: if (labelTable == null)
1468: return null;
1469:
1470: for (Enumeration list = labelTable.keys(); list.hasMoreElements();)
1471: {
1472: Object value = list.nextElement();
1473: if (! (value instanceof Integer))
1474: continue;
1475: tmpKey = (Integer) value;
1476: if (tmpKey.intValue() > key.intValue())
1477: key = tmpKey;
1478: }
1479: Object comp = labelTable.get(key);
1480: if (! (comp instanceof Component))
1481: return null;
1482: return (Component) comp;
1483: }
1484:
1485:
1493: public void paint(Graphics g, JComponent c)
1494: {
1495: recalculateIfInsetsChanged();
1496: recalculateIfOrientationChanged();
1497: if (slider.getPaintTrack() && hitClip(g, trackRect))
1498: paintTrack(g);
1499: if (slider.getPaintTicks() && hitClip(g, tickRect))
1500: paintTicks(g);
1501: if (slider.getPaintLabels() && hitClip(g, labelRect))
1502: paintLabels(g);
1503: if (slider.hasFocus() && hitClip(g, focusRect))
1504: paintFocus(g);
1505: if (hitClip(g, thumbRect))
1506: paintThumb(g);
1507: }
1508:
1509:
1513: protected void recalculateIfInsetsChanged()
1514: {
1515: Insets insets = slider.getInsets();
1516: if (! insets.equals(insetCache))
1517: {
1518: insetCache = insets;
1519: calculateGeometry();
1520: }
1521: }
1522:
1523:
1527: protected void recalculateIfOrientationChanged()
1528: {
1529:
1530:
1531: calculateThumbSize();
1532: calculateTrackBuffer();
1533: calculateTrackRect();
1534: calculateThumbLocation();
1535:
1536: calculateTickRect();
1537: calculateLabelRect();
1538: }
1539:
1540:
1547: public void paintFocus(Graphics g)
1548: {
1549: Color saved_color = g.getColor();
1550:
1551: g.setColor(getFocusColor());
1552:
1553: g.drawRect(focusRect.x, focusRect.y, focusRect.width, focusRect.height);
1554:
1555: g.setColor(saved_color);
1556: }
1557:
1558:
1584: public void paintTrack(Graphics g)
1585: {
1586: Color saved_color = g.getColor();
1587: int width;
1588: int height;
1589:
1590: Point a = new Point(trackRect.x, trackRect.y + 1);
1591: Point b = new Point(a);
1592: Point c = new Point(a);
1593: Point d = new Point(a);
1594:
1595: if (slider.getOrientation() == JSlider.HORIZONTAL)
1596: {
1597: width = trackRect.width;
1598: height = (thumbRect.height / 4 == 0) ? 1 : thumbRect.height / 4;
1599:
1600: a.translate(0, (trackRect.height / 2) - (height / 2));
1601: b.translate(0, (trackRect.height / 2) + (height / 2));
1602: c.translate(trackRect.width, (trackRect.height / 2) + (height / 2));
1603: d.translate(trackRect.width, (trackRect.height / 2) - (height / 2));
1604: }
1605: else
1606: {
1607: width = (thumbRect.width / 4 == 0) ? 1 : thumbRect.width / 4;
1608: height = trackRect.height;
1609:
1610: a.translate((trackRect.width / 2) - (width / 2), 0);
1611: b.translate((trackRect.width / 2) - (width / 2), trackRect.height);
1612: c.translate((trackRect.width / 2) + (width / 2), trackRect.height);
1613: d.translate((trackRect.width / 2) + (width / 2), 0);
1614: }
1615: g.setColor(Color.GRAY);
1616: g.fillRect(a.x, a.y, width, height);
1617:
1618: g.setColor(getHighlightColor());
1619: g.drawLine(b.x, b.y, c.x, c.y);
1620: g.drawLine(c.x, c.y, d.x, d.y);
1621:
1622: g.setColor(getShadowColor());
1623: g.drawLine(b.x, b.y, a.x, a.y);
1624: g.drawLine(a.x, a.y, d.x, d.y);
1625:
1626: g.setColor(saved_color);
1627: }
1628:
1629:
1636: public void paintTicks(Graphics g)
1637: {
1638: int max = slider.getMaximum();
1639: int min = slider.getMinimum();
1640: int majorSpace = slider.getMajorTickSpacing();
1641: int minorSpace = slider.getMinorTickSpacing();
1642:
1643: if (majorSpace > 0)
1644: {
1645: if (slider.getOrientation() == JSlider.HORIZONTAL)
1646: {
1647: g.translate(0, tickRect.y);
1648: for (int i = min; i <= max; i += majorSpace)
1649: paintMajorTickForHorizSlider(g, tickRect, xPositionForValue(i));
1650: g.translate(0, -tickRect.y);
1651: }
1652: else
1653: {
1654: g.translate(tickRect.x, 0);
1655: for (int i = min; i <= max; i += majorSpace)
1656: paintMajorTickForVertSlider(g, tickRect, yPositionForValue(i));
1657: g.translate(-tickRect.x, 0);
1658: }
1659: }
1660: if (minorSpace > 0)
1661: {
1662: if (slider.getOrientation() == JSlider.HORIZONTAL)
1663: {
1664: g.translate(0, tickRect.y);
1665: for (int i = min; i <= max; i += minorSpace)
1666: paintMinorTickForHorizSlider(g, tickRect, xPositionForValue(i));
1667: g.translate(0, -tickRect.y);
1668: }
1669: else
1670: {
1671: g.translate(tickRect.x, 0);
1672: for (int i = min; i <= max; i += minorSpace)
1673: paintMinorTickForVertSlider(g, tickRect, yPositionForValue(i));
1674: g.translate(-tickRect.x, 0);
1675: }
1676: }
1677: }
1678:
1679:
1684:
1685:
1693: protected void paintMinorTickForHorizSlider(Graphics g,
1694: Rectangle tickBounds, int x)
1695: {
1696: int y = tickRect.height / 4;
1697: Color saved = g.getColor();
1698: g.setColor(Color.BLACK);
1699:
1700: g.drawLine(x, y, x, y + tickRect.height / 4);
1701: g.setColor(saved);
1702: }
1703:
1704:
1712: protected void paintMajorTickForHorizSlider(Graphics g,
1713: Rectangle tickBounds, int x)
1714: {
1715: int y = tickRect.height / 4;
1716: Color saved = g.getColor();
1717: g.setColor(Color.BLACK);
1718:
1719: g.drawLine(x, y, x, y + tickRect.height / 2);
1720: g.setColor(saved);
1721: }
1722:
1723:
1731: protected void paintMinorTickForVertSlider(Graphics g, Rectangle tickBounds,
1732: int y)
1733: {
1734: int x = tickRect.width / 4;
1735: Color saved = g.getColor();
1736: g.setColor(Color.BLACK);
1737:
1738: g.drawLine(x, y, x + tickRect.width / 4, y);
1739: g.setColor(saved);
1740: }
1741:
1742:
1750: protected void paintMajorTickForVertSlider(Graphics g, Rectangle tickBounds,
1751: int y)
1752: {
1753: int x = tickRect.width / 4;
1754: Color saved = g.getColor();
1755: g.setColor(Color.BLACK);
1756:
1757: g.drawLine(x, y, x + tickRect.width / 2, y);
1758: g.setColor(saved);
1759: }
1760:
1761:
1769: public void paintLabels(Graphics g)
1770: {
1771: Dictionary table = slider.getLabelTable();
1772: if (table != null)
1773: {
1774: int min = slider.getMinimum();
1775: int max = slider.getMaximum();
1776: for (Enumeration list = table.keys(); list.hasMoreElements();)
1777: {
1778: Integer key = (Integer) list.nextElement();
1779: int value = key.intValue();
1780: if (value >= min && value <= max)
1781: {
1782: Component label = (Component) table.get(key);
1783: if (slider.getOrientation() == JSlider.HORIZONTAL)
1784: {
1785: g.translate(0, labelRect.y);
1786: paintHorizontalLabel(g, value, label);
1787: g.translate(0, -labelRect.y);
1788: }
1789: else
1790: {
1791: g.translate(labelRect.x, 0);
1792: paintVerticalLabel(g, value, label);
1793: g.translate(-labelRect.x, 0);
1794: }
1795: }
1796: }
1797: }
1798: }
1799:
1800:
1811: protected void paintHorizontalLabel(Graphics g, int value, Component label)
1812: {
1813: int center = xPositionForValue(value);
1814: int left = center - label.getPreferredSize().width / 2;
1815: g.translate(left, 0);
1816: label.paint(g);
1817: g.translate(-left, 0);
1818: }
1819:
1820:
1831: protected void paintVerticalLabel(Graphics g, int value, Component label)
1832: {
1833: int center = yPositionForValue(value);
1834: int top = center - label.getPreferredSize().height / 2;
1835: g.translate(0, top);
1836: label.paint(g);
1837: g.translate(0, -top);
1838: }
1839:
1840:
1862: public void paintThumb(Graphics g)
1863: {
1864: Color saved_color = g.getColor();
1865:
1866: Point a = new Point(thumbRect.x, thumbRect.y);
1867: Point b = new Point(a);
1868: Point c = new Point(a);
1869: Point d = new Point(a);
1870: Point e = new Point(a);
1871:
1872: Polygon bright;
1873: Polygon light;
1874: Polygon dark;
1875: Polygon all;
1876:
1877:
1878: int turnPoint;
1879:
1880: if (slider.getOrientation() == JSlider.HORIZONTAL)
1881: {
1882: turnPoint = thumbRect.height * 3 / 4;
1883:
1884: b.translate(thumbRect.width - 1, 0);
1885: c.translate(thumbRect.width - 1, turnPoint);
1886: d.translate(thumbRect.width / 2 - 1, thumbRect.height - 1);
1887: e.translate(0, turnPoint);
1888:
1889: bright = new Polygon(new int[] { b.x - 1, a.x, e.x, d.x },
1890: new int[] { b.y, a.y, e.y, d.y }, 4);
1891:
1892: dark = new Polygon(new int[] { b.x, c.x, d.x + 1 }, new int[] { b.y,
1893: c.y - 1,
1894: d.y }, 3);
1895:
1896: light = new Polygon(new int[] { b.x - 1, c.x - 1, d.x + 1 },
1897: new int[] { b.y + 1, c.y - 1, d.y - 1 }, 3);
1898:
1899: all = new Polygon(
1900: new int[] { a.x + 1, b.x - 2, c.x - 2, d.x, e.x + 1 },
1901: new int[] { a.y + 1, b.y + 1, c.y - 1, d.y - 1, e.y },
1902: 5);
1903: }
1904: else
1905: {
1906: turnPoint = thumbRect.width * 3 / 4 - 1;
1907:
1908: b.translate(turnPoint, 0);
1909: c.translate(thumbRect.width - 1, thumbRect.height / 2);
1910: d.translate(turnPoint, thumbRect.height - 1);
1911: e.translate(0, thumbRect.height - 1);
1912:
1913: bright = new Polygon(new int[] { c.x - 1, b.x, a.x, e.x },
1914: new int[] { c.y - 1, b.y, a.y, e.y - 1 }, 4);
1915:
1916: dark = new Polygon(new int[] { c.x, d.x, e.x }, new int[] { c.y, d.y,
1917: e.y }, 3);
1918:
1919: light = new Polygon(new int[] { c.x - 1, d.x, e.x + 1 },
1920: new int[] { c.y, d.y - 1, e.y - 1 }, 3);
1921: all = new Polygon(new int[] { a.x + 1, b.x, c.x - 2, c.x - 2, d.x,
1922: e.x + 1 }, new int[] { a.y + 1, b.y + 1,
1923: c.y - 1, c.y,
1924: d.y - 2, e.y - 2 },
1925: 6);
1926: }
1927:
1928: g.setColor(Color.WHITE);
1929: g.drawPolyline(bright.xpoints, bright.ypoints, bright.npoints);
1930:
1931: g.setColor(Color.BLACK);
1932: g.drawPolyline(dark.xpoints, dark.ypoints, dark.npoints);
1933:
1934: g.setColor(Color.GRAY);
1935: g.drawPolyline(light.xpoints, light.ypoints, light.npoints);
1936:
1937: g.setColor(Color.LIGHT_GRAY);
1938: g.drawPolyline(all.xpoints, all.ypoints, all.npoints);
1939: g.fillPolygon(all);
1940:
1941: g.setColor(saved_color);
1942: }
1943:
1944:
1950: public void setThumbLocation(int x, int y)
1951: {
1952: Rectangle union = new Rectangle(thumbRect);
1953: thumbRect.setLocation(x, y);
1954: SwingUtilities.computeUnion(thumbRect.x, thumbRect.y, thumbRect.width,
1955: thumbRect.height, union);
1956: slider.repaint(union);
1957: }
1958:
1959:
1968: public void scrollByBlock(int direction)
1969: {
1970: int unit = (slider.getMaximum() - slider.getMinimum()) / 10;
1971: int moveTo = slider.getValue();
1972: if (direction > 0)
1973: moveTo += unit;
1974: else
1975: moveTo -= unit;
1976:
1977: if (slider.getSnapToTicks())
1978: moveTo = findClosestTick(moveTo);
1979:
1980: slider.setValue(moveTo);
1981: }
1982:
1983:
1992: public void scrollByUnit(int direction)
1993: {
1994: int moveTo = slider.getValue();
1995: if (direction > 0)
1996: moveTo++;
1997: else
1998: moveTo--;
1999:
2000: if (slider.getSnapToTicks())
2001: moveTo = findClosestTick(moveTo);
2002:
2003: slider.setValue(moveTo);
2004: }
2005:
2006:
2013: protected void scrollDueToClickInTrack(int dir)
2014: {
2015: scrollTimer.stop();
2016:
2017: scrollListener.setDirection(dir);
2018: scrollListener.setScrollByBlock(true);
2019:
2020: scrollTimer.start();
2021: }
2022:
2023:
2032: protected int xPositionForValue(int value)
2033: {
2034: int min = slider.getMinimum();
2035: int max = slider.getMaximum();
2036: int len = trackRect.width;
2037: double range = max - min;
2038: double pixPerVal = len / range;
2039: int left = trackRect.x;
2040: int right = left + trackRect.width - 1;
2041: int xpos;
2042: if (! drawInverted())
2043: xpos = left + (int) Math.round(pixPerVal * ((double) value - min));
2044: else
2045: xpos = right - (int) Math.round(pixPerVal * ((double) value - min));
2046: xpos = Math.max(left, xpos);
2047: xpos = Math.min(right, xpos);
2048: return xpos;
2049: }
2050:
2051:
2060: protected int yPositionForValue(int value)
2061: {
2062: int min = slider.getMinimum();
2063: int max = slider.getMaximum();
2064: int len = trackRect.height;
2065: double range = max - min;
2066: double pixPerVal = len / range;
2067: int top = trackRect.y;
2068: int bottom = top + trackRect.height - 1;
2069: int ypos;
2070: if (! drawInverted())
2071: ypos = top + (int) Math.round(pixPerVal * ((double) max - value));
2072: else
2073: ypos = top + (int) Math.round(pixPerVal * ((double) value - min));
2074: ypos = Math.max(top, ypos);
2075: ypos = Math.min(bottom, ypos);
2076: return ypos;
2077: }
2078:
2079:
2088: public int valueForYPosition(int yPos)
2089: {
2090: int min = slider.getMinimum();
2091: int max = slider.getMaximum();
2092: int len = trackRect.height;
2093:
2094: int value;
2095:
2096:
2097:
2098:
2099: if (len == 0)
2100: return (max - min) / 2;
2101:
2102: if (! drawInverted())
2103: value = (len - (yPos - trackRect.y)) * (max - min) / len + min;
2104: else
2105: value = (yPos - trackRect.y) * (max - min) / len + min;
2106:
2107:
2108: if (value > max)
2109: value = max;
2110: else if (value < min)
2111: value = min;
2112: return value;
2113: }
2114:
2115:
2124: public int valueForXPosition(int xPos)
2125: {
2126: int min = slider.getMinimum();
2127: int max = slider.getMaximum();
2128: int len = trackRect.width;
2129:
2130: int value;
2131:
2132:
2133:
2134:
2135: if (len == 0)
2136: return (max - min) / 2;
2137:
2138: if (! drawInverted())
2139: value = (xPos - trackRect.x) * (max - min) / len + min;
2140: else
2141: value = (len - (xPos - trackRect.x)) * (max - min) / len + min;
2142:
2143:
2144: if (value > max)
2145: value = max;
2146: else if (value < min)
2147: value = min;
2148: return value;
2149: }
2150:
2151:
2159: int findClosestTick(int value)
2160: {
2161: int min = slider.getMinimum();
2162: int max = slider.getMaximum();
2163: int majorSpace = slider.getMajorTickSpacing();
2164: int minorSpace = slider.getMinorTickSpacing();
2165:
2166:
2167:
2168:
2169:
2170:
2171: int minor = min - value;
2172: int major = min - value;
2173:
2174:
2175:
2176:
2177: if (majorSpace <= 0 && minorSpace <= 0)
2178: return value;
2179:
2180:
2181: if (majorSpace > 0)
2182: {
2183: int lowerBound = (value - min) / majorSpace;
2184: int majLower = majorSpace * lowerBound + min;
2185: int majHigher = majorSpace * (lowerBound + 1) + min;
2186:
2187: if (majHigher <= max && majHigher - value <= value - majLower)
2188: major = majHigher - value;
2189: else
2190: major = majLower - value;
2191: }
2192:
2193: if (minorSpace > 0)
2194: {
2195: int lowerBound = value / minorSpace;
2196: int minLower = minorSpace * lowerBound;
2197: int minHigher = minorSpace * (lowerBound + 1);
2198:
2199: if (minHigher <= max && minHigher - value <= value - minLower)
2200: minor = minHigher - value;
2201: else
2202: minor = minLower - value;
2203: }
2204:
2205:
2206: if (Math.abs(minor) > Math.abs(major))
2207: return value + major;
2208: else
2209: return value + minor;
2210: }
2211:
2212: InputMap getInputMap(int condition)
2213: {
2214: if (condition == JComponent.WHEN_FOCUSED)
2215: return (InputMap) UIManager.get("Slider.focusInputMap");
2216: return null;
2217: }
2218:
2219:
2226: ActionMap getActionMap()
2227: {
2228: ActionMap map = (ActionMap) UIManager.get("Slider.actionMap");
2229:
2230: if (map == null)
2231: {
2232: map = createActionMap();
2233: if (map != null)
2234: UIManager.put("Slider.actionMap", map);
2235: }
2236: return map;
2237: }
2238:
2239:
2249: ActionMap createActionMap()
2250: {
2251: ActionMap map = new ActionMapUIResource();
2252: map.put("positiveUnitIncrement",
2253: new AbstractAction("positiveUnitIncrement") {
2254: public void actionPerformed(ActionEvent event)
2255: {
2256: JSlider slider = (JSlider) event.getSource();
2257: BasicSliderUI ui = (BasicSliderUI) slider.getUI();
2258: if (slider.getInverted())
2259: ui.scrollByUnit(BasicSliderUI.NEGATIVE_SCROLL);
2260: else
2261: ui.scrollByUnit(BasicSliderUI.POSITIVE_SCROLL);
2262: }
2263: }
2264: );
2265: map.put("negativeUnitIncrement",
2266: new AbstractAction("negativeUnitIncrement") {
2267: public void actionPerformed(ActionEvent event)
2268: {
2269: JSlider slider = (JSlider) event.getSource();
2270: BasicSliderUI ui = (BasicSliderUI) slider.getUI();
2271: if (slider.getInverted())
2272: ui.scrollByUnit(BasicSliderUI.POSITIVE_SCROLL);
2273: else
2274: ui.scrollByUnit(BasicSliderUI.NEGATIVE_SCROLL);
2275: }
2276: }
2277: );
2278: map.put("positiveBlockIncrement",
2279: new AbstractAction("positiveBlockIncrement") {
2280: public void actionPerformed(ActionEvent event)
2281: {
2282: JSlider slider = (JSlider) event.getSource();
2283: BasicSliderUI ui = (BasicSliderUI) slider.getUI();
2284: if (slider.getInverted())
2285: ui.scrollByBlock(BasicSliderUI.NEGATIVE_SCROLL);
2286: else
2287: ui.scrollByBlock(BasicSliderUI.POSITIVE_SCROLL);
2288: }
2289: }
2290: );
2291: map.put("negativeBlockIncrement",
2292: new AbstractAction("negativeBlockIncrement") {
2293: public void actionPerformed(ActionEvent event)
2294: {
2295: JSlider slider = (JSlider) event.getSource();
2296: BasicSliderUI ui = (BasicSliderUI) slider.getUI();
2297: if (slider.getInverted())
2298: ui.scrollByBlock(BasicSliderUI.POSITIVE_SCROLL);
2299: else
2300: ui.scrollByBlock(BasicSliderUI.NEGATIVE_SCROLL);
2301: }
2302: }
2303: );
2304: map.put("minScroll",
2305: new AbstractAction("minScroll") {
2306: public void actionPerformed(ActionEvent event)
2307: {
2308: JSlider slider = (JSlider) event.getSource();
2309: if (slider.getInverted())
2310: slider.setValue(slider.getMaximum());
2311: else
2312: slider.setValue(slider.getMinimum());
2313: }
2314: }
2315: );
2316: map.put("maxScroll",
2317: new AbstractAction("maxScroll") {
2318: public void actionPerformed(ActionEvent event)
2319: {
2320: JSlider slider = (JSlider) event.getSource();
2321: if (slider.getInverted())
2322: slider.setValue(slider.getMinimum());
2323: else
2324: slider.setValue(slider.getMaximum());
2325: }
2326: }
2327: );
2328: return map;
2329: }
2330:
2331:
2335: private boolean hitClip(Graphics g, Rectangle r)
2336: {
2337: return g.hitClip(r.x, r.y, r.width, r.height);
2338: }
2339: }