java swingworker_使用SwingWorker为界面执行异步任务

本文通过一个Java SwingWorker示例展示了如何在GUI应用程序中执行异步任务,以避免阻塞用户界面。当用户点击“Run”按钮时,程序使用SwingWorker从指定URL读取网页内容并在文本区域显示。SwingWorker在后台读取数据,然后在适当的时候更新UI,确保了良好的用户体验。
摘要由CSDN通过智能技术生成

packagecom.siwuxie095.swingworker;

importjava.awt.BorderLayout;

importjava.awt.EventQueue;

importjava.awt.event.MouseAdapter;

importjava.awt.event.MouseEvent;

importjava.io.BufferedReader;

importjava.io.InputStreamReader;

importjava.net.URL;

importjava.net.URLConnection;

importjava.util.List;

importjava.util.concurrent.ExecutionException;

importjavax.swing.JButton;

importjavax.swing.JFrame;

importjavax.swing.JPanel;

importjavax.swing.JScrollPane;

importjavax.swing.JTextArea;

importjavax.swing.SwingWorker;

importjavax.swing.UIManager;

importjavax.swing.UnsupportedLookAndFeelException;

importjavax.swing.border.EmptyBorder;

importcom.sun.java.swing.plaf.windows.WindowsLookAndFeel;

public classTestSwingWorker extendsJFrame {

privateJPanel contentPane;

privateJTextArea textArea;

/**

* Launch the application.

*/

public staticvoidmain(String[] args) {

EventQueue.invokeLater(newRunnable() {

publicvoidrun() {

try{

TestSwingWorker frame = newTestSwingWorker();

frame.setVisible(true);

} catch(Exception e) {

e.printStackTrace();

}

}

});

}

/**

* Create the frame.

*/

publicTestSwingWorker() {

try{

UIManager.setLookAndFeel(newWindowsLookAndFeel());

} catch(UnsupportedLookAndFeelException e1) {

e1.printStackTrace();

}

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

setBounds(100, 100, 450, 300);

contentPane = newJPanel();

contentPane.setBorder(newEmptyBorder(5, 5, 5, 5));

contentPane.setLayout(newBorderLayout(0, 0));

setContentPane(contentPane);

JButton btnRun = newJButton("Run");

btnRun.setFocusable(false);

btnRun.addMouseListener(newMouseAdapter() {

@Override

publicvoidmouseClicked(MouseEvent e) {

//鼠标点击Run按钮后执行读取网络数据的方法

webRead();

}

});

contentPane.add(btnRun, BorderLayout.NORTH);

JScrollPane scrollPane = newJScrollPane();

contentPane.add(scrollPane, BorderLayout.CENTER);

textArea = newJTextArea();

scrollPane.setViewportView(textArea);

}

publicvoidwebRead() {

/**

*创建一个SwingWorker,SwingWorker是一个专门为界面而实现的线程类,

*它可以非常方便的在当前的UI线程中执行一定的耗时操作,且可以很安全

*的将它的返回值发送给UI线程

*

*创建SwingWorker时,需要指定两个泛型:

*第一个泛型是SwingWorker线程执行之后得到的结果的类型(返回值的类型)

*第二个泛型是SwingWorker线程执行中间所发布(publish)的数据的类型

*

*这里将整个SwingWorker的返回值定义为StringBuilder,中间发布的数据定义为String

*

*覆盖三个方法:doInBackground()、process()、done()

*

* doInBackground()中执行耗时的操作,如:读取网络数据、读取本地文件、等待

* doInBackground()产生的中间数据publish()到process()中

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

*

*即两种方法都能获取最终的结果

*

*最后调用SwingWorker的execute()方法执行该线程

*/

newSwingWorker() {

//后台处理过程

@Override

protectedStringBuilder doInBackground() throwsException {

//创建一个URL对象,用于读取网络数据

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

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

//使用openConnection()方法获取一个互联网连接

//返回值是URLConnection类型,创建以接收返回值

URLConnection connection=url.openConnection();

//将读取的输入流getInputStream()层层包装,最后使用BufferedReader来读取网络数据

//先包装成InputStreamReader,并指定字符集,再包装成BufferedReader

BufferedReader reader=newBufferedReader(

newInputStreamReader(connection.getInputStream(),"UTF-8"));

//读取每一行数据

String line;

StringBuilder builder=newStringBuilder();

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

//SwingWorker线程并不属于UI线程,

//所以不能在doInBackground()方法中为UI元素设定属性

//可以将当前的数据传递(发布)给process(),这就是中间的数据

//publish(line);

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

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

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

}

//关闭流

reader.close();

returnbuilder;

}

@Override

protectedvoidprocess(List 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

protectedvoiddone() {

//可以在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();

}

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值