1
2
3
4
5
6 package io.github.olyutorskii.quetexj;
7
8 import java.awt.EventQueue;
9 import javax.swing.BoundedRangeModel;
10 import javax.swing.ButtonModel;
11 import javax.swing.DefaultButtonModel;
12
13
14
15
16
17
18
19
20
21
22
23
24 public class MaxTracker {
25
26
27 private static final int VAL_INVALID = -1;
28
29
30 private final BoundedRangeModel rangeModel;
31 private final ButtonModel trackModeModel;
32
33
34 private int trackStartPos;
35
36
37
38
39
40
41
42 public MaxTracker(BoundedRangeModel rangeModel) {
43 this(rangeModel, new DefaultButtonModel());
44 return;
45 }
46
47
48
49
50
51
52
53 public MaxTracker(
54 BoundedRangeModel rangeModel,
55 ButtonModel trackModeModel) {
56 super();
57
58 this.rangeModel = rangeModel;
59 this.trackModeModel = trackModeModel;
60
61 this.rangeModel.addChangeListener(ev -> {
62 eventBoundedRangeChanged();
63 });
64
65 this.trackModeModel.addItemListener(ev -> {
66 eventTrackModeChanged();
67 });
68
69 resetTrackStartPos();
70
71 return;
72 }
73
74
75
76
77
78
79
80 public BoundedRangeModel getBoundedRangeModel() {
81 return this.rangeModel;
82 }
83
84
85
86
87
88
89 public ButtonModel getButtonModel() {
90 return this.trackModeModel;
91 }
92
93
94
95
96
97
98
99
100 public boolean isTrackingMode() {
101 boolean result = this.trackModeModel.isSelected();
102 return result;
103 }
104
105
106
107
108
109
110
111
112
113
114
115
116 public void setTrackingMode(boolean tracking) {
117 if (EventQueue.isDispatchThread()) {
118 setTrackingModeImpl(tracking);
119 } else {
120 EventQueue.invokeLater(() -> {
121 setTrackingModeImpl(tracking);
122 });
123 }
124 return;
125 }
126
127
128
129
130
131
132
133
134 private void setTrackingModeImpl(boolean tracking) {
135 boolean oldCond = isTrackingMode();
136 if (tracking == oldCond) return;
137
138 this.trackModeModel.setSelected(tracking);
139
140 return;
141 }
142
143
144
145
146
147
148 private boolean isHandAdjusting() {
149 boolean result = this.rangeModel.getValueIsAdjusting();
150 return result;
151 }
152
153
154
155
156
157
158 private boolean isKnobTouchMax() {
159 int val = this.rangeModel.getValue();
160 int max = this.rangeModel.getMaximum();
161 int extent = this.rangeModel.getExtent();
162
163 boolean touchMax = val + extent >= max;
164 return touchMax;
165 }
166
167
168
169
170 private void setTrackStartPos() {
171 this.trackStartPos = this.rangeModel.getValue();
172 return;
173 }
174
175
176
177
178 private void resetTrackStartPos() {
179 this.trackStartPos = VAL_INVALID;
180 return;
181 }
182
183
184
185
186
187
188 private boolean keepingTrackStartPos() {
189 int modelVal = this.rangeModel.getValue();
190 boolean result = this.trackStartPos == modelVal;
191 return result;
192 }
193
194
195
196
197
198
199
200
201
202 private void forceKnobTouchMax() {
203 if (isKnobTouchMax()) return;
204 if (isHandAdjusting()) return;
205
206 int max = this.rangeModel.getMaximum();
207 int extent = this.rangeModel.getExtent();
208 int newVal = max - extent;
209 this.rangeModel.setValue(newVal);
210
211 return;
212 }
213
214
215
216
217
218
219
220
221
222
223
224
225
226 private void checkTrackingByKnob() {
227 boolean knobTouchMax = isKnobTouchMax();
228 if (knobTouchMax) {
229 setTrackingMode(true);
230 setTrackStartPos();
231 } else if (!keepingTrackStartPos()) {
232 setTrackingMode(false);
233 }
234
235 return;
236 }
237
238
239
240
241 private void eventBoundedRangeChanged() {
242 if (isHandAdjusting()) {
243 checkTrackingByKnob();
244 return;
245 } else {
246 resetTrackStartPos();
247 }
248
249 if (isTrackingMode()) {
250 forceKnobTouchMax();
251 }
252
253 return;
254 }
255
256
257
258
259
260
261 private void eventTrackModeChanged() {
262 if (isTrackingMode()) {
263 forceKnobTouchMax();
264 }
265 return;
266 }
267
268 }