001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: *
017: */
018:
019: package org.apache.jmeter.gui.action;
020:
021: import java.awt.event.ActionEvent;
022: import java.awt.event.KeyEvent;
023: import java.io.File;
024: import java.util.HashSet;
025: import java.util.LinkedList;
026: import java.util.List;
027: import java.util.Set;
028: import java.util.prefs.Preferences;
029:
030: import javax.swing.JMenuItem;
031: import javax.swing.JSeparator;
032:
033: /**
034: * Handles the loading of recent files, and also the content and
035: * visibility of menu items for loading the recent files
036: */
037: public class LoadRecentProject extends Load {
038: /** Prefix for the user preference key */
039: private static String USER_PREFS_KEY = "recent_file_"; //$NON-NLS-1$
040: /** The number of menu items used for recent files */
041: private static final int NUMBER_OF_MENU_ITEMS = 9;
042: private static Set commands = new HashSet();
043: static {
044: commands.add(ActionNames.OPEN_RECENT);
045: }
046:
047: public LoadRecentProject() {
048: super ();
049: }
050:
051: public Set getActionNames() {
052: return commands;
053: }
054:
055: public void doAction(ActionEvent e) {
056: // We must ask the user if it is ok to close current project
057: if (!Close.performAction(e))
058: return;
059: // Load the file for this recent file command
060: loadProjectFile(e, getRecentFile(e), false);
061: }
062:
063: /**
064: * Get the recent file for the menu item
065: */
066: private File getRecentFile(ActionEvent e) {
067: JMenuItem menuItem = (JMenuItem) e.getSource();
068: // Get the preference for the recent files
069: Preferences prefs = Preferences
070: .userNodeForPackage(LoadRecentProject.class);
071: return new File(getRecentFile(prefs, Integer.parseInt(menuItem
072: .getName())));
073: }
074:
075: /**
076: * Get the menu items to add to the menu bar, to get recent file functionality
077: *
078: * @return a List of JMenuItem and a JSeparator, representing recent files
079: */
080: public static List getRecentFileMenuItems() {
081: LinkedList menuItems = new LinkedList();
082: // Get the preference for the recent files
083: Preferences prefs = Preferences
084: .userNodeForPackage(LoadRecentProject.class);
085: for (int i = 0; i < NUMBER_OF_MENU_ITEMS; i++) {
086: // Create the menu item
087: JMenuItem recentFile = new JMenuItem();
088: // Use the index as the name, used when processing the action
089: recentFile.setName(Integer.toString(i));
090: recentFile.addActionListener(ActionRouter.getInstance());
091: recentFile.setActionCommand(ActionNames.OPEN_RECENT);
092: // Set the KeyStroke to use
093: int shortKey = getShortcutKey(i);
094: if (shortKey >= 0) {
095: recentFile.setMnemonic(shortKey);
096: }
097: // Add the menu item
098: menuItems.add(recentFile);
099: }
100: // Add separator as the last item
101: JSeparator separator = new JSeparator();
102: separator.setVisible(false);
103: menuItems.add(separator);
104:
105: // Update menu items to reflect recent files
106: updateMenuItems(menuItems, prefs);
107:
108: return menuItems;
109: }
110:
111: /**
112: * Update the content and visibility of the menu items for recent files
113: *
114: * @param menuItems the JMenuItem and JSeparator to update
115: * @param loadedFileName the file name of the project file that has just
116: * been loaded
117: */
118: public static void updateRecentFileMenuItems(List menuItems,
119: String loadedFileName) {
120: // Get the preference for the recent files
121: Preferences prefs = Preferences
122: .userNodeForPackage(LoadRecentProject.class);
123: LinkedList newRecentFiles = new LinkedList();
124: // Check if the new file is already in the recent list
125: boolean alreadyExists = false;
126: for (int i = 0; i < NUMBER_OF_MENU_ITEMS; i++) {
127: String recentFilePath = getRecentFile(prefs, i);
128: if (!loadedFileName.equals(recentFilePath)) {
129: newRecentFiles.add(recentFilePath);
130: } else {
131: alreadyExists = true;
132: }
133: }
134: // Add the new file at the start of the list
135: newRecentFiles.add(0, loadedFileName);
136: // Remove the last item from the list if it was a brand new file
137: if (!alreadyExists) {
138: newRecentFiles.removeLast();
139: }
140: // Store the recent files
141: for (int i = 0; i < NUMBER_OF_MENU_ITEMS; i++) {
142: String fileName = (String) newRecentFiles.get(i);
143: if (fileName != null) {
144: setRecentFile(prefs, i, fileName);
145: }
146: }
147: // Update menu items to reflect recent files
148: updateMenuItems(menuItems, prefs);
149: }
150:
151: /**
152: * Set the content and visibility of menu items and menu separator,
153: * based on the recent file stored user preferences.
154: */
155: private static void updateMenuItems(List menuItems,
156: Preferences prefs) {
157: // Assume no recent files
158: boolean someRecentFiles = false;
159: // Update the menu items
160: for (int i = 0; i < NUMBER_OF_MENU_ITEMS; i++) {
161: // Get the menu item
162: JMenuItem recentFile = (JMenuItem) menuItems.get(i);
163:
164: // Find and set the file for this recent file command
165: String recentFilePath = getRecentFile(prefs, i);
166: if (recentFilePath != null) {
167: File file = new File(recentFilePath);
168: StringBuffer sb = new StringBuffer(60);
169: if (i < 9)
170: sb.append(i + 1).append(" "); //$NON-NLS-1$
171: sb.append(getMenuItemDisplayName(file));
172: recentFile.setText(sb.toString());
173: recentFile.setToolTipText(recentFilePath);
174: recentFile.setEnabled(true);
175: recentFile.setVisible(true);
176: // At least one recent file menu item is visible
177: someRecentFiles = true;
178: } else {
179: recentFile.setEnabled(false);
180: recentFile.setVisible(false);
181: }
182: }
183: // If there are some recent files, we must make the separator visisble
184: // The separator is the last item in the list
185: JSeparator separator = (JSeparator) menuItems.get(menuItems
186: .size() - 1);
187: separator.setVisible(someRecentFiles);
188: }
189:
190: /**
191: * Get the name to display in the menu item, it will chop the file name
192: * if it is too long to display in the menu bar
193: */
194: private static String getMenuItemDisplayName(File file) {
195: // Limit the length of the menu text if needed
196: final int maxLength = 40;
197: String menuText = file.getName();
198: if (menuText.length() > maxLength) {
199: menuText = "..." + menuText.substring(menuText.length() - maxLength, menuText.length()); //$NON-NLS-1$
200: }
201: return menuText;
202: }
203:
204: /**
205: * Get the KeyEvent to use as shortcut key for menu item
206: */
207: private static int getShortcutKey(int index) {
208: int shortKey = -1;
209: switch (index + 1) {
210: case 1:
211: shortKey = KeyEvent.VK_1;
212: break;
213: case 2:
214: shortKey = KeyEvent.VK_2;
215: break;
216: case 3:
217: shortKey = KeyEvent.VK_3;
218: break;
219: case 4:
220: shortKey = KeyEvent.VK_4;
221: break;
222: case 5:
223: shortKey = KeyEvent.VK_5;
224: break;
225: case 6:
226: shortKey = KeyEvent.VK_6;
227: break;
228: case 7:
229: shortKey = KeyEvent.VK_7;
230: break;
231: case 8:
232: shortKey = KeyEvent.VK_8;
233: break;
234: case 9:
235: shortKey = KeyEvent.VK_9;
236: break;
237: default:
238: break;
239: }
240: return shortKey;
241: }
242:
243: /**
244: * Get the full path to the recent file where index 0 is the most recent
245: */
246: private static String getRecentFile(Preferences prefs, int index) {
247: return prefs.get(USER_PREFS_KEY + index, null);
248: }
249:
250: /**
251: * Set the full path to the recent file where index 0 is the most recent
252: */
253: private static void setRecentFile(Preferences prefs, int index,
254: String fileName) {
255: prefs.put(USER_PREFS_KEY + index, fileName);
256: }
257: }
|