Java Swing: Implementing a validity check of input

2019-02-06 20:50发布

问题:

In my Swing application, the user must insert numbers and values, before switching to the next window. Now as a clean program should, I check every input if its valid or not, and if not, an error message is displayed and the next window does not open.

The structure of this check is as following (example):

Button buttonToOpenNextWindow = new JButton("next");
button.addActionListener(new ActionListener(){

    public void actionPerformed(ActionEvent e){
        if(checkValidty){
            // (...)
            new WindowA();
            frame.dispose(); // (*)
        }
    }
});

(*) Note: I know that the principle of multiple JFrames is ugly, and I'm on to change that, but for this question it's irrelevant.

Now the focus of this question is this checkValidity(), which I structured like this:

private boolean checkValidity(){

    // check input 1
    try{
        Integer.parseInt(textField1.getText());
    }catch (NumberFormatException e){
        new ErrorDialog("input 1 is invalid!"); // own implemented dialog
        return false;
    }

    // check input 2
    try{
        Integer.parseInt(textField2.getText());
    }catch (NumberFormatException e){
        new ErrorDialog("input 2 is invalid!"); // own implemented dialog
        return false;
    }

    // (...)

    // check input n
    try{
        Integer.parseInt(textField_n.getText());
    }catch (NumberFormatException e){
        new ErrorDialog("input n is invalid!"); // own implemented dialog
        return false;
    }
    return true;
}

This works exactly as I want, BUT the code itself is very ugly, because having multiple input options the method gets 200, 300 or more lines long (as I do not only check if e.g. it's a number, but also if the number makes sense in context of the program logic and so on). Is there a Swing -own method to check such things? Or has anyone a better idea how to realize exactly this functionality with split methods?

回答1:

One solution would be to use Swing's InputVerifier to validate input for every JTextField used. As the validation functionality is the same for each field, a single instance could be used for all components:

public class MyNumericVerifier extends InputVerifier {
    @Override
    public boolean verify(JComponent input) {
       String text = ((JTextField) input).getText();
       try {
          Integer.parseInt(text);
       } catch (NumberFormatException e) {
          return false;
       }

       return true;
    }
}

InputVerifier verifier = new MyNumericVerifier()
textField1.setInputVerifier(verifier);


回答2:

I prefer to use an improved version of JFormattedTextField. By improved I mean better caret behavior, validation on each change to provide immediate user feedback (e.g. change background color when input is invalid), ... . That combined with a button which is disabled until the input is valid.

Main benefits over the "click the button and see error messages appear":

  • instant feedback for the user .If web-applications can avoid a round-trip to the server and use javascript for immediate feedback, there is no excuse for not having that in a desktop applications. Pressing a button to validate is so '90.
  • visual feedback is important, and better then the InputVerifier which just avoids changing focus
  • highly reusable component. Just make sure your 'utility code pack' contains a bunch of Formats (for dates, doubles, integers, ranges, ... ) and you can handle almost any situation
  • due to the use of Formats, easy adjustable for different Locales
  • You never need to parse the input after the JFormattedTextField. All the parsing code is contained in the format, and you can simply use JFormattedTextField#getValue
  • All validation is taken care of by the JFormattedTextField. You know that the value you retrieve using getValue is a valid one


回答3:

There are many things you can do. A simple one is to have a method that checks a list of strings for parseability into int. For additional checks you'd have more methods that check some typical thing, like number range. So split each kind of check into its own method and compose them as needed.

Otherwise there are full validation frameworks that handle this sort of thing. They are easiliy googlable, I'd say.



回答4:

You can get real time validation through the use a DocumentFilter

You check out this and this for some examples.

I do think, however, you might find the JFormattedTextField are more suitable solution in this case.



标签: java swing input