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