2012-06-20 58 views
7

我在我的應用程序中有一個textField,當用戶點擊JList中的一個項目時,將以編程方式啓動(textField.setText())。 以後用戶將手動更改此值。 我遇到了使用文檔偵聽器來檢測此文本字段中的更改。 當以編程方式發生更改時,它必須不做任何事情,但如果手動發生,它應該將背景更改爲紅色。如何區別textField.setText()和手動添加文本到textField在java中?

如何檢測textField是否已被手動填寫或通過textField.setText()?

txtMode.getDocument().addDocumentListener(new DocumentListener() { 
     public void insertUpdate(DocumentEvent e) { 
      if (!mode.equals(e.getDocument())) 
      txtMode.setBackground(Color.red); 
     } 

     public void removeUpdate(DocumentEvent e) { 
      if (mode.equals(e.getDocument())) 
      txtMode.setBackground(Color.white);    
     } 

     public void changedUpdate(DocumentEvent e) { 
      //To change body of implemented methods 
     } 
    }); 

回答

8

有兩種方式

  • 刪除DocumentListenersetText("...")前加DocumentListener回來,如果做

代碼

public void attachDocumentListener(JComponent compo){ 
     compo.addDocumentListener(someDocumentListener); 
} 

//similair void for remove.... 
  • 使用boolean值「如果需要」禁用的,但你必須改變你的DocumentListener

含量研究例如

txtMode.getDocument().addDocumentListener(new DocumentListener() { 
    public void insertUpdate(DocumentEvent e) { 
     if (!mode.equals(e.getDocument())) 

     if (!updateFromModel){ 
      txtMode.setBackground(Color.red); 
     } 
    } 

    public void removeUpdate(DocumentEvent e) { 
     if (mode.equals(e.getDocument())) 

     if (!updateFromModel){ 
      txtMode.setBackground(Color.white); 
     } 
    } 

    public void changedUpdate(DocumentEvent e) { 
     //To change body of implemented methods 
    } 
}); 
+1

這裏的問題是,有時候setText()被某個不是你自己的代碼的人調用。無論如何,這就是我現在要面對的問題。我希望他們可以在每個事件上都有一個wasTriggeredByUser()。 – Trejkaz

+0

@Trejkaz請問,如何,在哪裏,爲什麼有一些特殊的原因,btw文檔是JTextComponents的模型,然後消耗/觸發模型之間的所有更改/事件以查看,反之亦然 – mKorbel

4

請所有的事件偵聽器的Swing事件線程中執行的頭腦。所以事情可能不會按照你想要的順序進行。在這種情況下,任何解決方案都將是黑客攻擊,因爲您無法完全控制擺動線程以及誰在其上發佈事件。

我想說的是:假設你選擇使用一些標誌讓你的聽衆知道這是一個程序化的改變。下面是可能的情況(我假設你下面通過invokeLater做從Swing線程任何UI更新的不錯規則):

  1. 設置標記,以跳過事件
  2. 的setText
  3. 集標誌設置爲false

如果您在一次調用中完成所有操作,則setText將觸發更新事件發佈到事件隊列末尾,因此,在執行它們時,該標誌已經爲假。

所以,你應該做一個invokeLater通話,甚至invokeAndWait步驟1和2,然後再發布另一個事件與invokeLater取消設置標誌。並祈禱你的用戶沒有那麼快在這兩個調用之間做出一些改變,否則,他們也被認爲是一個程序化改變。

相關問題