无限期地运行UI线程

时间:2013-02-26 08:14:09

标签: java swing jdialog swingworker

我正在使用Java Swing编写一段代码。基本上它所做的是它处理一些冗长的任务。当任务正在运行时,我希望有一个等待弹出窗口,其中包含GIF图像。

我的问题是

        final InfoDialog infoDialog = new InfoDialog("Parsing file: " + fileToBeUploaded.getName());

        final File finalFileToBeUploaded = fileToBeUploaded;

        class FileParsingWorker extends SwingWorker<Void, String> {            
            @Override
            protected Void doInBackground() throws Exception {
                String text = fileParsers.parseFile(finalFileToBeUploaded);
                publish(text);
                return null;
            }

            @Override
            protected void process(List<String> chunks) {
                infoDialog.setVisible(false);
            }
        }

        infoDialog.setVisible(true);
        FileParsingWorker fileParsingWorker = new FileParsingWorker();
        fileParsingWorker.execute();

InfoDialog是一个带有GIF动画的小型UI弹出窗口。基本上,我把漫长的任务放在工作者身上,但UI的setVisibles放在两个地方。我在想是否有任何方法可以在一个线程中运行InfoDialog UI,以便我可以重用那段代码?

我遇到的问题是我想尝试无限期地运行InfoDialog,直到我故意停止它为止。如果我在一个线程中放入setVisible(true),该线程会立即终止,我的UI将不会更新。

有人可以告诉我该怎么做吗?

1 个答案:

答案 0 :(得分:3)

请专门阅读Concurrency in Swing The Event Dispatch Thread。这是应该创建和操作所有Swing组件的线程。即:

SwingUtilities.invokeLater(new Runnable () {
    @Override
    public void run() { 
        final InfoDialog infoDialog = new InfoDialog("Parsing file: " + fileToBeUploaded.getName());

        final File finalFileToBeUploaded = fileToBeUploaded;

        ...

        infoDialog.setVisible(true);
        FileParsingWorker fileParsingWorker = new FileParsingWorker();
        fileParsingWorker.execute();
    }
});

另外我认为另一个问题是你在Swing worker的override dialog中将process(List<String> chunks)设置为不可见,因此当读取第一个块时,dialog将被关闭。我认为Swing Workers done()方法可能更符合您的要求,并且在EDT上执行:

class FileParsingWorker extends SwingWorker<Void, String> {            
    @Override
    protected Void doInBackground() throws Exception {
        String text = fileParsers.parseFile(finalFileToBeUploaded);
        publish(text);
        return null;
    }

    @Override
    protected void process(List<String> chunks) {
      //each chunk will get processed here
    }

    @Override
    protected void done() {//when Swing worker is finished this method is called
        infoDialog.setVisible(false);
    }
}