使用SwingWorker為界面執行異步任務


------------------siwuxie095

   

   

   

   

   

   

   

工程名:TestSwingWorker

包名:com.siwuxie095.swingworker

類名:TestSwingWorker.java

   

   

工程結構目錄如下:

   

   

   

   

   

代碼:

   

package com.siwuxie095.swingworker;

   

import java.awt.BorderLayout;

import java.awt.EventQueue;

import java.awt.event.MouseAdapter;

import java.awt.event.MouseEvent;

import java.io.BufferedReader;

import java.io.InputStreamReader;

import java.net.URL;

import java.net.URLConnection;

import java.util.List;

import java.util.concurrent.ExecutionException;

   

import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JPanel;

import javax.swing.JScrollPane;

import javax.swing.JTextArea;

import javax.swing.SwingWorker;

import javax.swing.UIManager;

import javax.swing.UnsupportedLookAndFeelException;

import javax.swing.border.EmptyBorder;

   

import com.sun.java.swing.plaf.windows.WindowsLookAndFeel;

   

public class TestSwingWorker extends JFrame {

   

private JPanel contentPane;

private JTextArea textArea;

   

/**

* Launch the application.

*/

public static void main(String[] args) {

EventQueue.invokeLater(new Runnable() {

public void run() {

try {

TestSwingWorker frame = new TestSwingWorker();

frame.setVisible(true);

} catch (Exception e) {

e.printStackTrace();

}

}

});

}

   

/**

* Create the frame.

*/

public TestSwingWorker() {

 

try {

UIManager.setLookAndFeel(new WindowsLookAndFeel());

} catch (UnsupportedLookAndFeelException e1) {

e1.printStackTrace();

}

 

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

setBounds(100, 100, 450, 300);

contentPane = new JPanel();

contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));

contentPane.setLayout(new BorderLayout(0, 0));

setContentPane(contentPane);

 

JButton btnRun = new JButton("Run");

btnRun.setFocusable(false);

btnRun.addMouseListener(new MouseAdapter() {

@Override

public void mouseClicked(MouseEvent e) {

//鼠標點擊Run按鈕后執行讀取網絡數據的方法

webRead();

}

});

contentPane.add(btnRun, BorderLayout.NORTH);

 

JScrollPane scrollPane = new JScrollPane();

contentPane.add(scrollPane, BorderLayout.CENTER);

 

textArea = new JTextArea();

scrollPane.setViewportView(textArea);

}

 

 

public void webRead() {

 

/**

* 創建一個SwingWorkerSwingWorker是一個專門為界面而實現的線程類,

* 它可以非常方便的在當前的UI線程中執行一定的耗時操作,且可以很安全

* 的將它的返回值發送給UI線程

*

* 創建SwingWorker時,需要指定兩個泛型:

* 第一個泛型是SwingWorker線程執行之后得到的結果的類型(返回值的類型)

* 第二個泛型是SwingWorker線程執行中間所發布(publish)的數據的類型

*

* 這里將整個SwingWorker的返回值定義為StringBuilder,中間發布的數據定義為String

*

* 覆蓋三個方法:doInBackground()process()done()

*

* doInBackground() 中執行耗時的操作,如:讀取網絡數據、讀取本地文件、等待

* doInBackground() 產生的中間數據 publish() process()

* doInBackground() 的返回值在 done() 中被 get()

*

* 即兩種方法都能獲取最終的結果

*

* 最后調用SwingWorker execute() 方法執行該線程

*/

new SwingWorker<StringBuilder, String>() {

 

 

//后台處理過程

@Override

protected StringBuilder doInBackground() throws Exception {

//創建一個URL對象,用於讀取網絡數據

//指定網址:http://www.apache.org

URL url=new URL("http://www.apache.org");

 

//使用 openConnection() 方法獲取一個互聯網連接

//返回值是URLConnection類型,創建以接收返回值

URLConnection connection=url.openConnection();

 

//將讀取的輸入流 getInputStream() 層層包裝,最后使用 BufferedReader 來讀取網絡數據

//先包裝成 InputStreamReader,並指定字符集,再包裝成 BufferedReader

BufferedReader reader=new BufferedReader(

new InputStreamReader(connection.getInputStream(),"UTF-8"));

 

//讀取每一行數據

String line;

StringBuilder builder=new StringBuilder();

while ((line=reader.readLine())!=null) {

//SwingWorker線程並不屬於UI線程,

//所以不能在 doInBackground() 方法中為UI元素設定屬性

//可以將當前的數據傳遞(發布)給 process(),這就是中間的數據

//publish(line);

 

 

//也可以將 line 添加到builder中,一次性刷新到UI界面,

//而不像上面的 publish() 每讀取一行就刷新到UI界面

builder.append(line).append("\n");

}

 

//關閉流

reader.close();

 

return builder;

}

 

@Override

protected void process(List<String> chunks) {

//process() 方法被執行后,其中的內容會自動分發給UI線程

//process() 中的所有操作都是線程安全的

//

//使用 for 循環來接收傳入的值(即中間的數據,String類型)

//從傳入的 List 中獲取一行數據(取出數據)

for (String line : chunks) {

//添加到 textArea 並換行

textArea.append(line);

textArea.append("\n");

}

super.process(chunks);

}

 

 

//由於每讀取一行數據都要讓UI線程來執行一次刷新的工作,

//這對於UI線程來說工作量還是比較大的

//可以將網頁全部讀取后,讓這些數據一次性刷新到UI界面上,

//不過這樣,等待的時間會更長

@Override

protected void done() {

//可以在 done() 方法為UI元素設定屬性

//done() 中的所有操作都是線程安全的

try {

//get() 返回StringBuilder類型

//有異常拋出,用try catch 捕獲

textArea.setText(get().toString());

} catch (InterruptedException e) {

e.printStackTrace();

} catch (ExecutionException e) {

e.printStackTrace();

}

super.done();

}

}.execute();

}

   

}

   

   

   

將窗體 JFrame 的 LookAndFeel 設定為 Windows

   

   

在根面板 contentPane 的上方添加一個 JButton,

中間添加一個 JScrollPane

   

   

將 JButton 的文本(text)改為 Run,並 Rename 為 btnRun,

將 focusable 屬性設為 false

   

   

在 JScrollPane 的 Viewport 添加一個 JTextArea

   

   

為 JButton 添加 mouseClicked 事件,鼠標單擊 Run 按鈕后,

讀取 Apache官網 的 HTML 數據

   

Apache官網:http://www.apache.org

   

   

   

SwingWorker 線程中的 3 個方法:

   

1)doInBackground()

   

   

   

2)process()

   

   

   

(3)done()

   

   

   

   

   

運行程序:

   

   

   

   

   

關於 SwingWorker 參考鏈接:

參考鏈接1參考鏈接2參考鏈接3參考鏈接4

   

   

   

   

   

   

【made by siwuxie095】


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM