package net.sf.openrocket.gui.main;
-import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Toolkit;
+import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
-import java.io.FileInputStream;
+import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
+import java.util.concurrent.ExecutionException;
import javax.swing.Action;
import javax.swing.InputMap;
import javax.swing.LookAndFeel;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingUtilities;
-import javax.swing.SwingWorker;
import javax.swing.ToolTipManager;
import javax.swing.UIManager;
import javax.swing.border.TitledBorder;
import net.sf.openrocket.gui.dialogs.ComponentAnalysisDialog;
import net.sf.openrocket.gui.dialogs.LicenseDialog;
import net.sf.openrocket.gui.dialogs.PreferencesDialog;
+import net.sf.openrocket.gui.dialogs.SwingWorkerDialog;
import net.sf.openrocket.gui.scalefigure.RocketPanel;
import net.sf.openrocket.rocketcomponent.ComponentChangeEvent;
import net.sf.openrocket.rocketcomponent.ComponentChangeListener;
import net.sf.openrocket.rocketcomponent.Rocket;
import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.rocketcomponent.Stage;
-import net.sf.openrocket.util.ConcurrentProgressMonitor;
-import net.sf.openrocket.util.ConcurrentProgressMonitorInputStream;
import net.sf.openrocket.util.Icons;
+import net.sf.openrocket.util.OpenFileWorker;
import net.sf.openrocket.util.Prefs;
+import net.sf.openrocket.util.SaveFileWorker;
public class BasicFrame extends JFrame {
private static final long serialVersionUID = 1L;
* The RocketLoader instance used for loading all rocket designs.
*/
private static final RocketLoader ROCKET_LOADER = new GeneralRocketLoader();
+
+ // TODO: Always uses OpenRocketSaver
+ private static final RocketSaver ROCKET_SAVER = new OpenRocketSaver();
/**
}
});
frames.add(this);
-
}
Prefs.setDefaultDirectory(chooser.getCurrentDirectory());
File[] files = chooser.getSelectedFiles();
- boolean opened = false;
for (File file: files) {
System.out.println("Opening file: " + file);
if (open(file, this)) {
- opened = true;
+
+ // Close previous window if replacing
+ if (replaceable && document.isSaved()) {
+ closeAction();
+ replaceable = false;
+ }
}
}
-
- // Close this frame if replaceable and file opened successfully
- if (replaceable && opened) {
- closeAction();
- }
}
* @param parent the parent component for which a progress dialog is opened.
* @return whether the file was successfully loaded and opened.
*/
- private static boolean open(File file, Component parent) {
- OpenRocketDocument doc = null;
-
-
- try {
- doc = ROCKET_LOADER.load(file, parent);
- } catch (RocketLoadException e) {
- JOptionPane.showMessageDialog(null, "Unable to open file '" + file.getName()
- +"': " + e.getMessage(), "Error opening file", JOptionPane.ERROR_MESSAGE);
- e.printStackTrace();
+ private static boolean open(File file, Window parent) {
+
+ // Open the file in a Swing worker thread
+ OpenFileWorker worker = new OpenFileWorker(file);
+ if (!SwingWorkerDialog.runWorker(parent, "Opening file",
+ "Reading " + file.getName() + "...", worker)) {
+
+ // User cancelled the operation
return false;
}
+
+
+ // Handle the document
+ OpenRocketDocument doc = null;
+ try {
+
+ doc = worker.get();
+
+ } catch (ExecutionException e) {
+
+ Throwable cause = e.getCause();
+
+ if (cause instanceof FileNotFoundException) {
+
+ JOptionPane.showMessageDialog(parent,
+ "File not found: " + file.getName(),
+ "Error opening file", JOptionPane.ERROR_MESSAGE);
+ return false;
+
+ } else if (cause instanceof RocketLoadException) {
+
+ JOptionPane.showMessageDialog(parent,
+ "Unable to open file '" + file.getName() +"': "
+ + cause.getMessage(),
+ "Error opening file", JOptionPane.ERROR_MESSAGE);
+ return false;
+
+ } else {
+
+ throw new RuntimeException("Unknown error when opening file", e);
+
+ }
+
+ } catch (InterruptedException e) {
+ throw new RuntimeException("EDT was interrupted", e);
+ }
+
+ if (doc == null) {
+ throw new RuntimeException("BUG: Document loader returned null");
+ }
+
- if (doc == null) {
- throw new RuntimeException("BUG: Rocket loader returned null");
- }
-
// Show warnings
Iterator<Warning> warns = ROCKET_LOADER.getWarnings().iterator();
System.out.println("Warnings:");
- private static class OpenWorker extends SwingWorker<OpenRocketDocument, Void> {
- private final File file;
- private final Component parent;
- private ConcurrentProgressMonitor monitor = null;
-
- public OpenWorker(File file, Component parent) {
- this.file = file;
- this.parent = parent;
- }
-
- @Override
- protected OpenRocketDocument doInBackground() throws Exception {
- ConcurrentProgressMonitorInputStream is =
- new ConcurrentProgressMonitorInputStream(parent,
- "Loading " + file.getName(), new FileInputStream(file));
- monitor = is.getProgressMonitor();
- return ROCKET_LOADER.load(is);
- }
-
- public ConcurrentProgressMonitor getMonitor() {
- return monitor;
- }
- }
+
+
}
}
+
private boolean saveAsAction() {
File file = null;
while (file == null) {
StorageOptionChooser storageChooser =
- new StorageOptionChooser(document.getDefaultStorageOptions());
+ new StorageOptionChooser(document, document.getDefaultStorageOptions());
JFileChooser chooser = new JFileChooser();
chooser.setFileFilter(ROCKET_DESIGN_FILTER);
chooser.setCurrentDirectory(Prefs.getDefaultDirectory());
return false;
}
- RocketSaver saver = new OpenRocketSaver();
- try {
- saver.save(file, document);
- document.setFile(file);
- document.setSaved(true);
- saved = true;
- } catch (IOException e) {
- JOptionPane.showMessageDialog(this, new String[] {
- "An I/O error occurred while saving:",
- e.getMessage() }, "Saving failed", JOptionPane.ERROR_MESSAGE);
+
+ SaveFileWorker worker = new SaveFileWorker(document, file, ROCKET_SAVER);
+
+ if (!SwingWorkerDialog.runWorker(this, "Saving file",
+ "Writing " + file.getName() + "...", worker)) {
+
+ // User cancelled the save
+ file.delete();
+ return false;
}
- setTitle();
+
+ try {
+ worker.get();
+ document.setFile(file);
+ document.setSaved(true);
+ saved = true;
+ setTitle();
+ } catch (ExecutionException e) {
+ Throwable cause = e.getCause();
+
+ if (cause instanceof IOException) {
+ JOptionPane.showMessageDialog(this, new String[] {
+ "An I/O error occurred while saving:",
+ e.getMessage() }, "Saving failed", JOptionPane.ERROR_MESSAGE);
+ return false;
+ } else {
+ throw new RuntimeException("Unknown error when saving file", e);
+ }
+
+ } catch (InterruptedException e) {
+ throw new RuntimeException("EDT was interrupted", e);
+ }
+
return saved;
}
return true;
}
+
+ /**
+ * Closes this frame if it is replaceable.
+ */
+ public void closeIfReplaceable() {
+ if (this.replaceable && document.isSaved()) {
+ closeAction();
+ }
+ }
+
/**
* Open a new design window with a basic rocket+stage.
*/