【发布时间】: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