milk.gui.experiment.MIResultsPanel.java Source code

Java tutorial

Introduction

Here is the source code for milk.gui.experiment.MIResultsPanel.java

Source

/*
 *    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.
 */

/*
 *    ResultsPanel.java
 *    Copyright (C) 1999 Len Trigg
 *
 */

package milk.gui.experiment;

import weka.gui.ExtensionFileFilter;
import weka.gui.ListSelectorDialog;
import weka.gui.ResultHistoryPanel;
import weka.gui.SaveBuffer;
import milk.experiment.MIExperiment;
import milk.experiment.MIInstancesResultListener;
import milk.experiment.MIDatabaseResultListener;
import weka.experiment.PairedCorrectedTTester;
import weka.experiment.PairedTTester;
import milk.experiment.MIInstanceQuery;
import weka.core.Utils;
import weka.core.Attribute;
import weka.core.Instances;
import weka.core.Range;
import weka.core.Instance;

import java.io.Reader;
import java.io.FileReader;
import java.io.BufferedReader;
import java.io.File;
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.Font;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.JTextArea;
import javax.swing.BorderFactory;
import javax.swing.JScrollPane;
import javax.swing.SwingConstants;
import javax.swing.filechooser.FileFilter;
import javax.swing.JFileChooser;
import javax.swing.JComboBox;
import javax.swing.JTextField;
import javax.swing.DefaultComboBoxModel;
import javax.swing.DefaultListModel;
import javax.swing.JList;
import javax.swing.JSplitPane;
import javax.swing.ListSelectionModel;
import javax.swing.JOptionPane;
import javax.swing.JCheckBox;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import java.awt.Insets;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.awt.Dimension;
import javax.swing.SwingUtilities;

/** 
 * This panel controls simple analysis of experimental results.
 *
 * @author Len Trigg (trigg@cs.waikato.ac.nz)
 * @version $Revision: 1.25 $
 */
public class MIResultsPanel extends JPanel {

    /** Message shown when no experimental results have been loaded */
    protected static final String NO_SOURCE = "No source";

    /** Click to load results from a file */
    protected JButton m_FromFileBut = new JButton("File...");

    /** Click to load results from a database */
    protected JButton m_FromDBaseBut = new JButton("Database...");

    /** Click to get results from the destination given in the experiment */
    protected JButton m_FromExpBut = new JButton("Experiment");

    /** Displays a message about the current result set */
    protected JLabel m_FromLab = new JLabel(NO_SOURCE);

    /**
     * This is needed to get around a bug in Swing <= 1.1 -- Once everyone
     * is using Swing 1.1.1 or higher just remove this variable and use the
     * no-arg constructor to DefaultComboBoxModel
     */
    private static String[] FOR_JFC_1_1_DCBM_BUG = { "" };

    /** The model embedded in m_DatasetCombo */
    protected DefaultComboBoxModel m_DatasetModel = new DefaultComboBoxModel(FOR_JFC_1_1_DCBM_BUG);

    /** The model embedded in m_RunCombo */
    protected DefaultComboBoxModel m_RunModel = new DefaultComboBoxModel(FOR_JFC_1_1_DCBM_BUG);

    /** The model embedded in m_CompareCombo */
    protected DefaultComboBoxModel m_CompareModel = new DefaultComboBoxModel(FOR_JFC_1_1_DCBM_BUG);

    /** The model embedded in m_TestsList */
    protected DefaultListModel m_TestsModel = new DefaultListModel();

    /** Displays the currently selected column names for the scheme & options */
    protected JLabel m_DatasetKeyLabel = new JLabel("Row key fields", SwingConstants.RIGHT);

    /** Click to edit the columns used to determine the scheme */
    protected JButton m_DatasetKeyBut = new JButton("Select keys...");

    /** Stores the list of attributes for selecting the scheme columns */
    protected DefaultListModel m_DatasetKeyModel = new DefaultListModel();

    /** Displays the list of selected columns determining the scheme */
    protected JList m_DatasetKeyList = new JList(m_DatasetKeyModel);

    /** Lets the user select which column contains the run number */
    protected JComboBox m_RunCombo = new JComboBox(m_RunModel);

