使用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() {
/** * 创建一个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】
posted on 2017-04-06 16:39 siwuxie095 阅读(3523) 评论(0) 编辑 收藏 举报