Как проверить JTextField?

Как проверить текстовое поле, чтобы ввести только 4 цифры после десятичной точки в Swing?

Ответ 1

Любая проверка в Swing может выполняться с помощью InputVerifier.

1. Сначала создайте свой собственный верификатор ввода:

public class MyInputVerifier extends InputVerifier {
    @Override
    public boolean verify(JComponent input) {
        String text = ((JTextField) input).getText();
        try {
            BigDecimal value = new BigDecimal(text);
            return (value.scale() <= Math.abs(4)); 
        } catch (NumberFormatException e) {
            return false;
        }
    }
}

2. Затем назначьте экземпляр этого класса в текстовое поле. (Фактически любой JComponent можно проверить)

myTextField.setInputVerifier(new MyInputVerifier());

Конечно, вы также можете использовать анонимный внутренний класс, но если валидатор должен использоваться и на других компонентах, нормальный класс лучше.

Также ознакомьтесь с документацией SDK: JComponent # setInputVerifier.

Ответ 2

Возможно, вы можете сделать то же самое с DocumentListener. Все, что вам нужно сделать, это проверить входную строку на нужный шаблон строки. В этом случае шаблон представляется одной или несколькими цифрами, за которыми следует период, и ровно 4 цифры после десятичной точки. Код ниже демонстрирует использование DocumentListener для выполнения этого:

public class Dummy
{
  private static JTextField field = new JTextField(10);
  private static JLabel errorMsg = new JLabel("Invalid input");
  private static String pattern = "\\d+\\.\\d{4}";
  private static JFrame frame = new JFrame();
  private static JPanel panel = new JPanel();

  public static void main(String[] args)
  {
    errorMsg.setForeground(Color.RED);
    panel.setLayout(new GridBagLayout());
    GridBagConstraints c = new GridBagConstraints();
    c.insets = new Insets(5, 0, 0, 5);
    c.gridx = 1;
    c.gridy = 0;
    c.anchor = GridBagConstraints.SOUTH;
    panel.add(errorMsg, c);

    c.gridx = 1;
    c.gridy = 1;
    c.anchor = GridBagConstraints.CENTER;
    panel.add(field, c);

    frame.getContentPane().add(panel);
    field.getDocument().addDocumentListener(new DocumentListener()
    {
      @Override
      public void removeUpdate(DocumentEvent e)
      {
        validateInput();
      }

      @Override
      public void insertUpdate(DocumentEvent e)
      {
        validateInput();
      }

      @Override
      public void changedUpdate(DocumentEvent e) {} // Not needed for plain-text fields
  });

    frame.setSize(200, 200);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);
  }

  private static void validateInput()
  {
    String text = field.getText();
    Pattern r = Pattern.compile(pattern);
    Matcher m = r.matcher(text);
    if (m.matches())
    {
      errorMsg.setForeground(frame.getBackground());
    }
    else
    {
      errorMsg.setForeground(Color.RED);
    }
  }
}

Пока текстовое поле не содержит допустимого ввода, сообщение об ошибке отображается, как показано ниже.

недопустимый ввод

После подтверждения ввода сообщение об ошибке не будет видно.

действительный ввод

Конечно, вы можете заменить действие проверки на все, что вам нужно. Например, вы можете отображать некоторые всплывающие окна при нажатии кнопки, если вход недействителен и т.д.

Я бросил это вместе, чтобы показать альтернативу уже полученному ответу. Могут быть случаи, когда это решение может быть более подходящим. Бывают случаи, когда данный ответ может быть более подходящим. Но одно можно сказать наверняка, альтернативы всегда хорошие.