InputVerifier don't display each component icon(lable)

回眸只為那壹抹淺笑 提交于 2019-12-11 08:56:54

问题


I have a form that set a input verifier to it.

I want when a user type a correct value for a text field and want to go to other text field, a check icon should be display besides of text field. But now in my code, when user type a correct value on first text field an go to other, Two icons displayed together!

public class UserDialog extends JDialog {

JButton cancelBtn, okBtn;
JTextField fNameTf, lNameTf;
JRadioButton maleRb, femaleRb;
ButtonGroup group;
JLabel fNameLbl, fNamePicLbl, lNameLbl, lNamePicLbl, genderLbl, tempBtn, temp3;

    public UserDialog() {
    add(createForm(), BorderLayout.CENTER);
    setDefaultCloseOperation(DISPOSE_ON_CLOSE);
    setLocation(400, 100);
    pack();
    setVisible(true);
}
    public JPanel createForm() {
    JPanel panel = new JPanel();
    ImageIcon image = new ImageIcon("Check.png");

    okBtn = new JButton("Ok");
    cancelBtn = new JButton("Cancel");
    tempBtn = new JLabel();
    fNameLbl = new JLabel("First Name");
    fNamePicLbl = new JLabel(image);
    fNamePicLbl.setVisible(false);
    lNameLbl = new JLabel("Last Name");
    lNamePicLbl = new JLabel(image);
    lNamePicLbl.setVisible(false);
    genderLbl = new JLabel("Gender");

    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(fNamePicLbl);
    panel.add(lNameLbl);
    panel.add(lNameTf);
    panel.add(lNamePicLbl);
    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;
}
    public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            new UserDialog();
        }
    });
}

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);
        }
        fNamePicLbl.setVisible(true);
        lNamePicLbl.setVisible(true);
        return true;
    }
}
}
}

Updated

 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) {
                return false;
            }
        } else if (name.equals("LnTF")) {
            String text = ((JTextField) input).getText();
            if (text.matches(".*\\d.*") || text.length() == 0) {
                return false;
            }
        }
        return true;
    }

    @Override
    public boolean shouldYieldFocus(JComponent input) {
        boolean isValidDate = verify(input);
        if (isValidDate) {
            for (JComponent r : component) {
                r.setEnabled(true);
            }
        } else {
            for (JComponent r : component) {
                r.setEnabled(false);
            }
        }
        return isValidDate;
    }

回答1:


But now in my code, when user type a correct value on first text field an go to other, Two icons displayed together!

Because you did so: (Read the comments)

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

        if (name.equals("FnTF")) {
            // your code
            }
        } else if (name.equals("LnTF")) {
            // your code

        }
        //enable dependent components
        for (JComponent r : component) {
            r.setEnabled(true);
        }
        /* And Now we are here */
        fNamePicLbl.setVisible(true); 
        lNamePicLbl.setVisible(true);
         // making visible two of them at once as soon as verify is called 
            // on any one of the components, verifier is registered

        return true;
    }

setVisible should be controlled by the if-else condition too. For your better understanding you need to do something like this:

      if (text.matches(".*\\d.*") || text.length() == 0) {
           // your code
        }
        else
        {
            fNamePicLbl.setVisible(true);

        } 

Second Issue:

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

The MyVerfier has the common code to verify both input field. But you are creating two instances of it with same instances of components. Create one and set it as the input verifier of the two field.

You might want to create two different InputVerifier class for the two Text Field. FnTFVerifier and LnTFVerifier. Then put your verification code that relates them e.g., enabling the radio buttons and showing the label with check.png. most of the if-else checking will go-away.

But I think, this should not really be the preferable way. As the two text field has the common functionality, one InputVerifier class and instance is sufficient. you would have to just encapsulate the input text field and related cehckLabel to one component, then register the InputVerifier instances to this component.

Third issue: you are misusing verify function:

The verify function is meant to be used for nothing but verify data: whether data is valid or not with user required condition. It should do nothing more. InputVerifier has another function boolean ShouldYieldFocus(Jcomponent): Before focus is transfered to another Swing component that requests it, the input verifier's shouldYieldFocus method is called, which decides whither the component under verification should lose focus or not. Focus is transferred only if this method returns true. You should however write the required state change of components inside this function.

public boolean shouldYieldFocus(JComponent input) {
    boolean isDataValid =  verify(input);

    if(isDataValid); //do stuff

    return isDataValid; // if verify is true(valid) return true;
 }


来源:https://stackoverflow.com/questions/19499692/inputverifier-dont-display-each-component-iconlable

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