2013-03-28 57 views
2

有一個文本字段,當失去焦點時它會驗證輸入,如果沒有通過,打印出錯誤信息(這裏很簡單,只是有一個空的檢查)。並且在文本框旁邊有一個按鈕,一旦點擊它就會打印出文本。如何在UI上進行數據驗證時「忽略/丟棄」Swing UI事件?

正如我試過,當輸入一些文本,然後單擊按鈕,它將觸發文本字段的焦點丟失事件和按鈕事件。換句話說,它將首先進行驗證,然後打印輸入文本。

下面是我的問題如果驗證未通過,防止打印文本的好方法是什麼?或者如果驗證沒有通過,是否有辦法「忽略」按鈕上的點擊事件?

我試圖用一個布爾標誌來表示驗證結果,並檢查標誌時執行按鈕的動作,但我不認爲這是一個好方法。據我所知,Swing中有一個事件調度程序線程處理事件,是否可以從這裏取消事件?

下面是一段代碼,這說明了一個問題:

public class SimpleDemo 
{ 
    public static void main(String[] args) 
    { 
     JFrame frame = new JFrame("Demo"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     JPanel content = new JPanel(new FlowLayout()); 
     frame.setContentPane(content); 

     final JTextField textField = new JTextField(10); 
     textField.addFocusListener(new FocusAdapter() 
     { 
      @Override 
      public void focusLost(FocusEvent e) 
      { 
       String text = textField.getText(); 
       // do some validation here, if not validated 
       // do not trigger the event on button. 
       if ("".equals(text)) 
       { 
        System.out.print("please input a text!"); 
       } 
      } 
     }); 
     content.add(textField); 

     JButton button = new JButton("Print Text"); 
     button.addActionListener(new ActionListener() 
     { 
      @Override 
      public void actionPerformed(ActionEvent e) 
      { 
       // action performed for button 
       String text = textField.getText(); 
       System.out.println(text); 
      } 
     }); 
     content.add(button); 

     frame.setVisible(true); 
     frame.pack(); 
    } 
} 
+0

考慮使用InputVerifier(而不是低級別的focusListener) - [驗證示例](http:// stackoverflow。com/a/14041811/203657) – kleopatra 2013-03-28 11:26:22

+0

@kleopatra我試着用InputVerifier,但似乎按鈕不能在顯示錯誤信息後彈起來,你能檢查我的最新代碼並給出建議嗎? – Aaron 2013-03-28 14:37:18

+1

之前沒有看到您的非答案(另一個原因,您不應在答案部分發布澄清/後續問題:-)。修復你的InputVerifier的實現,並檢查按鈕是否仍然卡住(早期的jdks中有一個bug,所以它可能) – kleopatra 2013-03-28 14:50:54

回答

1

我面臨着類似問題上的應用程序工作時。我解決它像下面 我創建了一個抽象類ApplicationFrame其應用程序中的每一個框架延伸

public abstract class ApplicationFrame extends JFrame implements ActionListener { 
    @Override 
    final public void actionPerformed(ActionEvent event) { 
     if(validateInput()){ 
      performAction(event); 
     } 
    } 

    /* 
    * Sub class should override this method to receive any action 
    */ 
    protected void performAction(ActionEvent event) {}; 

    /* 
    * Sub class should override this method to perform validation 
    */ 
    abstract protected boolean validateInput(); 
} 

所有幀現在延長這一基本框架,如下圖所示:

public class Frame1 extends ApplicationFrame{ 
    @Override 
    protected void performAction(ActionEvent event) { 
     // perform action 
    } 
    @Override 
    protected boolean validateInput() { 
     // return true or false depending upon the validation results 
    } 
    // if you want to add Action Listener, you need to add like this: 
    btnSomeButton.addActionListener(this); 
} 

如果您需要處理重點事件中,您可以使ApplicationFrame或基框實現FocusListener。 這是我的自定義實現來解決問題,希望這有助於。

0
  • 請在啓動
  • 在失去重心禁用按鈕,確認只有當輸入通過驗證文本&啓動按鈕。
  • 在文本變化的開始,禁用按鈕
0

它總是有道理的,使用戶界面與用戶進行溝通。因此,當用戶輸入任何內容時,您可以顯示「請輸入文本」作爲textField的默認文本。 這裏是這樣的規矩文本字段代碼:

public class TextFieldWithDefaultText extends JTextField implements FocusListener{ 

private final String hint; 

public TextFieldWithDefaultText (String $text) 
{ 
    super($text); 
    this.hint = $text; 
    addFocusListener(this); 
} 

@Override 
public void focusGained (FocusEvent $e) 
{ 
    if (this.getText().isEmpty()) 
    { 
     super.setText(""); 
    } 
} 

@Override 
public void focusLost (FocusEvent $e) 
{ 
    if (this.getText().isEmpty()) 
    { 
     super.setText(hint); 
    } 
} 

@Override 
public String getText() 
{ 
    String typed = super.getText(); 
    return typed.equals(hint) ? "" : typed; 
} 

}

寫acttionListerner爲您的按鈕是這樣的:

JButton button = new JButton("Print Text"); 
    button.addActionListener(new ActionListener() 
    { 
     @Override 
     public void actionPerformed(ActionEvent e) 
     { 
      if(!textField.getText().isEmpty()) 
       System.out.println(textField.getText()); 
     } 
    }); 

和UR文本框的實現應該是:

final TextFieldWithDefaultText textField = new TextFieldWithDefaultText ("please input a text"); 

希望這會有所幫助:)

+0

感謝您的回答。我同意你的看法,但是令我困擾的是如何「忽略」事件。 :) – Aaron 2013-03-28 13:43:25

+0

其實我通過檢查if(!textField.getText()。isEmpty())的條件來忽略事件。但是,如果你想完全避免事件傳遞給java eventQueue,恐怕這是不可能的。處理用戶界面的手動事件是使用Java本地對等方完成的。因此,如果您想忽略它,請在actionPerformed()方法中檢查條件。我知道這是一種破解:) – 2013-04-01 06:17:10

+0

如果你認爲它回答你的問題,請不要忘記選擇它作爲答案:) – 2013-04-01 06:18:08