-1

我有一个微妙的问题!

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

在第二个文本字段(姓氏)中,当用户输入不正确的值时,其他组件完全禁用,但是当用户编辑该值以更正它时,(例如通过删除数字),用户应该使用键盘tab按钮来启用其他组件(收音机按钮),我也想通过单击单选按钮来启用。

这是我的代码:

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

1 回答 1

0

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

请尝试解决有关使用的问题InutVerifierverify并且shouldYieldFunction您之前的帖子中所述。如果你不改变你的做法,你将来会有危险。从验证功能中删除启用和禁用代码的组件。

您在这篇文章中的问题:在这种情况下,真正发生的是,当您的数据无效并且您尝试通过单击另一个组件来失去输入文本字段焦点时,您将JRadioButtons 被禁用。在重新启用之前,禁用的无法聚焦。由于输入验证器响应焦点丢失事件,因此单击disabled RadioButton不会导致焦点导航,因此ShouldYieldFocus(which calls verify)不会被调用以重新启用您的组件。

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


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

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

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()的。

教程资源: 如何使用 DocumentListener

于 2013-10-24T12:56:57.713 回答