SwingWorker没有正确运行doInBackground

时间:2014-10-24 12:38:45

标签: java multithreading swingworker

所以我进入SwingWorkers来处理我使用不同的Classes和Threads操作文本。如下所示,我的Swingworker获取文件路径并扫描文本,将行传递给String。使用getData()我将扫描的String返回到我的主类。但是,在我的Worker类的构造函数中运行方法scanFile()之前,这不起作用。 所以我的问题是:为什么我的SwingWorker类没有正确运行doInBackground()

public class ScanWorker extends SwingWorker<Void, Void> {

    private File file;
    private String text;

    ScanWorker(File file) {
        this.file = file;
    }

    @Override
    protected Void doInBackground() throws Exception {
        scanFile();
        return null;        
    }

    public String getData() {
        return text;
    }

    private void scanFile() {
        String line = "";
        try {

            Scanner scan = new Scanner(file);

            while(scan.hasNextLine()) {
                line = scan.nextLine();
                if(!scan.hasNextLine()) {
                    text += line;
                } else {
                    text += line + "\n";    
                }
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
}

2 个答案:

答案 0 :(得分:1)

  1. 您不应该为返回值添加自己的getData()方法,因为这不是线程安全的。正是SwingWorker试图通过提供自己的机制将结果传回Swing线程来避免的。结果类型是SwingWorker的第一个类型参数,因此您应该SwingWorker<Void,Void>而不是SwingWorker<String,Void>

  2. protected Void doInBackground()更改为protected String doInBackground()(因为这是您的结果类型)。

  3. 删除text字段,然后从doInBackground() 返回结果字符串。

  4. 从工作线程返回doInBackground()方法的结果后,将在Swing线程上调用done()方法。你错过了这种方法。从该方法,您可以调用get()来检索结果。添加方法如下:

    @Override
    protected void done() {
        String result;
        try {
            result = get();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        // Now do whatever you want with the loaded data:
        ...
    }
    
  5. 在您通过调用execute()方法启动之前,SwingWorker不会执行任何操作。确保你这样做!

  6. P.S。您不应该直接在String变量中构建文本,因为每次向其追加一行时都会重新遍历整个字符串,这会产生恶劣的性能。使用StringBuilder进行此类操作,仅在最后调用toString()

    或者,如果您只想将文件重新连接在一起,那么没有必要将文件拆分为行,您可以一次性读取整个文件:

    @Override
    protected String doInBackground() throws Exception {
        return new String(
            java.nio.file.Files.readAllBytes(file.toPath()),
            java.nio.charset.StandardCharsets.UTF_8);
    }
    

答案 1 :(得分:0)

如果你将scanFile()放在构造函数中,那么你在当前线程上执行了该方法,从而违背了SwingWorker的目的。

基于 pull 的方法,来自工作人员的getData(),可能是在你execute后立即出错的:你必须覆盖done()和做与生产结果有关的任何工作。或者,您可以使用publishprocess方法,在工作线程生成EDT时,您将收到EDT中的数据。