JOptionPane 在我加入线程时让我的程序崩溃

问题描述 投票:0回答:1

我正在写一个重命名文件的程序。用户选择文件夹后,文件将在线程中处理。线程完成后,程序关闭 GUI 并打开选定的文件夹。出于这个原因,我正在使用 join() 方法。

File folderToProcess = getFolder();
Thread t = new Thread(new Runnable() {
            public void run() {
                  SwingUtilities.invokeLater(new Runnable() {
                        public void run() {
                                    setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
                                    interfacciaGraficaPanel.tree.setVisible(false);
                                }
                            });
                            ProcessData operatore = new ProcessData();
                            operatore.flusso(folderToProcess);
                        }
                    });
                    t.start();
                    try {

                        t.join();
                    } catch (InterruptedException interruptedException) {
                        interruptedException.printStackTrace();
                    }
                    dispose();
                    try {
                        Desktop.getDesktop().open(folderToProcess);
                    } catch (IOException ioException) {
                        ioException.printStackTrace();
                    }
public class ProcessData {
    void flusso(File currentFolder) {
\\some code to rename files
int result = JOptionPane.showConfirmDialog(null, "Would you rename " + numberOfFilesToRename + " file?",
                    "Rinomina",
                    JOptionPane.YES_NO_OPTION,
                    JOptionPane.QUESTION_MESSAGE);
}
}

我希望 JOptionpane 提示用户确认。 如果我不加入线程,程序不会崩溃,但会在确认消息之前弹出所选文件夹。 我还尝试将 JOptionPane 包含在“SwingUtilities.invokeLater”和“SwingUtilities.invokeAndWait”中,但问题仍然存在。 有人可以提供帮助吗?

java joptionpane java-threads
1个回答
0
投票

当你想在事件调度线程上执行某些事情而不一定要等待它时,使用 SwingUtilities.invokeLater()。 因为你的线程应该做后台工作,所以在这个线程中继续做,所以基本上删除了对 SwingUtilities.invokeLater() 的调用。

您也不应该将已经运行的线程与后台线程连接起来。如果您阻止正在运行的线程(很可能是事件调度线程),UI 将冻结,直到后台工作完成。而是完全删除 join() 操作。

但是后台工作完成后如何打开另一个窗口? 这是在后台线程中 - 在它退出之前 - 你打开新窗口的地方。由于这可能会修改 UI,因此应该从事件调度线程完成,这就是您将包装到 SwingUtilities.invokeLater() 调用中的操作。

© www.soinside.com 2019 - 2024. All rights reserved.