使用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 ...
随机推荐
- Python 不可变对象
str是不变对象,而list是可变对象. 对于可变对象,比如list,对list进行操作,list内部的内容是会变化的,比如: >>> a = ['c', 'b', 'a'] > ...
- 每天一个Linux命令(13)less命令
less命令的作用与more十分相似,都可以用来浏览文字档案的内容,不同的是less命令允许用户向前或向后浏览文件,而more命令只能向前浏览. 用less命令显示文件时,用PageUp键向上翻页,用 ...
- java -ea
两题考的都是 assert和assertionassert是JDK1.4(&+)中新增的关键字,其功能称作assertionassert 条件表达式 如果条件表达式不成立 ...
- 20145229吴姗珊 《Java程序设计》第4周学习总结
20145229吴姗珊 <Java程序设计>第4周学习总结 教材学习内容总结 第六章 继承与多态 6.1继承共同行为 1.继承基本上就是避免多个类间重复定义共同行为 简单的类的定义 使用s ...
- Spring中如何动态注入Bean实例教程
前言 在Spring中提供了非常多的方式注入实例,但是由于在初始化顺序的不同,基于标注的注入方式,容易出现未被正确注入成功的情况. 本文将介绍一种在实际项目中基于动态的方式来提取Spring管理的Be ...
- 在macOS上使用***
写在教程之前[转] 本教程是通用的***在macOS上的使用教程.同时作为FzVPN的设备教程补充之一,适用于macOS. 若您在使用FzVPN,请在阅读前先仔细阅读FzVPN的使用帮助:>传送 ...
- Network IP Availability Extension
可以查询网络的IP使用情况 neutron net-ip-availability-list neutron net-ip-availability-show GET /v2.0/network-ip ...
- CSS: iPhone Custom CSS
1. [代码][CSS]代码 <style type="text/css" media="screen"> /* iPhone 4@media on ...
- SQL嵌套子查询和相关子查询的执行过程有什么区别(推荐)
SQLServer子查询可以分为 相关子查询 和 嵌套子查询 两类.前提, 假设Books表如下: 类编号 图书名 出版社 价格 ----------------------------------- ...
- Vue2.0 Transition常见用法全解惑
Vue2.0的过渡系统(transition)有了很大的改变,想把1.0的项目迁移到2.0,着实需要费一些功夫,今天我就要把vue2.0的过渡系统的用法搞清楚,因为之前确实踩了不少坑.这里只涉及单元素 ...