X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fnet%2Fsf%2Fopenrocket%2Fgui%2Fmain%2FBasicFrame.java;h=5357b3290add757453d6fc4dd93ad400c6d08eb7;hb=0d0afe488300aca47d09ac7651f8185190afb21f;hp=ebd86276b885925d47cc072030eaeb102f357ca9;hpb=3300ab50b96876523862913e63fe168a0fcdb2bd;p=debian%2Fopenrocket diff --git a/src/net/sf/openrocket/gui/main/BasicFrame.java b/src/net/sf/openrocket/gui/main/BasicFrame.java index ebd86276..5357b329 100644 --- a/src/net/sf/openrocket/gui/main/BasicFrame.java +++ b/src/net/sf/openrocket/gui/main/BasicFrame.java @@ -17,9 +17,14 @@ import java.awt.event.WindowEvent; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; import java.lang.reflect.InvocationTargetException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.URLDecoder; import java.util.ArrayList; -import java.util.Iterator; import java.util.concurrent.ExecutionException; import javax.swing.Action; @@ -53,7 +58,7 @@ import javax.swing.tree.TreePath; import javax.swing.tree.TreeSelectionModel; import net.miginfocom.swing.MigLayout; -import net.sf.openrocket.aerodynamics.Warning; +import net.sf.openrocket.aerodynamics.WarningSet; import net.sf.openrocket.document.OpenRocketDocument; import net.sf.openrocket.file.GeneralRocketLoader; import net.sf.openrocket.file.OpenRocketSaver; @@ -62,17 +67,21 @@ import net.sf.openrocket.file.RocketLoader; import net.sf.openrocket.file.RocketSaver; import net.sf.openrocket.gui.StorageOptionChooser; import net.sf.openrocket.gui.configdialog.ComponentConfigDialog; -import net.sf.openrocket.gui.dialogs.BugDialog; +import net.sf.openrocket.gui.dialogs.AboutDialog; +import net.sf.openrocket.gui.dialogs.BugReportDialog; import net.sf.openrocket.gui.dialogs.ComponentAnalysisDialog; +import net.sf.openrocket.gui.dialogs.ExampleDesignDialog; 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.dialogs.WarningDialog; 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.GUIUtil; import net.sf.openrocket.util.Icons; import net.sf.openrocket.util.OpenFileWorker; import net.sf.openrocket.util.Prefs; @@ -86,7 +95,6 @@ public class BasicFrame extends JFrame { */ private static final RocketLoader ROCKET_LOADER = new GeneralRocketLoader(); - // TODO: Always uses OpenRocketSaver private static final RocketSaver ROCKET_SAVER = new OpenRocketSaver(); @@ -235,7 +243,9 @@ public class BasicFrame extends JFrame { } }); this.setLocationByPlatform(true); - + + GUIUtil.setWindowIcons(this); + this.validate(); vertical.setDividerLocation(0.4); setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); @@ -402,6 +412,23 @@ public class BasicFrame extends JFrame { }); menu.add(item); + item = new JMenuItem("Open example..."); + item.getAccessibleContext().setAccessibleDescription("Open an example rocket design"); + item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, + ActionEvent.CTRL_MASK | ActionEvent.SHIFT_MASK)); + item.setIcon(Icons.FILE_OPEN_EXAMPLE); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + URL[] urls = ExampleDesignDialog.selectExampleDesigns(BasicFrame.this); + if (urls != null) { + for (URL u: urls) { + open(u, BasicFrame.this); + } + } + } + }); + menu.add(item); + menu.addSeparator(); item = new JMenuItem("Save",KeyEvent.VK_S); @@ -528,6 +555,13 @@ public class BasicFrame extends JFrame { menu.add(item); + //// Debug + // (shown if openrocket.debug.menu is defined) + if (System.getProperty("openrocket.debug.menu") != null) { + menubar.add(makeDebugMenu()); + } + + //// Help @@ -552,7 +586,8 @@ public class BasicFrame extends JFrame { "bugs in OpenRocket"); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - new BugDialog(BasicFrame.this).setVisible(true); +// new BugDialog(BasicFrame.this).setVisible(true); + BugReportDialog.showBugReportDialog(BasicFrame.this); } }); menu.add(item); @@ -571,6 +606,73 @@ public class BasicFrame extends JFrame { } + private JMenu makeDebugMenu() { + JMenu menu; + JMenuItem item; + + //// Debug menu + menu = new JMenu("Debug"); + menu.getAccessibleContext().setAccessibleDescription("OpenRocket debugging tasks"); + + item = new JMenuItem("What is this menu?"); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + JOptionPane.showMessageDialog(BasicFrame.this, + new Object[] { + "The 'Debug' menu includes actions for testing and debugging " + + "OpenRocket.", " ", + "The menu is made visible by defining the system property " + + "'openrocket.debug.menu' when starting OpenRocket.", + "It should not be visible by default." }, + "Debug menu", JOptionPane.INFORMATION_MESSAGE); + } + }); + menu.add(item); + + menu.addSeparator(); + + item = new JMenuItem("Exception here"); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + throw new RuntimeException("Testing exception from menu action listener"); + } + }); + menu.add(item); + + item = new JMenuItem("Exception from EDT"); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + throw new RuntimeException("Testing exception from " + + "later invoked EDT thread"); + } + }); + } + }); + menu.add(item); + + item = new JMenuItem("Exception from other thread"); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + new Thread() { + @Override + public void run() { + throw new RuntimeException("Testing exception from " + + "newly created thread"); + } + }.start(); + } + }); + menu.add(item); + + + + return menu; + } + + /** * Select the tab on the main pane. @@ -609,20 +711,91 @@ public class BasicFrame extends JFrame { } + + + private static boolean open(URL url, Window parent) { + String filename = null; + + // Try using URI.getPath(); + try { + URI uri = url.toURI(); + filename = uri.getPath(); + } catch (URISyntaxException ignore) { } + + // Try URL-decoding the URL + if (filename == null) { + try { + filename = URLDecoder.decode(url.toString(), "UTF-8"); + } catch (UnsupportedEncodingException ignore) { } + } + + // Last resort + if (filename == null) { + filename = ""; + } + + // Remove path from filename + if (filename.lastIndexOf('/') >= 0) { + filename = filename.substring(filename.lastIndexOf('/')+1); + } + + try { + InputStream is = url.openStream(); + open(is, filename, parent); + } catch (IOException e) { + JOptionPane.showMessageDialog(parent, + "An error occurred while opening the file " + filename, + "Error loading file", JOptionPane.ERROR_MESSAGE); + } + + return false; + } + + + /** + * Open the specified file from an InputStream in a new design frame. If an error + * occurs, an error dialog is shown and false is returned. + * + * @param stream the stream to load from. + * @param filename the file name to display in dialogs (not set to the document). + * @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(InputStream stream, String filename, Window parent) { + OpenFileWorker worker = new OpenFileWorker(stream, ROCKET_LOADER); + return open(worker, filename, null, parent); + } + + /** - * Open the specified file in a new design frame. If an error occurs, an error dialog - * is shown and false is returned. + * Open the specified file in a new design frame. If an error occurs, an error + * dialog is shown and false is returned. * * @param file the file to open. * @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, Window parent) { + OpenFileWorker worker = new OpenFileWorker(file, ROCKET_LOADER); + return open(worker, file.getName(), file, parent); + } + + + /** + * Open the specified file using the provided worker. + * + * @param worker the OpenFileWorker that loads the file. + * @param filename the file name to display in dialogs. + * @param file the File to set the document to (may be null). + * @param parent + * @return + */ + private static boolean open(OpenFileWorker worker, String filename, 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)) { + "Reading " + filename + "...", worker)) { // User cancelled the operation return false; @@ -642,14 +815,14 @@ public class BasicFrame extends JFrame { if (cause instanceof FileNotFoundException) { JOptionPane.showMessageDialog(parent, - "File not found: " + file.getName(), + "File not found: " + filename, "Error opening file", JOptionPane.ERROR_MESSAGE); return false; } else if (cause instanceof RocketLoadException) { JOptionPane.showMessageDialog(parent, - "Unable to open file '" + file.getName() +"': " + "Unable to open file '" + filename +"': " + cause.getMessage(), "Error opening file", JOptionPane.ERROR_MESSAGE); return false; @@ -670,12 +843,16 @@ public class BasicFrame extends JFrame { // Show warnings - Iterator warns = ROCKET_LOADER.getWarnings().iterator(); - System.out.println("Warnings:"); - while (warns.hasNext()) { - System.out.println(" "+warns.next()); - // TODO: HIGH: dialog - } + WarningSet warnings = worker.getRocketLoader().getWarnings(); + if (!warnings.isEmpty()) { + WarningDialog.showWarnings(parent, + new Object[] { + "The following problems were encountered while opening " + filename + ".", + "Some design features may not have been loaded correctly." + }, + "Warnings while opening file", warnings); + } + // Set document state doc.setFile(file); @@ -922,7 +1099,7 @@ public class BasicFrame extends JFrame { public static void main(final String[] args) { - // Run the actual startup method in the EDT since it can use dialogs etc. + // Run the actual startup method in the EDT since it can use progress dialogs etc. try { SwingUtilities.invokeAndWait(new Runnable() { @Override @@ -940,7 +1117,7 @@ public class BasicFrame extends JFrame { private static void runMain(String[] args) { - + /* * Set the look-and-feel. On Linux, Motif/Metal is sometimes incorrectly used * which is butt-ugly, so if the system l&f is Motif/Metal, we search for a few @@ -983,10 +1160,32 @@ public class BasicFrame extends JFrame { ToolTipManager.sharedInstance().setDismissDelay(30000); + // Setup the uncaught exception handler + ExceptionHandler.registerExceptionHandler(); + + // Load defaults Prefs.loadDefaultUnits(); + // Starting action + if (!handleCommandLine(args)) { + newAction(); + } + } + + + /** + * Handles arguments passed from the command line. This may be used either + * when starting the first instance of OpenRocket or later when OpenRocket is + * executed again while running. + * + * @param args the command-line arguments. + * @return whether a new frame was opened or similar user desired action was + * performed as a result. + */ + public static boolean handleCommandLine(String[] args) { + // Check command-line for files boolean opened = false; for (String file: args) { @@ -994,10 +1193,7 @@ public class BasicFrame extends JFrame { opened = true; } } - - if (!opened) { - newAction(); - } + return opened; } }