程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA編程入門知識 >> 再論Java Swing線程

再論Java Swing線程

編輯:JAVA編程入門知識

  不正確的Swing線程是運行緩慢、無響應和不穩定的Swing應用的主要原因之一。這是許多原因造成的,從開發人員對Swing單線程模型的誤解,到保證正確的線程執行的困難。即使對Swing線程進行了很多努力,應用線程邏輯也是很難理解和維護的。本文闡述了如何在開發Swing應用中使用事件驅動編程,以大大簡化開發、維護,並提供高靈活性。

  背景

  既然我們是要簡化Swing應用的線程,首先讓我們來看看Swing線程是怎麼工作的,為什麼它是必須的。Swing API是圍繞單線程模型設計的。這意味著Swing組件必須總是通過同一個線程來修改和操縱。為什麼采用單線程模型,這有很多原因,包括開發成本和同步Swing的復雜性--這都會造成一個遲鈍的API。為了達到單線程模型,有一個專門的線程用於和Swing組件交互。這個線程就是大家熟知的Swing線程,AWT(有時也發音為“ought”)線程,或者事件分派線程。在本文的下面的部分,我選用Swing線程的叫法。

  既然Swing線程是和Swing組件進行交互的唯一的線程,它就被賦予了很多責任。所有的繪制和圖形,鼠標事件,組件事件,按鈕事件,和所有其它事件都發生在Swing線程。因為Swing線程的工作已經非常沉重了,當太多其它工作在Swing線程中進行處理時就會發生問題。會引起這個問題的最常見的位置是在非Swing處理的地方,像發生在一個事件監聽器方法中,比如JButton的ActionListener,的數據庫查找。既然ActionListener的actionPerformed()方法自動在Swing線程中執行,那麼,數據庫查找也將在Swing線程中執行。這將占用了Swing的工作,阻止它處理它的其它任務--像繪制,響應鼠標移動,處理按鈕事件,和應用的縮放。用戶以為應用死掉了,但實際上並不是這樣。在適當的線程中執行代碼對確保系統正常地執行非常重要。

  既然我們已經看到了在適當的線程中執行Swing應用的代碼是多麼重要,現在讓我們如何實現這些線程。我們看看將代碼放入和移出Swing線程的標准機制。在講述過程中,我將突出幾個和標准機制有關的問題和難點。正如我們看到的,大部分的問題都來自於企圖在異步的Swing線程模型上實現同步的代碼模型。從那兒,我們將看到如何修改我們的例子到事件驅動--移植整個方式到異步模型。

  通用Swing線程解決方案

  讓我們以一個最常用的Swing線程錯誤開始。我們將企圖使用標准的技術來修正這個問題。在這個過程中,我們將看到實現正確的Swing線程的復雜性和常見困難。並且,注意在修正這個Swing線程問題中,許多中間的例子也是不能工作的。在例子中,我在代碼失敗的地方以//broken開頭標出。好了,現在,讓我們進入我們的例子吧。

  假設我們在執行圖書查找。我們有一個簡單的用戶界面,包括一個查找文本域,一個查找按鈕,和一個輸出的文本區域。這個接口如圖1所示。不要批評我的UI設計,這個確實很丑陋,我承認。

  圖 1. 基本查詢用戶界面

  用戶輸入書的標題,作者或者其它條件,然後顯示一個結果的列表。下面的代碼例子演示了按鈕的ActionListener在同一個線程中調用lookup()方法。在這些例子中,我使用了thread.sleep()休眠5秒來作為一個占位的外部查找。線程休眠的結果等同於一個耗時5秒的同步的服務器調用。

  

private void searchButton_actionPerformed()
{
  outputTA.setText("Searching for: " + searchTF.getText());
  //Broken!! Too much work in the Swing
  thread String[] results = lookup(searchTF.getText());
  outputTA.setText("");
  for (int i = 0; i < results.length; i++)
  {
   String result = results[i];
   outputTA.setText(outputTA.getText() + ´´\n´´ + result);
  }
}

  如果你運行這段代碼(完整的代碼可以在這兒下載),你會立即發現存在一些問題。圖2顯示了查找運行中的一個屏幕截圖。

  圖 2. 在Swing線程中進行查找

  注意Go按鈕看起來是被按下了。這是因為actionPerformed方法通知了按鈕繪制為非按下外觀,但是還沒有返回。你也會發現要查找的字串“abcde”並沒有出現在文本區域中。searchButton_actionPerformed的第1行代碼將文本區域設置為要查找的字串。但是,注意Swing重畫並不是立即執行的。而是把重畫請求放置到Swing事件隊列中等待Swing線程處理。但是這兒,我們因查找處理占用了Swing線程,所以,它還不能馬上進行重畫。

  • 首頁
  • 上一頁
  • 1
  • 2
  • 3
  • 4
  • 下一頁
  • 尾頁
  • 共4頁
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved