Added most recently used design file list to File menu.

This commit is contained in:
Doug Pedrick 2012-06-06 02:22:19 +00:00
parent 540097aed4
commit 17fa9ae55d
6 changed files with 622 additions and 342 deletions

View File

@ -1,6 +1,11 @@
2012-06-05 Doug Pedrick
* Most recently used design files added to File menu.
2012-05-23 Doug Pedrick
* Centering ring templates can now be chosen for printing.
* Calibration ruler added to printed templates.
2012-05-09 Kevin Ruland

View File

@ -1005,6 +1005,8 @@ main.menu.file.new = New
main.menu.file.new.desc = Create a new rocket design
main.menu.file.open = Open...
BasicFrame.item.Openrocketdesign = Open a rocket design
main.menu.file.openRecent = Open Recent...
BasicFrame.item.Openrecentrocketdesign = Open a recent rocket design
main.menu.file.openExample = Open example...
BasicFrame.item.Openexamplerocketdesign = Open an example rocket design
main.menu.file.save = Save

View File

@ -1,62 +1,5 @@
package net.sf.openrocket.gui.main;
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.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowAdapter;
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.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.InputMap;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JSpinner;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.ListSelectionModel;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingUtilities;
import javax.swing.border.BevelBorder;
import javax.swing.border.TitledBorder;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultTreeSelectionModel;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
import net.miginfocom.swing.MigLayout;
import net.sf.openrocket.aerodynamics.WarningSet;
import net.sf.openrocket.document.OpenRocketDocument;
@ -105,6 +48,62 @@ import net.sf.openrocket.util.MemoryManagement.MemoryData;
import net.sf.openrocket.util.Reflection;
import net.sf.openrocket.util.TestRockets;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.InputMap;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JSpinner;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.ListSelectionModel;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingUtilities;
import javax.swing.border.BevelBorder;
import javax.swing.border.TitledBorder;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultTreeSelectionModel;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
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.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowAdapter;
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.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ExecutionException;
public class BasicFrame extends JFrame {
private static final LogHelper log = Application.getLogger();
@ -441,6 +440,13 @@ public class BasicFrame extends JFrame {
});
menu.add(item);
//// Open Recent...
item = new MRUDesignFileAction(trans.get("main.menu.file.openRecent"), this);
//// Open a recent rocket design
item.getAccessibleContext().setAccessibleDescription(trans.get("BasicFrame.item.Openrecentrocketdesign"));
item.setIcon(Icons.FILE_OPEN);
menu.add(item);
//// Open example...
item = new JMenuItem(trans.get("main.menu.file.openExample"));
//// Open an example rocket design
@ -1050,11 +1056,12 @@ public class BasicFrame extends JFrame {
closeAction();
replaceable = false;
}
MRUDesignFile opts = MRUDesignFile.getInstance();
opts.addFile(file.getAbsolutePath());
}
}
}
/**
* Open a file based on a URL.
* @param url the file to open.

View File

@ -0,0 +1,179 @@
package net.sf.openrocket.gui.main;
import net.sf.openrocket.startup.Application;
import net.sf.openrocket.startup.Preferences;
import javax.swing.event.EventListenerList;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.List;
/**
* Implements a most-recently-used list backed by preferences. This is modified/adapted from an example on the
* Netbeans wiki.
*/
public class MRUDesignFile {
public static final String MRU_FILE_LIST_PROPERTY = "MRUFileList";
public static final int MAX_SIZE = 9;
private List<String> mruFileList;
private static MRUDesignFile instance; // The single instance
private EventListenerList listenerList;
static {
instance = new MRUDesignFile();
}
/**
* Returns the single instance, creating one if it's the first time this method is called.
*
* @return The single instance.
*/
public static MRUDesignFile getInstance() {
return instance;
}
/**
* Constructor.
*/
protected MRUDesignFile() {
mruFileList = new ArrayList<String>(MAX_SIZE);
listenerList = new EventListenerList();
retrieve();
}
/**
* Get the current most-recently-used list of design files.
*
* @return a list that contains absolute file names
*/
public List<String> getMRUFileList() {
return mruFileList;
}
/**
* Set the most-recently-used list to the given parameter and fire change events.
*
* @param list
*/
public void setMRUFileList(List<String> list) {
this.mruFileList.clear();
this.mruFileList.addAll(list.subList(0, Math.min(list.size(), MAX_SIZE)));
firePropertyChange(MRU_FILE_LIST_PROPERTY, null, mruFileList);
store();
}
/**
* Remove a file from the MRU list and fire change events.
*
* @param absolutePath the filename to be removed
*/
public void removeFile(String absolutePath) {
mruFileList.remove(absolutePath);
firePropertyChange(MRU_FILE_LIST_PROPERTY, null, mruFileList);
store();
}
/**
* Add a file to the MRU list and fire change events.
*
* @param absolutePath the filename to be added
*/
public void addFile(String absolutePath) {
// remove the old
mruFileList.remove(absolutePath);
// add to the top
mruFileList.add(0, absolutePath);
while (mruFileList.size() > MAX_SIZE) {
mruFileList.remove(mruFileList.size() - 1);
}
firePropertyChange(MRU_FILE_LIST_PROPERTY, null, mruFileList);
store();
}
/**
* Clear all existing MRU references in the preferences backing store.
*/
private void clear() {
Preferences prefs = getPreferences();
for (int i = 0; i < MAX_SIZE; i++) {
prefs.putString(MRU_FILE_LIST_PROPERTY + i, null);
}
}
/**
* Store the MRU list into the preferences backing store.
*/
protected void store() {
Preferences prefs = getPreferences();
// clear the backing store
clear();
for (int i = 0; i < mruFileList.size(); i++) {
String str = mruFileList.get(i);
prefs.putString(MRU_FILE_LIST_PROPERTY + i, str);
}
}
/**
* Load the MRU list from the backing store.
*/
protected void retrieve() {
mruFileList.clear();
Preferences prefs = getPreferences();
for (int i = 0; i < MAX_SIZE; i++) {
String str = prefs.getString(MRU_FILE_LIST_PROPERTY + i, null);
if (str != null) {
mruFileList.add(str);
}
else {
break;
}
}
}
/**
* {@inheritDoc}
*/
public void addPropertyChangeListener(PropertyChangeListener listener) {
listenerList.add(PropertyChangeListener.class, listener);
}
/**
* {@inheritDoc}
*/
public void removePropertyChangeListener(PropertyChangeListener listener) {
listenerList.remove(PropertyChangeListener.class, listener);
}
protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
// Guaranteed to return a non-null array
Object[] listeners = listenerList.getListenerList();
// Process the listeners last to first, notifying
// those that are interested in this event
PropertyChangeEvent event = new PropertyChangeEvent(this, propertyName, oldValue, newValue);
for (int i = listeners.length - 2; i >= 0; i -= 2) {
if (listeners[i] == PropertyChangeListener.class) {
((PropertyChangeListener) listeners[i + 1]).propertyChange(event);
}
}
}
/**
* Return the Preferences
*
* @return Preferences
*/
protected final Preferences getPreferences() {
return Application.getPreferences();
}
}

View File

@ -0,0 +1,86 @@
package net.sf.openrocket.gui.main;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.util.List;
/**
* Implements a menu for the Most-Recently-Used Open Rocket design files.
*/
public final class MRUDesignFileAction extends JMenu {
/**
* The window to which an open design file action will be parented to (typically an instance of BasicFrame).
*/
private Window 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 MRUDesignFileAction(String s, Window theParent) {
super(s);
parent = theParent;
MRUDesignFile opts = MRUDesignFile.getInstance();
opts.addPropertyChangeListener(new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
if (!evt.getPropertyName().equals(MRUDesignFile.MRU_FILE_LIST_PROPERTY)) {
return;
}
updateMenu();
}
});
updateMenu();
}
/**
* Create menu items.
*/
private void updateMenu() {
removeAll();
List<String> list = MRUDesignFile.getInstance().getMRUFileList();
for (String name : list) {
Action action = createAction(name);
action.putValue(Action.NAME, name);
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(String file) {
Action action = new AbstractAction() {
public void actionPerformed(ActionEvent e) {
String command = e.getActionCommand();
if (BasicFrame.open(new File(command), parent)) {
MRUDesignFile.getInstance().addFile(command);
}
else {
MRUDesignFile.getInstance().removeFile(command);
}
}
};
action.putValue(Action.ACTION_COMMAND_KEY, file);
return action;
}
}

View File

@ -76,10 +76,11 @@ public class Rule extends PrintableComponent {
g.drawString("in", x + width + 6, y + width + 18);
y += 6;
//Draw Inches first.
//Draw Inches first, with 1/2", 1/4", and 1/8" tick marks.
drawVerticalRule(g2, false, inchOutSide, x, y, width, 0, div * 2, div * 4, div * 8);
drawHorizontalRule(g2, true, inchOutSide, x, y + width, width, 0, div * 2, div * 4, div * 8);
div = PrintUnit.MILLIMETERS.toPoints(1); //mm increment
//Draw cm (10mm) and 1/2 cm (5mm) marks
drawVerticalRule(g2, false, !inchOutSide, x, y, width, 0, 0, div * 5, div * 10);
drawHorizontalRule(g2, true, !inchOutSide, x, y + width, width, 0, 0, div * 5, div * 10);
}