2013-04-10 104 views
0

這是我的問題與擺動:
想象與一個文本框和一個按鈕的框架。在這個框架後面有一個字段的數據類。
事件的優先級

  • 文本字段具有的FocusListener其對事件的內容與價值更新文本字段數據類字段
  • 按鈕具有的ActionListener將數據發送級服務器上點擊

,如果我在文本框,然後點擊修改值按鈕,有時將舊值的數據類發送到服務器。在我看來,不能保證在按鈕的ActionPerformed事件之前處理文本字段的FocusOut事件。如果是這樣,有什麼方法可以保護它?我的意思是一些乾淨的方式,如果不是必要的話,我不想全部弄髒它。

+0

什麼是'FocusOut'?我從未聽說過這件事。 – camickr 2013-04-10 15:39:13

+0

最近的QA顯示[窮人的表單驗證](http://stackoverflow.com/a/14041811/203657) - 對於更多的演化控制考慮使用像f.i這樣的驗證框架。 JGoodies數據。不是我每天仔細閱讀;-)只是注意到你的問題是關於控制綁定與驗證:將提交操作包裝到SwingUtilities.invokeLater應該保證在提交之前首先實際將字段值傳遞給數據類。 – kleopatra 2013-04-10 15:48:49

回答

1

的錯誤訂單,如果我在文本字段修改值,然後單擊該按鈕向右走,數據類舊值有時發送到服務器。在我看來,不能保證在按鈕的ActionPerformed事件之前處理文本字段的FocusOut事件。如果是這樣,有什麼方法可以保護它?

設計形式不同。那就是當你點擊按鈕時,ActionListener應該調用窗體上所有文本字段上的getText()方法。

+0

謝謝 – 2013-05-21 07:45:56

1

你可以這樣做。我只是給一個僞代碼。

private boolean check = false; 

txtField FocusOutMethod { 
check = true; 
} 

button ActionPerformedMethod(){ 

if(check){ 

     place your code that you want to execute in button click. 

     check = false; 
} 
} 

通過這個actionPerformed方法將只運行事件的內容方法的執行後,你的代碼。

+0

沒有冒犯的意思,但這正是我的意思,我不想骯髒它:)我也有一種感覺,如果我這樣做,用戶將被迫單擊按鈕兩次如果在FocusOut – 2013-04-10 13:11:20

+1

之前處理actionPerformed以點擊按鈕,用戶將首先將鼠標放在該按鈕上,這樣您還可以使用該按鈕的MouseEntered屬性調用您想要在FocusOut ....中執行的相同代碼: )。我希望這會起作用,並將滿足您的要求...... – 2013-04-10 13:17:53

+0

看起來很有趣。我仍然會尋找解決方案,那不會讓我添加另一個重複其他人的工作的監聽者,但是,這實際上應該是訣竅。謝謝 – 2013-04-10 13:29:43

1
  • 不可能在搖擺,沒有可能從一個監聽事件的排序沒有的情況下,兩個或多個監聽器觸發事件​​concurently

,如果我在文本框修改和價值有時候點擊按鈕, 具有舊值的dataclass被髮送到服務器。在我看來, 沒有保證TextOffice的FocusOut事件會在按鈕的ActionPerformed事件之前處理爲 。如果是這樣,是否有一些 方式如何保護它?我的意思是一些乾淨的方式,如果不是必要的話,我不想全都骯髒。

  • 重點是異步的,但在射擊適當的情況下,所有的情況下,問題可能出在你的代碼

  • 一些聽衆的組合可以造成相當無限循環(事件被觸發室內用延遲),然後您可以CONTROLER點火事件

+0

我已經爲我的聽衆添加了sysouts,它們的處理順序純屬巧合。恐怕我只剩下髒東西了......如果不涉及編程,那麼順便說一句就不一定是壞事:-) – 2013-04-10 13:41:11

+0

將DocumentListener添加到JTextComponent,然後所有更改都將是... ,請注意,但如何可能'哪些更新數據類字段與FocusOut'上的文本字段值消耗了大量的時間???,簡單地刪除,禁用,更改,最簡單,謝謝 – mKorbel 2013-04-10 13:56:24

2

只是爲了好玩,窮人使用InputVerifier實現的單向綁定:請注意,在傳輸焦點之前,inputVerifier保證被訪問(並且似乎在當前版本的jdk中工作 - 在舊版本中有一些問題

的驗證和一些粗俗的數據對象:

/** 
* Very simple uni-directional binding (component --> data) class. 
*/ 
public static class BindingVerifier extends InputVerifier { 

    private RawData data; 
    private boolean first; 
    public BindingVerifier(RawData data, boolean first) { 
     this.data = data; 
     this.first = first; 
    } 


    @Override 
    public boolean shouldYieldFocus(JComponent input) { 
     String text = ((JTextComponent) input).getText(); 
     if (first) { 
      data.one = text; 
     } else { 
      data.two = text; 
     } 
     return true; 
    } 


    @Override 
    public boolean verify(JComponent input) { 
     return true; 
    } 

} 

public static class RawData { 
    String one; 
    String two; 
    public RawData(String one, String two) { 
     this.one = one; 
     this.two = two; 
    } 

    public String toString() { 
     return one + "/" + two; 
    } 
} 

用法:

作爲重點轉移參與提交操作的),所以做任何更新的驗證應該是安全的,只要
final RawData data = new RawData(null, null); 
JTextField first = new JTextField(20); 
first.setInputVerifier(new BindingVerifier(data, true)); 
JTextField second = new JTextField(20); 
second.setInputVerifier(new BindingVerifier(data, false)); 
Action commit = new AbstractAction("commit") { 

    @Override 
    public void actionPerformed(ActionEvent e) { 
     System.out.println(data); 
    } 
}; 
JComponent form = new JPanel(); 
form.add(first); 
form.add(second); 
form.add(new JButton(commit));