Skip to content

Commit 3d3b555

Browse files
committed
Add focus listener to JSpinner text
This (mostly) ensures the text of a JSpinner is selected on focus. On OSX it seems to always work with tabs, and mostly work with mouse clicking. However there does seem to be a race condition where the text selection can be lost, presumably from the JSPinner firing a validation event after the text field's selection has been processed. See #12 for future work.
1 parent 97e63cf commit 3d3b555

File tree

1 file changed

+45
-0
lines changed

1 file changed

+45
-0
lines changed

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

+45
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,12 @@
3131
package org.scijava.ui.swing.widget;
3232

3333
import java.awt.Adjustable;
34+
import java.awt.Component;
3435
import java.awt.Dimension;
3536
import java.awt.event.AdjustmentEvent;
3637
import java.awt.event.AdjustmentListener;
38+
import java.awt.event.FocusEvent;
39+
import java.awt.event.FocusListener;
3740
import java.math.BigDecimal;
3841
import java.math.BigInteger;
3942
import java.text.DecimalFormat;
@@ -44,7 +47,9 @@
4447
import javax.swing.JScrollBar;
4548
import javax.swing.JSlider;
4649
import javax.swing.JSpinner;
50+
import javax.swing.JTextField;
4751
import javax.swing.SpinnerNumberModel;
52+
import javax.swing.SwingUtilities;
4853
import javax.swing.event.ChangeEvent;
4954
import javax.swing.event.ChangeListener;
5055

@@ -121,6 +126,9 @@ else if (model.isStyle(NumberWidget.SLIDER_STYLE)) {
121126
final SpinnerNumberModel spinnerModel =
122127
new SpinnerNumberModelFactory().createModel(value, min, max, stepSize);
123128
spinner = new JSpinner(spinnerModel);
129+
130+
fixSpinnerFocus();
131+
124132
fixSpinner(type);
125133
setToolTip(spinner);
126134
getComponent().add(spinner);
@@ -200,6 +208,43 @@ private void fixSpinner(final Class<?> type) {
200208
}
201209
}
202210

211+
/**
212+
* Adapted from <a href=
213+
* "http://stackoverflow.com/questions/20971050/jspinner-autoselect-onfocus"
214+
* >this SO post</a>.
215+
*
216+
* Tries to ensure that the text of a {@link JSpinner} is selected when it
217+
* has focus.
218+
*/
219+
private void fixSpinnerFocus() {
220+
for (final Component c : spinner.getEditor().getComponents()) {
221+
if (JTextField.class.isAssignableFrom(c.getClass())) {
222+
c.addFocusListener(new FocusListener() {
223+
224+
@Override
225+
public void focusGained(final FocusEvent e) {
226+
queueSelection();
227+
}
228+
229+
@Override
230+
public void focusLost(final FocusEvent e) {
231+
queueSelection();
232+
}
233+
234+
private void queueSelection() {
235+
SwingUtilities.invokeLater(new Runnable() {
236+
@Override
237+
public void run() {
238+
((JTextField) c).selectAll();
239+
}
240+
});
241+
}
242+
243+
});
244+
}
245+
}
246+
}
247+
203248
/** Sets slider values to match the spinner. */
204249
private void syncSliders() {
205250
if (slider != null) {

0 commit comments

Comments
 (0)