    /** Displays the currently selected column names for the scheme & options */
    protected JLabel m_ResultKeyLabel = new JLabel("Column key fields", SwingConstants.RIGHT);

    /** Click to edit the columns used to determine the scheme */
    protected JButton m_ResultKeyBut = new JButton("Select keys...");

    /** Stores the list of attributes for selecting the scheme columns */
    protected DefaultListModel m_ResultKeyModel = new DefaultListModel();

    /** Displays the list of selected columns determining the scheme */
    protected JList m_ResultKeyList = new JList(m_ResultKeyModel);

    /** Lets the user select which scheme to base comparisons against */
    protected JButton m_TestsButton = new JButton("Select base...");

    /** Holds the list of schemes to base the test against */
    protected JList m_TestsList = new JList(m_TestsModel);

    /** Lets the user select which performance measure to analyze */
    protected JComboBox m_CompareCombo = new JComboBox(m_CompareModel);

    /** Lets the user edit the test significance */
    protected JTextField m_SigTex = new JTextField("0.05");

    /** Lets the user select whether standard deviations are to be output
        or not */
    protected JCheckBox m_ShowStdDevs = new JCheckBox("");

    /** Click to start the test */
    protected JButton m_PerformBut = new JButton("Perform test");

    /** Click to save test output to a file */
    protected JButton m_SaveOutBut = new JButton("Save output");

    /** The buffer saving object for saving output */
    SaveBuffer m_SaveOut = new SaveBuffer(null, this);

    /** Displays the output of tests */
    protected JTextArea m_OutText = new JTextArea();

    /** A panel controlling results viewing */
    protected ResultHistoryPanel m_History = new ResultHistoryPanel(m_OutText);

    /** Filter to ensure only arff files are selected for result files */
    protected FileFilter m_ArffFilter = new ExtensionFileFilter(Instances.FILE_EXTENSION, "Arff data files");

    /** The file chooser for selecting result files */
    protected JFileChooser m_FileChooser = new JFileChooser(new File(System.getProperty("user.dir")));

    /** The PairedTTester object */
    protected PairedTTester m_TTester = new PairedCorrectedTTester();

    /** The instances we're extracting results from */
    protected Instances m_Instances;

    /** Does any database querying for us */
    protected MIInstanceQuery m_InstanceQuery;

    /** A thread to load results instances from a file or database */
    protected Thread m_LoadThread;

    /** An experiment (used for identifying a result source) -- optional */
    protected MIExperiment m_Exp;

