简体   繁体   中英

How to run a Save As menu on EDT (Java Swing)

(I am upgrading my fullscreen Java application to a Java Swing application that runs in a window.)

The essential class runs as a thread on EDT (event dispatching thread) and is invoked using invokeAndWait(this).

The active rendering loop is found in a method body in the same class, but it runs as a separate thread outside of EDT. (This is proven.)

When the appropriate key is pressed, the active rendering loop is paused and a Save As menu is called. The Save As menu runs on EDT and looks good in Linux, but it does not look good in Windows. The confirmation menu (for file overwriting) is blank in 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

屏幕快照2文件覆盖确认对话框

After a staggering number of experiments, I discovered interesting way to correct the look of confirmation dialogue in my Windows 8 featuring the latest Java from Oracle.

The Main class now extends JFrame for seemingly no other reason than to have the menu's running the way they should.

Main class also implements Runnable for reasons of code fashion, so the first code that runs goes like this ...

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

The essential program class called Perceptron, is the JFrame used as the main program window. Perceptron is instantiated in its own Runnable in method m.run() using invokeAndWait(perceptron_runnable).

The active rendering loop is called from the Perceptron constructor using executor service and runs outside of EDT.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM