Java Swing:实现输入值的有效性检查

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12997742/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 11:05:23  来源:igfitidea点击:

Java Swing: Implementing a validity check of input values

javaswinginput

提问by Valentino Ru

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.

在我的 Swing 应用程序中,用户必须在切换到下一个窗口之前插入数字和值。现在,作为一个干净的程序,我会检查每个输入是否有效,如果无效,则会显示一条错误消息,并且不会打开下一个窗口。

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.

(*) 注意:我知道多个 JFrame 的原则是丑陋的,我打算改变它,但对于这个问题,它无关紧要。

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

现在这个问题的重点是 this checkValidity(),我的结构是这样的:

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?

这完全符合我的要求,但代码本身非常难看,因为有多个输入选项,该方法的长度为 200、300 或更多行(因为我不仅检查例如它是否是一个数字,而且还检查该数字是否有意义在程序逻辑等上下文中)。是否有 Swing 自己的方法来检查这些事情?或者有没有人更好地了解如何使用 split 方法准确实现此功能?

回答by Reimeus

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

一种解决方案是使用 SwingInputVerifier来验证每个JTextField使用过的输入。由于每个字段的验证功能都相同,因此可以对所有组件使用单个实例:

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);

回答by Robin

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.

我更喜欢使用JFormattedTextField. 改进我的意思是更好的插入符号行为,验证每个更改以提供即时的用户反馈(例如,当输入无效时更改背景颜色),...。结合一个按钮,该按钮在输入有效之前被禁用。

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 InputVerifierwhich 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 getValueis a valid one
  • 为用户提供即时反馈。如果 Web 应用程序可以避免往返服务器并使用 javascript 进行即时反馈,那么在桌面应用程序中没有理由不使用它。按下按钮进行验证是如此'90。
  • 视觉反馈很重要,比InputVerifier避免改变焦点更好
  • 高度可重用的组件。只需确保您的“实用程序代码包”包含一堆Formats(用于日期、双精度、整数、范围等),您几乎可以处理任何情况
  • 由于使用了Formats,容易针对不同的Locales进行调整
  • 您永远不需要解析JFormattedTextField. 所有的解析代码都包含在格式中,你可以简单地使用JFormattedTextField#getValue
  • 所有验证都由JFormattedTextField. 您知道您检索使用的值getValue是有效的

回答by Marko Topolnik

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.

你可以做很多事情。一个简单的方法是使用一种方法来检查字符串列表是否可解析为 int。对于额外的检查,您有更多的方法来检查一些典型的事情,比如数字范围。因此,将每种检查拆分为自己的方法并根据需要组合它们。

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

否则有处理这类事情的完整验证框架。我会说,它们很容易用谷歌搜索。

回答by MadProgrammer

You can get real time validation through the use a DocumentFilter

您可以通过使用 a 来获得实时验证 DocumentFilter

You check out thisand thisfor some examples.

您可以查看thisthis以获取一些示例。

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

但是,我确实认为,JFormattedTextField在这种情况下,您可能会发现更合适的解决方案。