【问题标题】:Getting webpage source code without freezing UI在不冻结 UI 的情况下获取网页源代码
【发布时间】:2014-07-24 00:18:20
【问题描述】:

我正在尝试获取网页的源代码,但是当我这样做时,用户界面会冻结。我什至使用了 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 不会冻结的情况下获取源代码?怎么样?

【问题讨论】:

    标签: java swing concurrency swingworker


    【解决方案1】:

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

    【讨论】:

    • 两个建议,要么覆盖done 方法,要么将PropertyChangeListener 添加到worker 并监控done 状态...+1
    • @MadProgrammer 我将如何在方法中做到这一点?我正在从一个方法返回源代码。
    • @usama8800 并非如此,您在 actionPerformed 方法中创建了匿名类。覆盖done 方法并使用doInBackground 的结果调用另一个方法。当done被调用时,你可以调用get,它会返回从doInBackground返回的值,这保证了两件事,一,它不会阻塞,二,done是从上下文中调用的美国东部时间
    • @MadProgrammer 这是一个 SSCCE。在原程序中,我使用的是一种方法。
    • @usama8800 那么您的 SSCCE 应该更多地反映您正在做的事情,否则我们没有希望......您可能必须克服的问题是您调用的方法必须是 none - 阻塞或从SwingWorker...的上下文中调用...
    猜你喜欢
    • 2011-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-07
    • 1970-01-01
    • 2012-08-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多