2013-07-30 40 views
0

因此,我正在嘗試編寫一個搜索JTextField的代碼,以從Web中檢索結果(有點像Google的奇特搜索提示)。唯一的問題是...可能是我缺乏編程經驗。更具體地說,我將它設置爲當用戶點擊某個鍵時,它通過HttpURLConnection發送帶有JTextField輸入的請求,並檢索結果然後進行更新。但是每當HttpURLConnection運行時,它會凍結程序幾秒鐘,當它做它的事情時,主要是禁止在搜索字段中輸入更多字符,如果我不介意別的。我已經考慮過使用單獨的線程,但我不確定如何正確地中斷線程,並讓它重新開始使用新數據,同時讓所有其他數據等待,但仍接受新數據。我已經使用正在同步HttpURLConnection和KeyListener:

thread.stop(); 

,以幫助管理問題考慮的,但是從我讀過,這似乎是禁忌(是嗎?)。不管怎麼說,這裏幾乎是我使用的是什麼:

public class SearchField extends JTextField implements KeyListener { 
    public SearchField() { 
     addkeyListener(this); 
    } 

    public void updateData(ArrayList<String results) { 
     /*Pass the data off the the GUI*/ 
    { 

    @Override 
    public void keyTyped(KeyEvent e) { 
     SearchQuery query = new SearchQuery(this.getText()); 
     updateData(query.getResults()); 
    } 
} 


public class SearchQuery { 

    ArrayList<String> results = new ArrayList<String>(); 

    public SearchQuery(String search) { 
     String search_path = "http://www.whatever.com/" + search; 
     URL url = new URL(search_path); 
     conn = (HttpURLConnection) url.openConnection(); 
     conn.addRequestProperty("User-Agent", "Mozilla/4.76"); 
     in = new BufferedReader(
           new InputStreamReader(conn.getInputStream())); 
     StringBuffer buf = new StringBuffer(); 
     int i; 
     while((i = in.read()) != -1) { 
      buf.append((char) i); 
     } 
     String data = buf.toString(); 

     parse(data); 
    } 

    public void parse(String data) { 
     /*Parse a bunch of JSON, return the results in an array*/ 
     results.add(data); 
    } 

    public ArrayList<String> getResults() { 
     return results; 
    } 
} 

我只是在爲如何同步recieving連續輸入,同時獲得新的成果爲每個鍵中風和解聘未完成的連接,以及它們各自的數據處理時丟失它在下一個鍵擊時變爲無效。

+2

您需要在不同的線程執行搜索,如果你不希望事件調度線程凍結。 – Kayaman

+0

我應該在每次接收新輸入時處理當前線程嗎?我怎樣才能讓它在線程上等待,在更新GUI之前完成其結果? – Kyle

+0

您可以用簡單的布爾標誌將舊線程標記爲不需要,以便在更新的線程獲得結果時它們不會更新GUI。另請參閱tbodt提供的答案。 – Kayaman

回答

0

您正在響應用戶事件的同一線程中進行下載。您需要在另一個線程中進行下載,也許通過製作SearchQuery擴展Thread並執行run方法中的查詢。當需要更新文本字段時,可以使用SwingUtilities.invokeLater來更新文本字段。這裏有一個例子:

public class SearchQuery extends Thread { 
    private SearchField f; 
    public SearchQuery(JTextField f) { 
     this.f = f; 
    } 

    public void run() { 
     // do the query here 
     SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       f.updateData(results); 
      } 
     }); 
    } 
} 

然後換行:

SearchQuery query = new SearchQuery(this.getText()); 

這樣:

SearchQuery query = new SearchQuery(this); 
+0

哦,那可能就是答案。我將不得不對SwingUtilities.invokeLater進行一些研究,並找出如何使用它來更新我的組件。你有沒有好的資源? – Kyle

+0

我會添加一段代碼片段。 – tbodt

+0

那太棒了,謝謝! – Kyle