package jas.util;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.io.Reader;
import java.util.zip.GZIPInputStream;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.filechooser.FileFilter;
/**
* This class provides a convenient way to get a file name from the user. It is merely
* a panel with a text field for the file name with some built in convenience items.
* This panel does not actually open a file for you; it simply provides an easy way to get
* a file name from the user. Use getText()
to get the file name selected.
*
saveState()
method when you are done. This will set
* include the selected file in the drop-down list for the next time the panel is used.
* @author Jonas Gifford
* @author Tony Johnson
* @see JASEditableComboBox
* @see UserProperties
* @see #getText()
* @see #saveState()
*/
public class OpenLocalFilePanel extends JPanel implements ActionListener, ChangeListener
{
/**
* Creates an OpenLocalFilePanel component that you can add to a container.
* @param includePreviewButton whether a "Preview" button should be shown
* @param includeGZIP whether the GZip option should be shown
* @param key the key used to store the drop-down items and the last directory for the browse dialog
* @param filter sets a FileFilter for the browse dialog
*/
public OpenLocalFilePanel(boolean includePreviewButton, boolean includeGZIP, String key, FileFilter filter)
{
this(includePreviewButton, includeGZIP, key);
m_filter = filter;
}
/**
* Creates an OpenLocalFilePanel component that you can add to a container.
* @param includePreviewButton whether a "Preview" button should be shown
* @param includeGZIP whether the GZip option should be shown
* @param key the key used to store the drop-down items and the last directory for the browse dialog
*/
public OpenLocalFilePanel(boolean includePreviewButton, boolean includeGZIP, String key)
{
m_lastLocalDirectory_Key = key +"-directory";
m_fileName = new JASEditableComboBox(key +"-files", 4, true);
m_fileName.addChangeListener(this);
m_fileName.setMinWidth(250);
m_fileName.setMaxWidth(250);
add(m_fileName);
m_browse = new JButton("Browse...");
m_browse.addActionListener(this);
m_browse.setMnemonic('B');
add(m_browse);
if (includePreviewButton)
{
m_view = new JButton("Preview");
m_view.addActionListener(this);
m_view.setMnemonic('V');
add(m_view);
m_view.setEnabled(false);
}
if (includeGZIP)
{
m_gzip = new JCheckBox("GZIPed");
m_gzip.addActionListener(this);
m_gzip.setMnemonic('Z');
add(m_gzip);
m_gzip.setEnabled(false);
}
setBorder(BorderFactory.createTitledBorder("Enter the data file name"));
setViewEnabled();
}
/**
* The given ChangeListener will be notified when the visible
* text changes in the file name field.
*/
public void addChangeListener(ChangeListener cl)
{
m_fileName.addChangeListener(cl);
}
/**
* The given ActionListener will be notified when the "Enter" button
* is clicked in the file name text field.
*/
public void addActionListener(ActionListener al)
{
m_fileName.addActionListener(al);
}
/** This method is public as an implelentation side effect; do not call. */
public final void stateChanged(ChangeEvent e)
{
setViewEnabled();
}
private void setViewEnabled()
{
String text = m_fileName.getText();
boolean enable = text.length() > 0;
if (m_view != null) m_view.setEnabled(enable);
if (m_gzip != null)
{
m_gzip.setEnabled(enable);
m_gzip.setSelected(text.endsWith(".gz"));
}
}
/** This method is public as an implelentation side effect; do not call. */
public final void actionPerformed(ActionEvent e)
{
Object source = e.getSource();
if (source == m_browse)
{
JFileChooser dlg = new JFileChooser(m_prop.getString(m_lastLocalDirectory_Key, System.getProperty("user.home")));
dlg.setDialogTitle("Select a file");
if (m_filter != null)
dlg.setFileFilter(m_filter);
if (dlg.showDialog(this, "Select") == JFileChooser.APPROVE_OPTION)
{
final File file = dlg.getSelectedFile();
m_fileName.setText(file.getAbsolutePath());
m_prop.setString(m_lastLocalDirectory_Key, file.getParent());
}
}
else if (source == m_view)
{
try
{
java.awt.Component c = this;
while (! (c instanceof java.awt.Frame)) c = c.getParent();
new FilePreview((java.awt.Frame) c, new File(m_fileName.getText()),
m_gzip == null ? false : m_gzip.isSelected());
}
catch (Exception x)
{
JOptionPane.showMessageDialog(this,
x instanceof FileNotFoundException ? "File not found" : "Could not read file",
"Error...", JOptionPane.ERROR_MESSAGE);
}
}
}
/**
* Returns the file name showing in the text field.
* @return the selected file name
*/
public String getText()
{
String fileName = m_fileName.getText();
return fileName;
}
/**
* Includes the currently selected file name in the drop-down list for the next time
* this class is instantiated. It merely invokes the saveState()
method in the
* JASEditableComboBox that is shown on the panel.
* @see JASEditableComboBox
* @see JASEditableComboBox#saveState()
*/
public void saveState()
{
m_fileName.saveState();
}
/**
* Returns whether the user has selected the GZip option. If the GZip option was not
* available (i.e., in the constructor the parameter includeGZIP
was false
) then it will
* return false
.
* @return whether the GZip option was selected
*/
public boolean getGZIPed()
{
return m_gzip == null ? false : m_gzip.isSelected();
}
private String m_lastLocalDirectory_Key;
private JASEditableComboBox m_fileName;
private JButton m_browse, m_view = null;
private JCheckBox m_gzip = null;
final private UserProperties m_prop = UserProperties.getUserProperties();
private FileFilter m_filter = null;
}
class FilePreview extends JDialog
{
FilePreview(java.awt.Frame frame, File f, boolean gzip) throws IOException, FileNotFoundException
{
super(frame, "File preview");
JTextArea text = new JTextArea();
if (!gzip) text.read(new PreviewReader(new FileReader(f)), f);
else text.read(new PreviewReader(new InputStreamReader(new GZIPInputStream(new FileInputStream(f)))), f);
text.setEditable(false);
JScrollPane pane = new JScrollPane(text);
setContentPane(pane);
pack();
Dimension screenSize = getToolkit().getScreenSize();
Dimension dialogSize = getPreferredSize();
int maxHeight = (int) (screenSize.height * 0.6);
if (dialogSize.height > maxHeight)
dialogSize.height = maxHeight;
int maxWidth = (int) (screenSize.width * 0.9);
if (dialogSize.width > maxWidth)
dialogSize.width = maxWidth;
else dialogSize.width += 50;
Point position = getLocation();
position.translate((screenSize.width-dialogSize.width)/2,
(screenSize.height-dialogSize.height)/2);
setLocation(position);
setSize(dialogSize);
show();
}
}
class PreviewReader extends LineNumberReader
{
PreviewReader(Reader r)
{
super(r);
}
public int read() throws IOException
{
return getLineNumber()>maxLines ? -1 : super.read();
}
public int read(char[] cbuf, int off, int len) throws IOException
{
return getLineNumber()>maxLines ? -1 : super.read(cbuf,off,len);
}
public String readLine() throws IOException
{
return getLineNumber()>maxLines ? null : super.readLine();
}
private final int maxLines = 100;
}