Reimplement Example menu item as Action List just like the MRU menu

item.  Both the old dialog and new submenu are available in BasicFrame
to see what looks & works better.
This commit is contained in:
kruland2607 2012-10-26 12:09:23 -05:00
parent 02c04f2bf9
commit 3b65c1d970
4 changed files with 261 additions and 185 deletions

View File

@ -6,51 +6,31 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter; import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.util.ArrayList; import java.util.List;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import javax.swing.JButton; import javax.swing.JButton;
import javax.swing.JDialog; import javax.swing.JDialog;
import javax.swing.JLabel; import javax.swing.JLabel;
import javax.swing.JList; import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JScrollPane; import javax.swing.JScrollPane;
import javax.swing.ListSelectionModel; import javax.swing.ListSelectionModel;
import net.miginfocom.swing.MigLayout; import net.miginfocom.swing.MigLayout;
import net.sf.openrocket.gui.main.ExampleDesignFile;
import net.sf.openrocket.gui.util.GUIUtil; import net.sf.openrocket.gui.util.GUIUtil;
import net.sf.openrocket.l10n.Translator; import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.startup.Application; import net.sf.openrocket.startup.Application;
import net.sf.openrocket.util.BugException;
import net.sf.openrocket.util.JarUtil;
public class ExampleDesignDialog extends JDialog { public class ExampleDesignDialog extends JDialog {
private static final String DIRECTORY = "datafiles/examples/";
private static final String PATTERN = ".*\\.[oO][rR][kK]$";
private static final Translator trans = Application.getTranslator(); private static final Translator trans = Application.getTranslator();
private static final FilenameFilter FILTER = new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.matches(PATTERN);
}
};
private boolean open = false; private boolean open = false;
private final JList designSelection; private final JList<ExampleDesignFile> designSelection;
private ExampleDesignDialog(ExampleDesign[] designs, Window parent) { private ExampleDesignDialog(ExampleDesignFile[] designs, Window parent) {
//// Open example design //// Open example design
super(parent, trans.get("exdesigndlg.lbl.Openexampledesign"), Dialog.ModalityType.APPLICATION_MODAL); super(parent, trans.get("exdesigndlg.lbl.Openexampledesign"), Dialog.ModalityType.APPLICATION_MODAL);
@ -59,7 +39,7 @@ public class ExampleDesignDialog extends JDialog {
//// Select example designs to open: //// Select example designs to open:
panel.add(new JLabel(trans.get("exdesigndlg.lbl.Selectexample")), "wrap"); panel.add(new JLabel(trans.get("exdesigndlg.lbl.Selectexample")), "wrap");
designSelection = new JList(designs); designSelection = new JList<ExampleDesignFile>(designs);
designSelection.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); designSelection.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
designSelection.addMouseListener(new MouseAdapter() { designSelection.addMouseListener(new MouseAdapter() {
@Override @Override
@ -111,21 +91,7 @@ public class ExampleDesignDialog extends JDialog {
*/ */
public static URL[] selectExampleDesigns(Window parent) { public static URL[] selectExampleDesigns(Window parent) {
ExampleDesign[] designs; ExampleDesignFile[] designs = ExampleDesignFile.getExampleDesigns();
designs = getJarFileNames();
if (designs == null || designs.length == 0) {
designs = getDirFileNames();
}
if (designs == null || designs.length == 0) {
//// Example designs could not be found.
JOptionPane.showMessageDialog(parent, trans.get("exdesigndlg.lbl.Exampledesignsnotfound"),
//// Examples not found
trans.get("exdesigndlg.lbl.Examplesnotfound"), JOptionPane.ERROR_MESSAGE);
return null;
}
Arrays.sort(designs);
ExampleDesignDialog dialog = new ExampleDesignDialog(designs, parent); ExampleDesignDialog dialog = new ExampleDesignDialog(designs, parent);
dialog.setVisible(true); dialog.setVisible(true);
@ -134,133 +100,13 @@ public class ExampleDesignDialog extends JDialog {
return null; return null;
} }
Object[] selected = dialog.designSelection.getSelectedValues(); List<ExampleDesignFile> selected = dialog.designSelection.getSelectedValuesList();
URL[] urls = new URL[selected.length]; URL[] urls = new URL[selected.size()];
for (int i=0; i<selected.length; i++) { int i = 0;
urls[i] = ((ExampleDesign)selected[i]).getURL(); for (ExampleDesignFile file : selected) {
urls[i++] = file.getURL();
} }
return urls; return urls;
} }
private static ExampleDesign[] getDirFileNames() {
// Try to find directory as a system resource
File dir;
URL url = ClassLoader.getSystemResource(DIRECTORY);
try {
dir = JarUtil.urlToFile(url);
} catch (Exception e1) {
dir = new File(DIRECTORY);
}
// Get the list of files
File[] files = dir.listFiles(FILTER);
if (files == null)
return null;
ExampleDesign[] designs = new ExampleDesign[files.length];
for (int i=0; i<files.length; i++) {
String name = files[i].getName();
try {
designs[i] = new ExampleDesign(files[i].toURI().toURL(),
name.substring(0, name.length()-4));
} catch (MalformedURLException e) {
throw new BugException(e);
}
}
return designs;
}
private static ExampleDesign[] getJarFileNames() {
ArrayList<ExampleDesign> list = new ArrayList<ExampleDesign>();
int dirLength = DIRECTORY.length();
// Find and open the jar file this class is contained in
File file = JarUtil.getCurrentJarFile();
if (file == null)
return null;
// Generate URL pointing to JAR file
URL fileUrl;
try {
fileUrl = file.toURI().toURL();
} catch (MalformedURLException e1) {
e1.printStackTrace();
throw new BugException(e1);
}
// Iterate over JAR entries searching for designs
JarFile jarFile = null;
try {
jarFile = new JarFile(file);
// Loop through JAR entries searching for files to load
Enumeration<JarEntry> entries = jarFile.entries();
while (entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
String name = entry.getName();
if (name.startsWith(DIRECTORY) && FILTER.accept(null, name)) {
String urlName = "jar:" + fileUrl + "!/" + name;
URL url = new URL(urlName);
list.add(new ExampleDesign(url,
name.substring(dirLength, name.length()-4)));
}
}
} catch (IOException e) {
// Could be normal condition if not package in JAR
return null;
} finally {
if (jarFile != null) {
try {
jarFile.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return list.toArray(new ExampleDesign[0]);
}
/**
* Data holder class.
*/
private static class ExampleDesign implements Comparable<ExampleDesign> {
private final URL url;
private final String name;
public ExampleDesign(URL url, String name) {
this.url = url;
this.name = name;
}
@Override
public String toString() {
return name;
}
public URL getURL() {
return url;
}
@Override
public int compareTo(ExampleDesign o) {
return this.name.compareTo(o.name);
}
}
} }

View File

@ -436,6 +436,11 @@ public class BasicFrame extends JFrame {
item.setIcon(Icons.FILE_OPEN); item.setIcon(Icons.FILE_OPEN);
menu.add(item); menu.add(item);
item = new ExampleDesignFileAction(trans.get("main.menu.file.openExample"), this);
item.getAccessibleContext().setAccessibleDescription(trans.get("BasicFrame.item.Openexamplerocketdesign"));
item.setIcon(Icons.FILE_OPEN_EXAMPLE);
menu.add(item);
//// Open example... //// Open example...
item = new JMenuItem(trans.get("main.menu.file.openExample")); item = new JMenuItem(trans.get("main.menu.file.openExample"));
//// Open an example rocket design //// Open an example rocket design
@ -490,7 +495,7 @@ public class BasicFrame extends JFrame {
} }
}); });
menu.add(item); menu.add(item);
//// Export decal... //// Export decal...
item = new JMenuItem("Export Decal"); item = new JMenuItem("Export Decal");
item.addActionListener(new ActionListener() { item.addActionListener(new ActionListener() {
@ -1092,7 +1097,7 @@ public class BasicFrame extends JFrame {
* @param parent the parent window for dialogs. * @param parent the parent window for dialogs.
* @return <code>true</code> if opened successfully. * @return <code>true</code> if opened successfully.
*/ */
private static boolean open(URL url, BasicFrame parent) { public static boolean open(URL url, BasicFrame parent) {
String displayName = null; String displayName = null;
// First figure out the file name from the URL // First figure out the file name from the URL
@ -1126,13 +1131,7 @@ public class BasicFrame extends JFrame {
log.info("Opening file from url=" + url + " filename=" + displayName); log.info("Opening file from url=" + url + " filename=" + displayName);
try { try {
InputStream is = url.openStream(); InputStream is = url.openStream();
if (open(is, displayName, url, parent)) { open(is, displayName, url, parent, true);
// Close previous window if replacing
if (parent.replaceable && parent.document.isSaved()) {
parent.closeAction();
parent.replaceable = false;
}
}
} catch (IOException e) { } catch (IOException e) {
log.warn("Error opening file" + e); log.warn("Error opening file" + e);
JOptionPane.showMessageDialog(parent, JOptionPane.showMessageDialog(parent,
@ -1151,11 +1150,12 @@ public class BasicFrame extends JFrame {
* @param stream the stream to load from. * @param stream the stream to load from.
* @param displayName the file name to display in dialogs (not set to the document). * @param displayName the file name to display in dialogs (not set to the document).
* @param parent the parent component for which a progress dialog is opened. * @param parent the parent component for which a progress dialog is opened.
* @param openRocketConfigDialog if true will open the rocket configuration dialog
* @return whether the file was successfully loaded and opened. * @return whether the file was successfully loaded and opened.
*/ */
private static boolean open(InputStream stream, String displayName, URL fileURL, Window parent) { private static boolean open(InputStream stream, String displayName, URL fileURL, Window parent, boolean openRocketConfigDialog) {
OpenFileWorker worker = new OpenFileWorker(stream, fileURL, ROCKET_LOADER); OpenFileWorker worker = new OpenFileWorker(stream, fileURL, ROCKET_LOADER);
return open(worker, displayName, parent); return open(worker, displayName, parent, openRocketConfigDialog);
} }
@ -1169,7 +1169,7 @@ public class BasicFrame extends JFrame {
*/ */
public static boolean open(File file, Window parent) { public static boolean open(File file, Window parent) {
OpenFileWorker worker = new OpenFileWorker(file, ROCKET_LOADER); OpenFileWorker worker = new OpenFileWorker(file, ROCKET_LOADER);
return open(worker, file.getName(), parent); return open(worker, file.getName(), parent, false);
} }
@ -1180,9 +1180,10 @@ public class BasicFrame extends JFrame {
* @param displayName the file name to display in dialogs. * @param displayName the file name to display in dialogs.
* @param file the File to set the document to (may be null). * @param file the File to set the document to (may be null).
* @param parent * @param parent
* @param openRocketConfigDialog if true, will open the configuration dialog of the rocket. This is useful for examples.
* @return * @return
*/ */
private static boolean open(OpenFileWorker worker, String displayName, Window parent) { private static boolean open(OpenFileWorker worker, String displayName, Window parent, boolean openRocketConfigDialog) {
MotorDatabaseLoadingDialog.check(parent); MotorDatabaseLoadingDialog.check(parent);
@ -1243,13 +1244,13 @@ public class BasicFrame extends JFrame {
log.info("Warnings while reading file: " + warnings); log.info("Warnings while reading file: " + warnings);
WarningDialog.showWarnings(parent, WarningDialog.showWarnings(parent,
new Object[] { new Object[] {
//// The following problems were encountered while opening //// The following problems were encountered while opening
trans.get("BasicFrame.WarningDialog.txt1") + " " + displayName + ".", trans.get("BasicFrame.WarningDialog.txt1") + " " + displayName + ".",
//// Some design features may not have been loaded correctly. //// Some design features may not have been loaded correctly.
trans.get("BasicFrame.WarningDialog.txt2") trans.get("BasicFrame.WarningDialog.txt2")
}, },
//// Warnings while opening file //// Warnings while opening file
trans.get("BasicFrame.WarningDialog.title"), warnings); trans.get("BasicFrame.WarningDialog.title"), warnings);
} }
// Open the frame // Open the frame
@ -1260,6 +1261,10 @@ public class BasicFrame extends JFrame {
if ( parent != null && parent instanceof BasicFrame ) { if ( parent != null && parent instanceof BasicFrame ) {
((BasicFrame)parent).closeIfReplaceable(); ((BasicFrame)parent).closeIfReplaceable();
} }
if( openRocketConfigDialog ) {
ComponentConfigDialog.showDialog(frame, doc, doc.getRocket());
}
return true; return true;
} }

View File

@ -0,0 +1,158 @@
package net.sf.openrocket.gui.main;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import net.sf.openrocket.file.iterator.DirectoryIterator;
import net.sf.openrocket.file.iterator.FileIterator;
import net.sf.openrocket.gui.util.SimpleFileFilter;
import net.sf.openrocket.util.BugException;
import net.sf.openrocket.util.JarUtil;
import net.sf.openrocket.util.Pair;
public class ExampleDesignFile implements Comparable<ExampleDesignFile> {
private final URL url;
private final String name;
private ExampleDesignFile(URL url, String name) {
this.url = url;
this.name = name;
}
@Override
public String toString() {
return name;
}
public URL getURL() {
return url;
}
@Override
public int compareTo(ExampleDesignFile o) {
return this.name.compareTo(o.name);
}
public static ExampleDesignFile[] getExampleDesigns() {
ExampleDesignFile[] designs = getJarFileNames();
if (designs == null || designs.length == 0) {
designs = getDirFileNames();
}
if (designs == null || designs.length == 0) {
return null;
}
Arrays.sort(designs);
return designs;
}
private static final String DIRECTORY = "datafiles/examples/";
private static final String PATTERN = ".*\\.[oO][rR][kK]$";
private static final FilenameFilter FILTER = new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.matches(PATTERN);
}
};
private static ExampleDesignFile[] getDirFileNames() {
// Try to find directory as a system resource
File dir;
URL url = ClassLoader.getSystemResource(DIRECTORY);
try {
dir = JarUtil.urlToFile(url);
} catch (Exception e1) {
dir = new File(DIRECTORY);
}
// Get the list of files
File[] files = dir.listFiles(FILTER);
if (files == null)
return null;
ExampleDesignFile[] designs = new ExampleDesignFile[files.length];
for (int i=0; i<files.length; i++) {
String name = files[i].getName();
try {
designs[i] = new ExampleDesignFile(files[i].toURI().toURL(),
name.substring(0, name.length()-4));
} catch (MalformedURLException e) {
throw new BugException(e);
}
}
return designs;
}
private static ExampleDesignFile[] getJarFileNames() {
ArrayList<ExampleDesignFile> list = new ArrayList<ExampleDesignFile>();
int dirLength = DIRECTORY.length();
// Find and open the jar file this class is contained in
File file = JarUtil.getCurrentJarFile();
if (file == null)
return null;
// Generate URL pointing to JAR file
URL fileUrl;
try {
fileUrl = file.toURI().toURL();
} catch (MalformedURLException e1) {
e1.printStackTrace();
throw new BugException(e1);
}
// Iterate over JAR entries searching for designs
JarFile jarFile = null;
try {
jarFile = new JarFile(file);
// Loop through JAR entries searching for files to load
Enumeration<JarEntry> entries = jarFile.entries();
while (entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
String name = entry.getName();
if (name.startsWith(DIRECTORY) && FILTER.accept(null, name)) {
String urlName = "jar:" + fileUrl + "!/" + name;
URL url = new URL(urlName);
list.add(new ExampleDesignFile(url,
name.substring(dirLength, name.length()-4)));
}
}
} catch (IOException e) {
// Could be normal condition if not package in JAR
return null;
} finally {
if (jarFile != null) {
try {
jarFile.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return list.toArray(new ExampleDesignFile[0]);
}
}

View File

@ -0,0 +1,67 @@
package net.sf.openrocket.gui.main;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
/**
* Implements a menu for the example Open Rocket design files.
*/
public final class ExampleDesignFileAction extends JMenu {
/**
* The window to which an open design file action will be parented to (typically an instance of BasicFrame).
*/
private final BasicFrame parent;
/**
* Constructor.
*
* @param s the I18N menu string
* @param theParent the window to which an open design file action will be parented to (typically an instance of
* BasicFrame).
*/
public ExampleDesignFileAction(String s, BasicFrame theParent) {
super(s);
parent = theParent;
updateMenu();
}
/**
* Create menu items.
*/
private void updateMenu() {
removeAll();
ExampleDesignFile[] examples = ExampleDesignFile.getExampleDesigns();
for (ExampleDesignFile file : examples) {
Action action = createAction(file);
action.putValue(Action.NAME, file.toString());
JMenuItem menuItem = new JMenuItem(action);
add(menuItem);
}
}
/**
* When a user clicks on one of the recently used design files, open it.
*
* @param file the design file name (absolute path)
*
* @return the action to open a design file
*/
private Action createAction(final ExampleDesignFile example) {
Action action = new AbstractAction() {
public void actionPerformed(ActionEvent e) {
String command = e.getActionCommand();
BasicFrame.open(example.getURL(), parent);
}
};
action.putValue(Action.ACTION_COMMAND_KEY, example.toString());
return action;
}
}