2

我正在使用 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 是一个小的 UI 弹出窗口,其中包含 GIF 动画。基本上,我将冗长的任务放在工作人员中,但将 UI 的 setVisibles 放在两个地方。我在想是否有任何方法可以在线程中运行 InfoDialog UI,以便我可以重用那段代码?

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

有人可以告诉我如何做到这一点吗?

4

1 回答 1

3

请阅读Swing 中的 Concurrency特别是The Event Dispatch Thread。这是应该在其上创建和操作所有 Swing 组件的线程。IE:

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 工作dialog程序的覆盖中将 back 设置为不可见process(List<String> chunks),因此在读取第一个块dialog时将关闭。我认为 Swing Workersdone()方法可能更符合您的要求,并且在 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);
    }
}
于 2013-02-26T08:22:14.797 回答