------------------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() {
/** * 創建一個SwingWorker,SwingWorker是一個專門為界面而實現的線程類, * 它可以非常方便的在當前的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 參考鏈接:
【made by siwuxie095】