Skip to content

Commit d06dabb

Browse files
committed
WIP
1 parent 539fd61 commit d06dabb

File tree

1 file changed

+78
-22
lines changed

1 file changed

+78
-22
lines changed

src/main/java/org/scijava/ui/swing/widget/SwingNumberWidget.java

+78-22
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030

3131
package org.scijava.ui.swing.widget;
3232

33-
import java.awt.Adjustable;
3433
import java.awt.Component;
3534
import java.awt.Dimension;
3635
import java.awt.event.AdjustmentEvent;
@@ -84,7 +83,7 @@ public class SwingNumberWidget extends SwingInputWidget<Number> implements
8483
@Parameter
8584
private LogService log;
8685

87-
private JScrollBar scrollBar;
86+
private CalibratedScrollBar scrollBar;
8887
private CalibratedSlider slider;
8988
private JSpinner spinner;
9089

@@ -121,6 +120,9 @@ else if (model.isStyle(NumberWidget.SLIDER_STYLE)) {
121120
final SpinnerNumberModel spinnerModel =
122121
new SpinnerNumberModelFactory().createModel(value, min, max, stepSize);
123122
spinner = new JSpinner(spinnerModel);
123+
Dimension spinnerSize = spinner.getSize();
124+
spinnerSize.width = 50;
125+
spinner.setPreferredSize(spinnerSize);
124126
fixSpinner(type);
125127
setToolTip(spinner);
126128
getComponent().add(spinner);
@@ -143,7 +145,7 @@ public boolean supports(final WidgetModel model) {
143145
@Override
144146
public void adjustmentValueChanged(final AdjustmentEvent e) {
145147
// sync spinner with scroll bar value
146-
final int value = scrollBar.getValue();
148+
final Number value = scrollBar.getCalibratedValue();
147149
spinner.setValue(value);
148150
}
149151

@@ -168,9 +170,9 @@ else if (source == spinner) {
168170

169171
@Override
170172
public void mouseWheelMoved(final MouseWheelEvent e) {
171-
int value = getValue().intValue() + e.getWheelRotation(); // TODO convert from wheel rotations to steps on the slider
172-
value = Math.min(value, this.get().getMax().intValue());
173-
value = Math.max(value, this.get().getMin().intValue());
173+
Number value = getValue().doubleValue() + e.getWheelRotation() * get().getStepSize().doubleValue();
174+
value = Math.min(value.doubleValue(), this.get().getMax().doubleValue());
175+
value = Math.max(value.doubleValue(), this.get().getMin().doubleValue());
174176
spinner.setValue(value);
175177
syncSliders();
176178
}
@@ -184,14 +186,17 @@ private void addScrollBar(final Number min, final Number max,
184186
log.warn("Invalid min/max/step; cannot render scroll bar");
185187
return;
186188
}
187-
int mn = min.intValue();
188-
if (mn == Integer.MIN_VALUE) mn = Integer.MIN_VALUE + 1;
189-
int mx = max.intValue();
190-
if (mx < Integer.MAX_VALUE) mx++;
191-
final int st = step.intValue();
192-
193-
scrollBar = new JScrollBar(Adjustable.HORIZONTAL, mn, 1, mn, mx);
194-
scrollBar.setUnitIncrement(st);
189+
190+
// TODO Integer cases can possibly be handled in a simpler way
191+
int sMin = 0;
192+
int sMax = (int) ((max.doubleValue() - min.doubleValue()) / step.doubleValue());
193+
long range = sMax - sMin;
194+
if (range > Integer.MAX_VALUE) {
195+
log.warn("Scrollbar span too large; max - min < 2^31 required.");
196+
return;
197+
}
198+
199+
scrollBar = new CalibratedScrollBar(min, max, step);
195200
setToolTip(scrollBar);
196201
getComponent().add(scrollBar);
197202
scrollBar.addAdjustmentListener(this);
@@ -205,7 +210,8 @@ private void addSlider(final Number min, final Number max,
205210
log.warn("Invalid min/max/step; cannot render slider");
206211
return;
207212
}
208-
// TODO Integer cases can be handled in a simpler way
213+
214+
// TODO Integer cases can possibly be handled in a simpler way
209215
int sMin = 0;
210216
int sMax = (int) ((max.doubleValue() - min.doubleValue()) / step.doubleValue());
211217
long range = sMax - sMin;
@@ -214,7 +220,6 @@ private void addSlider(final Number min, final Number max,
214220
return;
215221
}
216222

217-
// slider = new JSlider(sMin, sMax, sMin);
218223
slider = new CalibratedSlider(min, max, step);
219224

220225
setToolTip(slider);
@@ -307,7 +312,7 @@ public void run() {
307312
private void syncSliders() {
308313
if (slider != null) {
309314
// clamp value within slider bounds
310-
Number value = getValue().intValue();
315+
Number value = getValue();
311316
if (value.doubleValue() < slider.getCalibratedMinimum().doubleValue()) value = slider.getCalibratedMinimum();
312317
else if (value.doubleValue() > slider.getCalibratedMaximum().doubleValue()) value = slider.getCalibratedMaximum();
313318
slider.removeChangeListener(this);
@@ -316,11 +321,11 @@ private void syncSliders() {
316321
}
317322
if (scrollBar != null) {
318323
// clamp value within scroll bar bounds
319-
int value = getValue().intValue();
320-
if (value < scrollBar.getMinimum()) value = scrollBar.getMinimum();
321-
else if (value > scrollBar.getMaximum()) value = scrollBar.getMaximum();
324+
Number value = getValue();
325+
if (value.doubleValue() < scrollBar.getCalibratedMinimum().doubleValue()) value = scrollBar.getCalibratedMinimum();
326+
else if (value.doubleValue() > scrollBar.getCalibratedMaximum().doubleValue()) value = scrollBar.getCalibratedMaximum();
322327
scrollBar.removeAdjustmentListener(this);
323-
scrollBar.setValue(getValue().intValue());
328+
scrollBar.setCalibratedValue(value);
324329
scrollBar.addAdjustmentListener(this);
325330
}
326331
}
@@ -409,7 +414,7 @@ private Number getCalibratedMaximum() {
409414
}
410415

411416
private int fromCalibrated(Number n) {
412-
return (int) ((n.doubleValue() - min.doubleValue()) / stepSize.doubleValue());
417+
return (int) Math.round((n.doubleValue() - min.doubleValue()) / stepSize.doubleValue());
413418
}
414419

415420
private Number toCalibrated(int n) {
@@ -421,4 +426,55 @@ private JLabel makeLabel(Number n, int scale) {
421426
}
422427

423428
}
429+
430+
private class CalibratedScrollBar extends JScrollBar {
431+
432+
private Number min;
433+
private Number max;
434+
private Number stepSize;
435+
436+
private CalibratedScrollBar(final Number min, final Number max, final Number stepSize) {
437+
// set extent to 1 to make sure the scroll bar is visible
438+
super(HORIZONTAL, 0, 1, 0, 1);
439+
440+
this.min = min;
441+
this.max = max;
442+
this.stepSize = stepSize;
443+
444+
int sMin = 0;
445+
int sMax = (int) ((max.doubleValue() - min.doubleValue()) / stepSize.doubleValue()) + 1;
446+
447+
// Adjust max to be an integer multiple of stepSize
448+
this.max = min.doubleValue() + (sMax-sMin) * stepSize.doubleValue();
449+
450+
setMinimum(sMin);
451+
setMaximum(sMax);
452+
setValue(sMin);
453+
}
454+
455+
private void setCalibratedValue(Number value) {
456+
setValue(fromCalibrated(value));
457+
}
458+
459+
private Number getCalibratedValue() {
460+
return toCalibrated(getValue());
461+
}
462+
463+
private Number getCalibratedMinimum() {
464+
return min;
465+
}
466+
467+
private Number getCalibratedMaximum() {
468+
return max;
469+
}
470+
471+
private int fromCalibrated(Number n) {
472+
return (int) Math.round((n.doubleValue() - min.doubleValue()) / stepSize.doubleValue());
473+
}
474+
475+
private Number toCalibrated(int n) {
476+
return n * stepSize.doubleValue() + min.doubleValue();
477+
}
478+
479+
}
424480
}

0 commit comments

Comments
 (0)