I am writing a program to rename files. Once the user selects the folder the files are processed in a thread. After the thread finishes the program closes the GUI and opens the selected folder. For this reason i'm using the join() method.
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);
}
}
I'd like JOptionpane to prompt user confirmation. If i don't join the thread the program doesn't crash but the selected folder pops up before the confirmation message. I also tried to enclose the JOptionPane in a "SwingUtilities.invokeLater" and in "SwingUtilities.invokeAndWait" but the problem persists. Could someone please provide some help?
Use SwingUtilities.invokeLater() when you want something to be executed on the Event Dispatching Thread and not necessarily wait for it. Since your thread is supposed to do background work, keep doing it in this thread, so essentially remove the call to SwingUtilities.invokeLater().
You also should not join your already running thread with the background thread. If you block the running one, which very likely is the Event Dispatching Thread the UI will freeze until the background work is done. Instead remove the join() operation completely.
But how to open another window once the background work is done? This is where inside your background thread - before it exits - you open the new window. As this likely modifies the UI it should be done from the Event Dispatching thread, and that is the operation you would wrap into a call of 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();