【问题标题】:How to run a Save As menu on EDT (Java Swing)如何在 EDT (Java Swing) 上运行另存为菜单
【发布时间】:2013-12-27 20:42:47
【问题描述】:

(我正在将我的全屏 Java application 升级为在窗口中运行的 Java Swing 应用程序。)

基本类作为 EDT(事件调度线程)上的线程运行,并使用 invokeAndWait(this) 调用。

活动渲染循环位于同一类的方法体中,但它在 EDT 之外作为单独的线程运行。 (这已被证明。)

当按下适当的键时,活动渲染循环将暂停并调用另存为菜单。 Save As 菜单在 EDT 上运行,在 Linux 中看起来不错,但在 Windows 中看起来不太好。 Windows 中的确认菜单(用于文件覆盖)为空白。

private void save_frame() {
    setVisible(false);
    try {invokeAndWait(new Runnable() {
        @Override
        public void run() {
            try {
                if (current_save_folder == null) {
                    current_save_folder = javax.swing.filechooser.FileSystemView.getFileSystemView().getDefaultDirectory().toString();
                }
                final JFileChooser saver = new JFileChooser();
                saver.setCurrentDirectory(new File(current_save_folder));
                saver.setDialogTitle("Save two frames and state as...");
                saver.setFileSelectionMode(JFileChooser.FILES_ONLY);
                saver.setAcceptAllFileFilterUsed(true);
                int approval = saver.showSaveDialog(getParent());
                File file = saver.getSelectedFile();
                if (approval == saver.APPROVE_OPTION && file != null) {
                    file = new File(file.getAbsolutePath());
                    current_save_folder = file.getParent();
                    File file_in_png = new File(file.getAbsolutePath());
                    File file_out_png = new File(file.getAbsolutePath());
                    File file_state = new File(file.getAbsolutePath());
                    String file_lowercase = file.getAbsolutePath().toLowerCase();
                    if (file_lowercase.endsWith(".in.png")) {
                        file = new File(file.getAbsolutePath().replace(".in.png", ""));
                    } else {
                        file_in_png = new File(file.getAbsolutePath() + ".in.png");
                    }
                    if (file_lowercase.endsWith(".out.png")) {
                        file = new File(file.getAbsolutePath().replace(".out.png", ""));
                    } else {
                        file_out_png = new File(file.getAbsolutePath() + ".out.png");
                    }
                    if (file_lowercase.endsWith(".state")) {
                        file = new File(file.getAbsolutePath().replace(".state", ""));
                    } else {
                        file_state = new File(file.getAbsolutePath() + ".state");
                    }
                    if (file.exists() || file_in_png.exists() || file_out_png.exists() || file_state.exists()) {
                        shortName name = new shortName(saver.getSelectedFile().getName());
                        int answer = JOptionPane.showConfirmDialog(getParent(), "File " + name.getShortName(30) + " already exists!\nOverwrite??", "Yes or No?", JOptionPane.YES_NO_CANCEL_OPTION);
                        switch (answer) {
                            case JOptionPane.YES_OPTION:
                                saver.approveSelection();
                                try {
                                    System.out.println("saving...");
                                    ImageIO.write(double_buffer.output.image, "png", new File(file.getAbsolutePath() + ".out.png"));   // save frame
                                    ImageIO.write(double_buffer.buffer.image, "png", new File(file.getAbsolutePath() + ".in.png"));
                                    // ImageIO.write(data_buffer.display.image, "png", new File(file.getAbsolutePath() + ".display.png"));   // cursor movements
                                    // ImageIO.write(data_buffer.image.image, "png", new File(file.getAbsolutePath() + ".sketch.png"));      // preloaded image
                                    Preset.write(Main.percept, new File(file.getAbsolutePath() + ".state")); // save with extension *.state
                                    System.out.println("...saved.");
                                    current_save_folder = file.getParent();
                                } catch (IOException e) { e.printStackTrace(); }
                                return;
                            case JOptionPane.NO_OPTION:
                                System.out.println("save file not accepted");
                                return;
                            case JOptionPane.CLOSED_OPTION:
                                System.out.println("save menu closed");
                                return;
                            case JOptionPane.CANCEL_OPTION:
                                saver.cancelSelection();
                                System.out.println("save menu cancelled");
                                return;
                        }
                    } else {
                        try {
                            System.out.println("saving...");
                            ImageIO.write(double_buffer.output.image, "png", new File(file.getAbsolutePath() + ".out.png"));   // save frame
                            ImageIO.write(double_buffer.buffer.image, "png", new File(file.getAbsolutePath() + ".in.png"));
                            // ImageIO.write(data_buffer.display.image, "png", new File(file.getAbsolutePath() + ".display.png"));   // cursor movements
                            // ImageIO.write(data_buffer.image.image, "png", new File(file.getAbsolutePath() + ".sketch.png"));      // preloaded image
                            Preset.write(Main.percept, new File(file.getAbsolutePath() + ".state")); // save with extension *.state
                            System.out.println("...saved.");
                            current_save_folder = file.getParent();
                        } catch (IOException e) { e.printStackTrace(); }
                    }
                }

            } catch (Exception E) {
                System.err.println("File write error while saving screenshot and state.");
                JOptionPane.showMessageDialog(getParent(), "Could not write files.", "Error", JOptionPane.ERROR_MESSAGE);
                E.printStackTrace();
            }
        }
    }); } catch (InterruptedException | InvocationTargetException e) { e.printStackTrace(); }

    if (windowed_mode) {
        setVisible(true);
    } else
        screen_mode();
    hide_cursor();
    save_as_running = false;
    running = true;

}

【问题讨论】:

  • 逻辑可能是 1. JFileChooser 中的所有内容都在 EDT 上完成(然后 invokeLater 非常适得其反),2. ImageIO.Xxx 可以重定向到 Runnable#Thread 或 SwingWorker,3. :-)跨度>
  • 全屏独占模式存在对话框问题(来自内存)
  • 原始问题已更新,所以让我们看看确认菜单...

标签: java multithreading swing joptionpane jfilechooser


【解决方案1】:

经过数量惊人的实验后,我发现了一种有趣的方法来纠正我的 Windows 8 中确认对话框的外观,该系统采用 Oracle 的最新 Java。

Main 类现在扩展了 JFrame,似乎没有其他原因,就是让菜单按应有的方式运行。

由于代码时尚的原因,Main 类也实现了 Runnable,所以运行的第一个代码是这样的......

    Main m = new Main();
    m.run();

称为 Perceptron 的基本程序类是用作主程序窗口的 JFrame。 Perceptron 在方法 m.run() 中使用 invokeAndWait(perceptron_runnable) 在其自己的 Runnable 中实例化。

使用执行器服务从 Perceptron 构造函数调用活动渲染循环,并在 EDT 之外运行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-05
    • 1970-01-01
    • 2011-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-21
    相关资源
    最近更新 更多