In my application I used the javafx.stage.FileChooser and for it the JavaFX thread would start. For my frame I set the default close operation to WindowConstants.DISPOSE_ON_CLOSE. When the user would exit the application all GUI would disappear but the application would continue running because of the JavaFX thread still being alive. The interesting thing is that I set Platform.setImplicitExit(true); . The documentation of the function says:"If this attribute is true, the JavaFX runtime will implicitly shutdown when the last window is closed;", but this did not happen. The problem could be solved by setting default close operation to WindowConstants.EXIT_ON_CLOSE or using the javax.swing.JFileChooser instead of FileChooser. I have fixed it, but am interested and would like to understand why the JavaFX thread did not shutdown even though I set the implicit exit and nothing was opened.
Here is a small example program (click button->close file chooser->close application):
public class JFXProblm {
public static void main(String[] args) {
EventQueue.invokeLater(() -> {
new MyFrame();
});
}
private static class MyFrame extends JFrame {
public MyFrame() {
setVisible(true);
setBounds(150, 150, 300, 300);
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
//WindowConstants.EXIT_ON_CLOSE->the application will close,
//but that is not the point of the question
add(new JButton(new AbstractAction("File chooser") {
@Override
public void actionPerformed(ActionEvent arg0) {
{
// to prepare toolkit
new JFXPanel();
Platform.setImplicitExit(true);
}
final FileWrapper f = new FileWrapper();
if (Platform.isFxApplicationThread()) {
FileChooser fc = new FileChooser();
f.setF(fc.showOpenDialog(null));
} else {
synchronized (f) {
Platform.runLater(() -> {
synchronized (f) {
FileChooser fc = new FileChooser();
f.setF(fc.showOpenDialog(null));
f.notify();
}
});
try {
f.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
File file = f.getF();
if(file!=null)
JOptionPane.showMessageDialog(null, f.getF().toString());
}
}));
}
}
/**
* Used because of the must be final in runnable.
* If there is a better way please educate me :)
*
*/
private static class FileWrapper {
private File f = null;
public synchronized File getF() {
return f;
}
public synchronized void setF(File f) {
this.f = f;
}
}
}
I just made this small test and the program does not end, again because of the JavaFX thread.
public class Main {
public static void main(String[] args) {
new JFXPanel();
Platform.setImplicitExit(true);
Platform.runLater(()->{
FileChooser fc = new FileChooser();
fc.showOpenDialog(null);
});
}
}