单击输入验证器效果不起作用,仅按选项卡按钮即可 [英] Input Verifier effect not work by click, just work by tab button

查看:88
本文介绍了单击输入验证器效果不起作用,仅按选项卡按钮即可的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个棘手的问题!

我有一个将输入验证程序设置为文本字段的表单,并且当用户键入不正确的值时,其他文本字段和单选按钮应该禁用。

I have a form that set input verifier to text fields, and when user type a incorrect value, other text fields and radio buttons should be disable.

在第二个文本字段(姓氏)中,当用户键入错误的值时,其他组件将完全禁用,但是当用户编辑该值以对其进行更正时,(例如删除数字),用户应该使用键盘上的 tab 按钮启用其他组件(单选按钮),我也想通过单击单选按钮来启用该功能。

In second text filed (last name), When user type a incorrect value, other components disable perfectly, But when user edit that value to correct it, (for e.x by removing digit), user should user keyboard tab button to enable other components (radio buttons) and I want to enable with clicking to radio buttons too.

这是我的代码:

public class UserDialog3 extends JDialog implements ActionListener {
JButton cancelBtn, okBtn;
JTextField fNameTf, lNameTf;
JRadioButton maleRb, femaleRb;
ButtonGroup group;
JLabel fNameLbl, lNameLbl, genderLbl, tempBtn, temp3, temp2, temp1;

public UserDialog3() {
    add(createForm(), BorderLayout.CENTER);
    setDefaultCloseOperation(DISPOSE_ON_CLOSE);
    setLocation(400, 100);
    pack();
    setVisible(true);
}

public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            new UserDialog3();
        }
    });
}

public JPanel createForm() {
    JPanel panel = new JPanel();

    okBtn = new JButton("Ok");
    cancelBtn = new JButton("Cancel");
    tempBtn = new JLabel();
    fNameLbl = new JLabel("First Name");
    lNameLbl = new JLabel("Last Name");
    genderLbl = new JLabel("Gender");
    temp2 = new JLabel();
    temp1 = new JLabel();

    maleRb = new JRadioButton("Male");
    femaleRb = new JRadioButton("Female");
    temp3 = new JLabel();
    group = new ButtonGroup();
    group.add(maleRb);
    group.add(femaleRb);

    fNameTf = new JTextField(10);
    fNameTf.setName("FnTF");
    fNameTf.setInputVerifier(new MyVerifier(new JComponent[]{maleRb, femaleRb, okBtn}));
    lNameTf = new JTextField(10);
    lNameTf.setName("LnTF");
    lNameTf.setInputVerifier(new MyVerifier(new JComponent[]{maleRb, femaleRb, okBtn}));

    panel.add(fNameLbl);
    panel.add(fNameTf);
    panel.add(temp1);
    panel.add(lNameLbl);
    panel.add(lNameTf);
    panel.add(temp2);
    panel.add(genderLbl);
    JPanel radioPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
    radioPanel.add(maleRb);
    radioPanel.add(femaleRb);
    panel.add(radioPanel);
    panel.add(temp3);
    panel.add(okBtn);
    panel.add(cancelBtn);
    panel.add(tempBtn);

    panel.setLayout(new SpringLayout());
    SpringUtilities.makeCompactGrid(panel, 4, 3, 50, 10, 80, 60);
    return panel;
}

@Override
public void actionPerformed(ActionEvent e) {

}

public class MyVerifier extends InputVerifier {
    private JComponent[] component;

    public MyVerifier(JComponent[] components) {
        component = components;
    }

    @Override
    public boolean verify(JComponent input) {
        String name = input.getName();

        if (name.equals("FnTF")) {
            String text = ((JTextField) input).getText().trim();
            if (text.matches(".*\\d.*") || text.length() == 0) {
                //disable dependent components
                for (JComponent r : component) {
                    r.setEnabled(false);
                }
                return false;
            }
        } else if (name.equals("LnTF")) {
            String text = ((JTextField) input).getText();
            if (text.matches(".*\\d.*") || text.length() == 0) {
                //disable dependent components
                for (JComponent r : component) {
                    r.setEnabled(false);
                }
                return false;
            }
        }
        //enable dependent components
        for (JComponent r : component) {
            r.setEnabled(true);
        }
        return true;
    }
}
}