    /** An actionlisteners that updates ttest settings */
    protected ActionListener m_ConfigureListener = new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            m_TTester.setRunColumn(m_RunCombo.getSelectedIndex());
            setTTester();
        }
    };

    private Dimension COMBO_SIZE = new Dimension(150, m_ResultKeyBut.getPreferredSize().height);

    /**
     * Creates the results panel with no initial experiment.
     */
    public MIResultsPanel() {

        // Create/Configure/Connect components
        m_FileChooser.setFileFilter(m_ArffFilter);
        m_FileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
        m_FromExpBut.setEnabled(false);
        m_FromExpBut.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if (m_LoadThread == null) {
                    m_LoadThread = new Thread() {
                        public void run() {
                            setInstancesFromExp(m_Exp);
                            m_LoadThread = null;
                        }
                    };
                    m_LoadThread.start();
                }
            }
        });
        m_FromDBaseBut.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if (m_LoadThread == null) {
                    m_LoadThread = new Thread() {
                        public void run() {
                            setInstancesFromDBaseQuery();
                            m_LoadThread = null;
                        }
                    };
                    m_LoadThread.start();
                }
            }
        });
        m_FromFileBut.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                int returnVal = m_FileChooser.showOpenDialog(MIResultsPanel.this);
                if (returnVal == JFileChooser.APPROVE_OPTION) {
                    final File selected = m_FileChooser.getSelectedFile();
                    if (m_LoadThread == null) {
                        m_LoadThread = new Thread() {
                            public void run() {
                                setInstancesFromFile(selected);
                                m_LoadThread = null;
                            }
                        };
                        m_LoadThread.start();
                    }
                }
            }
        });
        setComboSizes();
        m_DatasetKeyBut.setEnabled(false);
        m_DatasetKeyBut.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                setDatasetKeyFromDialog();
            }
        });
        m_DatasetKeyList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
        m_RunCombo.setEnabled(false);
        m_RunCombo.addActionListener(m_ConfigureListener);
        m_ResultKeyBut.setEnabled(false);
        m_ResultKeyBut.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                setResultKeyFromDialog();
            }
        });
        m_ResultKeyList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
        m_CompareCombo.setEnabled(false);

        m_SigTex.setEnabled(false);
        m_TestsButton.setEnabled(false);
        m_TestsButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                setTestBaseFromDialog();
            }
        });

        m_PerformBut.setEnabled(false);
        m_PerformBut.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                performTest();
                m_SaveOutBut.setEnabled(true);
            }
        });

        m_PerformBut.setToolTipText("Performs test using corrected resampled t-test statistic (Nadeau and Bengio)");

        m_SaveOutBut.setEnabled(false);
        m_SaveOutBut.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                saveBuffer();
            }
        });
        m_OutText.setFont(new Font("Monospaced", Font.PLAIN, 12));
        m_OutText.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
        m_OutText.setEditable(false);
        m_History.setBorder(BorderFactory.createTitledBorder("Result list"));

        // Set up the GUI layout
        JPanel p1 = new JPanel();
        p1.setBorder(BorderFactory.createTitledBorder("Source"));
        JPanel p2 = new JPanel();
        GridBagLayout gb = new GridBagLayout();
        GridBagConstraints constraints = new GridBagConstraints();
        p2.setBorder(BorderFactory.createEmptyBorder(5, 5, 10, 5));
        //    p2.setLayout(new GridLayout(1, 3));
        p2.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);
        p2.add(m_FromFileBut, constraints);
        constraints.gridx = 1;
        constraints.gridy = 0;
        constraints.weightx = 5;
        constraints.gridwidth = 1;
        constraints.gridheight = 1;
        p2.add(m_FromDBaseBut, constraints);
        constraints.gridx = 2;
        constraints.gridy = 0;
        constraints.weightx = 5;
        constraints.gridwidth = 1;
        constraints.gridheight = 1;
        p2.add(m_FromExpBut, constraints);
        p1.setLayout(new BorderLayout());
        p1.add(m_FromLab, BorderLayout.CENTER);
        p1.add(p2, BorderLayout.EAST);

        JPanel p3 = new JPanel();
        p3.setBorder(BorderFactory.createTitledBorder("Configure test"));
        GridBagLayout gbL = new GridBagLayout();
        p3.setLayout(gbL);

        GridBagConstraints gbC = new GridBagConstraints();
        gbC.anchor = GridBagConstraints.EAST;
        gbC.gridy = 0;
        gbC.gridx = 0;
        gbC.insets = new Insets(2, 10, 2, 10);
        gbL.setConstraints(m_DatasetKeyLabel, gbC);
        p3.add(m_DatasetKeyLabel);
        gbC = new GridBagConstraints();
        gbC.gridy = 0;
        gbC.gridx = 1;
        gbC.weightx = 100;
        gbC.insets = new Insets(5, 0, 5, 0);
        gbL.setConstraints(m_DatasetKeyBut, gbC);
        p3.add(m_DatasetKeyBut);

        JLabel lab = new JLabel("Run field", SwingConstants.RIGHT);
        gbC = new GridBagConstraints();
        gbC.anchor = GridBagConstraints.EAST;
        gbC.gridy = 1;
        gbC.gridx = 0;
        gbC.insets = new Insets(2, 10, 2, 10);
        gbL.setConstraints(lab, gbC);
        p3.add(lab);
        gbC = new GridBagConstraints();
        gbC.gridy = 1;
        gbC.gridx = 1;
        gbC.weightx = 100;
        gbC.insets = new Insets(5, 0, 5, 0);
        gbL.setConstraints(m_RunCombo, gbC);
        p3.add(m_RunCombo);

        gbC = new GridBagConstraints();
        gbC.anchor = GridBagConstraints.EAST;
        gbC.gridy = 2;
        gbC.gridx = 0;
        gbC.insets = new Insets(2, 10, 2, 10);
        gbL.setConstraints(m_ResultKeyLabel, gbC);
        p3.add(m_ResultKeyLabel);
        gbC = new GridBagConstraints();
        gbC.gridy = 2;
        gbC.gridx = 1;
        gbC.weightx = 100;
        gbC.insets = new Insets(5, 0, 5, 0);
        gbL.setConstraints(m_ResultKeyBut, gbC);
        p3.add(m_ResultKeyBut);

        lab = new JLabel("Comparison field", SwingConstants.RIGHT);
        gbC = new GridBagConstraints();
        gbC.anchor = GridBagConstraints.EAST;
        gbC.gridy = 3;
        gbC.gridx = 0;
        gbC.insets = new Insets(2, 10, 2, 10);
        gbL.setConstraints(lab, gbC);
        p3.add(lab);
        gbC = new GridBagConstraints();
        gbC.gridy = 3;
        gbC.gridx = 1;
        gbC.weightx = 100;
        gbC.insets = new Insets(5, 0, 5, 0);
        gbL.setConstraints(m_CompareCombo, gbC);
        p3.add(m_CompareCombo);

        lab = new JLabel("Significance", SwingConstants.RIGHT);
        gbC = new GridBagConstraints();
        gbC.anchor = GridBagConstraints.EAST;
        gbC.gridy = 4;
        gbC.gridx = 0;
        gbC.insets = new Insets(2, 10, 2, 10);
        gbL.setConstraints(lab, gbC);
        p3.add(lab);
        gbC = new GridBagConstraints();
        gbC.gridy = 4;
        gbC.gridx = 1;
        gbC.weightx = 100;
        gbL.setConstraints(m_SigTex, gbC);
        p3.add(m_SigTex);

        lab = new JLabel("Test base", SwingConstants.RIGHT);
        gbC = new GridBagConstraints();
        gbC.anchor = GridBagConstraints.EAST;
        gbC.gridy = 5;
        gbC.gridx = 0;
        gbC.insets = new Insets(2, 10, 2, 10);
        gbL.setConstraints(lab, gbC);
        p3.add(lab);
        gbC = new GridBagConstraints();
        gbC.fill = GridBagConstraints.HORIZONTAL;
        gbC.gridy = 5;
        gbC.gridx = 1;
        gbC.weightx = 100;
        gbC.insets = new Insets(5, 0, 5, 0);
        gbL.setConstraints(m_TestsButton, gbC);
        p3.add(m_TestsButton);

        lab = new JLabel("Show std. deviations", SwingConstants.RIGHT);
        gbC = new GridBagConstraints();
        gbC.anchor = GridBagConstraints.EAST;
        gbC.gridy = 6;
        gbC.gridx = 0;
        gbC.insets = new Insets(2, 10, 2, 10);
        gbL.setConstraints(lab, gbC);
        p3.add(lab);
        gbC = new GridBagConstraints();
        gbC.anchor = GridBagConstraints.WEST;
        gbC.gridy = 6;
        gbC.gridx = 1;
        gbC.weightx = 100;
        gbC.insets = new Insets(5, 0, 5, 0);
        gbL.setConstraints(m_ShowStdDevs, gbC);
        p3.add(m_ShowStdDevs);

        JPanel output = new JPanel();
        output.setLayout(new BorderLayout());
        output.setBorder(BorderFactory.createTitledBorder("Test output"));
        output.add(new JScrollPane(m_OutText), BorderLayout.CENTER);

        JPanel mondo = new JPanel();
        gbL = new GridBagLayout();
        mondo.setLayout(gbL);
        gbC = new GridBagConstraints();
        //    gbC.anchor = GridBagConstraints.WEST;
        //    gbC.fill = GridBagConstraints.HORIZONTAL;
        gbC.gridy = 0;
        gbC.gridx = 0;
        gbL.setConstraints(p3, gbC);
        mondo.add(p3);

        JPanel bts = new JPanel();
        bts.setLayout(new GridLayout(1, 2, 5, 5));
        bts.add(m_PerformBut);
        bts.add(m_SaveOutBut);

        gbC = new GridBagConstraints();
        gbC.anchor = GridBagConstraints.NORTH;
        gbC.fill = GridBagConstraints.HORIZONTAL;
        gbC.gridy = 1;
        gbC.gridx = 0;
        gbC.insets = new Insets(5, 5, 5, 5);
        gbL.setConstraints(bts, gbC);
        mondo.add(bts);
        gbC = new GridBagConstraints();
        //gbC.anchor = GridBagConstraints.NORTH;
        gbC.fill = GridBagConstraints.BOTH;
        gbC.gridy = 2;
        gbC.gridx = 0;
        gbC.weightx = 0;
        gbC.weighty = 100;
        gbL.setConstraints(m_History, gbC);
        mondo.add(m_History);
        /*gbC = new GridBagConstraints();
        gbC.fill = GridBagConstraints.BOTH;
        gbC.gridy = 0;     gbC.gridx = 1;
        gbC.gridheight = 3;
        gbC.weightx = 100; gbC.weighty = 100;
        gbL.setConstraints(output, gbC);*/
        //mondo.add(output);
        JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, mondo, output);
        splitPane.setOneTouchExpandable(true);
        //splitPane.setDividerLocation(100);

        setLayout(new BorderLayout());
        add(p1, BorderLayout.NORTH);
        //add(mondo , BorderLayout.CENTER);
        add(splitPane, BorderLayout.CENTER);
    }

    /**
     * Sets the combo-boxes to a fixed size so they don't take up too much room
     * that would be better devoted to the test output box
     */
    protected void setComboSizes() {

        m_DatasetKeyBut.setPreferredSize(COMBO_SIZE);
        m_RunCombo.setPreferredSize(COMBO_SIZE);
        m_ResultKeyBut.setPreferredSize(COMBO_SIZE);
        m_CompareCombo.setPreferredSize(COMBO_SIZE);
        m_SigTex.setPreferredSize(COMBO_SIZE);

        m_DatasetKeyBut.setMaximumSize(COMBO_SIZE);
        m_RunCombo.setMaximumSize(COMBO_SIZE);
        m_ResultKeyBut.setMaximumSize(COMBO_SIZE);
        m_CompareCombo.setMaximumSize(COMBO_SIZE);
        m_SigTex.setMaximumSize(COMBO_SIZE);

        m_DatasetKeyBut.setMinimumSize(COMBO_SIZE);
        m_RunCombo.setMinimumSize(COMBO_SIZE);
        m_ResultKeyBut.setMinimumSize(COMBO_SIZE);
        m_CompareCombo.setMinimumSize(COMBO_SIZE);
        m_SigTex.setMinimumSize(COMBO_SIZE);
    }

    /**
     * Tells the panel to use a new experiment.
     *
     * @param exp a value of type 'Experiment'
     */
    public void setExperiment(MIExperiment exp) {

        m_Exp = exp;
        setFromExpEnabled();
    }

    /**
     * Updates whether the current experiment is of a type that we can
     * determine the results destination.
     */
    protected void setFromExpEnabled() {

        if ((m_Exp.getResultListener() instanceof MIInstancesResultListener)
                || (m_Exp.getResultListener() instanceof MIDatabaseResultListener)) {
            m_FromExpBut.setEnabled(true);
        } else {
            m_FromExpBut.setEnabled(false);
        }
    }

    /**
     * Queries the user enough to make a database query to retrieve experiment
     * results.
     */
    protected void setInstancesFromDBaseQuery() {

        try {
            if (m_InstanceQuery == null) {
                m_InstanceQuery = new MIInstanceQuery();
            }
            String dbaseURL = m_InstanceQuery.getDatabaseURL();
            dbaseURL = (String) JOptionPane.showInputDialog(this, "Enter the database URL", "Query Database",
                    JOptionPane.PLAIN_MESSAGE, null, null, dbaseURL);
            if (dbaseURL == null) {
                m_FromLab.setText("Cancelled");
                return;
            }
            m_InstanceQuery.setDatabaseURL(dbaseURL);
            m_InstanceQuery.connectToDatabase();
            if (!m_InstanceQuery.experimentIndexExists()) {
                m_FromLab.setText("No experiment index");
                return;
            }
            m_FromLab.setText("Getting experiment index");
            Instances index = m_InstanceQuery.retrieveInstances("SELECT * FROM " + MIInstanceQuery.EXP_INDEX_TABLE);
            if (index.numInstances() == 0) {
                m_FromLab.setText("No experiments available");
                return;
            }
            m_FromLab.setText("Got experiment index");

            DefaultListModel lm = new DefaultListModel();
            for (int i = 0; i < index.numInstances(); i++) {
                lm.addElement(index.instance(i).toString());
            }
            JList jl = new JList(lm);
            ListSelectorDialog jd = new ListSelectorDialog(null, jl);
            int result = jd.showDialog();
            if (result != ListSelectorDialog.APPROVE_OPTION) {
                m_FromLab.setText("Cancelled");
                return;
            }
            Instance selInst = index.instance(jl.getSelectedIndex());
            Attribute tableAttr = index.attribute(MIInstanceQuery.EXP_RESULT_COL);
            String table = MIInstanceQuery.EXP_RESULT_PREFIX + selInst.toString(tableAttr);

            setInstancesFromDatabaseTable(table);
        } catch (Exception ex) {
            m_FromLab.setText("Problem reading database");
        }
    }

    /**
     * Examines the supplied experiment to determine the results destination
     * and attempts to load the results.
     *
     * @param exp a value of type 'Experiment'
     */
    protected void setInstancesFromExp(MIExperiment exp) {

        if (exp.getResultListener() instanceof MIInstancesResultListener) {
            File resultFile = ((MIInstancesResultListener) exp.getResultListener()).getOutputFile();
            if ((resultFile == null) || (resultFile.getName().equals("-"))) {
                m_FromLab.setText("No result file");
            } else {
                setInstancesFromFile(resultFile);
            }
        } else if (exp.getResultListener() instanceof MIDatabaseResultListener) {
            String dbaseURL = ((MIDatabaseResultListener) exp.getResultListener()).getDatabaseURL();
            try {
                if (m_InstanceQuery == null) {
                    m_InstanceQuery = new MIInstanceQuery();
                }
                m_InstanceQuery.setDatabaseURL(dbaseURL);
                m_InstanceQuery.connectToDatabase();
                String tableName = m_InstanceQuery.getResultsTableName(exp.getResultProducer());
                setInstancesFromDatabaseTable(tableName);
            } catch (Exception ex) {
                m_FromLab.setText("Problem reading database");
            }
        } else {
            m_FromLab.setText("Can't get results from experiment");
        }
    }

    /**
     * Queries a database to load results from the specified table name. The
     * database connection must have already made by m_InstanceQuery.
     *
     * @param tableName the name of the table containing results to retrieve.
     */
    protected void setInstancesFromDatabaseTable(String tableName) {

        try {
            m_FromLab.setText("Reading from database, please wait...");
            final Instances i = m_InstanceQuery.retrieveInstances("SELECT * FROM " + tableName);
            SwingUtilities.invokeAndWait(new Runnable() {
                public void run() {
                    setInstances(i);
                }
            });
            m_InstanceQuery.disconnectFromDatabase();
        } catch (Exception ex) {
            m_FromLab.setText(ex.getMessage());
        }
    }

    /**
     * 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 {
            m_FromLab.setText("Reading from file...");
            Reader r = new BufferedReader(new FileReader(f));
            setInstances(new Instances(r));
        } catch (Exception ex) {
            ex.printStackTrace();
            m_FromLab.setText(ex.getMessage());
        }
    }

    /**
     * Sets up the panel with a new set of instances, attempting
     * to guess the correct settings for various columns.
     *
     * @param newInstances the new set of results.
     */
    public void setInstances(Instances newInstances) {

        m_Instances = newInstances;
        m_TTester.setInstances(m_Instances);
        m_FromLab.setText("Got " + m_Instances.numInstances() + " results");

        // Temporarily remove the configuration listener
        m_RunCombo.removeActionListener(m_ConfigureListener);

        // Do other stuff
        m_DatasetKeyModel.removeAllElements();
        m_RunModel.removeAllElements();
        m_ResultKeyModel.removeAllElements();
        m_CompareModel.removeAllElements();
        int datasetCol = -1;
        int runCol = -1;
        String selectedList = "";
        String selectedListDataset = "";
        for (int i = 0; i < m_Instances.numAttributes(); i++) {
            String name = m_Instances.attribute(i).name();
            m_DatasetKeyModel.addElement(name);
            m_RunModel.addElement(name);
            m_ResultKeyModel.addElement(name);
            m_CompareModel.addElement(name);

            if (name.toLowerCase().equals("key_dataset")) {
                m_DatasetKeyList.addSelectionInterval(i, i);
                selectedListDataset += "," + (i + 1);
            } else if ((runCol == -1) && (name.toLowerCase().equals("key_run"))) {
                m_RunCombo.setSelectedIndex(i);
                runCol = i;
            } else if (name.toLowerCase().equals("key_fold")) {
                m_TTester.setFoldColumn(i);
            } else if (name.toLowerCase().equals("key_scheme") || name.toLowerCase().equals("key_scheme_options")
                    || name.toLowerCase().equals("key_scheme_version_id")) {
                m_ResultKeyList.addSelectionInterval(i, i);
                selectedList += "," + (i + 1);
            } else if (name.toLowerCase().indexOf("percent_correct") != -1) {
                m_CompareCombo.setSelectedIndex(i);
                //   break;
            } else if ((name.toLowerCase().indexOf("root_relative_squared_error") != -1)
                    && (m_CompareCombo.getSelectedIndex() < 0)) {
                m_CompareCombo.setSelectedIndex(i);
            }
        }
        if (runCol == -1) {
            runCol = 0;
        }
        m_DatasetKeyBut.setEnabled(true);
        m_RunCombo.setEnabled(true);
        m_ResultKeyBut.setEnabled(true);
        m_CompareCombo.setEnabled(true);

        // Reconnect the configuration listener
        m_RunCombo.addActionListener(m_ConfigureListener);

        // Set up the TTester with the new data
        m_TTester.setRunColumn(runCol);
        Range generatorRange = new Range();
        if (selectedList.length() != 0) {
            try {
                generatorRange.setRanges(selectedList);
            } catch (Exception ex) {
                ex.printStackTrace();
                System.err.println(ex.getMessage());
            }
        }
        m_TTester.setResultsetKeyColumns(generatorRange);

        generatorRange = new Range();
        if (selectedListDataset.length() != 0) {
            try {
                generatorRange.setRanges(selectedListDataset);
            } catch (Exception ex) {
                ex.printStackTrace();
                System.err.println(ex.getMessage());
            }
        }
        m_TTester.setDatasetKeyColumns(generatorRange);

        m_SigTex.setEnabled(true);

        setTTester();
    }

    /**
     * Updates the test chooser with possible tests
     */
    protected void setTTester() {

        String name = (new SimpleDateFormat("HH:mm:ss - ")).format(new Date()) + "Available resultsets";
        StringBuffer outBuff = new StringBuffer();
        outBuff.append("Available resultsets\n" + m_TTester.resultsetKey() + "\n\n");
        m_History.addResult(name, outBuff);
        m_History.setSingle(name);

        m_TestsModel.removeAllElements();
        for (int i = 0; i < m_TTester.getNumResultsets(); i++) {
            String tname = m_TTester.getResultsetName(i);
            /*      if (tname.length() > 20) {
            tname = tname.substring(0, 20);
            } */
            m_TestsModel.addElement(tname);
        }
        m_TestsModel.addElement("Summary");
        m_TestsModel.addElement("Ranking");
        m_TestsList.setSelectedIndex(0);
        m_TestsButton.setEnabled(true);

        m_PerformBut.setEnabled(true);

    }

    /**
     * Carries out a t-test using the current configuration.
     */
    protected void performTest() {

        String sigStr = m_SigTex.getText();
        if (sigStr.length() != 0) {
            m_TTester.setSignificanceLevel((new Double(sigStr)).doubleValue());
        } else {
            m_TTester.setSignificanceLevel(0.05);
        }

        // Carry out the test chosen and biff the results to the output area
        m_TTester.setShowStdDevs(m_ShowStdDevs.isSelected());
        int compareCol = m_CompareCombo.getSelectedIndex();
        int tType = m_TestsList.getSelectedIndex();

        String name = (new SimpleDateFormat("HH:mm:ss - ")).format(new Date())
                + (String) m_CompareCombo.getSelectedItem() + " - " + (String) m_TestsList.getSelectedValue();
        StringBuffer outBuff = new StringBuffer();
        outBuff.append(m_TTester.header(compareCol));
        outBuff.append("\n");
        m_History.addResult(name, outBuff);
        m_History.setSingle(name);
        try {
            if (tType < m_TTester.getNumResultsets()) {
                outBuff.append(m_TTester.multiResultsetFull(tType, compareCol));
            } else if (tType == m_TTester.getNumResultsets()) {
                outBuff.append(m_TTester.multiResultsetSummary(compareCol));
            } else {
                outBuff.append(m_TTester.multiResultsetRanking(compareCol));
            }
            outBuff.append("\n");
        } catch (Exception ex) {
            outBuff.append(ex.getMessage() + "\n");
        }
        m_History.updateResult(name);
    }

    public void setResultKeyFromDialog() {

        ListSelectorDialog jd = new ListSelectorDialog(null, m_ResultKeyList);

        // Open the dialog
        int result = jd.showDialog();

        // If accepted, update the ttester
        if (result == ListSelectorDialog.APPROVE_OPTION) {
            int[] selected = m_ResultKeyList.getSelectedIndices();
            String selectedList = "";
            for (int i = 0; i < selected.length; i++) {
                selectedList += "," + (selected[i] + 1);
            }
            Range generatorRange = new Range();
            if (selectedList.length() != 0) {
                try {
                    generatorRange.setRanges(selectedList);
                } catch (Exception ex) {
                    ex.printStackTrace();
                    System.err.println(ex.getMessage());
                }
            }
            m_TTester.setResultsetKeyColumns(generatorRange);
            setTTester();
        }
    }

    public void setDatasetKeyFromDialog() {

        ListSelectorDialog jd = new ListSelectorDialog(null, m_DatasetKeyList);

        // Open the dialog
        int result = jd.showDialog();

        // If accepted, update the ttester
        if (result == ListSelectorDialog.APPROVE_OPTION) {
            int[] selected = m_DatasetKeyList.getSelectedIndices();
            String selectedList = "";
            for (int i = 0; i < selected.length; i++) {
                selectedList += "," + (selected[i] + 1);
            }
            Range generatorRange = new Range();
            if (selectedList.length() != 0) {
                try {
                    generatorRange.setRanges(selectedList);
                } catch (Exception ex) {
                    ex.printStackTrace();
                    System.err.println(ex.getMessage());
                }
            }
            m_TTester.setDatasetKeyColumns(generatorRange);
            setTTester();
        }
    }

    public void setTestBaseFromDialog() {
        ListSelectorDialog jd = new ListSelectorDialog(null, m_TestsList);

        // Open the dialog
        jd.showDialog();
    }

    /**
     * Save the currently selected result buffer to a file.
     */
    protected void saveBuffer() {
        StringBuffer sb = m_History.getSelectedBuffer();
        if (sb != null) {
            if (m_SaveOut.save(sb)) {
                JOptionPane.showMessageDialog(this, "File saved", "Results", JOptionPane.INFORMATION_MESSAGE);
            }
        } else {
            m_SaveOutBut.setEnabled(false);
        }
    }

    /**
     * Tests out the results panel from the command line.
     *
     * @param args ignored
     */
    public static void main(String[] args) {

        try {
            final JFrame jf = new JFrame("Weka Experiment: Results Analysis");
            jf.getContentPane().setLayout(new BorderLayout());
            final MIResultsPanel sp = new MIResultsPanel();
            //sp.setBorder(BorderFactory.createTitledBorder("Setup"));
            jf.getContentPane().add(sp, BorderLayout.CENTER);
            jf.addWindowListener(new WindowAdapter() {
                public void windowClosing(WindowEvent e) {
                    jf.dispose();
                    System.exit(0);
                }
            });
            jf.pack();
            jf.setSize(700, 550);
            jf.setVisible(true);
        } catch (Exception ex) {
            ex.printStackTrace();
            System.err.println(ex.getMessage());
        }
    }
}