weka.gui.experiment.SimpleSetupPanel Maven / Gradle / Ivy
Show all versions of weka-dev Show documentation
/*
* 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 3 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, see .
*/
/*
* SimpleSetupPanel.java
* Copyright (C) 2002-2015 University of Waikato, Hamilton, New Zealand
*
*/
package weka.gui.experiment;
import weka.classifiers.Classifier;
import weka.core.Utils;
import weka.core.xml.KOML;
import weka.experiment.CSVResultListener;
import weka.experiment.ClassifierSplitEvaluator;
import weka.experiment.CrossValidationResultProducer;
import weka.experiment.DatabaseResultListener;
import weka.experiment.Experiment;
import weka.experiment.InstancesResultListener;
import weka.experiment.PropertyNode;
import weka.experiment.RandomSplitResultProducer;
import weka.experiment.RegressionSplitEvaluator;
import weka.experiment.SplitEvaluator;
import weka.gui.DatabaseConnectionDialog;
import weka.gui.ExtensionFileFilter;
import weka.gui.WekaFileChooser;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.filechooser.FileFilter;
import java.awt.BorderLayout;
import java.awt.Frame;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.*;
import java.beans.IntrospectionException;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.beans.PropertyDescriptor;
import java.io.File;
/**
* This panel controls the configuration of an experiment.
*
* If KOML
* is in the classpath the experiments can also be serialized to XML instead of a
* binary format.
*
* @author Richard kirkby ([email protected])
* @author FracPete (fracpete at waikato dot ac dot nz)
* @version $Revision: 15302 $
*/
public class SimpleSetupPanel
extends AbstractSetupPanel {
/** for serialization */
private static final long serialVersionUID = 5257424515609176509L;
/** The experiment being configured */
protected Experiment m_Exp;
/** The panel which switched between simple and advanced setup modes */
protected SetupModePanel m_modePanel = null;
/** The database destination URL to store results into */
protected String m_destinationDatabaseURL;
/** The filename to store results into */
protected String m_destinationFilename = "";
/** The number of folds for a cross-validation experiment */
protected int m_numFolds = 10;
/** The training percentage for a train/test split experiment */
protected double m_trainPercent = 66;
/** The number of times to repeat the sub-experiment */
protected int m_numRepetitions = 10;
/** Whether or not the user has consented for the experiment to be simplified */
protected boolean m_userHasBeenAskedAboutConversion;
/** Filter for choosing CSV files */
protected ExtensionFileFilter m_csvFileFilter =
new ExtensionFileFilter(".csv", "Comma separated value files");
/** FIlter for choosing ARFF files */
protected ExtensionFileFilter m_arffFileFilter =
new ExtensionFileFilter(".arff", "ARFF files");
/** Click to load an experiment */
protected JButton m_OpenBut = new JButton("Open...");
/** Click to save an experiment */
protected JButton m_SaveBut = new JButton("Save...");
/** Click to create a new experiment with default settings */
protected JButton m_NewBut = new JButton("New");
/** A filter to ensure only experiment files get shown in the chooser */
protected FileFilter m_ExpFilter =
new ExtensionFileFilter(Experiment.FILE_EXTENSION,
"Experiment configuration files (*" + Experiment.FILE_EXTENSION + ")");
/** A filter to ensure only experiment (in KOML format) files get shown in the chooser */
protected FileFilter m_KOMLFilter =
new ExtensionFileFilter(KOML.FILE_EXTENSION,
"Experiment configuration files (*" + KOML.FILE_EXTENSION + ")");
/** A filter to ensure only experiment (in XML format) files get shown in the chooser */
protected FileFilter m_XMLFilter =
new ExtensionFileFilter(".xml",
"Experiment configuration files (*.xml)");
/** The file chooser for selecting experiments */
protected WekaFileChooser m_FileChooser =
new WekaFileChooser(new File(System.getProperty("user.dir")));
/** The file chooser for selecting result destinations */
protected WekaFileChooser m_DestFileChooser =
new WekaFileChooser(new File(System.getProperty("user.dir")));
/** Combo box for choosing experiment destination type */
protected JComboBox m_ResultsDestinationCBox = new JComboBox();
/** Label for destination field */
protected JLabel m_ResultsDestinationPathLabel = new JLabel("Filename:");
/** Input field for result destination path */
protected JTextField m_ResultsDestinationPathTField = new JTextField();
/** Button for browsing destination files */
protected JButton m_BrowseDestinationButton = new JButton("Browse...");
/** Combo box for choosing experiment type */
protected JComboBox m_ExperimentTypeCBox = new JComboBox();
/** Label for parameter field */
protected JLabel m_ExperimentParameterLabel = new JLabel("Number of folds:");
/** Input field for experiment parameter */
protected JTextField m_ExperimentParameterTField = new JTextField();
/** Radio button for choosing classification experiment */
protected JRadioButton m_ExpClassificationRBut =
new JRadioButton("Classification");
/** Radio button for choosing regression experiment */
protected JRadioButton m_ExpRegressionRBut =
new JRadioButton("Regression");
/** Input field for number of repetitions */
protected JTextField m_NumberOfRepetitionsTField = new JTextField();
/** Radio button for choosing datasets first in order of execution */
protected JRadioButton m_OrderDatasetsFirstRBut =
new JRadioButton("Data sets first");
/** Radio button for choosing algorithms first in order of execution */
protected JRadioButton m_OrderAlgorithmsFirstRBut =
new JRadioButton("Algorithms first");
/** The strings used to identify the combo box choices */
protected static String DEST_DATABASE_TEXT = ("JDBC database");
protected static String DEST_ARFF_TEXT = ("ARFF file");
protected static String DEST_CSV_TEXT = ("CSV file");
protected static String TYPE_CROSSVALIDATION_TEXT = ("Cross-validation");
protected static String TYPE_RANDOMSPLIT_TEXT = ("Train/Test Percentage Split (data randomized)");
protected static String TYPE_FIXEDSPLIT_TEXT = ("Train/Test Percentage Split (order preserved)");
/** The panel for configuring selected datasets */
protected DatasetListPanel m_DatasetListPanel = new DatasetListPanel();
/** The panel for configuring selected algorithms */
protected AlgorithmListPanel m_AlgorithmListPanel = new AlgorithmListPanel();
/** A button for bringing up the notes */
protected JButton m_NotesButton = new JButton("Notes");
/** Frame for the notes */
protected JFrame m_NotesFrame;
/** Area for user notes Default of 10 rows */
protected JTextArea m_NotesText = new JTextArea(null, 10, 0);
/**
* Manages sending notifications to people when we change the experiment,
* at this stage, only the resultlistener so the resultpanel can update.
*/
protected PropertyChangeSupport m_Support = new PropertyChangeSupport(this);
/**
* Creates the setup panel with the supplied initial experiment.
*
* @param exp a value of type 'Experiment'
*/
public SimpleSetupPanel(Experiment exp) {
this();
setExperiment(exp);
}
/**
* Creates the setup panel with no initial experiment.
*/
public SimpleSetupPanel() {
// everything disabled on startup
m_ResultsDestinationCBox.setEnabled(false);
m_ResultsDestinationPathLabel.setEnabled(false);
m_ResultsDestinationPathTField.setEnabled(false);
m_BrowseDestinationButton.setEnabled(false);
m_ExperimentTypeCBox.setEnabled(false);
m_ExperimentParameterLabel.setEnabled(false);
m_ExperimentParameterTField.setEnabled(false);
m_ExpClassificationRBut.setEnabled(false);
m_ExpRegressionRBut.setEnabled(false);
m_NumberOfRepetitionsTField.setEnabled(false);
m_OrderDatasetsFirstRBut.setEnabled(false);
m_OrderAlgorithmsFirstRBut.setEnabled(false);
// get sensible default database address
try {
m_destinationDatabaseURL = (new DatabaseResultListener()).getDatabaseURL();
} catch (Exception e) {}
// create action listeners
m_NewBut.setMnemonic('N');
m_NewBut.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Experiment newExp = new Experiment();
CrossValidationResultProducer cvrp = new CrossValidationResultProducer();
cvrp.setNumFolds(10);
cvrp.setSplitEvaluator(new ClassifierSplitEvaluator());
newExp.setResultProducer(cvrp);
newExp.setPropertyArray(new Classifier[0]);
newExp.setUsePropertyIterator(true);
setExperiment(newExp);
// defaults
if (ExperimenterDefaults.getUseClassification())
m_ExpClassificationRBut.setSelected(true);
else
m_ExpRegressionRBut.setSelected(true);
setSelectedItem(
m_ResultsDestinationCBox, ExperimenterDefaults.getDestination());
destinationTypeChanged();
setSelectedItem(
m_ExperimentTypeCBox, ExperimenterDefaults.getExperimentType());
m_numRepetitions = ExperimenterDefaults.getRepetitions();
m_NumberOfRepetitionsTField.setText(
"" + m_numRepetitions);
if (ExperimenterDefaults.getExperimentType().equals(
TYPE_CROSSVALIDATION_TEXT)) {
m_numFolds = ExperimenterDefaults.getFolds();
m_ExperimentParameterTField.setText(
"" + m_numFolds);
}
else {
m_trainPercent = ExperimenterDefaults.getTrainPercentage();
m_ExperimentParameterTField.setText(
"" + m_trainPercent);
}
if (ExperimenterDefaults.getDatasetsFirst())
m_OrderDatasetsFirstRBut.setSelected(true);
else
m_OrderAlgorithmsFirstRBut.setSelected(true);
expTypeChanged();
}
});
m_SaveBut.setEnabled(false);
m_SaveBut.setMnemonic('S');
m_SaveBut.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
saveExperiment();
}
});
m_OpenBut.setMnemonic('O');
m_OpenBut.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
openExperiment();
}
});
m_FileChooser.addChoosableFileFilter(m_ExpFilter);
if (KOML.isPresent())
m_FileChooser.addChoosableFileFilter(m_KOMLFilter);
m_FileChooser.addChoosableFileFilter(m_XMLFilter);
if (ExperimenterDefaults.getExtension().equals(".xml"))
m_FileChooser.setFileFilter(m_XMLFilter);
else if (KOML.isPresent() && ExperimenterDefaults.getExtension().equals(KOML.FILE_EXTENSION))
m_FileChooser.setFileFilter(m_KOMLFilter);
else
m_FileChooser.setFileFilter(m_ExpFilter);
m_FileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
m_DestFileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
m_BrowseDestinationButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//using this button for both browsing file & setting username/password
if (m_ResultsDestinationCBox.getSelectedItem() == DEST_DATABASE_TEXT){
chooseURLUsername();
} else {
chooseDestinationFile();
}
}
});
m_ExpClassificationRBut.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
expTypeChanged();
}
});
m_ExpRegressionRBut.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
expTypeChanged();
}
});
m_OrderDatasetsFirstRBut.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (m_Exp != null) {
m_Exp.setAdvanceDataSetFirst(true);
m_Support.firePropertyChange("", null, null);
}
}
});
m_OrderAlgorithmsFirstRBut.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (m_Exp != null) {
m_Exp.setAdvanceDataSetFirst(false);
m_Support.firePropertyChange("", null, null);
}
}
});
m_ResultsDestinationPathTField.getDocument().addDocumentListener(new DocumentListener() {
public void insertUpdate(DocumentEvent e) {destinationAddressChanged();}
public void removeUpdate(DocumentEvent e) {destinationAddressChanged();}
public void changedUpdate(DocumentEvent e) {destinationAddressChanged();}
});
m_ExperimentParameterTField.getDocument().addDocumentListener(new DocumentListener() {
public void insertUpdate(DocumentEvent e) {expParamChanged();}
public void removeUpdate(DocumentEvent e) {expParamChanged();}
public void changedUpdate(DocumentEvent e) {expParamChanged();}
});
m_NumberOfRepetitionsTField.getDocument().addDocumentListener(new DocumentListener() {
public void insertUpdate(DocumentEvent e) {numRepetitionsChanged();}
public void removeUpdate(DocumentEvent e) {numRepetitionsChanged();}
public void changedUpdate(DocumentEvent e) {numRepetitionsChanged();}
});
m_NotesFrame = Utils.getWekaJFrame("Notes", this);
m_NotesFrame.setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE);
m_NotesFrame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
m_NotesButton.setEnabled(true);
}
});
m_NotesFrame.getContentPane().add(new JScrollPane(m_NotesText));
m_NotesFrame.pack();
m_NotesFrame.setSize(800, 600);
m_NotesButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
m_NotesButton.setEnabled(false);
m_NotesFrame.setIconImage(((JFrame)SwingUtilities.getWindowAncestor(SimpleSetupPanel.this)).getIconImage());
m_NotesFrame.setLocationRelativeTo(SwingUtilities.getWindowAncestor(SimpleSetupPanel.this));
m_NotesFrame.setVisible(true);
}
});
m_NotesButton.setEnabled(false);
m_NotesText.setEditable(true);
//m_NotesText.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
m_NotesText.addKeyListener(new KeyAdapter() {
public void keyReleased(KeyEvent e) {
m_Exp.setNotes(m_NotesText.getText());
}
});
m_NotesText.addFocusListener(new FocusAdapter() {
public void focusLost(FocusEvent e) {
m_Exp.setNotes(m_NotesText.getText());
}
});
// Set up the GUI layout
JPanel buttons = new JPanel();
GridBagLayout gb = new GridBagLayout();
GridBagConstraints constraints = new GridBagConstraints();
buttons.setBorder(BorderFactory.createEmptyBorder(10, 5, 10, 5));
buttons.setLayout(gb);
constraints.gridx=0;constraints.gridy=0;constraints.weightx=5;
constraints.fill = GridBagConstraints.HORIZONTAL;
constraints.gridwidth=1;constraints.gridheight=1;
constraints.insets = new Insets(0,2,0,2);
buttons.add(m_OpenBut,constraints);
constraints.gridx=1;constraints.gridy=0;constraints.weightx=5;
constraints.gridwidth=1;constraints.gridheight=1;
buttons.add(m_SaveBut,constraints);
constraints.gridx=2;constraints.gridy=0;constraints.weightx=5;
constraints.gridwidth=1;constraints.gridheight=1;
buttons.add(m_NewBut,constraints);
JPanel destName = new JPanel();
destName.setLayout(new BorderLayout(5, 5));
destName.add(m_ResultsDestinationPathLabel, BorderLayout.WEST);
destName.add(m_ResultsDestinationPathTField, BorderLayout.CENTER);
m_ResultsDestinationCBox.addItem(DEST_ARFF_TEXT);
m_ResultsDestinationCBox.addItem(DEST_CSV_TEXT);
m_ResultsDestinationCBox.addItem(DEST_DATABASE_TEXT);
m_ResultsDestinationCBox.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
destinationTypeChanged();
}
});
JPanel destInner = new JPanel();
destInner.setLayout(new BorderLayout(5, 5));
destInner.add(m_ResultsDestinationCBox, BorderLayout.WEST);
destInner.add(destName, BorderLayout.CENTER);
destInner.add(m_BrowseDestinationButton, BorderLayout.EAST);
JPanel dest = new JPanel();
dest.setLayout(new BorderLayout());
dest.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createTitledBorder("Results Destination"),
BorderFactory.createEmptyBorder(0, 5, 5, 5)
));
dest.add(destInner, BorderLayout.NORTH);
JPanel expParam = new JPanel();
expParam.setLayout(new BorderLayout(5, 5));
expParam.add(m_ExperimentParameterLabel, BorderLayout.WEST);
expParam.add(m_ExperimentParameterTField, BorderLayout.CENTER);
ButtonGroup typeBG = new ButtonGroup();
typeBG.add(m_ExpClassificationRBut);
typeBG.add(m_ExpRegressionRBut);
m_ExpClassificationRBut.setSelected(true);
JPanel typeRButtons = new JPanel();
typeRButtons.setLayout(new GridLayout(1,0));
typeRButtons.add(m_ExpClassificationRBut);
typeRButtons.add(m_ExpRegressionRBut);
m_ExperimentTypeCBox.addItem(TYPE_CROSSVALIDATION_TEXT);
m_ExperimentTypeCBox.addItem(TYPE_RANDOMSPLIT_TEXT);
m_ExperimentTypeCBox.addItem(TYPE_FIXEDSPLIT_TEXT);
m_ExperimentTypeCBox.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
expTypeChanged();
}
});
JPanel typeInner = new JPanel();
typeInner.setLayout(new GridLayout(0,1));
typeInner.add(m_ExperimentTypeCBox);
typeInner.add(expParam);
typeInner.add(typeRButtons);
JPanel type = new JPanel();
type.setLayout(new BorderLayout());
type.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createTitledBorder("Experiment Type"),
BorderFactory.createEmptyBorder(0, 5, 5, 5)
));
type.add(typeInner, BorderLayout.NORTH);
ButtonGroup iterBG = new ButtonGroup();
iterBG.add(m_OrderDatasetsFirstRBut);
iterBG.add(m_OrderAlgorithmsFirstRBut);
m_OrderDatasetsFirstRBut.setSelected(true);
JPanel numIter = new JPanel();
numIter.setLayout(new BorderLayout(5, 5));
numIter.add(new JLabel("Number of repetitions:"), BorderLayout.WEST);
numIter.add(m_NumberOfRepetitionsTField, BorderLayout.CENTER);
JPanel controlInner = new JPanel();
controlInner.setLayout(new GridLayout(0,1));
controlInner.add(numIter);
controlInner.add(m_OrderDatasetsFirstRBut);
controlInner.add(m_OrderAlgorithmsFirstRBut);
JPanel control = new JPanel();
control.setLayout(new BorderLayout());
control.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createTitledBorder("Iteration Control"),
BorderFactory.createEmptyBorder(0, 5, 5, 5)
));
control.add(controlInner, BorderLayout.NORTH);
JPanel type_control = new JPanel();
type_control.setLayout(new GridLayout(1,0));
type_control.add(type);
type_control.add(control);
JPanel notes = new JPanel();
notes.setLayout(new BorderLayout());
notes.add(m_NotesButton, BorderLayout.CENTER);
JPanel top1 = new JPanel();
top1.setLayout(new BorderLayout());
top1.add(dest, BorderLayout.NORTH);
top1.add(type_control, BorderLayout.CENTER);
JPanel top = new JPanel();
top.setLayout(new BorderLayout());
top.add(buttons, BorderLayout.NORTH);
top.add(top1, BorderLayout.CENTER);
JPanel datasets = new JPanel();
datasets.setLayout(new BorderLayout());
datasets.add(m_DatasetListPanel, BorderLayout.CENTER);
JPanel algorithms = new JPanel();
algorithms.setLayout(new BorderLayout());
algorithms.add(m_AlgorithmListPanel, BorderLayout.CENTER);
JPanel schemes = new JPanel();
schemes.setLayout(new GridLayout(1,0));
schemes.add(datasets);
schemes.add(algorithms);
setLayout(new BorderLayout());
add(top, BorderLayout.NORTH);
add(schemes, BorderLayout.CENTER);
add(notes, BorderLayout.SOUTH);
}
/**
* Terminates this panel, which means, in the case of this panel, that it sets all references
* to associated JFrame objects to null.
*/
public void terminate() {
if (m_NotesFrame != null) {
for (WindowListener w : m_NotesFrame.getWindowListeners()) {
m_NotesFrame.removeWindowListener(w);
}
m_NotesFrame.setContentPane(new JPanel());
m_NotesFrame.dispose();
m_NotesFrame = null;
}
if (m_AlgorithmListPanel != null) {
m_AlgorithmListPanel.terminate();
m_AlgorithmListPanel = null;
}
if (m_Support != null) {
for (PropertyChangeListener l : m_Support.getPropertyChangeListeners()) {
m_Support.removePropertyChangeListener(l);
}
m_Support = null;
}
m_modePanel = null;
}
/**
* Returns the name of the panel.
*
* @return the name
*/
public String getName() {
return "Simple";
}
/**
* Sets the selected item of an combobox, since using setSelectedItem(...)
* doesn't work, if one checks object references!
*
* @param cb the combobox to set the item for
* @param item the item to set active
*/
protected void setSelectedItem(JComboBox cb, String item) {
int i;
for (i = 0; i < cb.getItemCount(); i++) {
if (cb.getItemAt(i).toString().equals(item)) {
cb.setSelectedIndex(i);
break;
}
}
}
/**
* Deletes the notes frame.
*/
protected void removeNotesFrame() {
m_NotesFrame.setVisible(false);
}
/**
* Gets te users consent for converting the experiment to a simpler form.
*
* @return true if the user has given consent, false otherwise
*/
private boolean userWantsToConvert() {
if (m_userHasBeenAskedAboutConversion) return true;
m_userHasBeenAskedAboutConversion = true;
return (JOptionPane.showConfirmDialog(this,
"This experiment has settings that are too advanced\n" +
"to be represented in the simple setup mode.\n" +
"Do you want the experiment to be converted,\n" +
"losing some of the advanced settings?\n",
"Confirm conversion",
JOptionPane.YES_NO_OPTION,
JOptionPane.WARNING_MESSAGE) == JOptionPane.YES_OPTION);
}
/**
* Sets the panel used to switch between simple and advanced modes.
*
* @param modePanel the panel
*/
public void setModePanel(SetupModePanel modePanel) {
m_modePanel = modePanel;
}
/**
* Sets the experiment to configure.
*
* @param exp a value of type 'Experiment'
* @return true if experiment could be configured, false otherwise
*/
public boolean setExperiment(Experiment exp) {
m_userHasBeenAskedAboutConversion = false;
m_Exp = null; // hold off until we are sure we want conversion
m_SaveBut.setEnabled(true);
if (exp.getResultListener() instanceof DatabaseResultListener) {
m_ResultsDestinationCBox.setSelectedItem(DEST_DATABASE_TEXT);
m_ResultsDestinationPathLabel.setText("URL:");
m_destinationDatabaseURL = ((DatabaseResultListener)exp.getResultListener()).getDatabaseURL();
m_ResultsDestinationPathTField.setText(m_destinationDatabaseURL);
m_BrowseDestinationButton.setEnabled(true);
} else if (exp.getResultListener() instanceof InstancesResultListener) {
m_ResultsDestinationCBox.setSelectedItem(DEST_ARFF_TEXT);
m_ResultsDestinationPathLabel.setText("Filename:");
m_destinationFilename = ((InstancesResultListener)exp.getResultListener()).outputFileName();
m_ResultsDestinationPathTField.setText(m_destinationFilename);
m_BrowseDestinationButton.setEnabled(true);
} else if (exp.getResultListener() instanceof CSVResultListener) {
m_ResultsDestinationCBox.setSelectedItem(DEST_CSV_TEXT);
m_ResultsDestinationPathLabel.setText("Filename:");
m_destinationFilename = ((CSVResultListener)exp.getResultListener()).outputFileName();
m_ResultsDestinationPathTField.setText(m_destinationFilename);
m_BrowseDestinationButton.setEnabled(true);
} else {
// unrecognised result listener
System.out.println("SimpleSetup incompatibility: unrecognised result destination");
if (userWantsToConvert()) {
m_ResultsDestinationCBox.setSelectedItem(DEST_ARFF_TEXT);
m_ResultsDestinationPathLabel.setText("Filename:");
m_destinationFilename = "";
m_ResultsDestinationPathTField.setText(m_destinationFilename);
m_BrowseDestinationButton.setEnabled(true);
} else {
return false;
}
}
m_ResultsDestinationCBox.setEnabled(true);
m_ResultsDestinationPathLabel.setEnabled(true);
m_ResultsDestinationPathTField.setEnabled(true);
if (exp.getResultProducer() instanceof CrossValidationResultProducer) {
CrossValidationResultProducer cvrp = (CrossValidationResultProducer) exp.getResultProducer();
m_numFolds = cvrp.getNumFolds();
m_ExperimentParameterTField.setText("" + m_numFolds);
if (cvrp.getSplitEvaluator() instanceof ClassifierSplitEvaluator) {
m_ExpClassificationRBut.setSelected(true);
m_ExpRegressionRBut.setSelected(false);
} else if (cvrp.getSplitEvaluator() instanceof RegressionSplitEvaluator) {
m_ExpClassificationRBut.setSelected(false);
m_ExpRegressionRBut.setSelected(true);
} else {
// unknown split evaluator
System.out.println("SimpleSetup incompatibility: unrecognised split evaluator");
if (userWantsToConvert()) {
m_ExpClassificationRBut.setSelected(true);
m_ExpRegressionRBut.setSelected(false);
} else {
return false;
}
}
m_ExperimentTypeCBox.setSelectedItem(TYPE_CROSSVALIDATION_TEXT);
} else if (exp.getResultProducer() instanceof RandomSplitResultProducer) {
RandomSplitResultProducer rsrp = (RandomSplitResultProducer) exp.getResultProducer();
if (rsrp.getRandomizeData()) {
m_ExperimentTypeCBox.setSelectedItem(TYPE_RANDOMSPLIT_TEXT);
} else {
m_ExperimentTypeCBox.setSelectedItem(TYPE_FIXEDSPLIT_TEXT);
}
if (rsrp.getSplitEvaluator() instanceof ClassifierSplitEvaluator) {
m_ExpClassificationRBut.setSelected(true);
m_ExpRegressionRBut.setSelected(false);
} else if (rsrp.getSplitEvaluator() instanceof RegressionSplitEvaluator) {
m_ExpClassificationRBut.setSelected(false);
m_ExpRegressionRBut.setSelected(true);
} else {
// unknown split evaluator
System.out.println("SimpleSetup incompatibility: unrecognised split evaluator");
if (userWantsToConvert()) {
m_ExpClassificationRBut.setSelected(true);
m_ExpRegressionRBut.setSelected(false);
} else {
return false;
}
}
m_trainPercent = rsrp.getTrainPercent();
m_ExperimentParameterTField.setText("" + m_trainPercent);
} else {
// unknown experiment type
System.out.println("SimpleSetup incompatibility: unrecognised resultProducer");
if (userWantsToConvert()) {
m_ExperimentTypeCBox.setSelectedItem(TYPE_CROSSVALIDATION_TEXT);
m_ExpClassificationRBut.setSelected(true);
m_ExpRegressionRBut.setSelected(false);
} else {
return false;
}
}
m_ExperimentTypeCBox.setEnabled(true);
m_ExperimentParameterLabel.setEnabled(true);
m_ExperimentParameterTField.setEnabled(true);
m_ExpClassificationRBut.setEnabled(true);
m_ExpRegressionRBut.setEnabled(true);
if (exp.getRunLower() == 1) {
m_numRepetitions = exp.getRunUpper();
m_NumberOfRepetitionsTField.setText("" + m_numRepetitions);
} else {
// unsupported iterations
System.out.println("SimpleSetup incompatibility: runLower is not 1");
if (userWantsToConvert()) {
exp.setRunLower(1);
if (m_ExperimentTypeCBox.getSelectedItem() == TYPE_FIXEDSPLIT_TEXT) {
exp.setRunUpper(1);
m_NumberOfRepetitionsTField.setEnabled(false);
m_NumberOfRepetitionsTField.setText("1");
} else {
exp.setRunUpper(10);
m_numRepetitions = 10;
m_NumberOfRepetitionsTField.setText("" + m_numRepetitions);
}
} else {
return false;
}
}
m_NumberOfRepetitionsTField.setEnabled(true);
m_OrderDatasetsFirstRBut.setSelected(exp.getAdvanceDataSetFirst());
m_OrderAlgorithmsFirstRBut.setSelected(!exp.getAdvanceDataSetFirst());
m_OrderDatasetsFirstRBut.setEnabled(true);
m_OrderAlgorithmsFirstRBut.setEnabled(true);
m_NotesText.setText(exp.getNotes());
m_NotesButton.setEnabled(true);
if (!exp.getUsePropertyIterator() || !(exp.getPropertyArray() instanceof Classifier[])) {
// unknown property iteration
System.out.println("SimpleSetup incompatibility: unrecognised property iteration");
if (userWantsToConvert()) {
exp.setPropertyArray(new Classifier[0]);
exp.setUsePropertyIterator(true);
} else {
return false;
}
}
m_DatasetListPanel.setExperiment(exp);
m_AlgorithmListPanel.setExperiment(exp);
m_Exp = exp;
expTypeChanged(); // recreate experiment
m_Support.firePropertyChange("", null, null);
return true;
}
/**
* Gets the currently configured experiment.
*
* @return the currently configured experiment.
*/
public Experiment getExperiment() {
return m_Exp;
}
/**
* Prompts the user to select an experiment file and loads it.
*/
private void openExperiment() {
int returnVal = m_FileChooser.showOpenDialog(this);
if (returnVal != JFileChooser.APPROVE_OPTION) {
return;
}
File expFile = m_FileChooser.getSelectedFile();
// add extension if necessary
if (m_FileChooser.getFileFilter() == m_ExpFilter) {
if (!expFile.getName().toLowerCase().endsWith(Experiment.FILE_EXTENSION))
expFile = new File(expFile.getParent(), expFile.getName() + Experiment.FILE_EXTENSION);
}
else if (m_FileChooser.getFileFilter() == m_KOMLFilter) {
if (!expFile.getName().toLowerCase().endsWith(KOML.FILE_EXTENSION))
expFile = new File(expFile.getParent(), expFile.getName() + KOML.FILE_EXTENSION);
}
else if (m_FileChooser.getFileFilter() == m_XMLFilter) {
if (!expFile.getName().toLowerCase().endsWith(".xml"))
expFile = new File(expFile.getParent(), expFile.getName() + ".xml");
}
try {
Experiment exp = Experiment.read(expFile.getAbsolutePath());
if (!setExperiment(exp)) {
if (m_modePanel != null) m_modePanel.switchToAdvanced(exp);
}
System.err.println("Opened experiment:\n" + exp);
} catch (Exception ex) {
ex.printStackTrace();
JOptionPane.showMessageDialog(this, "Couldn't open experiment file:\n"
+ expFile
+ "\nReason:\n" + ex.getMessage(),
"Open Experiment",
JOptionPane.ERROR_MESSAGE);
// Pop up error dialog
}
}
/**
* Prompts the user for a filename to save the experiment to, then saves
* the experiment.
*/
private void saveExperiment() {
int returnVal = m_FileChooser.showSaveDialog(this);
if (returnVal != JFileChooser.APPROVE_OPTION) {
return;
}
File expFile = m_FileChooser.getSelectedFile();
// add extension if necessary
if (m_FileChooser.getFileFilter() == m_ExpFilter) {
if (!expFile.getName().toLowerCase().endsWith(Experiment.FILE_EXTENSION))
expFile = new File(expFile.getParent(), expFile.getName() + Experiment.FILE_EXTENSION);
}
else if (m_FileChooser.getFileFilter() == m_KOMLFilter) {
if (!expFile.getName().toLowerCase().endsWith(KOML.FILE_EXTENSION))
expFile = new File(expFile.getParent(), expFile.getName() + KOML.FILE_EXTENSION);
}
else if (m_FileChooser.getFileFilter() == m_XMLFilter) {
if (!expFile.getName().toLowerCase().endsWith(".xml"))
expFile = new File(expFile.getParent(), expFile.getName() + ".xml");
}
try {
Experiment.write(expFile.getAbsolutePath(), m_Exp);
System.err.println("Saved experiment:\n" + m_Exp);
} catch (Exception ex) {
ex.printStackTrace();
JOptionPane.showMessageDialog(this, "Couldn't save experiment file:\n"
+ expFile
+ "\nReason:\n" + ex.getMessage(),
"Save Experiment",
JOptionPane.ERROR_MESSAGE);
}
}
/**
* Adds a PropertyChangeListener who will be notified of value changes.
*
* @param l a value of type 'PropertyChangeListener'
*/
public void addPropertyChangeListener(PropertyChangeListener l) {
if (m_Support != null && l != null) {
m_Support.addPropertyChangeListener(l);
}
}
/**
* Removes a PropertyChangeListener.
*
* @param l a value of type 'PropertyChangeListener'
*/
public void removePropertyChangeListener(PropertyChangeListener l) {
if (m_Support != null && l != null) {
m_Support.removePropertyChangeListener(l);
}
}
/**
* Responds to a change in the destination type.
*/
private void destinationTypeChanged() {
if (m_Exp == null) return;
String str = "";
if (m_ResultsDestinationCBox.getSelectedItem() == DEST_DATABASE_TEXT) {
m_ResultsDestinationPathLabel.setText("URL:");
str = m_destinationDatabaseURL;
m_BrowseDestinationButton.setEnabled(true); //!!!
m_BrowseDestinationButton.setText("User...");
} else {
m_ResultsDestinationPathLabel.setText("Filename:");
if (m_ResultsDestinationCBox.getSelectedItem() == DEST_ARFF_TEXT) {
int ind = m_destinationFilename.lastIndexOf(".csv");
if (ind > -1) {
m_destinationFilename = m_destinationFilename.substring(0, ind) + ".arff";
}
}
if (m_ResultsDestinationCBox.getSelectedItem() == DEST_CSV_TEXT) {
int ind = m_destinationFilename.lastIndexOf(".arff");
if (ind > -1) {
m_destinationFilename = m_destinationFilename.substring(0, ind) + ".csv";
}
}
str = m_destinationFilename;
if (m_ResultsDestinationCBox.getSelectedItem() == DEST_ARFF_TEXT) {
int ind = str.lastIndexOf(".csv");
if (ind > -1) {
str = str.substring(0, ind) + ".arff";
}
}
if (m_ResultsDestinationCBox.getSelectedItem() == DEST_CSV_TEXT) {
int ind = str.lastIndexOf(".arff");
if (ind > -1) {
str = str.substring(0, ind) + ".csv";
}
}
m_BrowseDestinationButton.setEnabled(true);
m_BrowseDestinationButton.setText("Browse...");
}
if (m_ResultsDestinationCBox.getSelectedItem() == DEST_DATABASE_TEXT) {
DatabaseResultListener drl = null;
try {
drl = new DatabaseResultListener();
} catch (Exception e) {
e.printStackTrace();
}
drl.setDatabaseURL(m_destinationDatabaseURL);
m_Exp.setResultListener(drl);
} else {
if (m_ResultsDestinationCBox.getSelectedItem() == DEST_ARFF_TEXT) {
InstancesResultListener irl = new InstancesResultListener();
if (!m_destinationFilename.equals("")) {
irl.setOutputFile(new File(m_destinationFilename));
}
m_Exp.setResultListener(irl);
} else if (m_ResultsDestinationCBox.getSelectedItem() == DEST_CSV_TEXT) {
CSVResultListener crl = new CSVResultListener();
if (!m_destinationFilename.equals("")) {
crl.setOutputFile(new File(m_destinationFilename));
}
m_Exp.setResultListener(crl);
}
}
m_ResultsDestinationPathTField.setText(str);
m_Support.firePropertyChange("", null, null);
}
/**
* Responds to a change in the destination address.
*/
private void destinationAddressChanged() {
if (m_Exp == null) return;
if (m_ResultsDestinationCBox.getSelectedItem() == DEST_DATABASE_TEXT) {
m_destinationDatabaseURL = m_ResultsDestinationPathTField.getText();
if (m_Exp.getResultListener() instanceof DatabaseResultListener) {
((DatabaseResultListener)m_Exp.getResultListener()).setDatabaseURL(m_destinationDatabaseURL);
}
} else {
File resultsFile = null;
m_destinationFilename = m_ResultsDestinationPathTField.getText();
// Use temporary file if no file name is provided
if (m_destinationFilename.equals("")) {
try {
if (m_ResultsDestinationCBox.getSelectedItem() == DEST_ARFF_TEXT) {
resultsFile = File.createTempFile("weka_experiment", ".arff");
}
if (m_ResultsDestinationCBox.getSelectedItem() == DEST_CSV_TEXT) {
resultsFile = File.createTempFile("weka_experiment", ".csv");
}
resultsFile.deleteOnExit();
} catch (Exception e) {
System.err.println("Cannot create temp file, writing to standard out.");
resultsFile = new File("-");
}
} else {
if (m_ResultsDestinationCBox.getSelectedItem() == DEST_ARFF_TEXT) {
if (!m_destinationFilename.endsWith(".arff")) {
m_destinationFilename += ".arff";
}
}
if (m_ResultsDestinationCBox.getSelectedItem() == DEST_CSV_TEXT) {
if (!m_destinationFilename.endsWith(".csv")) {
m_destinationFilename += ".csv";
}
}
resultsFile = new File(m_destinationFilename);
}
((CSVResultListener)m_Exp.getResultListener()).setOutputFile(resultsFile);
((CSVResultListener)m_Exp.getResultListener()).setOutputFileName(m_destinationFilename);
}
m_Support.firePropertyChange("", null, null);
}
/**
* Responds to a change in the experiment type.
*/
private void expTypeChanged() {
if (m_Exp == null) return;
// update parameter ui
if (m_ExperimentTypeCBox.getSelectedItem() == TYPE_CROSSVALIDATION_TEXT) {
m_ExperimentParameterLabel.setText("Number of folds:");
m_ExperimentParameterTField.setText("" + m_numFolds);
} else {
m_ExperimentParameterLabel.setText("Train percentage:");
m_ExperimentParameterTField.setText("" + m_trainPercent);
}
// update iteration ui
if (m_ExperimentTypeCBox.getSelectedItem() == TYPE_FIXEDSPLIT_TEXT) {
m_NumberOfRepetitionsTField.setEnabled(false);
m_NumberOfRepetitionsTField.setText("1");
m_Exp.setRunLower(1);
m_Exp.setRunUpper(1);
} else {
m_NumberOfRepetitionsTField.setText("" + m_numRepetitions);
m_NumberOfRepetitionsTField.setEnabled(true);
m_Exp.setRunLower(1);
m_Exp.setRunUpper(m_numRepetitions);
}
SplitEvaluator se = null;
Classifier sec = null;
if (m_ExpClassificationRBut.isSelected()) {
se = new ClassifierSplitEvaluator();
sec = ((ClassifierSplitEvaluator)se).getClassifier();
} else {
se = new RegressionSplitEvaluator();
sec = ((RegressionSplitEvaluator)se).getClassifier();
}
// build new ResultProducer
if (m_ExperimentTypeCBox.getSelectedItem() == TYPE_CROSSVALIDATION_TEXT) {
CrossValidationResultProducer cvrp = new CrossValidationResultProducer();
cvrp.setNumFolds(m_numFolds);
cvrp.setSplitEvaluator(se);
PropertyNode[] propertyPath = new PropertyNode[2];
try {
propertyPath[0] = new PropertyNode(se, new PropertyDescriptor("splitEvaluator",
CrossValidationResultProducer.class),
CrossValidationResultProducer.class);
propertyPath[1] = new PropertyNode(sec, new PropertyDescriptor("classifier",
se.getClass()),
se.getClass());
} catch (IntrospectionException e) {
e.printStackTrace();
}
m_Exp.setResultProducer(cvrp);
m_Exp.setPropertyPath(propertyPath);
} else {
RandomSplitResultProducer rsrp = new RandomSplitResultProducer();
rsrp.setRandomizeData(m_ExperimentTypeCBox.getSelectedItem() == TYPE_RANDOMSPLIT_TEXT);
rsrp.setTrainPercent(m_trainPercent);
rsrp.setSplitEvaluator(se);
PropertyNode[] propertyPath = new PropertyNode[2];
try {
propertyPath[0] = new PropertyNode(se, new PropertyDescriptor("splitEvaluator",
RandomSplitResultProducer.class),
RandomSplitResultProducer.class);
propertyPath[1] = new PropertyNode(sec, new PropertyDescriptor("classifier",
se.getClass()),
se.getClass());
} catch (IntrospectionException e) {
e.printStackTrace();
}
m_Exp.setResultProducer(rsrp);
m_Exp.setPropertyPath(propertyPath);
}
m_Exp.setUsePropertyIterator(true);
m_Support.firePropertyChange("", null, null);
}
/**
* Responds to a change in the experiment parameter.
*/
private void expParamChanged() {
if (m_Exp == null) return;
if (m_ExperimentTypeCBox.getSelectedItem() == TYPE_CROSSVALIDATION_TEXT) {
try {
m_numFolds = Integer.parseInt(m_ExperimentParameterTField.getText());
} catch (NumberFormatException e) {
return;
}
} else {
try {
m_trainPercent = Double.parseDouble(m_ExperimentParameterTField.getText());
} catch (NumberFormatException e) {
return;
}
}
if (m_ExperimentTypeCBox.getSelectedItem() == TYPE_CROSSVALIDATION_TEXT) {
if (m_Exp.getResultProducer() instanceof CrossValidationResultProducer) {
CrossValidationResultProducer cvrp = (CrossValidationResultProducer) m_Exp.getResultProducer();
cvrp.setNumFolds(m_numFolds);
} else {
return;
}
} else {
if (m_Exp.getResultProducer() instanceof RandomSplitResultProducer) {
RandomSplitResultProducer rsrp = (RandomSplitResultProducer) m_Exp.getResultProducer();
rsrp.setRandomizeData(m_ExperimentTypeCBox.getSelectedItem() == TYPE_RANDOMSPLIT_TEXT);
rsrp.setTrainPercent(m_trainPercent);
} else {
//System.err.println("not rsrp");
return;
}
}
m_Support.firePropertyChange("", null, null);
}
/**
* Responds to a change in the number of repetitions.
*/
private void numRepetitionsChanged() {
if (m_Exp == null || !m_NumberOfRepetitionsTField.isEnabled()) return;
try {
m_numRepetitions = Integer.parseInt(m_NumberOfRepetitionsTField.getText());
} catch (NumberFormatException e) {
return;
}
m_Exp.setRunLower(1);
m_Exp.setRunUpper(m_numRepetitions);
m_Support.firePropertyChange("", null, null);
}
/**
* Lets user enter username/password/URL.
*/
private void chooseURLUsername() {
String dbaseURL=((DatabaseResultListener)m_Exp.getResultListener()).getDatabaseURL();
String username=((DatabaseResultListener)m_Exp.getResultListener()).getUsername();
DatabaseConnectionDialog dbd= new DatabaseConnectionDialog((Frame)SwingUtilities.
getWindowAncestor(SimpleSetupPanel.this),dbaseURL,username);
dbd.setLocationRelativeTo(SwingUtilities.getWindowAncestor(SimpleSetupPanel.this));
dbd.setVisible(true);
//if (dbaseURL == null) {
if (dbd.getReturnValue()==JOptionPane.CLOSED_OPTION) {
return;
}
((DatabaseResultListener)m_Exp.getResultListener()).setUsername(dbd.getUsername());
((DatabaseResultListener)m_Exp.getResultListener()).setPassword(dbd.getPassword());
((DatabaseResultListener)m_Exp.getResultListener()).setDatabaseURL(dbd.getURL());
((DatabaseResultListener)m_Exp.getResultListener()).setDebug(dbd.getDebug());
m_ResultsDestinationPathTField.setText(dbd.getURL());
}
/**
* Lets user browse for a destination file..
*/
private void chooseDestinationFile() {
FileFilter fileFilter = null;
if (m_ResultsDestinationCBox.getSelectedItem() == DEST_CSV_TEXT) {
fileFilter = m_csvFileFilter;
} else {
fileFilter = m_arffFileFilter;
}
m_DestFileChooser.setFileFilter(fileFilter);
int returnVal = m_DestFileChooser.showSaveDialog(this);
if (returnVal != JFileChooser.APPROVE_OPTION) {
return;
}
m_ResultsDestinationPathTField.setText(m_DestFileChooser.getSelectedFile().toString());
}
/**
* Hook method for cleaning up the interface after a switch.
*/
public void cleanUpAfterSwitch() {
removeNotesFrame();
}
}