Here is a relatively simple Swing interface item that is much more useful for most games than a file chooser is. Basically, it scans an array of directories for files that end in an array of file extensions. Finally, the results are given in a JList, with an accept or cancel button. It also has the useful feature of being able to browse files that are both on your local file system and/or in your classpath. I haven’t actually tested the classpath part when coming from a JAR yet, but I believe it should work.
Easy to use and customizable. I’m making a pure LWJGL version in the near future.
import java.util.ArrayList;
import java.io.File;
import java.io.FilenameFilter;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.JButton;
import javax.swing.JPanel;
import java.awt.Container;
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.DefaultListSelectionModel;
/**
* A FileList is a window that contains a JList. The JList automatically fills with all files in
* a list of given directories of a list of given extensions. Finally, the JList notifies a
* FileListener of the final choice.
* @author Eli Delventhal
*
*/
public class FileList extends JFrame implements ActionListener
{
private FileListener listener;
private ArrayList<File> files;
private JList list;
private JButton confirm = new JButton("Select");
private JButton cancel = new JButton("Cancel");
public FileList(FileListener listen, String[] directories, String[] extensions, boolean allowMultiple)
{
super("Select a File");
listener = listen;
list = createFileList(directories,extensions);
if (allowMultiple)
((DefaultListSelectionModel)list.getSelectionModel()).setSelectionMode(DefaultListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
else
((DefaultListSelectionModel)list.getSelectionModel()).setSelectionMode(DefaultListSelectionModel.SINGLE_INTERVAL_SELECTION);
Container cp = getContentPane();
cp.setLayout(new BorderLayout());
cp.add(new JScrollPane(list),BorderLayout.CENTER);
JPanel p = new JPanel();
p.setLayout(new GridLayout(1,2));
p.add(cancel); p.add(confirm);
cp.add(p,BorderLayout.SOUTH);
cancel.addActionListener(this);
confirm.addActionListener(this);
setSize(400,600);
setVisible(true);
}
private JList createFileList(String[] directories, String[] extensions)
{
ArrayList<String> allFiles = new ArrayList<String>();
//Browse through all directories.
for (int i = 0; i < directories.length; i++)
{
//Try this directory as a "physical" file directory.
try
{
String[] files = new File(directories[i]).list(new ExtensionFilter(extensions));
for (int j = 0; j < files.length; j++)
{
if (!allFiles.contains(directories[i] + files[j]))
allFiles.add(directories[i] + files[j]);
}
}
catch (Exception e) {}
//Try this directory as a classpath file directory.
try
{
String[] files = new File(Thread.currentThread().getContextClassLoader().getResource(directories[i]).getFile()).list(new ExtensionFilter(extensions));
for (int j = 0; j < files.length; j++)
{
if (!allFiles.contains(directories[i] + files[j]))
allFiles.add(directories[i] + files[j]);
}
}
catch (Exception e) {}
}
//Return all files that were found to be okay.
return new JList(allFiles.toArray());
}
public void actionPerformed(ActionEvent e)
{
Object s = e.getSource();
if (s == cancel)
dispose();
else if (s == confirm)
{
Object[] o = list.getSelectedValues();
String[] files = new String[o.length];
for (int i = 0; i < o.length; i++)
files[i] = o[i].toString();
listener.filesSelected(files);
dispose();
}
}
/**
* A simple file filter that allows files with any extensions from the list.
* Automatically disallows files with no extension.
* @author Eli Delventhal
*
*/
private class ExtensionFilter implements FilenameFilter
{
private String[] extensions;
public ExtensionFilter(String[] ext)
{
extensions = ext;
}
public boolean accept(File directory, String name)
{
int lastPeriod = name.lastIndexOf(".");
if (lastPeriod < 0 || lastPeriod >= name.length()-1)
return false;
String extension = name.substring(lastPeriod+1);
for (int i = 0; i < extensions.length; i++)
if (!extensions[i].equalsIgnoreCase(extension))
return false;
return true;
}
}
}
/**
* The FileListener is a simple interface to be used with FileList.
* @author Eli Delventhal
*
*/
public interface FileListener
{
public void filesSelected(String[] files);
}
Example usage:
public class PlanetPanel extends JPanel implements FileListener
...
new FileList(this,new String[]{"Systems/",FileManager.getResourceFolder().getAbsolutePath()+"/Systems/"},new String[]{"ps"},false);
...
/**
* Called when files have been selected. The first selected file will be loaded.
*/
public void filesSelected(String[] files)
{
if (files.length <= 0)
return;
ObjectInputStream is = null;
//First, search for the file in local directories.
try
{
is = new ObjectInputStream(Thread.currentThread().getContextClassLoader().getResourceAsStream(files[0]));
}
catch (Exception e)
{
//If the file isn't found, it must not be in the classpath, so search local directories.
try
{
is = new ObjectInputStream(new FileInputStream(new File(files[0])));
}
catch (Exception ex)
{
//If it still isn't found, show an exception and then return.
ex.printStackTrace();
return;
}
}
//Finally, read the input stream.
try
{
x = (Double) is.readObject();
y = (Double) is.readObject();
METERS_PER_PIXEL = (Double) is.readObject();
TIMESTEPS_PER_RENDER = (Integer) is.readObject();
bodies = (ArrayList<Body>) is.readObject();
is.close();
}
catch (Exception e)
{
e.printStackTrace();
}
repaint();
}