使用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 EventQueue.invokeLater(new Runnable() { public 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 //鼠标点击Run按钮后执行读取网络数据的方法 webRead(); } }); contentPane.add(btnRun, BorderLayout.NORTH);
JScrollPane scrollPane = new JScrollPane(); contentPane.add(scrollPane, BorderLayout.CENTER);
textArea = new JTextArea(); scrollPane.setViewportView(textArea); }
public
/** * 创建一个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 //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 //可以在 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】
使用SwingWorker为界面执行异步任务的更多相关文章
- 使用Timer为界面执行异步任务
-------------------siwuxie095 工程名:TestSwingTimer 包名:com.siwuxie095.timer 类名: ...
- 更优雅的方式: JavaScript 中顺序执行异步函数
火于异步 1995年,当时最流行的浏览器--网景中开始运行 JavaScript (最初称为 LiveScript). 1996年,微软发布了 JScript 兼容 JavaScript.随着网景.微 ...
- PowerShell 中 RunspacePool 执行异步多线程任务
在 PowerShell 中要执行任务脚本,现在通常使用 Runspace,效率很高:任务比较多时,用 Runspace pool 来执行异步操作,可以控制资源池数量,就像 C# 中的线程池一样 == ...
- Laravel框架中实现supervisor执行异步进程
问题描述:在使用Laravel框架实现动态网页时,若有些操作计算量较大,为了不影响用户体验,往往需要使用异步方式去处理.这里使用supervisor和laravel自带的queues实现. Super ...
- 计算属性 vs 侦听属性 当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的
https://cn.vuejs.org/v2/guide/computed.html#基础例子 计算属性 vs 侦听属性 Vue 提供了一种更通用的方式来观察和响应 Vue 实例上的数据变动:侦听属 ...
- WPF界面的异步后台加载
private void Init() { BackgroundWorker worker = new BackgroundWorker(); ...
- selenium无界面执行和反爬
selenium无界面执行和反爬 无界面执行 from selenium import webdriver from selenium.webdriver.chrome.options import ...
- celery执行异步任务和定时任务
一.什么是Clelery Celery是一个简单.灵活且可靠的,处理大量消息的分布式系统 专注于实时处理的异步任务队列 同时也支持任务调度 Celery架构 Celery的架构由三部分组成,消息中间件 ...
- redux本来是同步的为什么它能执行异步代码(chunk)实现原理是什么 中间件的实现原理是什么
我们用redux执行同步的时候,都是先发起一个dispatch(actionCreator()) 1.先在actionCreator()中生成一个action对象. 2.由dispatch方法将act ...
随机推荐
- iOS 代码延迟执行
1. [NSTread sleepForTimeInterval:0.8f] 这个方法 实际效果 好比打断点 等你再恢复断点执行 2. [self performSelector:@selector ...
- 【LeetCode】数组排列问题(permutations)(附加next_permutation解析)
描述 Given a collection of distinct integers, return all possible permutations. Example: Input: [1,2,3 ...
- socket通信——通过Udp传输方式,将一段文字数据发送出去
需求:通过Udp传输方式,将一段文字数据发送出去 定义一个Udp发送端 思路: 1.建立updsocket服务 2.提供数据,并将数据封装到数据包中. 3.通过socket服务的发送功能,将数据包发出 ...
- [原创]java WEB学习笔记17:关于中文乱码的问题 和 tomcat在eclipse中起动成功,主页却打不开
本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...
- ubuntu下搭建Scrapy框架简单办法
1. 先执行以下命令 sudo apt-get install python-lxml sudo apt-get install libxslt1-dev sudo apt-get install p ...
- MySQL中处理Null时要注意两大陷阱
MySQL数据库是一个基于结构化数据的开源数据库.SQL语句是MySQL数据库中核心语言.不过在MySQL数据库中执行SQL语句,需要小心两个陷阱. 陷阱一:空值不一定为空 空值是一个比较特殊的字段. ...
- JS获取ListBox所有项
JS代码: var listbox = document.getElementById("<%=lbCustom.ClientID %>"); var values = ...
- Hibernate学习---第七节:关联关系
一.关联关系一对一外键(双向) 1.实体类,代码如下: package learn.hibernate.bean; import java.util.Date; /** * 持久化类设计 * 注意: ...
- Linux 网卡操作与安全初始化
一.Linux网络相关概念和修改IP地址的方法 1.1 网卡命名方式 CENTOS6的网卡命名方式: 它会根据情况有所改变而非唯一且固定,在CENTOS6之前,网络接口使用连续号码命名: eth0. ...
- OpenCV——旋转模糊 (二)
// define head function #ifndef PS_ALGORITHM_H_INCLUDED #define PS_ALGORITHM_H_INCLUDED #include < ...