Skip to content

Commit

Permalink
Add focus listener to JSpinner text
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
hinerm committed Apr 30, 2015
1 parent 97e63cf commit 3d3b555
Showing 1 changed file with 45 additions and 0 deletions.
45 changes: 45 additions & 0 deletions src/main/java/org/scijava/ui/swing/widget/SwingNumberWidget.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,12 @@
package org.scijava.ui.swing.widget;

import java.awt.Adjustable;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.DecimalFormat;
Expand All @@ -44,7 +47,9 @@
import javax.swing.JScrollBar;
import javax.swing.JSlider;
import javax.swing.JSpinner;
import javax.swing.JTextField;
import javax.swing.SpinnerNumberModel;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

Expand Down Expand Up @@ -121,6 +126,9 @@ else if (model.isStyle(NumberWidget.SLIDER_STYLE)) {
final SpinnerNumberModel spinnerModel =
new SpinnerNumberModelFactory().createModel(value, min, max, stepSize);
spinner = new JSpinner(spinnerModel);

fixSpinnerFocus();

fixSpinner(type);
setToolTip(spinner);
getComponent().add(spinner);
Expand Down Expand Up @@ -200,6 +208,43 @@ private void fixSpinner(final Class<?> type) {
}
}

/**
* Adapted from <a href=
* "http://stackoverflow.com/questions/20971050/jspinner-autoselect-onfocus"

This comment has been minimized.

Copy link
@ctrueden

ctrueden Apr 30, 2015

Member

Use the shorter "share" link (minus your personal SO ID) for linking more succinctly.

* >this SO post</a>.
*
* Tries to ensure that the text of a {@link JSpinner} is selected when it
* has focus.
*/
private void fixSpinnerFocus() {
for (final Component c : spinner.getEditor().getComponents()) {
if (JTextField.class.isAssignableFrom(c.getClass())) {
c.addFocusListener(new FocusListener() {

@Override
public void focusGained(final FocusEvent e) {
queueSelection();
}

@Override
public void focusLost(final FocusEvent e) {
queueSelection();
}

private void queueSelection() {
SwingUtilities.invokeLater(new Runnable() {

This comment has been minimized.

Copy link
@ctrueden

ctrueden Apr 30, 2015

Member

Use ThreadService.queue

@Override
public void run() {
((JTextField) c).selectAll();
}
});
}

});
}
}
}

/** Sets slider values to match the spinner. */
private void syncSliders() {
if (slider != null) {
Expand Down

0 comments on commit 3d3b555

Please sign in to comment.