这是 SSCCE 上我之前问题的后续:
当用户输入无效值时,该 JSpinner 背景将变为红色,而当用户输入有效值时,该背景将变为白色。但是,如果值无效并且用户单击远离此字段的值,则该值将恢复为之前的值。
我想在发生这种情况时注意到/捕获并通知用户他键入的值未被使用,并禁用依赖于该值的任何其他功能。
如何修改以下代码来实现此目的?
public static void main(String[] args) {
// TODO Auto-generated method stub
JFrame F = new JFrame();
F.setVisible(true);
JPanel p = new JPanel();
final JSpinner spin2 = new JSpinner();
spin2.setModel(new SpinnerNumberModel(10, 10, 100, 1));
JComponent comp = spin2.getEditor();
JFormattedTextField field = (JFormattedTextField) comp.getComponent(0);
DefaultFormatter formatter = (DefaultFormatter) field.getFormatter();
formatter.setCommitsOnValidEdit(true);
((JSpinner.DefaultEditor)Position.getEditor()).getTextField().addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
//LOG.info("" + evt);
if ("editValid".equals(evt.getPropertyName())) {
if (Boolean.FALSE.equals(evt.getNewValue())) {
SpinnerNumberModel model = (SpinnerNumberModel) Position.getModel();
((JSpinner.DefaultEditor)Position.getEditor()).getTextField().setBackground(Color.RED);
((JSpinner.DefaultEditor)Position.getEditor()).getTextField().setToolTipText("Amount must be in range [ " + model.getMinimum() + " ... " + model.getMaximum() + " ] for this symbol");
}
else{
((JSpinner.DefaultEditor)Position.getEditor()).getTextField().setBackground(Color.WHITE);
}
}
}
});
p.add(spin2);
F.add(p);
F.pack();
F.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
最佳答案
如果您需要用户的输入即使在输入错误时也能保留,请将焦点丢失行为设置为PERSIST
。
如果您需要通知用户键入无效值,请向微调器的文本字段添加KeyListener
。该 KeyListener
将调用 commitEdit()
,如果用户的输入无效,则该方法将会失败,抛出一个已检查的异常,您将捕获该异常并通知用户。
如果您需要在失去焦点时通知用户无效值,请向微调器的文本字段添加一个FocusListener
。该 FocusListener
将调用 commitEdit()
,如果用户的输入无效,则该方法将会失败,抛出一个已检查的异常,您将捕获该异常并通知用户。
将它们放在一起:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.text.ParseException;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.JSpinner.DefaultEditor;
import javax.swing.SpinnerNumberModel;
public class Main {
public static void warn(final JSpinner spin) {
final JFormattedTextField jftf = ((DefaultEditor) spin.getEditor()).getTextField();
try {
spin.commitEdit(); //Try to commit given value.
jftf.setBackground(Color.WHITE); //If successfull the revert back to white background.
}
catch (final ParseException px) {
if (!jftf.getBackground().equals(Color.RED)) { //Guard.
jftf.setBackground(Color.RED); //Error value given.
//Inform user:
Toolkit.getDefaultToolkit().beep();
JOptionPane.showMessageDialog(spin, "Invalid value given in spinner!");
}
//else if the background is already red, means we already checked previously,
//so we do not inform the user again. We inform him only once.
}
}
public static void main(final String[] args) {
final JSpinner spin = new JSpinner(new SpinnerNumberModel());
spin.setPreferredSize(new Dimension(150, 30));
spin.addChangeListener(e -> warn(spin)); //Needed for reverting back to white if the user enters valid input.
final JFormattedTextField jftf = ((DefaultEditor) spin.getEditor()).getTextField();
jftf.setFocusLostBehavior(JFormattedTextField.PERSIST);
jftf.addKeyListener(new KeyAdapter() {
//Needed to inform user if they type something wrong:
@Override public void keyReleased(final KeyEvent kevt) { warn(spin); }
});
jftf.addFocusListener(new FocusAdapter() {
//Needed to inform user if the text field loses focus and has a wrong value:
@Override public void focusLost(final FocusEvent fevt) { warn(spin); }
});
final JPanel contents = new JPanel(); //FlowLayout.
contents.add(new JLabel("Spinning values:", JLabel.CENTER));
contents.add(spin);
final JFrame frame = new JFrame("JSpinner mouse");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(contents);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
关于java - 当 JSpinner 失去焦点时用户输入无效值时如何 'notice/trap",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20966239/