问题
I am trying to make a JSpinner (containing a minute/second timer) work for a bunch of set-in-their-ways folks who don't care beans about the mouse but want every keystroke to do exactly what they are used to. It works almost as I'd like it to but the last mile is the hardest.
What this means in practice is that the spinner should look and behave when one of its text fields gains focus exactly as it looks and behaves after the user has pressed an arrow key from one of those fields.
Spinner is created as follows:
this.countdown = new JSpinner(this.model);
this.editor = new JSpinner.DateEditor(countdown, "m:ss");
JFormattedTextField textField = editor.getTextField();
step 1. When my spinner comes up it looks like this: ('|' indicates the caret, bold indicates the selction)
|1:00
(Nothing is selected)
step 2. If Up Arrow is pressed from here It looks like this:
2|:00
(2 in minutes field is selected)
step 3. If Right Arrow is pressed from here we get:
2:|00
(Nothing is selected)
step 4. If Up Arrow is pressed from here we get
2:01|
(01 in seconds field is selected)
I'd like it to work in all these cases as it does in steps 2 and 4. When one of the subfields gains focus, it should be selected.
Is there any way to make this happen?
回答1:
Maybe you can use a FocusListener.
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
public class SpinnerFocusTest {
private static final String PATTERN = "m:ss";
public JComponent makeUI() {
Calendar c = Calendar.getInstance();
c.setTimeInMillis(60*1000);
Date value = c.getTime();
SpinnerDateModel m = new SpinnerDateModel(
value, null, null, Calendar.MINUTE);
JSpinner sp1 = new JSpinner(m);
sp1.setEditor(new JSpinner.DateEditor(sp1, PATTERN));
JSpinner sp2 = new JSpinner(m);
final JSpinner.DateEditor editor =
new JSpinner.DateEditor(sp2, PATTERN);
sp2.setEditor(editor);
editor.getTextField().addFocusListener(new FocusAdapter() {
@Override public void focusGained(FocusEvent e) {
EventQueue.invokeLater(new Runnable() {
@Override public void run() {
JTextField f = editor.getTextField();
int i = f.getText().lastIndexOf(":");
f.select(i+1, i+3);
}
});
}
});
JPanel p = new JPanel(new GridLayout(2,1,5,5));
p.add(sp1);
p.add(sp2);
JPanel panel = new JPanel(new BorderLayout());
panel.add(p, BorderLayout.NORTH);
panel.setBorder(BorderFactory.createEmptyBorder(8,8,8,8));
return panel;
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override public void run() {
createAndShowGUI();
}
});
}
public static void createAndShowGUI() {
JFrame f = new JFrame("");
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new SpinnerFocusTest().makeUI());
f.setSize(320, 240);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
来源:https://stackoverflow.com/questions/16470613/howto-select-jspinner-date-field-when-jspinner-gets-focus