Input Verifier effect not work by click, just work by tab button

霸气de小男生 提交于 2019-12-13 22:09:37

问题


I have a delicate problem!

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.

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.

Here is my code:

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

回答1:


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.

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.

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.

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.


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.

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) function is as follows:

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

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

Tutorial Resources: How to use DocumentListener.



来源:https://stackoverflow.com/questions/19565839/input-verifier-effect-not-work-by-click-just-work-by-tab-button

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!