获取网页源代码而不冻结UI

时间:2014-07-24 00:18:21

标签: java swing concurrency swingworker

我正在尝试获取网页的源代码但是当我这样做时,UI会冻结。我甚至使用过SwingWorker但它没有用。这是一个SSCCE:

import java.awt.Dimension;
import java.awt.HeadlessException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.concurrent.ExecutionException;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
public class SSCCE extends JPanel {

    public SSCCE() {
        setPreferredSize(new Dimension(200, 50));
        JFrame frame = new JFrame();
        frame.add(this);
        frame.pack();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);

        JButton action = new JButton("Action");
        action.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                SwingWorker<String, Void> worker = new SwingWorker<String, Void>(){
                    protected String doInBackground() {
                        try {
                            URL url = new URL("http://stackoverflow.com/");
                            InputStream is = url.openStream();
                            BufferedReader br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
                            StringBuilder sb = new StringBuilder();
                            String line;
                            while ((line = br.readLine()) != null) {
                                sb.append(line);
                            }
                            if (is != null) is.close();
                            String source = sb.toString();
                            return source;
                        } catch (IOException e) {
                            return null;
                        }
                    }
                };
                worker.execute();
                try {
                    System.out.println(worker.get());
                } catch (HeadlessException | InterruptedException | ExecutionException e1) {
                    e1.printStackTrace();
                }
            }
        });
        add(action);

        JButton nothing = new JButton("Nothing");
        add(nothing);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new SSCCE();
            }
        });
    }
}

有没有更好的方法来获取源代码或在UI不冻结的地方获取它?怎么样?

1 个答案:

答案 0 :(得分:3)

您的问题是,即使您正在使用SwingWorker,您也会立即转身告诉用户界面等待它(worker.get())。相反,你的工作者应该使用回调 - 当它的工作完成时,它应该调用一些动作,可能在事件线程上,告诉UI做下一件事。