package org.freehep.swing;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.Properties;
import java.util.Vector;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.event.EventListenerList;
/**
* A class for maintaining a "Recent File List".
* The recent file list can be stored between program invocations in
* a properties file. One or more RecentFileLists can easily
* be embedded in a JMenu.
*
* @author Tony Johnson (tonyj@slac.stanford.edu)
* @version $Id: RecentFileList.java 8584 2006-08-10 23:06:37Z duns $
*/
public class RecentFileList implements ActionListener
{
/**
* Create a RecentFileList
*/
public RecentFileList()
{
this(null);
}
/**
* Create a RecentFileList with a given maximum length
* @param size the maximum number of files to remember
*/
public RecentFileList(int size)
{
this(null,size);
}
/**
* Create a recent file list. The type parameter is used to
* prefix entries in the properties file, so that multiple
* RecentFileLists can be used in an application.
* @param type The prefix to use
*/
public RecentFileList(String type)
{
this(type,4);
}
/**
* Create a recent file list with a given type and size
* @param type The prefix to use
* @param size the maximum number of files to remember
*/
public RecentFileList(String type, int size)
{
files = new Vector(size);
this.size = size;
this.type = type;
used = 0;
}
public void addActionListener(ActionListener l)
{
listenerList.add(ActionListener.class, l);
}
public void removeActionListener(ActionListener l)
{
listenerList.remove(ActionListener.class, l);
}
/**
* An action event is fired when the user selects one of the
* files from a menu. The "actionCommand" in the event will be
* set to the name of the selected file.
*/
protected void fireActionPerformed(ActionEvent e)
{
// 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
for (int i = listeners.length-2; i>=0; i-=2)
{
if (listeners[i]==ActionListener.class)
{
((ActionListener)listeners[i+1]).actionPerformed(e);
}
}
}
public void actionPerformed(ActionEvent e)
{
fireActionPerformed(e);
}
/**
* Save the recent file list in a Properties set
* @param props The Properties set to save the files in
*/
public void save(Properties props)
{
String key = "RecentFile_" + (type!=null ? type+"_" : "" );
for (int i=0; i<used; i++)
{
props.put(key+i,files.elementAt(i).toString());
}
props.put(key+"Used",String.valueOf(used));
}
/**
* Load the recent file list from a Properties set
* @param props The Properties set to load from
*/
public void load(Properties props)
{
String key = "RecentFile_" + (type!=null ? type+"_" : "" );
files.removeAllElements();
used = Integer.parseInt(props.getProperty(key+"Used","0"));
for (int i=0; i<used; i++)
{
String value = props.getProperty(key+i);
if (value == null) break;
files.addElement(value);
}
}
/**
* Add a file to the list
* @param f The file to add
*/
public void add(File f)
{
try
{
add(f.getCanonicalPath());
}
catch (java.io.IOException x)
{
add(f.getAbsolutePath());
}
}
/**
* Remove a file from the list
* @param f Remove a file from the list
*/
public void remove(File f)
{
remove(f.getName());
}
/**
* Add a file to the list
* @param name The name of the file to add
*/
public void add(String name)
{
int pos = files.indexOf(name);
if (pos > 0)
{
files.removeElementAt(pos);
files.insertElementAt(name,0);
}
else if (pos != 0)
{
if (used == size) files.removeElementAt(size-1);
else used++;
files.insertElementAt(name,0);
}
}
/**
* Remove a file from the list
* @param name The name of the file to remove
*/
public void remove(String name)
{
if (files.removeElement(name)) used--;
}
/**
* Adds the recent file list to a menu.
* The files will be added at the end of the menu, with a
* separator before the files (if there are >0 files in the list)
*/
public void buildMenu(JMenu menu)
{
if (used > 0)
{
menu.addSeparator();
for (int i=0; i<used; i++)
{
JMenuItem item = new JMenuItem(String.valueOf(i+1)+" "+files.elementAt(i));
item.setActionCommand(files.elementAt(i).toString());
if (size<9) item.setMnemonic(Character.forDigit(i+1,10));
item.addActionListener(this);
menu.add(item);
}
}
}
private Vector files;
private String type;
private int size;
private int used;
private EventListenerList listenerList = new EventListenerList();
}