/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* SetInstancesPanel.java
* Copyright (C) 1999 Len Trigg
*
*/
package weka.gui;
import weka.core.Instances;
import java.net.URL;
import java.io.File;
import java.io.Reader;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.InputStreamReader;
import java.awt.GridLayout;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeSupport;
import javax.swing.JPanel;
import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.filechooser.FileFilter;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.BorderFactory;
/**
* A panel that displays an instance summary for a set of instances and
* lets the user open a set of instances from either a file or URL.
*
* @author Len Trigg (trigg@cs.waikato.ac.nz)
* @version $Revision: 1.1.1.1 $
*/
public class SetInstancesPanel extends JPanel {
/** Click to open instances from a file */
protected JButton m_OpenFileBut = new JButton("Open file...");
/** Click to open instances from a URL */
protected JButton m_OpenURLBut = new JButton("Open URL...");
/** The instance summary component */
protected InstancesSummaryPanel m_Summary = new InstancesSummaryPanel();
/** Filter to ensure only arff files are selected */
protected FileFilter m_ArffFilter =
new ExtensionFileFilter(Instances.FILE_EXTENSION, "Arff data files");
/** The file chooser for selecting arff files */
protected JFileChooser m_FileChooser
= new JFileChooser(new File(System.getProperty("user.dir")));
/** Stores the last URL that instances were loaded from */
protected String m_LastURL = "http://";
/** The thread we do loading in */
protected Thread m_IOThread;
/**
* Manages sending notifications to people when we change the set of
* working instances.
*/
protected PropertyChangeSupport m_Support = new PropertyChangeSupport(this);
/** The current set of instances loaded */
protected Instances m_Instances;
/**
* Create the panel.
*/
public SetInstancesPanel() {
m_OpenFileBut.setToolTipText("Open a set of instances from a file");
m_OpenURLBut.setToolTipText("Open a set of instances from a URL");
m_FileChooser.setFileFilter(m_ArffFilter);
m_FileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
m_OpenURLBut.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
setInstancesFromURLQ();
}
});
m_OpenFileBut.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
setInstancesFromFileQ();
}
});
m_Summary.setBorder(BorderFactory.createEmptyBorder(5, 10, 5, 10));
JPanel buttons = new JPanel();
buttons.setLayout(new GridLayout(1, 2));
buttons.add(m_OpenFileBut);
buttons.add(m_OpenURLBut);
setLayout(new BorderLayout());
add(m_Summary, BorderLayout.CENTER);
add(buttons, BorderLayout.SOUTH);
}
/**
* Queries the user for a file to load instances from, then loads the
* instances in a background process. This is done in the IO
* thread, and an error message is popped up if the IO thread is busy.
*/
public void setInstancesFromFileQ() {
if (m_IOThread == null) {
int returnVal = m_FileChooser.showOpenDialog(this);
if (returnVal == JFileChooser.APPROVE_OPTION) {
final File selected = m_FileChooser.getSelectedFile();
m_IOThread = new Thread() {
public void run() {
setInstancesFromFile(selected);
m_IOThread = null;
}
};
m_IOThread.setPriority(Thread.MIN_PRIORITY); // UI has most priority
m_IOThread.start();
}
} else {
JOptionPane.showMessageDialog(this,
"Can't load at this time,\n"
+ "currently busy with other IO",
"Load Instances",
JOptionPane.WARNING_MESSAGE);
}
}
/**
* Queries the user for a URL to load instances from, then loads the
* instances in a background process. This is done in the IO
* thread, and an error message is popped up if the IO thread is busy.
*/
public void setInstancesFromURLQ() {
if (m_IOThread == null) {
try {
String urlName = (String) JOptionPane.showInputDialog(this,
"Enter the source URL",
"Load Instances",
JOptionPane.QUESTION_MESSAGE,
null,
null,
m_LastURL);
if (urlName != null) {
m_LastURL = urlName;
final URL url = new URL(urlName);
m_IOThread = new Thread() {
public void run() {
setInstancesFromURL(url);
m_IOThread = null;
}
};
m_IOThread.setPriority(Thread.MIN_PRIORITY); // UI has most priority
m_IOThread.start();
}
} catch (Exception ex) {
JOptionPane.showMessageDialog(this,
"Problem with URL:\n"
+ ex.getMessage(),
"Load Instances",
JOptionPane.ERROR_MESSAGE);
}
} else {
JOptionPane.showMessageDialog(this,
"Can't load at this time,\n"
+ "currently busy with other IO",
"Load Instances",
JOptionPane.WARNING_MESSAGE);
}
}
/**
* Loads results from a set of instances contained in the supplied
* file.
*
* @param f a value of type 'File'
*/
protected void setInstancesFromFile(File f) {
try {
Reader r = new BufferedReader(new FileReader(f));
setInstances(new Instances(r));
r.close();
} catch (Exception ex) {
JOptionPane.showMessageDialog(this,
"Couldn't read from file:\n"
+ f.getName(),
"Load Instances",
JOptionPane.ERROR_MESSAGE);
}
}
/**
* Loads instances from a URL.
*
* @param u the URL to load from.
*/
protected void setInstancesFromURL(URL u) {
try {
Reader r = new BufferedReader(new InputStreamReader(u.openStream()));
setInstances(new Instances(r));
r.close();
} catch (Exception ex) {
JOptionPane.showMessageDialog(this,
"Couldn't read from URL:\n"
+ u,
"Load Instances",
JOptionPane.ERROR_MESSAGE);
}
}
/**
* Updates the set of instances that is currently held by the panel
*
* @param i a value of type 'Instances'
*/
public void setInstances(Instances i) {
m_Instances = i;
m_Summary.setInstances(m_Instances);
// Fire property change event for those interested.
m_Support.firePropertyChange("", null, null);
}
/**
* Gets the set of instances currently held by the panel
*
* @return a value of type 'Instances'
*/
public Instances getInstances() {
return m_Instances;
}
/**
* Gets the instances summary panel associated with
* this panel
* @return the instances summary panel
*/
public InstancesSummaryPanel getSummary() {
return m_Summary;
}
/**
* Adds a PropertyChangeListener who will be notified of value changes.
*
* @param l a value of type 'PropertyChangeListener'
*/
public void addPropertyChangeListener(PropertyChangeListener l) {
m_Support.addPropertyChangeListener(l);
}
/**
* Removes a PropertyChangeListener.
*
* @param l a value of type 'PropertyChangeListener'
*/
public void removePropertyChangeListener(PropertyChangeListener l) {
m_Support.removePropertyChangeListener(l);
}
}