尽管我设置了Platform.setImplicitExit(true),JavaFX线程仍然没有死?

时间:2016-01-16 10:16:01

标签: java multithreading swing javafx

在我的应用程序中,我使用了 javafx.stage.FileChooser ,为此它将启动JavaFX线程。 对于我的框架,我将默认关闭操作设置为WindowConstants.DISPOSE_ON_CLOSE 。 当用户退出应用程序时,所有GUI都将消失但应用程序将继续运行,因为JavaFX线程仍处于活动状态。有趣的是我设置了Platform.setImplicitExit(true); 。 该函数的文档说:“如果此属性为true,则JavaFX运行时将在最后一个窗口关闭时隐式关闭;”,但这没有发生。 可以通过将默认关闭操作设置为WindowConstants.EXIT_ON_CLOSE或使用javax.swing.JFileChooser而不是FileChooser来解决此问题。 我已修复它,但感兴趣并想了解为什么JavaFX线程没有关闭,即使我设置隐式退出并且没有打开任何内容。

这是一个小示例程序(单击按钮 - >关闭文件选择器 - >关闭应用程序):

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;
        }
    }
}

我刚刚进行了这个小测试,程序也没有结束,因为JavaFX线程。

public class Main {

    public static void main(String[] args) {
        new JFXPanel();
        Platform.setImplicitExit(true);
        Platform.runLater(()->{
            FileChooser fc = new FileChooser();
            fc.showOpenDialog(null);
        });
    }

}

0 个答案:

没有答案