1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package com.cosylab.gui.components;
21
22 import java.awt.Color;
23 import java.awt.Dimension;
24 import java.awt.Font;
25 import java.awt.GridBagConstraints;
26 import java.awt.GridBagLayout;
27 import java.awt.Insets;
28 import java.awt.event.ActionEvent;
29 import java.awt.event.ActionListener;
30 import java.awt.event.MouseAdapter;
31 import java.awt.event.MouseEvent;
32 import java.util.ArrayList;
33
34 import javax.swing.AbstractAction;
35 import javax.swing.Icon;
36 import javax.swing.JPanel;
37 import javax.swing.JSlider;
38 import javax.swing.Timer;
39 import javax.swing.UIDefaults;
40 import javax.swing.UIManager;
41 import javax.swing.event.ChangeEvent;
42 import javax.swing.event.ChangeListener;
43
44 import com.cosylab.application.state.State;
45 import com.cosylab.application.state.StateFactory;
46 import com.cosylab.application.state.StateOriginator;
47 import com.cosylab.events.SetEvent;
48 import com.cosylab.events.SetListener;
49 import com.cosylab.gui.components.customizer.AbstractCustomizerPanel;
50 import com.cosylab.gui.components.range2.IntegerValuePolicy;
51 import com.cosylab.gui.components.range2.LinearRange;
52 import com.cosylab.gui.components.range2.ManualTickCalculator;
53 import com.cosylab.gui.components.range2.RangedValueController;
54 import com.cosylab.gui.components.range2.RangedValueEvent;
55 import com.cosylab.gui.components.range2.RangedValueListener;
56 import com.cosylab.gui.components.range2.RangedValuePolicy;
57 import com.cosylab.gui.components.range2.TickParameters;
58 import com.cosylab.gui.components.slider.CosySliderUI;
59 import com.cosylab.gui.components.slider.InfoBar;
60 import com.cosylab.gui.components.slider.NavigationBar;
61 import com.cosylab.gui.components.util.ColorHelper;
62 import com.cosylab.gui.components.util.CosyTransferHandler;
63 import com.cosylab.gui.components.util.CosyUIElements;
64 import com.cosylab.gui.components.util.PopupManageable;
65 import com.cosylab.gui.components.util.PopupManager;
66 import com.cosylab.gui.components.util.RunnerHelper;
67 import com.cosylab.util.PrintfFormat;
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84 public class Slider extends JPanel implements TickParameters, PopupManageable, StateOriginator {
85
86
87
88
89
90
91
92
93 public enum Button {
94 FAST_INCREMENT, FAST_DECREMENT, BIT_INCREMENT, BIT_DECREMENT, SLOW_INCREMENT, SLOW_DECREMENT,
95 }
96
97 private static final long serialVersionUID = 1L;
98
99 private boolean popupEnabled;
100
101
102
103
104
105
106 @Deprecated
107 public static final int SET_MANUAL = 0;
108
109
110
111
112
113
114 @Deprecated
115 public static final int SET_ON_RELEASE = 1;
116
117
118
119
120
121
122 @Deprecated
123 public static final int SET_ON_CHANGE = 2;
124
125 private AbstractCustomizerPanel customizer;
126 private PopupManager popupManager;
127
128 private final ArrayList<SetListener> listeners = new ArrayList<SetListener>();
129
130 private JSlider slider;
131 private CosySliderUI sliderUI;
132 private InfoBar infoBar;
133 private NavigationBar navigationBar;
134
135 private RangedValueController rangedValue;
136
137
138 private int suspended = 0;
139 private boolean showIntegerOnly = false;
140 private boolean supressChanges = false;
141 private boolean supressSetEvent = false;
142 private boolean supressPropChEvent = false;
143 private boolean externalSet = false;
144
145 private static final double DEFAULT_BIT_STEP = 1;
146 private static final double DEFAULT_SMALL_STEP = 10;
147 private static final double DEFAULT_LARGE_STEP = 25;
148
149
150 private double bitStep = DEFAULT_BIT_STEP;
151
152 private boolean isBitStepRelative = true;
153
154 private double smallStep = DEFAULT_SMALL_STEP;
155
156 private boolean isSmallStepRelative = true;
157
158 private double largeStep = DEFAULT_LARGE_STEP;
159
160 private boolean isLargeStepRelative = true;
161
162
163
164 private Timer autoSyncTimer;
165
166
167
168
169
170 private boolean autoSynchronize = false;
171
172
173
174
175 private long autoSynchronizeDelay = 2000;
176 private boolean allowAutoSync = true;
177 private double storedValue = Double.NaN;
178 private boolean continuousControlVisible = false;
179 private boolean continuousModeEnabled = false;
180
181 private PrintfFormat formatter;
182 private String title = " ";
183 private boolean settable = true;
184 private SliderSetMode mode = SliderSetMode.SET_ON_CHANGE;
185 private boolean snapToTicks = false;
186
187 private ManualTickCalculator manualTickProvider = new ManualTickCalculator();
188
189 private class ValueListener implements RangedValueListener {
190
191
192
193 public void valueChanged(RangedValueEvent event) {
194 if (event.isMinOrMaxChanged()) {
195
196 getSlider().setValue((int)getRangedValue().getRelativeValue());
197
198 getSliderUI().setTrailerPosition(getSliderUI().getTrailerPosition());
199 getNavigationBar().setMinimum(getRangedValue().getMinimum());
200 getNavigationBar().setMaximum(getRangedValue().getMaximum());
201 repaint();
202
203 }
204 }
205 }
206
207
208
209
210 public void resetSteps() {
211 setBitStep(DEFAULT_BIT_STEP);
212 setBitStepRelative(true);
213 setSmallStep(DEFAULT_SMALL_STEP);
214 setSmallStepRelative(true);
215 setLargeStep(DEFAULT_LARGE_STEP);
216 setLargeStepRelative(true);
217 }
218
219 private PrintfFormat getFormatter() {
220 if (formatter == null) {
221 formatter = new PrintfFormat("%f");
222 }
223 return formatter;
224 }
225
226
227
228
229
230
231
232 private class SliderChange implements ChangeListener {
233
234
235
236
237
238
239 public void stateChanged(ChangeEvent event) {
240 if (mode == SliderSetMode.SET_ON_CHANGE || mode == SliderSetMode.SET_MANUAL) {
241 performInternalSliderSet();
242 }
243 if (!externalSet || mode == SliderSetMode.SET_ON_RELEASE) {
244 getNavigationBar().setValue(getRangedValue().toAbsolute(getSlider().getValue()));
245 }
246 }
247 }
248
249
250
251
252 public Slider() {
253 super();
254 initialize();
255 }
256
257
258
259
260
261
262
263 public void addSetListener(SetListener listener) {
264 synchronized (listeners) {
265 listeners.add(listener);
266 }
267 }
268
269
270
271
272
273
274 public void removeSetListener(SetListener listener) {
275 synchronized (listeners) {
276 listeners.remove(listener);
277 }
278 }
279
280
281
282
283
284
285 protected void fireSetPerformed(double newValue) {
286 final SetEvent e = new SetEvent(this,newValue);
287
288 synchronized (listeners) {
289 final int n = listeners.size();
290
291 for (int i = 0; i < n; i++) {
292 listeners.get(i).setPerformed(e);
293 }
294 }
295 }
296
297 private void initialize() {
298 setLayout(new GridBagLayout());
299 setBorder(CosyUIElements.getPlainBorder(true));
300 setBackground(ColorHelper.getCosyControl());
301
302 add(getInfoBar(),new GridBagConstraints(0,0,1,1,1,0,GridBagConstraints.CENTER,GridBagConstraints.HORIZONTAL,new Insets(1,2,2,2),0,0));
303 add(getNavigationBar(),new GridBagConstraints(0,1,1,1,1,0,GridBagConstraints.CENTER,GridBagConstraints.HORIZONTAL,new Insets(1,2,2,2),0,0));
304
305 GridBagConstraints gc = new GridBagConstraints();
306
307 gc.gridx = 0;
308 gc.gridy = 2;
309 gc.weightx = 1.0;
310 gc.weighty = 0.0;
311 gc.fill = GridBagConstraints.HORIZONTAL;
312 gc.insets = new Insets(0,2,0,2);
313
314 getSliderUI().setTolerance(0.0000001);
315 add(getSlider(),gc);
316
317 setValue(0);
318 setForeground(Color.BLACK);
319 setStorageButtonsVisible(false);
320 setContinuousControlVisible(false);
321 setPopupEnabled(true);
322 }
323
324 protected InfoBar getInfoBar() {
325 if (infoBar == null) {
326 infoBar = new InfoBar(this);
327 }
328
329 return infoBar;
330 }
331
332 protected NavigationBar getNavigationBar() {
333 if (navigationBar == null) {
334 navigationBar = new NavigationBar(this);
335 navigationBar.addSetListener(new SetListener() {
336
337 public void setPerformed(SetEvent e) {
338 performInternalSet(e.getDoubleValue());
339 }
340
341 });
342 }
343
344 return navigationBar;
345 }
346
347 protected JSlider getSlider() {
348 if (slider == null) {
349 slider = new JSlider();
350 slider.setBackground(ColorHelper.getCosyControl());
351 slider.setPaintLabels(true);
352 slider.setPaintTicks(true);
353 slider.setMinorTickSpacing(10000);
354 slider.setMajorTickSpacing(10000);
355
356 slider.setMinimum(0);
357 slider.setMaximum(10000);
358
359
360
361
362
363
364
365
366
367 UIManager.put("Slider.trackWidth",new Integer(7));
368 UIManager.put("Slider.majorTickLength",new Integer(6));
369 UIManager.put("Slider.horizontalThumbIcon",new UIDefaults.ProxyLazyValue("javax.swing.plaf.metal.MetalIconFactory",
370 "getHorizontalSliderThumbIcon"));
371 UIManager.put("Slider.verticalThumbIcon",new UIDefaults.ProxyLazyValue("javax.swing.plaf.metal.MetalIconFactory",
372 "getVerticalSliderThumbIcon"));
373
374
375 slider.setUI(getSliderUI());
376 slider.addChangeListener(new SliderChange());
377 slider.addMouseListener(new MouseAdapter() {
378
379 @Override
380 public void mousePressed(MouseEvent e) {
381 allowAutoSync = false;
382 }
383
384 @Override
385 public void mouseReleased(MouseEvent e) {
386 if (mode == SliderSetMode.SET_ON_RELEASE) {
387 performInternalSliderSet();
388 } else if (showIntegerOnly) {
389 getSlider().setValue((int)(getRangedValue().getRelativeValue()));
390 }
391 allowAutoSync = true;
392
393 }
394 });
395 slider.setPreferredSize(new Dimension(150,50));
396 }
397 return slider;
398 }
399
400 private int old = Integer.MIN_VALUE;
401
402 private void performInternalSliderSet() {
403 synchronized (this) {
404 if (!supressChanges) {
405 int newV = getSlider().getValue();
406 if (old != newV) {
407 performInternalSetRelative(newV);
408 }
409 old = newV;
410 }
411 }
412 }
413
414 private void performInternalSet(double value) {
415
416 value = getRangedValue().validate(value);
417
418 if (value == getValue()) {
419 return;
420 }
421
422 getNavigationBar().setValue(value);
423
424 if (mode == SliderSetMode.SET_MANUAL) {
425 synchronized (this) {
426 if (!supressChanges) {
427 supressChanges = true;
428
429 getRangedValue().setValue(value);
430
431 getSlider().setValue((int)getRangedValue().getRelativeValue());
432 getNavigationBar().setValue(getValue());
433
434 supressChanges = false;
435 }
436 }
437 return;
438 }
439
440 synchronized (this) {
441 if (!supressChanges) {
442 supressChanges = true;
443
444 getAutoSyncTimer().stop();
445
446 double old = getValue();
447 getRangedValue().setValue(value);
448
449
450 getSlider().setValue((int)getRangedValue().getRelativeValue());
451 getNavigationBar().setValue(getValue());
452
453 if (!isEditable()) {
454 setReadback(getValue());
455 }
456
457 if (!supressSetEvent && !isSuspended()) {
458 fireSetPerformed(getValue());
459 }
460 if (!supressPropChEvent && !isSuspended()) {
461 firePropertyChange("value",old,getValue());
462 }
463
464 if (autoSynchronize) {
465 getAutoSyncTimer().restart();
466 }
467
468 supressChanges = false;
469 }
470 }
471
472 }
473
474 private void performInternalSetRelative(double rVal) {
475 performInternalSet(getRangedValue().toAbsolute(rVal));
476 }
477
478 private void performInternalFractionSet(double fraction) {
479 performInternalSetRelative(getRangedValue().getRelativeValue() + fraction * getRangedValue().getScalingFactor());
480
481 }
482
483
484
485
486
487
488 protected CosySliderUI getSliderUI() {
489 if (sliderUI == null) {
490 sliderUI = new CosySliderUI(getRangedValue());
491 }
492
493 return sliderUI;
494 }
495
496
497
498
499
500
501 public void setMinimum(double minimum) {
502 double oldValue = getMinimum();
503
504 getRangedValue().setMinimum(minimum);
505
506
507
508
509 getNavigationBar().setMinimum(minimum);
510 modifySliderPosition();
511 firePropertyChange("minimum",oldValue,minimum);
512 }
513
514
515
516
517
518
519 public void setMaximum(double maximum) {
520 double oldValue = getMaximum();
521
522 getRangedValue().setMaximum(maximum);
523
524
525
526
527 getNavigationBar().setMaximum(maximum);
528 modifySliderPosition();
529 firePropertyChange("maximum",oldValue,maximum);
530 }
531
532
533
534
535
536
537
538 public void setValue(double value) {
539 getAutoSyncTimer().stop();
540
541 double oldValue = getValue();
542
543 synchronized (this) {
544 supressChanges = true;
545 getRangedValue().setValue(value);
546
547
548 externalSet = true;
549 getSlider().setValue((int)getRangedValue().getRelativeValue());
550 getNavigationBar().setValue(getValue());
551
552 if (!isEditable()) {
553 setReadback(getValue());
554 }
555
556 supressChanges = false;
557 }
558
559 if (autoSynchronize) {
560 getAutoSyncTimer().restart();
561 }
562
563 firePropertyChange("value",oldValue,value);
564 }
565
566 private Timer getAutoSyncTimer() {
567 if (autoSyncTimer == null) {
568 autoSyncTimer = new Timer((int)autoSynchronizeDelay,new ActionListener() {
569 public void actionPerformed(ActionEvent e) {
570 if (allowAutoSync) synchronize();
571 autoSyncTimer.stop();
572 }
573 });
574 }
575 return autoSyncTimer;
576 }
577
578
579
580
581
582
583 public double getMinimum() {
584 return getRangedValue().getMinimum();
585 }
586
587
588
589
590
591
592 public double getMaximum() {
593 return getRangedValue().getMaximum();
594 }
595
596
597
598
599
600
601 public double getValue() {
602
603
604
605
606 return getRangedValue().getRawValue();
607 }
608
609
610
611
612
613
614 public void setUnits(String units) {
615 String oldValue = getUnits();
616 getNavigationBar().setUnits(units);
617 firePropertyChange("units",oldValue,units);
618 }
619
620
621
622
623
624
625 public String getUnits() {
626 return getNavigationBar().getUnits();
627 }
628
629
630
631
632
633
634 public void setUnitsVisible(boolean b) {
635 if (isUnitsVisible() == b) return;
636 getNavigationBar().setUnitsVisible(b);
637 firePropertyChange("unitsVisible",!b,b);
638 }
639
640
641
642
643
644
645 public boolean isUnitsVisible() {
646 return getNavigationBar().isUnitsVisible();
647 }
648
649
650 private double lastReadbackValue = Double.NaN;
651
652
653
654
655
656
657
658
659 public void setReadback(double value) {
660 double oldValue = getReadback();
661 getSliderUI().setTrailerPosition(value);
662 if (value < getMinimum() || value > getMaximum()) {
663 getNavigationBar().setValue(value);
664 }
665 if (autoSynchronize) {
666 if (lastReadbackValue != value) {
667 getAutoSyncTimer().restart();
668 } else {
669 if (!getAutoSyncTimer().isRunning()) {
670 getAutoSyncTimer().start();
671 }
672 }
673
674 }
675
676 lastReadbackValue = value;
677 firePropertyChange("readBack",oldValue,value);
678 if (!isEditable() || !isSyncButtonVisible()) {
679 synchronize();
680 }
681 }
682
683
684
685
686
687
688 private RangedValueController getRangedValue() {
689 if (rangedValue == null) {
690 rangedValue = new RangedValueController();
691 rangedValue.setRange(new LinearRange());
692 rangedValue.setScalingFactor(10000);
693 rangedValue.addRangedValueListener(new ValueListener());
694 }
695
696 return rangedValue;
697 }
698
699
700
701
702
703
704
705
706 public double getReadback() {
707 return getSliderUI().getTrailerPosition();
708 }
709
710
711
712
713
714
715
716 @Deprecated
717 public void setFormat(String s) {
718 String oldValue = getFormat();
719 setFieldFormat(s);
720 setTicksFormat(s);
721 firePropertyChange("format",oldValue,s);
722 }
723
724
725
726
727
728
729
730
731 @Deprecated
732 public String getFormat() {
733 return getFieldFormat();
734 }
735
736
737
738
739
740
741
742 public void setFieldFormat(String s) {
743 String oldValue = getFieldFormat();
744 getNavigationBar().setFormat(s);
745 if (Double.isNaN(storedValue)) {
746 getInfoBar().setStoredValue(null);
747 } else {
748 getInfoBar().setStoredValue(getNavigationBar().format(storedValue));
749 }
750 firePropertyChange("fieldFormat",oldValue,s);
751 }
752
753
754
755
756
757
758 public String getFieldFormat() {
759 return getNavigationBar().getFormat();
760 }
761
762 private RangedValuePolicy integerPolicy = new IntegerValuePolicy();
763
764
765
766
767
768
769
770
771 public void setTicksFormat(String ticksFormat) {
772 String oldValue = getTicksFormat();
773 if (ticksFormat.contains("%d")) {
774 showIntegerOnly = true;
775 getRangedValue().addPolicy(integerPolicy);
776
777 setValue(getValue());
778 } else {
779 getRangedValue().removePolicy(integerPolicy);
780 showIntegerOnly = false;
781 }
782 getSliderUI().setFormat(ticksFormat);
783 formatter = new PrintfFormat(ticksFormat);
784 firePropertyChange("ticksFormat",oldValue,ticksFormat);
785
786 repaint();
787 }
788
789
790
791
792
793
794 public String getTicksFormat() {
795 return getSliderUI().getFormat();
796 }
797
798
799
800
801
802
803 public String getTitle() {
804 return getInfoBar().getTitle();
805 }
806
807
808
809
810
811
812 public void setTitle(String title) {
813 String oldValue = getTitle();
814 this.title = title;
815 getInfoBar().setTitle(title);
816 firePropertyChange("title",oldValue,title);
817 }
818
819
820
821
822
823
824 public void setTitleVisible(boolean titleVisible) {
825 if (getTitleVisible() == titleVisible) return;
826 if (!titleVisible) {
827 title = getInfoBar().getTitle();
828 getInfoBar().setTitle(" ");
829 } else {
830 getInfoBar().setTitle(this.title);
831 }
832 firePropertyChange("titleVisible",!titleVisible,titleVisible);
833 }
834
835
836
837
838
839
840 public boolean getTitleVisible() {
841 return !getInfoBar().getTitle().equals("");
842 }
843
844
845
846
847
848
849 public void incrementSmall() {
850 if (isSmallStepRelative()) {
851 performInternalFractionSet(getSmallStep() / 100);
852 } else {
853 performInternalSet(getRangedValue().validate(getValue() + getSmallStep()));
854 }
855 }
856
857
858
859
860
861
862 public void incrementLarge() {
863 if (isLargeStepRelative() == true) {
864 performInternalFractionSet(getLargeStep() / 100);
865 } else {
866 performInternalSet(getRangedValue().validate(getValue() + getLargeStep()));
867 }
868 }
869
870
871
872
873
874
875 public void incrementBit() {
876 if (isBitStepRelative()) {
877 performInternalFractionSet(getBitStep() / 100);
878 } else {
879 performInternalSet(getRangedValue().validate(getValue() + getBitStep()));
880 }
881 }
882
883
884
885
886
887
888 public void decrementBit() {
889 if (isBitStepRelative()) {
890 performInternalFractionSet(-getBitStep() / 100);
891 } else {
892 performInternalSet(getRangedValue().validate(getValue() - getBitStep()));
893 }
894 }
895
896
897
898
899
900
901 public void decrementSmall() {
902 if (isSmallStepRelative()) {
903 performInternalFractionSet(-getSmallStep() / 100);
904 } else {
905 performInternalSet(getRangedValue().validate(getValue() - getSmallStep()));
906 }
907 }
908
909
910
911
912
913
914 public void decrementLarge() {
915 if (isLargeStepRelative()) {
916 performInternalFractionSet(-getLargeStep() / 100);
917 } else {
918 performInternalSet(getRangedValue().validate(getValue() - getLargeStep()));
919 }
920 }
921
922
923
924
925
926
927 public void setBitStep(double value) {
928 double oldValue = getBitStep();
929 bitStep = value;
930 firePropertyChange("bitStep",oldValue,value);
931 }
932
933
934
935
936
937
938 public double getBitStep() {
939 return bitStep;
940 }
941
942
943
944
945
946
947 public double getSmallStep() {
948 return smallStep;
949 }
950
951
952
953
954
955
956 public void setSmallStep(double value) {
957 double oldValue = getSmallStep();
958 smallStep = value;
959 firePropertyChange("smallStep",oldValue,value);
960 }
961
962
963
964
965
966
967 public void setLargeStep(double value) {
968 double oldValue = getLargeStep();
969 largeStep = value;
970 firePropertyChange("largeStep",oldValue,value);
971 }
972
973
974
975
976
977
978 public double getLargeStep() {
979 return largeStep;
980 }
981
982
983
984
985
986
987 public boolean isBitStepRelative() {
988 return isBitStepRelative;
989 }
990
991
992
993
994
995
996
997 public void setBitStepRelative(boolean value) {
998 if (isBitStepRelative() == value) return;
999 isBitStepRelative = value;
1000 firePropertyChange("bitStepRelative",!value,value);
1001 }
1002
1003
1004
1005
1006
1007
1008 public boolean isSmallStepRelative() {
1009 return isSmallStepRelative;
1010 }
1011
1012
1013
1014
1015
1016
1017
1018 public void setSmallStepRelative(boolean value) {
1019 if (isSmallStepRelative() == value) return;
1020 isSmallStepRelative = value;
1021 firePropertyChange("smallStepRelative",!value,value);
1022 }
1023
1024
1025
1026
1027
1028
1029 public boolean isLargeStepRelative() {
1030 return isLargeStepRelative;
1031 }
1032
1033
1034
1035
1036
1037
1038
1039 public void setLargeStepRelative(boolean value) {
1040 if (isLargeStepRelative() == value) return;
1041 isLargeStepRelative = value;
1042 firePropertyChange("largeStepRelative",!value,value);
1043 }
1044
1045
1046
1047
1048
1049
1050
1051 @Deprecated
1052 public int getMode() {
1053 return mode.ordinal();
1054 }
1055
1056
1057
1058
1059
1060
1061
1062
1063 @Deprecated
1064 public void setMode(int newMode) {
1065 setSetMode(SliderSetMode.valueOf(newMode));
1066 }
1067
1068
1069
1070
1071
1072
1073
1074 public void setSetMode(SliderSetMode mode) {
1075 SliderSetMode oldValue = getSetMode();
1076 this.mode = mode;
1077 getInfoBar().setSetButtonVisible(mode == SliderSetMode.SET_MANUAL);
1078 firePropertyChange("setMode",oldValue,this.mode);
1079 }
1080
1081
1082
1083
1084
1085
1086 public SliderSetMode getSetMode() {
1087 return mode;
1088 }
1089
1090
1091
1092
1093
1094
1095 public int measureTick(double position, String text) {
1096 if (text == null) {
1097 return 0;
1098 }
1099
1100 return getGraphics().getFontMetrics().stringWidth(text);
1101 }
1102
1103
1104
1105
1106
1107
1108
1109 public void setEditable(boolean settable) {
1110 this.settable = settable;
1111 getNavigationBar().setEnabled(settable && isEnabled());
1112 getInfoBar().setEnabled(settable && isEnabled());
1113 slider.setEnabled(settable && isEnabled());
1114 }
1115
1116
1117
1118
1119
1120
1121 public boolean isEditable() {
1122 return settable;
1123 }
1124
1125
1126
1127
1128
1129 public PopupManager getPopupManager() {
1130 if (popupManager == null) {
1131 popupManager = new PopupManager(this,false);
1132 popupManager.addAction(new AbstractAction("Synchronize") {
1133 private static final long serialVersionUID = 1L;
1134
1135 public void actionPerformed(ActionEvent e) {
1136 synchronize();
1137 }
1138 });
1139 popupManager.addAction(null);
1140 popupManager.addAction(new AbstractAction("Preferences...") {
1141 private static final long serialVersionUID = 1L;
1142
1143 public void actionPerformed(ActionEvent e) {
1144 getCustomizer().showDialog();
1145 }
1146 });
1147 }
1148
1149 return popupManager;
1150 }
1151
1152
1153
1154
1155
1156
1157 public AbstractCustomizerPanel getCustomizer() {
1158 if (customizer == null) {
1159 customizer = AbstractCustomizerPanel.findCustomizer(this);
1160 }
1161
1162 return customizer;
1163 }
1164
1165
1166
1167
1168
1169 public void synchronize() {
1170 synchronized (this) {
1171 supressPropChEvent = supressSetEvent = true;
1172 performInternalSet(getReadback());
1173 supressPropChEvent = supressSetEvent = false;
1174 }
1175 }
1176
1177
1178
1179
1180
1181 public void setManual() {
1182 if (mode == SliderSetMode.SET_MANUAL) {
1183 double oldValue = getValue();
1184 double value = getRangedValue().validate(getNavigationBar().getValue());
1185
1186 synchronized (this) {
1187 if (!supressChanges) {
1188 supressChanges = true;
1189
1190 getAutoSyncTimer().stop();
1191
1192 getRangedValue().setValue(value);
1193
1194 if (!isSuspended()) {
1195 fireSetPerformed(getValue());
1196 firePropertyChange("value",oldValue,getValue());
1197 }
1198
1199 if (autoSynchronize) {
1200 getAutoSyncTimer().restart();
1201 }
1202
1203 supressChanges = false;
1204 }
1205 }
1206 }
1207 }
1208
1209
1210
1211
1212
1213 public State getState() {
1214 State s = StateFactory.createState();
1215 s.putDouble("Min",getMinimum());
1216 s.putDouble("Max",getMaximum());
1217 s.putString("Format",getFormat());
1218 s.putString("Units",getUnits());
1219
1220 return s;
1221 }
1222
1223
1224
1225
1226
1227
1228
1229 public void setState(State state) {
1230 setMinimum(state.getDouble("Min",getMinimum()));
1231 setMaximum(state.getDouble("Max",getMaximum()));
1232 setFormat(state.getString("Format",getFormat()));
1233 setUnits(state.getString("Units",getUnits()));
1234 }
1235
1236
1237
1238
1239
1240
1241
1242 public boolean isPopupEnabled() {
1243 return popupEnabled;
1244 }
1245
1246
1247
1248
1249
1250
1251 public void setPopupEnabled(boolean b) {
1252 if (b == popupEnabled) return;
1253 popupEnabled = b;
1254 if (b) {
1255 getSlider().addMouseListener(getPopupManager().getMouseHook());
1256 addMouseListener(getPopupManager().getMouseHook());
1257 } else {
1258 getSlider().removeMouseListener(getPopupManager().getMouseHook());
1259 removeMouseListener(getPopupManager().getMouseHook());
1260 }
1261 firePropertyChange("popupEnabled",!b,b);
1262 }
1263
1264
1265
1266
1267
1268 @Override
1269 public String getToolTipText() {
1270 StringBuffer sb = new StringBuffer();
1271 sb.append("setpoint= ");
1272 sb.append(getNavigationBar().format(getValue()));
1273 sb.append(" readback= ");
1274 sb.append(getNavigationBar().format(getReadback()));
1275
1276 return sb.toString();
1277 }
1278
1279
1280
1281
1282
1283 public void suspend() {
1284 suspended++;
1285 setEnabled(false);
1286 }
1287
1288
1289
1290
1291
1292
1293
1294 public void resume() {
1295 if (suspended > 0) {
1296 suspended--;
1297 } else {
1298 setEnabled(true);
1299 }
1300 }
1301
1302
1303
1304
1305
1306
1307
1308 public boolean isSuspended() {
1309 return suspended > 0;
1310 }
1311
1312
1313
1314
1315
1316 @Override
1317 public void setEnabled(boolean enabled) {
1318 super.setEnabled(enabled);
1319 getSlider().setEnabled(enabled && settable);
1320 getNavigationBar().setEnabled(enabled && settable);
1321 getInfoBar().setEnabled(enabled && settable);
1322 }
1323
1324
1325
1326
1327
1328
1329 public boolean isAutoSynchronize() {
1330 return autoSynchronize;
1331 }
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341 public void setAutoSynchronize(boolean autoSynchronize) {
1342 if (isAutoSynchronize() == autoSynchronize) return;
1343 this.autoSynchronize = autoSynchronize;
1344 if (autoSynchronize) {
1345 getAutoSyncTimer().restart();
1346 } else {
1347 getAutoSyncTimer().stop();
1348 }
1349 firePropertyChange("autoSynchronize",!autoSynchronize,autoSynchronize);
1350 }
1351
1352
1353
1354
1355
1356
1357 public long getAutoSynchronizeDelay() {
1358 return autoSynchronizeDelay;
1359 }
1360
1361
1362
1363
1364
1365
1366 public void setAutoSynchronizeDelay(long autoSynchronizeDelay) {
1367 long oldValue = getAutoSynchronizeDelay();
1368 this.autoSynchronizeDelay = autoSynchronizeDelay;
1369
1370 getAutoSyncTimer().setDelay((int)autoSynchronizeDelay);
1371 getAutoSyncTimer().setInitialDelay((int)autoSynchronizeDelay);
1372 if (autoSynchronize) {
1373 getAutoSyncTimer().restart();
1374 } else {
1375 getAutoSyncTimer().stop();
1376 }
1377 firePropertyChange("autoSynchronizeDelay",oldValue,this.autoSynchronizeDelay);
1378
1379 }
1380
1381
1382
1383
1384
1385 private void modifySliderPosition() {
1386 getSlider().setValue((int)getRangedValue().getRelativeValue());
1387 repaint();
1388 }
1389
1390
1391
1392
1393
1394
1395
1396 public void setDragEnabled(boolean enabled) {
1397 if (isDragEnabled() == enabled) return;
1398 if (getTransferHandler() instanceof CosyTransferHandler) {
1399 if (((CosyTransferHandler)getTransferHandler()).isExportEnabled() == enabled) return;
1400
1401 ((CosyTransferHandler)getTransferHandler()).setExportEnabled(enabled,this);
1402 }
1403 firePropertyChange("dragEnabled",!enabled,enabled);
1404 }
1405
1406
1407
1408
1409
1410
1411 public boolean isDragEnabled() {
1412 if (getTransferHandler() instanceof CosyTransferHandler) {
1413 return ((CosyTransferHandler)getTransferHandler()).isExportEnabled();
1414 }
1415 return getTransferHandler() != null;
1416 }
1417
1418
1419
1420
1421
1422
1423
1424 public void setDropEnabled(boolean enabled) {
1425 if (isDropEnabled() == enabled) return;
1426 if (getTransferHandler() instanceof CosyTransferHandler) {
1427 if (((CosyTransferHandler)getTransferHandler()).isReceiveEnabled() == enabled) return;
1428
1429 ((CosyTransferHandler)getTransferHandler()).setReceiveEnabled(enabled,this);
1430 }
1431 firePropertyChange("dropEnabled",!enabled,enabled);
1432 }
1433
1434
1435
1436
1437
1438
1439 public boolean isDropEnabled() {
1440 if (getTransferHandler() instanceof CosyTransferHandler) {
1441 return ((CosyTransferHandler)getTransferHandler()).isReceiveEnabled();
1442 }
1443 return getTransferHandler() != null;
1444 }
1445
1446
1447
1448
1449
1450 @Override
1451 public void setBackground(Color bg) {
1452 super.setBackground(bg);
1453 getNavigationBar().setBackground(bg);
1454 getSlider().setBackground(bg);
1455 getInfoBar().setBackground(bg);
1456 }
1457
1458
1459
1460
1461
1462 @Override
1463 public void setForeground(Color fg) {
1464 super.setForeground(fg);
1465 getNavigationBar().setForeground(fg);
1466 getSlider().setForeground(fg);
1467 getInfoBar().setForeground(fg);
1468 }
1469
1470
1471
1472
1473
1474 public String formatNumber(double value) {
1475 return this.getFormatter().sprintf(value);
1476 }
1477
1478
1479
1480
1481
1482
1483
1484
1485 public void setButtonText(Button b, String text) {
1486 if (b == Button.FAST_INCREMENT || b == Button.FAST_DECREMENT || b == Button.SLOW_INCREMENT || b == Button.SLOW_DECREMENT
1487 || b == Button.BIT_INCREMENT || b == Button.BIT_DECREMENT) {
1488 getNavigationBar().setButtonText(b,text);
1489 }
1490 }
1491
1492
1493
1494
1495
1496
1497
1498
1499 public void setButtonIcon(Button b, Icon icon) {
1500 if (b == Button.FAST_INCREMENT || b == Button.FAST_DECREMENT || b == Button.SLOW_INCREMENT || b == Button.SLOW_DECREMENT
1501 || b == Button.BIT_INCREMENT || b == Button.BIT_DECREMENT) {
1502 getNavigationBar().setButtonIcon(b,icon);
1503 }
1504 }
1505
1506
1507
1508
1509
1510
1511
1512
1513 public String getButtonText(Button b) {
1514 if (b == Button.FAST_INCREMENT || b == Button.FAST_DECREMENT || b == Button.SLOW_INCREMENT || b == Button.SLOW_DECREMENT
1515 || b == Button.BIT_INCREMENT || b == Button.BIT_DECREMENT) {
1516 return getNavigationBar().getButtonText(b);
1517 }
1518 return null;
1519 }
1520
1521
1522
1523
1524
1525
1526
1527
1528 public Icon getButtonIcon(Button b) {
1529 if (b == Button.FAST_INCREMENT || b == Button.FAST_DECREMENT || b == Button.SLOW_INCREMENT || b == Button.SLOW_DECREMENT
1530 || b == Button.BIT_INCREMENT || b == Button.BIT_DECREMENT) {
1531 return getNavigationBar().getButtonIcon(b);
1532 }
1533 return null;
1534 }
1535
1536
1537
1538
1539
1540
1541
1542
1543 public void setButtonTooltip(Button b, String tooltip) {
1544 if (b == Button.FAST_INCREMENT || b == Button.FAST_DECREMENT || b == Button.SLOW_INCREMENT || b == Button.SLOW_DECREMENT
1545 || b == Button.BIT_INCREMENT || b == Button.BIT_DECREMENT) {
1546 getNavigationBar().setButtonTooltip(b,tooltip);
1547 }
1548 }
1549
1550
1551
1552
1553
1554
1555
1556
1557 public String getButtonTooltip(Button b) {
1558 if (b == Button.FAST_INCREMENT || b == Button.FAST_DECREMENT || b == Button.SLOW_INCREMENT || b == Button.SLOW_DECREMENT
1559 || b == Button.BIT_INCREMENT || b == Button.BIT_DECREMENT) {
1560 return getNavigationBar().getButtonTooltip(b);
1561 }
1562 return null;
1563 }
1564
1565
1566
1567
1568
1569
1570
1571 public void setButtonVisible(Button b, boolean visible) {
1572 if (b == Button.FAST_INCREMENT || b == Button.FAST_DECREMENT || b == Button.SLOW_INCREMENT || b == Button.SLOW_DECREMENT
1573 || b == Button.BIT_INCREMENT || b == Button.BIT_DECREMENT) {
1574 getNavigationBar().setButtonVisible(b,visible);
1575 }
1576 }
1577
1578
1579
1580
1581
1582
1583
1584 public boolean isButtonVisible(Button b) {
1585 if (b == Button.FAST_INCREMENT || b == Button.FAST_DECREMENT || b == Button.SLOW_INCREMENT || b == Button.SLOW_DECREMENT
1586 || b == Button.BIT_INCREMENT || b == Button.BIT_DECREMENT) {
1587 return getNavigationBar().isButtonVisible(b);
1588 }
1589 return false;
1590 }
1591
1592
1593
1594
1595
1596
1597 public void setStorageButtonsVisible(boolean visible) {
1598 if (isStorageButtonsVisible() == visible) return;
1599 getInfoBar().setStorageButtonsVisible(visible);
1600 firePropertyChange("storageButtonsVisible",!visible,visible);
1601 }
1602
1603
1604
1605
1606
1607
1608
1609
1610 public boolean isStoredValueLabelVisible() {
1611 return getInfoBar().isStoredValueLabelVisible();
1612 }
1613
1614
1615
1616
1617
1618
1619
1620
1621 public void setStoredValueLabelVisible(boolean visible) {
1622 if (isStoredValueLabelVisible() == visible) return;
1623 getInfoBar().setStoredValueLabelVisible(visible);
1624 firePropertyChange("storedValueLabelVisible",!visible,visible);
1625 }
1626
1627
1628
1629
1630
1631
1632 public boolean isStorageButtonsVisible() {
1633 return getInfoBar().isStorageButtonsVisible();
1634 }
1635
1636
1637
1638
1639
1640
1641 public void setSyncButtonVisible(boolean visible) {
1642 if (isSyncButtonVisible() == visible) return;
1643 getInfoBar().setSyncButtonVisible(visible);
1644 getSliderUI().setPaintTrailer(visible);
1645 firePropertyChange("syncButtonVisible",!visible,visible);
1646 }
1647
1648
1649
1650
1651
1652
1653 public boolean isSyncButtonVisible() {
1654 return getInfoBar().isSyncButtonVisible();
1655 }
1656
1657
1658
1659
1660
1661
1662
1663
1664 public void setValuePrecision(double precision) {
1665 getSliderUI().setTolerance(precision);
1666 }
1667
1668
1669
1670
1671
1672
1673
1674 public double getValuePrecision() {
1675 return getSliderUI().getTolerance();
1676 }
1677
1678
1679
1680
1681
1682
1683 public void setTitleFont(Font font) {
1684 Font oldFont = getTitleFont();
1685 getInfoBar().setFont(font);
1686 firePropertyChange("titleFont",oldFont,font);
1687 }
1688
1689
1690
1691
1692
1693
1694 public Font getTitleFont() {
1695 return getInfoBar().getFont();
1696 }
1697
1698
1699
1700
1701
1702
1703 public void setUnitsFont(Font font) {
1704 Font oldFont = getUnitsFont();
1705 getNavigationBar().setUnitsFont(font);
1706 firePropertyChange("unitsFont",oldFont,font);
1707 }
1708
1709
1710
1711
1712
1713
1714 public Font getUnitsFont() {
1715 return getNavigationBar().getFont();
1716 }
1717
1718
1719
1720
1721
1722
1723 public double[] getMajorTicks() {
1724 return manualTickProvider.getMajorTicks();
1725 }
1726
1727
1728
1729
1730
1731
1732
1733 public double[] getMajorTickLabels() {
1734 return manualTickProvider.getLabels();
1735 }
1736
1737
1738
1739
1740
1741
1742 public double getMinorTicksStep() {
1743 return manualTickProvider.getMinor();
1744 }
1745
1746
1747
1748
1749
1750
1751
1752 public void setMajorTicks(double[] ticks) {
1753 double[] oldValue = getMajorTicks();
1754 manualTickProvider.setMajorTicks(ticks);
1755 if (ticks != null) {
1756 getRangedValue().setTickCalculator(manualTickProvider);
1757 } else {
1758 getRangedValue().setTickCalculator(null);
1759 }
1760 repaint();
1761 firePropertyChange("majorTicks",oldValue,ticks);
1762 }
1763
1764
1765
1766
1767
1768
1769 public void setMinorTicksStep(double step) {
1770 double oldValue = getMinorTicksStep();
1771 if (oldValue == step) return;
1772 manualTickProvider.setMinor(step);
1773 firePropertyChange("minorTicksNumber",oldValue,step);
1774 if (getMajorTicks() != null) repaint();
1775 }
1776
1777
1778
1779
1780
1781
1782
1783 public void setMajorTickLabels(double[] labelledTicks) {
1784 double[] oldValue = getMajorTickLabels();
1785 manualTickProvider.setLabels(labelledTicks);
1786 firePropertyChange("majorTickLabels",oldValue,labelledTicks);
1787 if (getMajorTicks() != null) repaint();
1788 }
1789
1790
1791
1792
1793
1794
1795 public double getStoredValue() {
1796 return storedValue;
1797 }
1798
1799
1800
1801
1802
1803
1804
1805
1806 public void setStoredValue(double storedValue) {
1807 if (this.storedValue == storedValue) return;
1808 double oldValue = this.storedValue;
1809 this.storedValue = storedValue;
1810 if (Double.isNaN(storedValue)) {
1811 getInfoBar().setStoredValue(null);
1812 } else {
1813 getInfoBar().setStoredValue(getNavigationBar().format(storedValue));
1814 }
1815 firePropertyChange("storedValue",oldValue,storedValue);
1816 }
1817
1818
1819
1820
1821 public void storeValue() {
1822 setStoredValue(getValue());
1823 }
1824
1825
1826
1827
1828
1829
1830 public void restoreValue() {
1831 if (Double.isNaN(getStoredValue())) return;
1832 performInternalSet(getStoredValue());
1833 }
1834
1835
1836
1837
1838
1839
1840 public void setRestoreButtonTitle(String title) {
1841 String oldValue = getRestoreButtonTitle();
1842 if (oldValue != null && oldValue.equals(title)) return;
1843 getInfoBar().setRestoreButtonTitle(title);
1844 firePropertyChange("restoreButtonTitle",oldValue,title);
1845 }
1846
1847
1848
1849
1850
1851
1852 public String getRestoreButtonTitle() {
1853 return getInfoBar().getRestoreButtonTitle();
1854 }
1855
1856
1857
1858
1859
1860
1861 public int getContinuousModeDelayTime() {
1862 return getNavigationBar().getContinuousModeDelayTime();
1863 }
1864
1865
1866
1867
1868
1869
1870
1871 public void setContinuousModeDelayTime(int continuousModeDelayTime) {
1872 if (getContinuousModeDelayTime() == continuousModeDelayTime) return;
1873 int old = getContinuousModeDelayTime();
1874 getNavigationBar().setContinuousModeDelayTime(continuousModeDelayTime);
1875 firePropertyChange("continuousModeDelayTime",old,continuousModeDelayTime);
1876 }
1877
1878
1879
1880
1881
1882
1883 public boolean isContinuousModeEnabled() {
1884 return continuousModeEnabled;
1885 }
1886
1887
1888
1889
1890
1891
1892 public void setContinuousModeEnabled(boolean continuousModeEnabled) {
1893 if (this.continuousModeEnabled == continuousModeEnabled) return;
1894 this.continuousModeEnabled = continuousModeEnabled;
1895 this.getInfoBar().setContinuousMode(continuousModeEnabled);
1896 firePropertyChange("continuousModeEnabled",!continuousModeEnabled,continuousModeEnabled);
1897 }
1898
1899
1900
1901
1902
1903
1904 public int getContinuousModeRepeatTime() {
1905 return getNavigationBar().getContinuousModeRepeatTime();
1906 }
1907
1908
1909
1910
1911
1912
1913
1914 public void setContinuousModeRepeatTime(int continuousModeRepeatTime) {
1915 if (getContinuousModeRepeatTime() == continuousModeRepeatTime) return;
1916 int old = getContinuousModeRepeatTime();
1917 getNavigationBar().setContinuousModeRepeatTime(continuousModeRepeatTime);
1918 firePropertyChange("continuousModeRepeatTime",old,continuousModeRepeatTime);
1919 }
1920
1921
1922
1923
1924
1925
1926 public void setContinuousControlVisible(boolean continuousControlVisible) {
1927 if (this.continuousControlVisible == continuousControlVisible) return;
1928 this.continuousControlVisible = continuousControlVisible;
1929 this.getInfoBar().setContinuousModeVisible(continuousControlVisible);
1930 firePropertyChange("continuousControlVisible",!continuousControlVisible,continuousControlVisible);
1931 }
1932
1933
1934
1935
1936
1937
1938 public boolean isContinuousControlVisible() {
1939 return continuousControlVisible;
1940 }
1941
1942
1943
1944
1945
1946
1947 @Override
1948 public void setToolTipText(String tooltip) {
1949 super.setToolTipText(tooltip);
1950
1951 this.slider.setToolTipText(tooltip);
1952 this.getInfoBar().setToolTipText(tooltip);
1953 this.getNavigationBar().setToolTipText(tooltip);
1954 }
1955
1956
1957
1958
1959
1960
1961
1962 public void setSnapToTicks(boolean snapToTicks) {
1963 if (this.snapToTicks == snapToTicks) return;
1964 this.snapToTicks = snapToTicks;
1965 firePropertyChange("snapToTicks",!snapToTicks, snapToTicks);
1966 getRangedValue().setSnapToTicks(snapToTicks);
1967 }
1968
1969
1970
1971
1972
1973
1974
1975 public boolean isSnapToTicks() {
1976 return snapToTicks;
1977 }
1978
1979
1980
1981
1982
1983
1984
1985 public static void main(String[] args) {
1986 Slider sliderAmplitude = new Slider();
1987 sliderAmplitude.setPopupEnabled(true);
1988 sliderAmplitude.setTitle("Some title");
1989 sliderAmplitude.setToolTipText("Some tool tip text");
1990 sliderAmplitude.setUnits("Some unit");
1991 sliderAmplitude.setUnitsVisible(true);
1992 sliderAmplitude.setStorageButtonsVisible(true);
1993 sliderAmplitude.setStoredValue(0.0f);
1994 sliderAmplitude.setRestoreButtonTitle("OLD");
1995 sliderAmplitude.setSyncButtonVisible(false);
1996 sliderAmplitude.setAutoSynchronize(false);
1997 sliderAmplitude.setFormat("%3.2f");
1998 sliderAmplitude.setTicksFormat("%3.4f");
1999
2000
2001
2002
2003 sliderAmplitude.setMinimum(0.0);
2004 sliderAmplitude.setMaximum(100.0);
2005 RunnerHelper.runComponent(sliderAmplitude, 400,400);
2006 }
2007
2008 }
2009
2010