Package weka.gui

Source Code of weka.gui.SetInstancesPanel

/*
*    This program is free software; you can redistribute it and/or modify
*    it under the terms of the GNU General Public License as published by
*    the Free Software Foundation; either version 2 of the License, or
*    (at your option) any later version.
*
*    This program is distributed in the hope that it will be useful,
*    but WITHOUT ANY WARRANTY; without even the implied warranty of
*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*    GNU General Public License for more details.
*
*    You should have received a copy of the GNU General Public License
*    along with this program; if not, write to the Free Software
*    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

/*
*    SetInstancesPanel.java
*    Copyright (C) 1999 University of Waikato, Hamilton, New Zealand
*
*/

package weka.gui;

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.File;
import java.net.URL;

import javax.swing.BorderFactory;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

import weka.core.Attribute;
import weka.core.Instances;
import weka.core.converters.ConverterUtils;
import weka.core.converters.FileSourcedConverter;
import weka.core.converters.IncrementalConverter;
import weka.core.converters.URLSourcedLoader;

/**
* A panel that displays an instance summary for a set of instances and
* lets the user open a set of instances from either a file or URL.
*
* Instances may be obtained either in a batch or incremental fashion.
* If incremental reading is used, then
* the client should obtain the Loader object (by calling
* getLoader()) and read the instances one at a time. If
* batch loading is used, then SetInstancesPanel will load
* the data into memory inside of a separate thread and notify
* the client when the operation is complete. The client can
* then retrieve the instances by calling getInstances().
*
* @author Len Trigg (trigg@cs.waikato.ac.nz)
* @version $Revision: 6890 $
*/
public class SetInstancesPanel
  extends JPanel {

  /** for serialization. */
  private static final long serialVersionUID = -384804041420453735L;

  /** the text denoting "no class" in the class combobox. */
  public final static String NO_CLASS = "No class";
 
  /** Click to open instances from a file. */
  protected JButton m_OpenFileBut = new JButton("Open file...");

  /** Click to open instances from a URL. */
  protected JButton m_OpenURLBut = new JButton("Open URL...");

  /** Click to close the dialog. */
  protected JButton m_CloseBut = new JButton("Close");

  /** The instance summary component. */
  protected InstancesSummaryPanel m_Summary = new InstancesSummaryPanel();

  /** the label for the class combobox. */
  protected JLabel m_ClassLabel = new JLabel("Class");
 
  /** the class combobox. */
  protected JComboBox m_ClassComboBox = new JComboBox(new DefaultComboBoxModel(new String[]{NO_CLASS}));
 
  /** The file chooser for selecting arff files. */
  protected ConverterFileChooser m_FileChooser
    = new ConverterFileChooser(new File(System.getProperty("user.dir")));

  /** Stores the last URL that instances were loaded from. */
  protected String m_LastURL = "http://";

  /** The thread we do loading in. */
  protected Thread m_IOThread;

  /**
   * Manages sending notifications to people when we change the set of
   * working instances.
   */
  protected PropertyChangeSupport m_Support = new PropertyChangeSupport(this);

  /** The current set of instances loaded. */
  protected Instances m_Instances;

  /** The current loader used to obtain the current instances. */
  protected weka.core.converters.Loader m_Loader;
 
  /** the parent frame. if one is provided, the close-button is displayed */
  protected JFrame m_ParentFrame = null;

  /** the panel the Close-Button is located in. */
  protected JPanel m_CloseButPanel = null;

  /** whether to read the instances incrementally, if possible. */
  protected boolean m_readIncrementally = true;
 
  /** whether to display zero instances as unknown ("?"). */
  protected boolean m_showZeroInstancesAsUnknown = false;
 
  /** whether to display a combobox that allows the user to choose the class
   * attribute. */
  protected boolean m_showClassComboBox;
 
  /**
   * Default constructor.
   */
  public SetInstancesPanel() {
    this(false, false);
  }
 
  /**
   * Create the panel.
   *
   * @param showZeroInstancesAsUnknown  whether to display zero instances
   *           as unknown (e.g., when reading data
   *           incrementally)
   * @param showClassComboBox    whether to display a combobox
   *           allowing the user to choose the class
   *           attribute
   */
  public SetInstancesPanel(boolean showZeroInstancesAsUnknown, boolean showClassComboBox) {
    m_showZeroInstancesAsUnknown = showZeroInstancesAsUnknown;
    m_showClassComboBox = showClassComboBox;
   
    m_OpenFileBut.setToolTipText("Open a set of instances from a file");
    m_OpenURLBut.setToolTipText("Open a set of instances from a URL");
    m_CloseBut.setToolTipText("Closes the dialog");
    m_FileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
    m_OpenURLBut.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
  setInstancesFromURLQ();
      }
    });
    m_OpenFileBut.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
  setInstancesFromFileQ();
      }
    });
    m_CloseBut.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        closeFrame();
      }
    });
    m_Summary.setBorder(BorderFactory.createEmptyBorder(5, 10, 5, 10));

    m_ClassComboBox.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
  if ((m_Instances != null) && (m_ClassComboBox.getSelectedIndex() != -1)) {
    if (m_Instances.numAttributes() >= m_ClassComboBox.getSelectedIndex()) {
      m_Instances.setClassIndex(m_ClassComboBox.getSelectedIndex() - 1);   // -1 because of NO_CLASS element
      m_Support.firePropertyChange("", null, null);
    }
  }
      }
    });
   
    JPanel panelButtons = new JPanel(new FlowLayout(FlowLayout.LEFT));
    panelButtons.add(m_OpenFileBut);
    panelButtons.add(m_OpenURLBut);

    JPanel panelClass = new JPanel(new FlowLayout(FlowLayout.LEFT));
    panelClass.add(m_ClassLabel);
    panelClass.add(m_ClassComboBox);

    JPanel panelButtonsAndClass;
    if (m_showClassComboBox) {
      panelButtonsAndClass = new JPanel(new GridLayout(2, 1));
      panelButtonsAndClass.add(panelButtons);
      panelButtonsAndClass.add(panelClass);
    }
    else {
      panelButtonsAndClass = new JPanel(new GridLayout(1, 1));
      panelButtonsAndClass.add(panelButtons);
    }
   
    m_CloseButPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
    m_CloseButPanel.add(m_CloseBut);
    m_CloseButPanel.setVisible(false);
   
    JPanel panelButtonsAll = new JPanel(new BorderLayout());
    panelButtonsAll.add(panelButtonsAndClass, BorderLayout.CENTER);
    panelButtonsAll.add(m_CloseButPanel, BorderLayout.SOUTH);
   
    setLayout(new BorderLayout());
    add(m_Summary, BorderLayout.CENTER);
    add(panelButtonsAll, BorderLayout.SOUTH);
  }

  /**
   * Sets the frame, this panel resides in. Used for displaying the close
   * button, i.e., the close-button is visible if the given frame is not null.
   * @param parent        the parent frame
   */
  public void setParentFrame(JFrame parent) {
    m_ParentFrame = parent;
    m_CloseButPanel.setVisible(m_ParentFrame != null);
  }
 
  /**
   * Returns the current frame the panel knows of, that it resides in. Can be
   * null.
   * @return the current parent frame
   */
  public JFrame getParentFrame() {
    return m_ParentFrame;
  }

  /**
   * closes the frame, i.e., the visibility is set to false.
   */
  public void closeFrame() {
    if (m_ParentFrame != null)
      m_ParentFrame.setVisible(false);
  }

  /**
   * Queries the user for a file to load instances from, then loads the
   * instances in a background process. This is done in the IO
   * thread, and an error message is popped up if the IO thread is busy.
   */
  public void setInstancesFromFileQ() {
   
    if (m_IOThread == null) {
      int returnVal = m_FileChooser.showOpenDialog(this);
      if (returnVal == JFileChooser.APPROVE_OPTION) {
  final File selected = m_FileChooser.getSelectedFile();
  m_IOThread = new Thread() {
    public void run() {
      setInstancesFromFile(selected);
      m_IOThread = null;
    }
  };
  m_IOThread.setPriority(Thread.MIN_PRIORITY); // UI has most priority
  m_IOThread.start();
      }
    } else {
      JOptionPane.showMessageDialog(this,
            "Can't load at this time,\n"
            + "currently busy with other IO",
            "Load Instances",
            JOptionPane.WARNING_MESSAGE);
    }
  }
   
  /**
   * Queries the user for a URL to load instances from, then loads the
   * instances in a background process. This is done in the IO
   * thread, and an error message is popped up if the IO thread is busy.
   */
  public void setInstancesFromURLQ() {
   
    if (m_IOThread == null) {
      try {
  String urlName = (String) JOptionPane.showInputDialog(this,
      "Enter the source URL",
      "Load Instances",
      JOptionPane.QUESTION_MESSAGE,
      null,
      null,
      m_LastURL);
  if (urlName != null) {
    m_LastURL = urlName;
    final URL url = new URL(urlName);
    m_IOThread = new Thread() {
      public void run() {
        setInstancesFromURL(url);
        m_IOThread = null;
      }
    };
    m_IOThread.setPriority(Thread.MIN_PRIORITY); // UI has most priority
    m_IOThread.start();
  }
      } catch (Exception ex) {
  JOptionPane.showMessageDialog(this,
              "Problem with URL:\n"
              + ex.getMessage(),
              "Load Instances",
              JOptionPane.ERROR_MESSAGE);
      }
    } else {
      JOptionPane.showMessageDialog(this,
            "Can't load at this time,\n"
            + "currently busy with other IO",
            "Load Instances",
            JOptionPane.WARNING_MESSAGE);
    }
  }
 
  /**
   * Loads results from a set of instances contained in the supplied
   * file.
   *
   * @param f a value of type 'File'
   */
  protected void setInstancesFromFile(File f) {
    boolean incremental = m_readIncrementally;
   
    try {
      m_Loader = ConverterUtils.getLoaderForFile(f);
      if (m_Loader == null)
  throw new Exception("No suitable FileSourcedConverter found for file!\n" + f);
     
      // not an incremental loader?
      if (!(m_Loader instanceof IncrementalConverter))
  incremental = false;

      // load
      ((FileSourcedConverter) m_Loader).setFile(f);
      if (incremental) {
        m_Summary.setShowZeroInstancesAsUnknown(m_showZeroInstancesAsUnknown);
  setInstances(m_Loader.getStructure());
      } else {
        // If we are batch loading then we will know for sure that
        // the data has no instances
        m_Summary.setShowZeroInstancesAsUnknown(false);
  setInstances(m_Loader.getDataSet());
      }
    } catch (Exception ex) {
      JOptionPane.showMessageDialog(this,
            "Couldn't read from file:\n"
            + f.getName(),
            "Load Instances",
            JOptionPane.ERROR_MESSAGE);
    }
  }

  /**
   * Loads instances from a URL.
   *
   * @param u the URL to load from.
   */
  protected void setInstancesFromURL(URL u) {
    boolean incremental = m_readIncrementally;
   
    try {
      m_Loader = ConverterUtils.getURLLoaderForFile(u.toString());
      if (m_Loader == null)
  throw new Exception("No suitable URLSourcedLoader found for URL!\n" + u);
     
      // not an incremental loader?
      if (!(m_Loader instanceof IncrementalConverter))
  incremental = false;

      // load
      ((URLSourcedLoader) m_Loader).setURL(u.toString());
      if (incremental) {
        m_Summary.setShowZeroInstancesAsUnknown(m_showZeroInstancesAsUnknown);
  setInstances(m_Loader.getStructure());
      } else {
        m_Summary.setShowZeroInstancesAsUnknown(false);
  setInstances(m_Loader.getDataSet());
      }
    } catch (Exception ex) {
      JOptionPane.showMessageDialog(this,
            "Couldn't read from URL:\n"
            + u,
            "Load Instances",
            JOptionPane.ERROR_MESSAGE);
    }
  }

  /**
   * Updates the set of instances that is currently held by the panel.
   *
   * @param i a value of type 'Instances'
   */
  public void setInstances(Instances i) {

    m_Instances = i;
    m_Summary.setInstances(m_Instances);
   
    if (m_showClassComboBox) {
      DefaultComboBoxModel model = (DefaultComboBoxModel) m_ClassComboBox.getModel();
      model.removeAllElements();
      model.addElement(NO_CLASS);
      for (int n = 0; n < m_Instances.numAttributes(); n++) {
  Attribute att = m_Instances.attribute(n);
  String type = "(" + Attribute.typeToStringShort(att) + ")";
  model.addElement(type + " " + att.name());
      }
      if (m_Instances.classIndex() == -1)
  m_ClassComboBox.setSelectedIndex(m_Instances.numAttributes());
      else
  m_ClassComboBox.setSelectedIndex(m_Instances.classIndex() + 1);   // +1 because of NO_CLASS element
    }
   
    // Fire property change event for those interested.
    m_Support.firePropertyChange("", null, null);
  }

  /**
   * Gets the set of instances currently held by the panel.
   *
   * @return a value of type 'Instances'
   */
  public Instances getInstances() {
   
    return m_Instances;
  }

  /**
   * Returns the currently selected class index.
   *
   * @return    the class index, -1 if none selected
   */
  public int getClassIndex() {
    if (m_ClassComboBox.getSelectedIndex() <= 0)
      return -1;
    else
      return m_ClassComboBox.getSelectedIndex() - 1;
  }
 
  /**
   * Gets the currently used Loader.
   *
   * @return a value of type 'Loader'
   */
  public weka.core.converters.Loader getLoader() {
    return m_Loader;
  }

  /**
   * Gets the instances summary panel associated with
   * this panel.
   *
   * @return the instances summary panel
   */
  public InstancesSummaryPanel getSummary() {
    return m_Summary;
  }

  /**
   * Sets whether or not instances should be read incrementally
   * by the Loader. If incremental reading is used, then
   * the client should obtain the Loader object (by calling
   * getLoader()) and read the instances one at a time. If
   * batch loading is used, then SetInstancesPanel will load
   * the data into memory inside of a separate thread and notify
   * the client when the operation is complete. The client can
   * then retrieve the instances by calling getInstances().
   *
   * @param incremental true if instances are to be read incrementally
   *
   */
  public void setReadIncrementally(boolean incremental) {
    m_readIncrementally = incremental;
  }

  /**
   * Gets whether instances are to be read incrementally or not.
   *
   * @return true if instances are to be read incrementally
   */
  public boolean getReadIncrementally() {
    return m_readIncrementally;
  }
 
  /**
   * Adds a PropertyChangeListener who will be notified of value changes.
   *
   * @param l a value of type 'PropertyChangeListener'
   */
  public void addPropertyChangeListener(PropertyChangeListener l) {
    m_Support.addPropertyChangeListener(l);
  }

  /**
   * Removes a PropertyChangeListener.
   *
   * @param l a value of type 'PropertyChangeListener'
   */
  public void removePropertyChangeListener(PropertyChangeListener l) {
    m_Support.removePropertyChangeListener(l);
  }
}
TOP

Related Classes of weka.gui.SetInstancesPanel

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.