InputVerifier не отображает каждый значок компонента (ярлык)

У меня есть форма, которая устанавливает входной верификатор для него.

Я хочу, когда пользователь вводит правильное значение для текстового поля и хочет перейти в другое текстовое поле, кроме текстового поля должен отображаться значок проверки. Но теперь в моем коде, когда пользователь вводит правильное значение в первом текстовом поле и переходит к другому, две иконки отображаются вместе!

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

обновленный

 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 ответ

Решение

Но теперь в моем коде, когда пользователь вводит правильное значение в первом текстовом поле и переходит к другому, две иконки отображаются вместе!

Потому что ты так и сделал: (читай комментарии)

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 должны контролироваться if-else состояние тоже. Для вашего лучшего понимания вам нужно сделать что-то вроде этого:

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

        } 

Второй выпуск:

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

MyVerfier имеет общий код для проверки обоих полей ввода. Но вы создаете два его экземпляра с одинаковыми экземплярами компонентов. Создайте один и установите его как входной верификатор двух полей.

Возможно, вы захотите создать два разных класса InputVerifier для двух текстовых полей. FnTFVerifier а также LnTFVerifier, Затем введите проверочный код, который их связывает, например, включив переключатели и показывая метку с check.png, большинство из if-else проверка уйдет.

Но я думаю, это не должно быть предпочтительным способом. Поскольку два текстовых поля имеют общую функциональность, одно InputVerifier класс и экземпляр достаточно. вам нужно будет просто инкапсулировать поле ввода текста и связанный cehckLabel в один компонент, а затем зарегистрировать экземпляры InputVerifier для этого компонента.

Третья проблема: вы неправильно используете функцию проверки:

Функция проверки предназначена для использования только для проверки данных: являются ли данные действительными или нет с требуемым пользователем условием. Это не должно делать больше ничего. InputVerifier имеет другую функцию boolean ShouldYieldFocus(Jcomponent) Перед передачей фокуса другому компоненту Swing, который его запрашивает, входной верификатор shouldYieldFocus вызывается метод, который решает, должен ли проверяемый компонент потерять фокус или нет. Фокус переносится только если этот метод возвращает true, Однако вы должны написать требуемое изменение состояния компонентов внутри этой функции.

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

    if(isDataValid); //do stuff

    return isDataValid; // if verify is true(valid) return true;
 }
Другие вопросы по тегам