2013-10-24 35 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