• 使用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() {

     

    /**

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

    * 它可以非常方便的在当前的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(" ");

    }

     

    //关闭流

    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(" ");

    }

    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 参考链接:

    参考链接1参考链接2参考链接3参考链接4

       

       

       

       

       

       

    【made by siwuxie095】

  • 相关阅读:
    安装oracle11g 并且开启APEX 安装
    爬虫基础
    深度优先广度优先
    部署静态页面到nginx
    Nginx 实现端口转发
    五步教你实现使用Nginx+uWSGI+Django方法部署Django程序
    Please select Android SDK解决办法
    android与JS交互,互相调用方法,跳转到网页
    Android:你要的WebView与 JS 交互方式 都在这里了
    Android与js交互拍照上传资料
  • 原文地址:https://www.cnblogs.com/siwuxie095/p/6674177.html
Copyright © 2020-2023  润新知