ResultsPanel.java
Upload User: rhdiban
Upload Date: 2013-08-09
Package Size: 15085k
Code Size: 30k
Category:

Windows Develop

Development Platform:

Java

  1. /*
  2.  *    This program is free software; you can redistribute it and/or modify
  3.  *    it under the terms of the GNU General Public License as published by
  4.  *    the Free Software Foundation; either version 2 of the License, or
  5.  *    (at your option) any later version.
  6.  *
  7.  *    This program is distributed in the hope that it will be useful,
  8.  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  9.  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  10.  *    GNU General Public License for more details.
  11.  *
  12.  *    You should have received a copy of the GNU General Public License
  13.  *    along with this program; if not, write to the Free Software
  14.  *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15.  */
  16. /*
  17.  *    ResultsPanel.java
  18.  *    Copyright (C) 1999 Len Trigg
  19.  *
  20.  */
  21. package weka.gui.experiment;
  22. import weka.gui.ExtensionFileFilter;
  23. import weka.gui.ListSelectorDialog;
  24. import weka.gui.ResultHistoryPanel;
  25. import weka.gui.SaveBuffer;
  26. import weka.experiment.Experiment;
  27. import weka.experiment.InstancesResultListener;
  28. import weka.experiment.DatabaseResultListener;
  29. import weka.experiment.PairedTTester;
  30. import weka.experiment.InstanceQuery;
  31. import weka.core.Utils;
  32. import weka.core.Attribute;
  33. import weka.core.Instances;
  34. import weka.core.Range;
  35. import weka.core.Instance;
  36. import java.io.Reader;
  37. import java.io.FileReader;
  38. import java.io.BufferedReader;
  39. import java.io.File;
  40. import java.awt.BorderLayout;
  41. import java.awt.GridLayout;
  42. import java.awt.Font;
  43. import java.awt.event.ActionListener;
  44. import java.awt.event.ActionEvent;
  45. import java.awt.event.WindowAdapter;
  46. import java.awt.event.WindowEvent;
  47. import javax.swing.JPanel;
  48. import javax.swing.JLabel;
  49. import javax.swing.JFrame;
  50. import javax.swing.JButton;
  51. import javax.swing.JTextArea;
  52. import javax.swing.BorderFactory;
  53. import javax.swing.JScrollPane;
  54. import javax.swing.SwingConstants;
  55. import javax.swing.filechooser.FileFilter;
  56. import javax.swing.JFileChooser;
  57. import javax.swing.JComboBox;
  58. import javax.swing.JTextField;
  59. import javax.swing.DefaultComboBoxModel;
  60. import javax.swing.DefaultListModel;
  61. import javax.swing.JList;
  62. import javax.swing.ListSelectionModel;
  63. import javax.swing.JOptionPane;
  64. import javax.swing.JCheckBox;
  65. import java.awt.GridBagLayout;
  66. import java.awt.GridBagConstraints;
  67. import java.awt.Insets;
  68. import java.util.Date;
  69. import java.text.SimpleDateFormat;
  70. import java.awt.Dimension;
  71. import javax.swing.SwingUtilities;
  72. /** 
  73.  * This panel controls simple analysis of experimental results.
  74.  *
  75.  * @author Len Trigg (trigg@cs.waikato.ac.nz)
  76.  * @version $Revision: 1.20 $
  77.  */
  78. public class ResultsPanel extends JPanel {
  79.   /** Message shown when no experimental results have been loaded */
  80.   protected final static String NO_SOURCE = "No source";
  81.   /** Click to load results from a file */
  82.   protected JButton m_FromFileBut = new JButton("File...");
  83.   /** Click to load results from a database */
  84.   protected JButton m_FromDBaseBut = new JButton("Database...");
  85.   /** Click to get results from the destination given in the experiment */
  86.   protected JButton m_FromExpBut = new JButton("Experiment");
  87.   /** Displays a message about the current result set */
  88.   protected JLabel m_FromLab = new JLabel(NO_SOURCE);
  89.   /**
  90.    * This is needed to get around a bug in Swing <= 1.1 -- Once everyone
  91.    * is using Swing 1.1.1 or higher just remove this variable and use the
  92.    * no-arg constructor to DefaultComboBoxModel
  93.    */
  94.   static private String [] FOR_JFC_1_1_DCBM_BUG = {""};
  95.   /** The model embedded in m_DatasetCombo */
  96.   protected DefaultComboBoxModel m_DatasetModel =
  97.     new DefaultComboBoxModel(FOR_JFC_1_1_DCBM_BUG);
  98.   
  99.   /** The model embedded in m_RunCombo */
  100.   protected DefaultComboBoxModel m_RunModel =
  101.     new DefaultComboBoxModel(FOR_JFC_1_1_DCBM_BUG);
  102.   
  103.   /** The model embedded in m_CompareCombo */
  104.   protected DefaultComboBoxModel m_CompareModel = 
  105.     new DefaultComboBoxModel(FOR_JFC_1_1_DCBM_BUG);
  106.   
  107.   /** The model embedded in m_TestsList */
  108.   protected DefaultListModel m_TestsModel = new DefaultListModel();
  109.   /** Displays the currently selected column names for the scheme & options */
  110.   protected JLabel m_DatasetKeyLabel = new JLabel("Row key fields",
  111.  SwingConstants.RIGHT);
  112.   /** Click to edit the columns used to determine the scheme */
  113.   protected JButton m_DatasetKeyBut = new JButton("Select keys...");
  114.   /** Stores the list of attributes for selecting the scheme columns */
  115.   protected DefaultListModel m_DatasetKeyModel = new DefaultListModel();
  116.   /** Displays the list of selected columns determining the scheme */
  117.   protected JList m_DatasetKeyList = new JList(m_DatasetKeyModel);
  118.   /** Lets the user select which column contains the run number */
  119.   protected JComboBox m_RunCombo = new JComboBox(m_RunModel);
  120.   /** Displays the currently selected column names for the scheme & options */
  121.   protected JLabel m_ResultKeyLabel = new JLabel("Column key fields",
  122.  SwingConstants.RIGHT);
  123.   /** Click to edit the columns used to determine the scheme */
  124.   protected JButton m_ResultKeyBut = new JButton("Select keys...");
  125.   /** Stores the list of attributes for selecting the scheme columns */
  126.   protected DefaultListModel m_ResultKeyModel = new DefaultListModel();
  127.   /** Displays the list of selected columns determining the scheme */
  128.   protected JList m_ResultKeyList = new JList(m_ResultKeyModel);
  129.   /** Lets the user select which scheme to base comparisons against */
  130.   protected JButton m_TestsButton = new JButton("Select base...");
  131.   /** Holds the list of schemes to base the test against */
  132.   protected JList m_TestsList = new JList(m_TestsModel);
  133.   /** Lets the user select which performance measure to analyze */
  134.   protected JComboBox m_CompareCombo = new JComboBox(m_CompareModel);
  135.   /** Lets the user edit the test significance */
  136.   protected JTextField m_SigTex = new JTextField("0.05");
  137.   /** Lets the user select whether standard deviations are to be output
  138.       or not */
  139.   protected JCheckBox m_ShowStdDevs = 
  140.     new JCheckBox("");
  141.   /** Click to start the test */
  142.   protected JButton m_PerformBut = new JButton("Perform test");
  143.   
  144.   /** Click to save test output to a file */
  145.   protected JButton m_SaveOutBut = new JButton("Save output");
  146.   /** The buffer saving object for saving output */
  147.   SaveBuffer m_SaveOut = new SaveBuffer(null, this);
  148.   /** Displays the output of tests */
  149.   protected JTextArea m_OutText = new JTextArea();
  150.   /** A panel controlling results viewing */
  151.   protected ResultHistoryPanel m_History = new ResultHistoryPanel(m_OutText);
  152.   /** Filter to ensure only arff files are selected for result files */  
  153.   protected FileFilter m_ArffFilter =
  154.     new ExtensionFileFilter(Instances.FILE_EXTENSION, "Arff data files");
  155.   
  156.   /** The file chooser for selecting result files */
  157.   protected JFileChooser m_FileChooser = new JFileChooser(new File(System.getProperty("user.dir")));
  158.   /** The PairedTTester object */
  159.   protected PairedTTester m_TTester = new PairedTTester();
  160.   
  161.   /** The instances we're extracting results from */
  162.   protected Instances m_Instances;
  163.   /** Does any database querying for us */
  164.   protected InstanceQuery m_InstanceQuery;
  165.   /** A thread to load results instances from a file or database */
  166.   protected Thread m_LoadThread;
  167.   
  168.   /** An experiment (used for identifying a result source) -- optional */
  169.   protected Experiment m_Exp;
  170.   /** An actionlisteners that updates ttest settings */
  171.   protected ActionListener m_ConfigureListener = new ActionListener() {
  172.     public void actionPerformed(ActionEvent e) {
  173.       m_TTester.setRunColumn(m_RunCombo.getSelectedIndex());
  174.       setTTester();
  175.     }
  176.   };
  177.   
  178.   private Dimension COMBO_SIZE = new Dimension(150, m_ResultKeyBut
  179.        .getPreferredSize().height);
  180.   /**
  181.    * Creates the results panel with no initial experiment.
  182.    */
  183.   public ResultsPanel() {
  184.     // Create/Configure/Connect components
  185.     m_FileChooser.setFileFilter(m_ArffFilter);
  186.     m_FileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
  187.     m_FromExpBut.setEnabled(false);
  188.     m_FromExpBut.addActionListener(new ActionListener() {
  189.       public void actionPerformed(ActionEvent e) {
  190. if (m_LoadThread == null) {
  191.   m_LoadThread = new Thread() {
  192.     public void run() {
  193.       setInstancesFromExp(m_Exp);
  194.       m_LoadThread = null;
  195.     }
  196.   };
  197.   m_LoadThread.start();
  198. }
  199.       }
  200.     });
  201.     m_FromDBaseBut.addActionListener(new ActionListener() {
  202.       public void actionPerformed(ActionEvent e) {
  203. if (m_LoadThread == null) {
  204.   m_LoadThread = new Thread() {
  205.     public void run() {
  206.       setInstancesFromDBaseQuery();
  207.     m_LoadThread = null;
  208.     }
  209.   };
  210.   m_LoadThread.start();
  211. }
  212.       }
  213.     });
  214.     m_FromFileBut.addActionListener(new ActionListener() {
  215.       public void actionPerformed(ActionEvent e) {
  216. int returnVal = m_FileChooser.showOpenDialog(ResultsPanel.this);
  217. if (returnVal == JFileChooser.APPROVE_OPTION) {
  218.   final File selected = m_FileChooser.getSelectedFile();
  219.   if (m_LoadThread == null) {
  220.     m_LoadThread = new Thread() {
  221.       public void run() {
  222. setInstancesFromFile(selected);
  223. m_LoadThread = null;
  224.       }
  225.     };
  226.     m_LoadThread.start();
  227.   }
  228. }
  229.       }
  230.     });
  231.     setComboSizes();
  232.     m_DatasetKeyBut.setEnabled(false);
  233.     m_DatasetKeyBut.addActionListener(new ActionListener() {
  234.       public void actionPerformed(ActionEvent e) {
  235. setDatasetKeyFromDialog();
  236.       }
  237.     });
  238.     m_DatasetKeyList.setSelectionMode(ListSelectionModel
  239.       .MULTIPLE_INTERVAL_SELECTION);
  240.     m_RunCombo.setEnabled(false);
  241.     m_RunCombo.addActionListener(m_ConfigureListener);
  242.     m_ResultKeyBut.setEnabled(false);
  243.     m_ResultKeyBut.addActionListener(new ActionListener() {
  244.       public void actionPerformed(ActionEvent e) {
  245. setResultKeyFromDialog();
  246.       }
  247.     });
  248.     m_ResultKeyList.setSelectionMode(ListSelectionModel
  249.      .MULTIPLE_INTERVAL_SELECTION);
  250.     m_CompareCombo.setEnabled(false);
  251.     m_SigTex.setEnabled(false);
  252.     m_TestsButton.setEnabled(false);
  253.     m_TestsButton.addActionListener(new ActionListener() {
  254. public void actionPerformed(ActionEvent e) {
  255.   setTestBaseFromDialog();
  256. }
  257.       });
  258.     m_PerformBut.setEnabled(false);
  259.     m_PerformBut.addActionListener(new ActionListener() {
  260.       public void actionPerformed(ActionEvent e) {
  261. performTest();
  262. m_SaveOutBut.setEnabled(true);
  263.       }
  264.     });
  265.     m_SaveOutBut.setEnabled(false);
  266.     m_SaveOutBut.addActionListener(new ActionListener() {
  267. public void actionPerformed(ActionEvent e) {
  268.   saveBuffer();
  269. }
  270.       });
  271.     m_OutText.setFont(new Font("Monospaced", Font.PLAIN, 12));
  272.     m_OutText.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
  273.     m_OutText.setEditable(false);
  274.     m_History.setBorder(BorderFactory.createTitledBorder("Result list"));
  275.     // Set up the GUI layout
  276.     JPanel p1 = new JPanel();
  277.     p1.setBorder(BorderFactory.createTitledBorder("Source"));
  278.     JPanel p2 = new JPanel();
  279.     GridBagLayout gb = new GridBagLayout();
  280.     GridBagConstraints constraints = new GridBagConstraints();
  281.     p2.setBorder(BorderFactory.createEmptyBorder(5, 5, 10, 5));
  282.     //    p2.setLayout(new GridLayout(1, 3));
  283.     p2.setLayout(gb);
  284.     constraints.gridx=0;constraints.gridy=0;constraints.weightx=5;
  285.     constraints.fill = GridBagConstraints.HORIZONTAL;
  286.     constraints.gridwidth=1;constraints.gridheight=1;
  287.     constraints.insets = new Insets(0,2,0,2);
  288.     p2.add(m_FromFileBut,constraints);
  289.     constraints.gridx=1;constraints.gridy=0;constraints.weightx=5;
  290.     constraints.gridwidth=1;constraints.gridheight=1;
  291.     p2.add(m_FromDBaseBut,constraints);
  292.     constraints.gridx=2;constraints.gridy=0;constraints.weightx=5;
  293.     constraints.gridwidth=1;constraints.gridheight=1;
  294.     p2.add(m_FromExpBut,constraints);
  295.     p1.setLayout(new BorderLayout());
  296.     p1.add(m_FromLab, BorderLayout.CENTER);
  297.     p1.add(p2, BorderLayout.EAST);
  298.     JPanel p3 = new JPanel();
  299.     p3.setBorder(BorderFactory.createTitledBorder("Configure test"));
  300.     GridBagLayout gbL = new GridBagLayout();
  301.     p3.setLayout(gbL);
  302.     GridBagConstraints gbC = new GridBagConstraints();
  303.     gbC.anchor = GridBagConstraints.EAST;
  304.     gbC.gridy = 0;     gbC.gridx = 0;
  305.     gbC.insets = new Insets(2, 10, 2, 10);
  306.     gbL.setConstraints(m_DatasetKeyLabel,gbC);
  307.     p3.add(m_DatasetKeyLabel);
  308.     gbC = new GridBagConstraints();
  309.     gbC.gridy = 0;     gbC.gridx = 1;  gbC.weightx = 100;
  310.     gbC.insets = new Insets(5,0,5,0);
  311.     gbL.setConstraints(m_DatasetKeyBut, gbC);
  312.     p3.add(m_DatasetKeyBut);
  313.     JLabel lab = new JLabel("Run field", SwingConstants.RIGHT);
  314.     gbC = new GridBagConstraints();
  315.     gbC.anchor = GridBagConstraints.EAST;
  316.     gbC.gridy = 1;     gbC.gridx = 0;
  317.     gbC.insets = new Insets(2, 10, 2, 10);
  318.     gbL.setConstraints(lab, gbC);
  319.     p3.add(lab);
  320.     gbC = new GridBagConstraints();
  321.     gbC.gridy = 1;     gbC.gridx = 1;  gbC.weightx = 100;
  322.     gbC.insets = new Insets(5,0,5,0);
  323.     gbL.setConstraints(m_RunCombo, gbC);
  324.     p3.add(m_RunCombo);
  325.     
  326.     gbC = new GridBagConstraints();
  327.     gbC.anchor = GridBagConstraints.EAST;
  328.     gbC.gridy = 2;     gbC.gridx = 0;
  329.     gbC.insets = new Insets(2, 10, 2, 10);
  330.     gbL.setConstraints(m_ResultKeyLabel, gbC);
  331.     p3.add(m_ResultKeyLabel);
  332.     gbC = new GridBagConstraints();
  333.     gbC.gridy = 2;     gbC.gridx = 1;  gbC.weightx = 100;
  334.     gbC.insets = new Insets(5,0,5,0);
  335.     gbL.setConstraints(m_ResultKeyBut, gbC);
  336.     p3.add(m_ResultKeyBut);
  337.     
  338.     lab = new JLabel("Comparison field", SwingConstants.RIGHT);
  339.     gbC = new GridBagConstraints();
  340.     gbC.anchor = GridBagConstraints.EAST;
  341.     gbC.gridy = 3;     gbC.gridx = 0;
  342.     gbC.insets = new Insets(2, 10, 2, 10);
  343.     gbL.setConstraints(lab, gbC);
  344.     p3.add(lab);
  345.     gbC = new GridBagConstraints();
  346.     gbC.gridy = 3;     gbC.gridx = 1;  gbC.weightx = 100;
  347.     gbC.insets = new Insets(5,0,5,0);
  348.     gbL.setConstraints(m_CompareCombo, gbC);
  349.     p3.add(m_CompareCombo);
  350.     
  351.     lab = new JLabel("Significance", SwingConstants.RIGHT);
  352.     gbC = new GridBagConstraints();
  353.     gbC.anchor = GridBagConstraints.EAST;
  354.     gbC.gridy = 4;     gbC.gridx = 0;
  355.     gbC.insets = new Insets(2, 10, 2, 10);
  356.     gbL.setConstraints(lab, gbC);
  357.     p3.add(lab);
  358.     gbC = new GridBagConstraints();
  359.     gbC.gridy = 4;     gbC.gridx = 1;  gbC.weightx = 100;
  360.     gbL.setConstraints(m_SigTex, gbC);
  361.     p3.add(m_SigTex);
  362.     
  363.     lab = new JLabel("Test base", SwingConstants.RIGHT);
  364.     gbC = new GridBagConstraints();
  365.     gbC.anchor = GridBagConstraints.EAST;
  366.     gbC.gridy = 5;     gbC.gridx = 0;
  367.     gbC.insets = new Insets(2, 10, 2, 10);
  368.     gbL.setConstraints(lab, gbC);
  369.     p3.add(lab);
  370.     gbC = new GridBagConstraints();
  371.     gbC.fill = GridBagConstraints.HORIZONTAL;
  372.     gbC.gridy = 5;     gbC.gridx = 1;  gbC.weightx = 100;
  373.     gbC.insets = new Insets(5,0,5,0);
  374.     gbL.setConstraints(m_TestsButton, gbC);
  375.     p3.add(m_TestsButton);
  376.     lab = new JLabel("Show std. deviations", SwingConstants.RIGHT);
  377.     gbC = new GridBagConstraints();
  378.     gbC.anchor = GridBagConstraints.EAST;
  379.     gbC.gridy = 6;     gbC.gridx = 0;
  380.     gbC.insets = new Insets(2, 10, 2, 10);
  381.     gbL.setConstraints(lab, gbC);
  382.     p3.add(lab);
  383.     gbC = new GridBagConstraints();
  384.     gbC.anchor = GridBagConstraints.WEST;
  385.     gbC.gridy = 6;     gbC.gridx = 1;  gbC.weightx = 100;
  386.     gbC.insets = new Insets(5,0,5,0);
  387.     gbL.setConstraints(m_ShowStdDevs, gbC);
  388.     p3.add(m_ShowStdDevs);
  389.     JPanel output = new JPanel();
  390.     output.setLayout(new BorderLayout());
  391.     output.setBorder(BorderFactory.createTitledBorder("Test output"));
  392.     output.add(new JScrollPane(m_OutText), BorderLayout.CENTER);
  393.     JPanel mondo = new JPanel();
  394.     gbL = new GridBagLayout();
  395.     mondo.setLayout(gbL);
  396.     gbC = new GridBagConstraints();
  397.     //    gbC.anchor = GridBagConstraints.WEST;
  398.     //    gbC.fill = GridBagConstraints.HORIZONTAL;
  399.     gbC.gridy = 0;     gbC.gridx = 0;
  400.     gbL.setConstraints(p3, gbC);
  401.     mondo.add(p3);
  402.     JPanel bts = new JPanel();
  403.     bts.setLayout(new GridLayout(1,2,5,5));
  404.     bts.add(m_PerformBut);
  405.     bts.add(m_SaveOutBut);
  406.     gbC = new GridBagConstraints();
  407.     gbC.anchor = GridBagConstraints.NORTH;
  408.     gbC.fill = GridBagConstraints.HORIZONTAL;
  409.     gbC.gridy = 1;     gbC.gridx = 0;
  410.     gbC.insets = new Insets(5,5,5,5);
  411.     gbL.setConstraints(bts, gbC);
  412.     mondo.add(bts);
  413.     gbC = new GridBagConstraints();
  414.     //gbC.anchor = GridBagConstraints.NORTH;
  415.     gbC.fill = GridBagConstraints.BOTH;
  416.     gbC.gridy = 2;     gbC.gridx = 0; gbC.weightx = 0;
  417.     gbL.setConstraints(m_History, gbC);
  418.     mondo.add(m_History);
  419.     gbC = new GridBagConstraints();
  420.     gbC.fill = GridBagConstraints.BOTH;
  421.     gbC.gridy = 0;     gbC.gridx = 1;
  422.     gbC.gridheight = 3;
  423.     gbC.weightx = 100; gbC.weighty = 100;
  424.     gbL.setConstraints(output, gbC);
  425.     mondo.add(output);
  426.     setLayout(new BorderLayout());
  427.     add(p1, BorderLayout.NORTH);
  428.     add(mondo , BorderLayout.CENTER);
  429.   }
  430.   /**
  431.    * Sets the combo-boxes to a fixed size so they don't take up too much room
  432.    * that would be better devoted to the test output box
  433.    */
  434.   protected void setComboSizes() {
  435.     
  436.     m_DatasetKeyBut.setPreferredSize(COMBO_SIZE);
  437.     m_RunCombo.setPreferredSize(COMBO_SIZE);
  438.     m_ResultKeyBut.setPreferredSize(COMBO_SIZE);
  439.     m_CompareCombo.setPreferredSize(COMBO_SIZE);
  440.     m_SigTex.setPreferredSize(COMBO_SIZE);
  441.     m_DatasetKeyBut.setMaximumSize(COMBO_SIZE);
  442.     m_RunCombo.setMaximumSize(COMBO_SIZE);
  443.     m_ResultKeyBut.setMaximumSize(COMBO_SIZE);
  444.     m_CompareCombo.setMaximumSize(COMBO_SIZE);
  445.     m_SigTex.setMaximumSize(COMBO_SIZE);
  446.     m_DatasetKeyBut.setMinimumSize(COMBO_SIZE);
  447.     m_RunCombo.setMinimumSize(COMBO_SIZE);
  448.     m_ResultKeyBut.setMinimumSize(COMBO_SIZE);
  449.     m_CompareCombo.setMinimumSize(COMBO_SIZE);
  450.     m_SigTex.setMinimumSize(COMBO_SIZE);
  451.   }
  452.   
  453.   /**
  454.    * Tells the panel to use a new experiment.
  455.    *
  456.    * @param exp a value of type 'Experiment'
  457.    */
  458.   public void setExperiment(Experiment exp) {
  459.     
  460.     m_Exp = exp;
  461.     setFromExpEnabled();
  462.   }
  463.   /**
  464.    * Updates whether the current experiment is of a type that we can
  465.    * determine the results destination.
  466.    */
  467.   protected void setFromExpEnabled() {
  468.     if ((m_Exp.getResultListener() instanceof InstancesResultListener)
  469. || (m_Exp.getResultListener() instanceof DatabaseResultListener)) {
  470.       m_FromExpBut.setEnabled(true);
  471.     } else {
  472.       m_FromExpBut.setEnabled(false);
  473.     }
  474.   }
  475.   /**
  476.    * Queries the user enough to make a database query to retrieve experiment
  477.    * results.
  478.    */
  479.   protected void setInstancesFromDBaseQuery() {
  480.     try {
  481.       if (m_InstanceQuery == null) {
  482. m_InstanceQuery = new InstanceQuery();
  483.       }
  484.       String dbaseURL = m_InstanceQuery.getDatabaseURL();
  485.       dbaseURL = (String) JOptionPane.showInputDialog(this,
  486.      "Enter the database URL",
  487.      "Query Database",
  488.      JOptionPane.PLAIN_MESSAGE,
  489.      null,
  490.      null,
  491.      dbaseURL);
  492.       if (dbaseURL == null) {
  493. m_FromLab.setText("Cancelled");
  494. return;
  495.       }
  496.       m_InstanceQuery.setDatabaseURL(dbaseURL);
  497.       m_InstanceQuery.connectToDatabase();
  498.       if (!m_InstanceQuery.experimentIndexExists()) {
  499. m_FromLab.setText("No experiment index");
  500. return;
  501.       }
  502.       m_FromLab.setText("Getting experiment index");
  503.       Instances index = m_InstanceQuery.retrieveInstances("SELECT * FROM "
  504.        + InstanceQuery.EXP_INDEX_TABLE);
  505.       if (index.numInstances() == 0) {
  506. m_FromLab.setText("No experiments available");
  507. return;
  508.       }
  509.       m_FromLab.setText("Got experiment index");
  510.       DefaultListModel lm = new DefaultListModel();
  511.       for (int i = 0; i < index.numInstances(); i++) {
  512. lm.addElement(index.instance(i).toString());
  513.       }
  514.       JList jl = new JList(lm);
  515.       ListSelectorDialog jd = new ListSelectorDialog(null, jl);
  516.       int result = jd.showDialog();
  517.       if (result != ListSelectorDialog.APPROVE_OPTION) {
  518. m_FromLab.setText("Cancelled");
  519. return;
  520.       }
  521.       Instance selInst = index.instance(jl.getSelectedIndex());
  522.       Attribute tableAttr = index.attribute(InstanceQuery.EXP_RESULT_COL);
  523.       String table = InstanceQuery.EXP_RESULT_PREFIX
  524. + selInst.toString(tableAttr);
  525.       setInstancesFromDatabaseTable(table);
  526.     } catch (Exception ex) {
  527.       m_FromLab.setText("Problem reading database");
  528.     }
  529.   }
  530.   
  531.   /**
  532.    * Examines the supplied experiment to determine the results destination
  533.    * and attempts to load the results.
  534.    *
  535.    * @param exp a value of type 'Experiment'
  536.    */
  537.   protected void setInstancesFromExp(Experiment exp) {
  538.     if (exp.getResultListener() instanceof InstancesResultListener) {
  539.       File resultFile = ((InstancesResultListener) exp.getResultListener())
  540. .getOutputFile();
  541.       if ((resultFile == null) || (resultFile.getName().equals("-"))) {
  542. m_FromLab.setText("No result file");
  543.       } else {
  544. setInstancesFromFile(resultFile);
  545.       }
  546.     } else if (exp.getResultListener() instanceof DatabaseResultListener) {
  547.       String dbaseURL = ((DatabaseResultListener) exp.getResultListener())
  548. .getDatabaseURL();
  549.       try {
  550. if (m_InstanceQuery == null) {
  551.   m_InstanceQuery = new InstanceQuery();
  552. }
  553. m_InstanceQuery.setDatabaseURL(dbaseURL);
  554. m_InstanceQuery.connectToDatabase();
  555. String tableName = m_InstanceQuery
  556.   .getResultsTableName(exp.getResultProducer());
  557. setInstancesFromDatabaseTable(tableName);
  558.       } catch (Exception ex) {
  559. m_FromLab.setText("Problem reading database");
  560.       }
  561.     } else {
  562.       m_FromLab.setText("Can't get results from experiment");
  563.     }
  564.   }
  565.   
  566.   /**
  567.    * Queries a database to load results from the specified table name. The
  568.    * database connection must have already made by m_InstanceQuery.
  569.    *
  570.    * @param tableName the name of the table containing results to retrieve.
  571.    */
  572.   protected void setInstancesFromDatabaseTable(String tableName) {
  573.     try {
  574.       m_FromLab.setText("Reading from database, please wait...");
  575.       final Instances i = m_InstanceQuery.retrieveInstances("SELECT * FROM "
  576.       + tableName);
  577.       SwingUtilities.invokeAndWait(new Runnable() {
  578. public void run() {
  579.   setInstances(i);
  580. }
  581.       });
  582.       m_InstanceQuery.disconnectFromDatabase();
  583.     } catch (Exception ex) {
  584.       m_FromLab.setText(ex.getMessage());
  585.     }
  586.   }
  587.   
  588.   /**
  589.    * Loads results from a set of instances contained in the supplied
  590.    * file.
  591.    *
  592.    * @param f a value of type 'File'
  593.    */
  594.   protected void setInstancesFromFile(File f) {
  595.       
  596.     try {
  597.       m_FromLab.setText("Reading from file...");
  598.       Reader r = new BufferedReader(new FileReader(f));
  599.       setInstances(new Instances(r));
  600.     } catch (Exception ex) {
  601.       ex.printStackTrace();
  602.       m_FromLab.setText(ex.getMessage());
  603.     }
  604.   }
  605.   /**
  606.    * Sets up the panel with a new set of instances, attempting
  607.    * to guess the correct settings for various columns.
  608.    *
  609.    * @param newInstances the new set of results.
  610.    */
  611.   public void setInstances(Instances newInstances) {
  612.     m_Instances = newInstances;
  613.     m_TTester.setInstances(m_Instances);
  614.     m_FromLab.setText("Got " + m_Instances.numInstances() + " results");
  615.     // Temporarily remove the configuration listener
  616.     m_RunCombo.removeActionListener(m_ConfigureListener);
  617.     
  618.     // Do other stuff
  619.     m_DatasetKeyModel.removeAllElements();
  620.     m_RunModel.removeAllElements();
  621.     m_ResultKeyModel.removeAllElements();
  622.     m_CompareModel.removeAllElements();
  623.     int datasetCol = -1;
  624.     int runCol = -1;
  625.     String selectedList = "";
  626.     String selectedListDataset = "";
  627.     for (int i = 0; i < m_Instances.numAttributes(); i++) {
  628.       String name = m_Instances.attribute(i).name();
  629.       m_DatasetKeyModel.addElement(name);
  630.       m_RunModel.addElement(name);
  631.       m_ResultKeyModel.addElement(name);
  632.       m_CompareModel.addElement(name);
  633.       if (name.toLowerCase().equals("key_dataset")) {
  634. m_DatasetKeyList.addSelectionInterval(i, i);
  635. selectedListDataset += "," + (i + 1);
  636.       } else if ((runCol == -1)
  637.  && (name.toLowerCase().equals("key_run"))) {
  638. m_RunCombo.setSelectedIndex(i);
  639. runCol = i;
  640.       } else if (name.toLowerCase().equals("key_scheme") ||
  641.  name.toLowerCase().equals("key_scheme_options") ||
  642.  name.toLowerCase().equals("key_scheme_version_id")) {
  643. m_ResultKeyList.addSelectionInterval(i, i);
  644. selectedList += "," + (i + 1);
  645.       } else if (name.toLowerCase().indexOf("percent_correct") != -1) {
  646. m_CompareCombo.setSelectedIndex(i);
  647. // break;
  648.       }
  649.     }
  650.     if (runCol == -1) {
  651.       runCol = 0;
  652.     }
  653.     m_DatasetKeyBut.setEnabled(true);
  654.     m_RunCombo.setEnabled(true);
  655.     m_ResultKeyBut.setEnabled(true);
  656.     m_CompareCombo.setEnabled(true);
  657.     
  658.     // Reconnect the configuration listener
  659.     m_RunCombo.addActionListener(m_ConfigureListener);
  660.     
  661.     // Set up the TTester with the new data
  662.     m_TTester.setRunColumn(runCol);
  663.     Range generatorRange = new Range();
  664.     if (selectedList.length() != 0) {
  665.       try {
  666. generatorRange.setRanges(selectedList);
  667.       } catch (Exception ex) {
  668. ex.printStackTrace();
  669. System.err.println(ex.getMessage());
  670.       }
  671.     }
  672.     m_TTester.setResultsetKeyColumns(generatorRange);
  673.     generatorRange = new Range();
  674.     if (selectedListDataset.length() != 0) {
  675.       try {
  676. generatorRange.setRanges(selectedListDataset);
  677.       } catch (Exception ex) {
  678. ex.printStackTrace();
  679. System.err.println(ex.getMessage());
  680.       }
  681.     }
  682.     m_TTester.setDatasetKeyColumns(generatorRange);
  683.     m_SigTex.setEnabled(true);
  684.     setTTester();
  685.   }
  686.   /**
  687.    * Updates the test chooser with possible tests
  688.    */
  689.   protected void setTTester() {
  690.     
  691.     String name = (new SimpleDateFormat("HH:mm:ss - "))
  692.       .format(new Date())
  693.       + "Available resultsets";
  694.     StringBuffer outBuff = new StringBuffer();
  695.     outBuff.append("Available resultsetsn"
  696.    + m_TTester.resultsetKey() + "nn");
  697.     m_History.addResult(name, outBuff);
  698.     m_History.setSingle(name);
  699.     m_TestsModel.removeAllElements();
  700.     for (int i = 0; i < m_TTester.getNumResultsets(); i++) {
  701.       String tname = m_TTester.getResultsetName(i);
  702.       /*      if (tname.length() > 20) {
  703. tname = tname.substring(0, 20);
  704. } */
  705.       m_TestsModel.addElement(tname);
  706.     }
  707.     m_TestsModel.addElement("Summary");
  708.     m_TestsModel.addElement("Ranking");
  709.     m_TestsList.setSelectedIndex(0);
  710.     m_TestsButton.setEnabled(true);
  711.     m_PerformBut.setEnabled(true);
  712.     
  713.   }
  714.   
  715.   /**
  716.    * Carries out a t-test using the current configuration.
  717.    */
  718.   protected void performTest() {
  719.     String sigStr = m_SigTex.getText();
  720.     if (sigStr.length() != 0) {
  721.       m_TTester.setSignificanceLevel((new Double(sigStr)).doubleValue());
  722.     } else {
  723.       m_TTester.setSignificanceLevel(0.05);
  724.     }
  725.     // Carry out the test chosen and biff the results to the output area
  726.     m_TTester.setShowStdDevs(m_ShowStdDevs.isSelected());
  727.     int compareCol = m_CompareCombo.getSelectedIndex();
  728.     int tType = m_TestsList.getSelectedIndex();
  729.     String name = (new SimpleDateFormat("HH:mm:ss - "))
  730.       .format(new Date())
  731.       + (String) m_CompareCombo.getSelectedItem() + " - "
  732.       + (String) m_TestsList.getSelectedValue();
  733.     StringBuffer outBuff = new StringBuffer();
  734.     outBuff.append(m_TTester.header(compareCol));
  735.     outBuff.append("n");
  736.     m_History.addResult(name, outBuff);
  737.     m_History.setSingle(name);
  738.     try {
  739.       if (tType < m_TTester.getNumResultsets()) {
  740. outBuff.append(m_TTester.multiResultsetFull(tType, compareCol));
  741.       } else if (tType == m_TTester.getNumResultsets()) {
  742. outBuff.append(m_TTester.multiResultsetSummary(compareCol));
  743.       } else {
  744. outBuff.append(m_TTester.multiResultsetRanking(compareCol));
  745.       }
  746.       outBuff.append("n");
  747.     } catch (Exception ex) {
  748.       outBuff.append(ex.getMessage() + "n");
  749.     }
  750.     m_History.updateResult(name);
  751.   }
  752.   
  753.   public void setResultKeyFromDialog() {
  754.     ListSelectorDialog jd = new ListSelectorDialog(null, m_ResultKeyList);
  755.     // Open the dialog
  756.     int result = jd.showDialog();
  757.     
  758.     // If accepted, update the ttester
  759.     if (result == ListSelectorDialog.APPROVE_OPTION) {
  760.       int [] selected = m_ResultKeyList.getSelectedIndices();
  761.       String selectedList = "";
  762.       for (int i = 0; i < selected.length; i++) {
  763. selectedList += "," + (selected[i] + 1);
  764.       }
  765.       Range generatorRange = new Range();
  766.       if (selectedList.length() != 0) {
  767. try {
  768.   generatorRange.setRanges(selectedList);
  769. } catch (Exception ex) {
  770.   ex.printStackTrace();
  771.   System.err.println(ex.getMessage());
  772. }
  773.       }
  774.       m_TTester.setResultsetKeyColumns(generatorRange);
  775.       setTTester();
  776.     }
  777.   }
  778.   
  779.   public void setDatasetKeyFromDialog() {
  780.     ListSelectorDialog jd = new ListSelectorDialog(null, m_DatasetKeyList);
  781.     // Open the dialog
  782.     int result = jd.showDialog();
  783.     
  784.     // If accepted, update the ttester
  785.     if (result == ListSelectorDialog.APPROVE_OPTION) {
  786.       int [] selected = m_DatasetKeyList.getSelectedIndices();
  787.       String selectedList = "";
  788.       for (int i = 0; i < selected.length; i++) {
  789. selectedList += "," + (selected[i] + 1);
  790.       }
  791.       Range generatorRange = new Range();
  792.       if (selectedList.length() != 0) {
  793. try {
  794.   generatorRange.setRanges(selectedList);
  795. } catch (Exception ex) {
  796.   ex.printStackTrace();
  797.   System.err.println(ex.getMessage());
  798. }
  799.       }
  800.       m_TTester.setDatasetKeyColumns(generatorRange);
  801.       setTTester();
  802.     }
  803.   }
  804.   public void setTestBaseFromDialog() {
  805.     ListSelectorDialog jd = new ListSelectorDialog(null, m_TestsList);
  806.     // Open the dialog
  807.     jd.showDialog();
  808.   }
  809.   /**
  810.    * Save the currently selected result buffer to a file.
  811.    */
  812.   protected void saveBuffer() {
  813.     StringBuffer sb = m_History.getSelectedBuffer();
  814.     if (sb != null) {
  815.       if (m_SaveOut.save(sb)) {
  816. JOptionPane.showMessageDialog(this,
  817.       "File saved",
  818.       "Results",
  819.       JOptionPane.INFORMATION_MESSAGE);
  820.       }
  821.     } else {
  822.       m_SaveOutBut.setEnabled(false);
  823.     }
  824.   }
  825.   
  826.   /**
  827.    * Tests out the results panel from the command line.
  828.    *
  829.    * @param args ignored
  830.    */
  831.   public static void main(String [] args) {
  832.     try {
  833.       final JFrame jf = new JFrame("Weka Experiment: Results Analysis");
  834.       jf.getContentPane().setLayout(new BorderLayout());
  835.       final ResultsPanel sp = new ResultsPanel();
  836.       //sp.setBorder(BorderFactory.createTitledBorder("Setup"));
  837.       jf.getContentPane().add(sp, BorderLayout.CENTER);
  838.       jf.addWindowListener(new WindowAdapter() {
  839. public void windowClosing(WindowEvent e) {
  840.   jf.dispose();
  841.   System.exit(0);
  842. }
  843.       });
  844.       jf.pack();
  845.       jf.setSize(700, 550);
  846.       jf.setVisible(true);
  847.     } catch (Exception ex) {
  848.       ex.printStackTrace();
  849.       System.err.println(ex.getMessage());
  850.     }
  851.   }
  852. }