2013-10-24 34 views
-1

我有一个微妙的问题!输入验证器效果不能通过点击工作,只需按Tab按钮

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

在第二个文本字段(姓氏)中,当用户键入一个不正确的值时,其他组件完全禁用,但是当用户编辑该值来纠正它时,(用于删除数字的ex),用户应该用键盘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; 
    } 
} 
} 
+0

那么问题是什么? – jzd

+0

@jzd问题是,我怎样才能通过单击它启用单选按钮? – Sajad

+0

当你的名字输入字段错误时,不应该让你去姓氏字段。不是吗? – Sage

回答

0

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

请尝试解决有关使用InutVerifierverify,并在your previous post提到shouldYieldFunction问题。如果你不打算改变你的做法,你将来会有危险。删除您启用和禁用验证功能代码的组件。

你在这个岗位问题:在这种情况下,真正发生的是,当你的数据是无效的,并试图通过单击另一个组件失去你输入文本字段焦点,您JRadioButtons得到禁止。一个残疾人无法专注,直到它被重新启用。由于输入验证器响应焦点丢失事件,因此单击disabled RadioButton不会导致焦点导航,因此不会调用ShouldYieldFocus(which calls verify)以重新启用组件。

因为按照挥杆的焦点遍历策略将焦点发送到第二个文本输入字段,所以按下该选项卡的方式起作用。因此,在第一个输入文本字段发生焦点丢失事件,并且此时InputVerifier的验证函数被调用,最终启用您的组件。要更好地理解问题,请尝试用一个JRadioButton和一个JTextFeild重写您自己的示例。


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

我写一个示例代码段演示如何将DocumentListenerfNameTFlNameTF文本字段将解决您的问题:

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

教程资源:How to use DocumentListener

+0

对downvote有何评论? – Sage

+0

的[JavaDoc中](http://docs.oracle.com/javase/7/docs/api/javax/swing/InputVerifier.html#verify(javax.swing.JComponent中))的状态,该'verify'方法*”应该没有副作用“*。 OP正在改变'verify'方法中其他组件的状态,这是实际的问题。相反,应该鼓励OP使用不同的方法来确定组件状态是否应该改变,例如“PropertyChangeListener”,例如 - 恕我直言 - 另一个问题是,虽然我喜欢'DocumentFilter',并且不会反对使用在这种情况下,它并没有解决我也考虑过使用单'InputVerifier'的多个部件,其中的逻辑是每个字段的相同问题 – MadProgrammer

+0

... – MadProgrammer