3131package org .scijava .ui .swing .widget ;
3232
3333import java .awt .Adjustable ;
34+ import java .awt .Component ;
3435import java .awt .Dimension ;
3536import java .awt .event .AdjustmentEvent ;
3637import java .awt .event .AdjustmentListener ;
38+ import java .awt .event .FocusEvent ;
39+ import java .awt .event .FocusListener ;
3740import java .math .BigDecimal ;
3841import java .math .BigInteger ;
3942import java .text .DecimalFormat ;
4447import javax .swing .JScrollBar ;
4548import javax .swing .JSlider ;
4649import javax .swing .JSpinner ;
50+ import javax .swing .JTextField ;
4751import javax .swing .SpinnerNumberModel ;
4852import javax .swing .event .ChangeEvent ;
4953import javax .swing .event .ChangeListener ;
5054
55+ import org .scijava .plugin .Parameter ;
5156import org .scijava .plugin .Plugin ;
57+ import org .scijava .thread .ThreadService ;
5258import org .scijava .util .NumberUtils ;
5359import org .scijava .widget .InputWidget ;
5460import org .scijava .widget .NumberWidget ;
@@ -64,6 +70,9 @@ public class SwingNumberWidget extends SwingInputWidget<Number> implements
6470 NumberWidget <JPanel >, AdjustmentListener , ChangeListener
6571{
6672
73+ @ Parameter
74+ private ThreadService threadService ;
75+
6776 private JScrollBar scrollBar ;
6877 private JSlider slider ;
6978 private JSpinner spinner ;
@@ -121,6 +130,9 @@ else if (model.isStyle(NumberWidget.SLIDER_STYLE)) {
121130 final SpinnerNumberModel spinnerModel =
122131 new SpinnerNumberModelFactory ().createModel (value , min , max , stepSize );
123132 spinner = new JSpinner (spinnerModel );
133+
134+ fixSpinnerFocus ();
135+
124136 fixSpinner (type );
125137 setToolTip (spinner );
126138 getComponent ().add (spinner );
@@ -200,6 +212,43 @@ private void fixSpinner(final Class<?> type) {
200212 }
201213 }
202214
215+ /**
216+ * Adapted from <a href=
217+ * "http://stackoverflow.com/q/20971050/1027800"
218+ * >this SO post</a>.
219+ *
220+ * Tries to ensure that the text of a {@link JSpinner} is selected when it
221+ * has focus.
222+ */
223+ private void fixSpinnerFocus () {
224+ for (final Component c : spinner .getEditor ().getComponents ()) {
225+ if (JTextField .class .isAssignableFrom (c .getClass ())) {
226+ c .addFocusListener (new FocusListener () {
227+
228+ @ Override
229+ public void focusGained (final FocusEvent e ) {
230+ queueSelection ();
231+ }
232+
233+ @ Override
234+ public void focusLost (final FocusEvent e ) {
235+ queueSelection ();
236+ }
237+
238+ private void queueSelection () {
239+ threadService .queue (new Runnable () {
240+ @ Override
241+ public void run () {
242+ ((JTextField ) c ).selectAll ();
243+ }
244+ });
245+ }
246+
247+ });
248+ }
249+ }
250+ }
251+
203252 /** Sets slider values to match the spinner. */
204253 private void syncSliders () {
205254 if (slider != null ) {
0 commit comments