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

zqry0prt  于 2023-02-28  发布在  Java
关注(0)|答案(1)|浏览(158)

我正在写一个重命名文件的程序。一旦用户选择了文件夹,文件就在一个线程中处理。线程完成后,程序关闭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”中,但问题仍然存在。有人能提供一些帮助吗?

but5z9lq

but5z9lq1#

当你想在事件调度线程上执行某个东西而不需要等待它时,使用SwingUtilities.invokeLater()。因为你的线程应该做后台工作,所以继续在这个线程中做它,所以本质上删除了对SwingUtilities.invokeLater()的调用。
您也不应该将已经运行的线程与后台线程连接起来。如果您阻塞了正在运行的线程,很可能是事件调度线程,UI将冻结,直到后台工作完成。相反,请完全删除join()操作。
但是如何在后台工作完成后打开另一个窗口呢?这是在后台线程中-在它退出之前-打开新窗口的地方。由于这可能会修改UI,因此应该从事件调度线程中完成,这是一个可以 Package 到SwingUtilities.invokeLater()调用中的操作。

Thread t = new Thread(new Runnable() {
    public void run() {
        ProcessData operatore = new ProcessData();
        operatore.flusso(folderToProcess);

        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                try {
                    Desktop.getDesktop().open(folderToProcess);
                } catch (IOException ioException) {
                    ioException.printStackTrace();
                }                }
        });
    }
});
interfacciaGraficaPanel.tree.setVisible(false);
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
t.start();

相关问题