java - 当 JSpinner 失去焦点时用户输入无效值时如何 'notice/trap"

标签 java jspinner

这是 SSCCE 上我之前问题的后续:

Previous Question

当用户输入无效值时,该 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/

相关文章:

java - 使用maven将java文件打包成exe for windows

java - 从 jOptionPane 中的 jSpinner 获取值

java - 在 JSpinner 中显示货币

java - 在 JSpinner 中的值后面添加一个字符串

java - Float 和 BigDecimal 精度差异

java - ConcurrentHashMap 中的并发级别

java - 如何在cxf拦截器中获取camel交换

java - 无法找到命名空间 http ://www. 的 NamespaceHandler mulesoft.org/schema/mule/jersey

java - 从 JSpinner (SWING) 获取值

Java - 如何获取 JSpinner 所选项目的索引?