推荐答案

InputVerifier 类的目的是帮助客户支持通过带有文本字段的GUI的平滑焦点导航。在将焦点转移到另一个请求它的Swing组件之前,调用输入验证程序的 shouldYieldFocus 方法(这要求 verify 验证数据的功能)。仅在该方法返回 true 时转移焦点。

The purpose of InputVerifier class is to help clients support smooth focus navigation through GUIs with text fields. Before focus is transfered to another Swing component that requests it, the input verifier's shouldYieldFocus method is called(which ask the verify function to validate data). Focus is transfered only if that method returns true.

请尝试解决有关使用<如InutVerifier , verify shouldYieldFunction https://stackoverflow.com/questions/19499692/inputverifier-dont-display-each-component-iconlable>您之前的帖子。如果您不打算改变自己的做法,那么将来将会有危险。从验证功能中删除启用和禁用代码的组件。

Please Try to fix the issues about using InutVerifier, verify and shouldYieldFunction as mentioned in your previous post. If you are not going to change your practice, you will be danger in future. Remove you components enabling and disabling code from verify function.

您在此帖子中遇到的问题:在这种情况下,实际发生的情况就是说,当您的数据无效并且您尝试通过单击其他组件来失去输入文本字段的焦点时,您的 JRadioButtons 被禁用。禁用后才能重新启用它。当输入验证程序以焦点丢失事件响应时,单击禁用的RadioButton 不会导致焦点导航,因此 ShouldYieldFocus(调用验证)不会重新启用您的组件。

Your Problem in this post: In this case, what really happening is that, when your data is invalid and you try to lose your input text field focus by clicking another component, your JRadioButtons get disabled. A disabled cant be focused until it is re-enabled. As input-verifier responds with focus-lose event, clicking on the disabled RadioButton isn't resulting in focus navigation, and thus ShouldYieldFocus(which calls verify) is not being called to re-enable your components.

按此选项卡有效,因为它会根据swing的焦点遍历策略将焦点发送到第二个文本输入字段。因此,焦点丢失事件发生在第一个输入文本字段上,这一次 InputVerifier 的验证函数被调用,最终启用了组件。为了更好地理解问题,请尝试使用一个 JRadioButton 和一个 JTextFeild 重写您自己的示例。

Pressing the tab works, because it is sending the Focus to your second text input field according to swing's focus traversal policy. Hence a focus lose event occur on first input text field and this time InputVerifier's verify function get called which eventually enables your component. To understand the problem better, try rewriting your own example with one JRadioButton and one JTextFeild.

尝试使用 DocumentListener 和您的文本字段。在发生数据插入和删除事件时,使用 InputVerifier 检查数据的有效性,然后启用/禁用相关组件。

Try using a DocumentListener with your text Field. upon data insertion and removal event, check your data validity using InputVerifier and then, enable/disable related components.

我正在编写一个示例代码片段来演示如何将 DocumentListener 添加到您的 fNameTF lNameTF 文本字段将解决您的问题:

I am writing a sample code snippets to demonstrate, how adding DocumentListener to your fNameTF and lNameTF text fields will resolve your problem:

fNameTF.getDocument().addDocumentListener(new DocumentListener() {

            @Override
            public void insertUpdate(DocumentEvent e) {
              doOnDataValidity(verifier.verify(fNameTF));
           }

            @Override
            public void removeUpdate(DocumentEvent e) {
               doOnDataValidity(verifier.verify(fNameTF));
            }

            @Override
            public void changedUpdate(DocumentEvent e) {}
        });

doOnValidity(boolean isValid)函数如下

public void doOnDataValidity(boolean isDataValid)
    {
         if(isDataValid) 
         {
            //enable your components 
         }else 
          {
              //disable your components
          }
    }

以相同方式将DocumentListener添加到您的 lNameTf.getDocument()中。

Add a DocumentListener to your lNameTf.getDocument() the same way.

教程资源: 如何使用DocumentListener

这篇关于单击输入验证器效果不起作用,仅按选项卡按钮即可的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