![JAR search and dependency download from the Maven repository](/logo.png)
moa.gui.featureanalysis.VisualizeFeaturesPanel Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of moa Show documentation
Show all versions of moa Show documentation
Massive On-line Analysis is an environment for massive data mining. MOA
provides a framework for data stream mining and includes tools for evaluation
and a collection of machine learning algorithms. Related to the WEKA project,
also written in Java, while scaling to more demanding problems.
The newest version!
/*
* 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 .
*/
/*
* VisualizeFeaturesPanel.java
* Copyright (C) 2003-2020 University of Waikato, Hamilton, New Zealand
*/
package moa.gui.featureanalysis;
import com.yahoo.labs.samoa.instances.Instance;
import com.yahoo.labs.samoa.instances.Instances;
import com.yahoo.labs.samoa.instances.SamoaToWekaInstanceConverter;
import com.yahoo.labs.samoa.instances.WekaToSamoaInstanceConverter;
import moa.streams.ArffFileStream;
import weka.core.*;
import weka.core.converters.AbstractFileSaver;
import weka.filters.AllFilter;
import weka.filters.Filter;
import weka.filters.SupervisedFilter;
import weka.filters.unsupervised.attribute.Remove;
import weka.gui.*;
import weka.gui.explorer.PreprocessPanel;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.filechooser.FileFilter;
import javax.swing.table.TableModel;
import java.awt.*;
import java.awt.event.*;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.File;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
/**
* This is VisualizeFeatures tab main panel which loads data stream and shows other sub panels.
* This panel refers to weka.gui.explorer.PreprocessPanel.
*
* @author Richard Kirkby ([email protected])
* @author Len Trigg ([email protected])
* @author Yongheng Ma ([email protected])
*/
public class VisualizeFeaturesPanel extends AbstractPerspective {
/** for serialization */
private static final long serialVersionUID = 1L;
/** Displays simple stats on the working instances */
protected InstancesSummaryPanel m_InstSummaryPanel =
new InstancesSummaryPanel();
/** Click to load base instances from a file */
protected JButton m_OpenFileBut = new JButton("Open file...");
/** Panel to let the user toggle attributes */
protected AttributeSelectionPanel m_AttPanel = new AttributeSelectionPanel();
/** Button for removing attributes */
protected JButton m_RemoveButton = new JButton("Remove");
/** Click to apply filters and save the results */
protected JButton m_SaveBut = new JButton("Save...");
/** Click to amplify line graph or scatter diagram so that user can see plot more clearly*/
protected JButton m_plotAmplify=new JButton("plotAmplify");
/**The start instance index label to prompt user to input start index number */
protected JLabel m_startIndex = new JLabel("startIndex:");
/**The start instance index label to prompt user to input end index number */
protected JLabel m_endIndex = new JLabel("endIndex:");
/**The start instance index of x axis for line graph or scatter diagram */
protected int m_intStartIndex;
/**The end instance index of x axis for line graph or scatter diagram */
protected int m_intEndIndex;
/**Visualize all line graphs or scatter diagrams, not histograms or bar charts*/
protected JButton m_visAllGraphBut = new JButton("Visualize All");
/**Format m_intStartIndex*/
protected JFormattedTextField m_startInstanceInput=new JFormattedTextField(NumberFormat.getIntegerInstance());
/**Format m_intEndIndex*/
protected JFormattedTextField m_endInstanceInput=new JFormattedTextField(NumberFormat.getIntegerInstance());
/** Displays summary stats on the selected attribute */
protected AttributeSummaryPanel m_AttSummaryPanel =
new AttributeSummaryPanel();
/** The file chooser for selecting data files */
protected ConverterFileChooser m_FileChooser;
/** The working instances */
protected Instances m_Instances;
/** The visualization of the attribute values */
protected AttributeVisualizationPanel m_AttVisualizePanel =
new AttributeVisualizationPanel();
/**
* Manages sending notifications to people when we change the set of working
* instances.
*/
protected PropertyChangeSupport m_Support = new PropertyChangeSupport(this);
/** A thread for loading/saving instances from a file or URL */
protected Thread m_IOThread;
/** The message logger */
protected Logger m_Log = new SysErrLog();
/**Instance converter from Samoa instance to Weak Instance*/
protected SamoaToWekaInstanceConverter m_samoaToWekaInstanceConverter;
/**Instance converter from Weak instance to Samoa Instance*/
protected WekaToSamoaInstanceConverter m_wekaToSamoaInstanceConverter;
/** plot type drop list:
* "plot type: Line graph"
* "plot type: Scatter diagram"
* "No plot type"
*/
protected JComboBox m_plotTypeBox;
/** The index of the selected plot type index*/
protected int m_selectedPlotTypeIndex;
/** Set feature range shown in a popup window
* In default, Nine plots is shown in every popup window at most.
*/
protected JComboBox m_featureRangeBox;
/**
* For line graph or scatter diagram, the default max instance index is 500.
* In other words, the default x axis is from 1 to 500 if the total instance number is bigger than 500,
* or the default x axis is from 1 to numInstance if the total instance number is no more than 500.
* Why: let the graph be more clear.
*/
private static final int m_defaultMaxInstanceIndex=500;
/** This panel is used to draw line graphs or scatter diagrams */
protected LineAndScatterPanel m_graphPanel =new LineAndScatterPanel();
/**This is the FeatureImportance Tab panel */
protected FeatureImportancePanel fip=FeatureImportancePanel.getInstance();
/** For sending instances to various perspectives/tabs */
protected JMenu m_sendToPerspective;
/**
* Creates the instances panel with no initial instances.
*/
public VisualizeFeaturesPanel() {
this.m_samoaToWekaInstanceConverter=new SamoaToWekaInstanceConverter();
this.m_wekaToSamoaInstanceConverter =new WekaToSamoaInstanceConverter();
m_FileChooser = new ConverterFileChooser();
m_FileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
m_OpenFileBut.setToolTipText("Open a set of instances from a file");
m_OpenFileBut.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
setInstancesFromFileQ();
}
});
m_SaveBut.setToolTipText("Save the working relation to a file");
m_SaveBut.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
saveWorkingInstancesToFileQ();
}
});
m_AttPanel.getSelectionModel().addListSelectionListener(
new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
if (!e.getValueIsAdjusting()) {
ListSelectionModel lm = (ListSelectionModel) e.getSource();
for (int i = e.getFirstIndex(); i <= e.getLastIndex(); i++) {
if (lm.isSelectedIndex(i)) {
m_AttSummaryPanel.setAttribute(i);
m_AttVisualizePanel.setAttribute(i);
break;
}
}
}
}
});
m_InstSummaryPanel.setBorder(BorderFactory
.createTitledBorder("Current relation"));
JPanel attStuffHolderPanel = new JPanel();
attStuffHolderPanel.setBorder(BorderFactory
.createTitledBorder("Attributes"));
attStuffHolderPanel.setLayout(new BorderLayout());
attStuffHolderPanel.add(m_AttPanel, BorderLayout.CENTER);
m_RemoveButton.setEnabled(false);
m_RemoveButton.setToolTipText("Remove selected attributes.");
m_RemoveButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
Remove r = new Remove();
int[] selected = m_AttPanel.getSelectedAttributes();
if (selected.length == 0) {
return;
}
/** SamoaToWekaInstanceConverter.wekaInstances() method does not support class attribute**/
for(int i=0; i=m_Instances.numInstances()) {
m_startInstanceInput.setValue(1);
Toolkit.getDefaultToolkit().beep();
JOptionPane.showMessageDialog(m_startInstanceInput.getParent(), "The instance start index must be positive integer, \n" +
"more than 0 and less than total instance number!",
"Instance startIndex input error prompt!",JOptionPane.WARNING_MESSAGE);
}
}
} catch (ParseException parseException) {
Toolkit.getDefaultToolkit().beep();
JOptionPane.showMessageDialog(m_startInstanceInput.getParent(), "The instance start index must be positive integer, \n" +
"more than 0 and less than total instance number!",
"Instance startIndex input error prompt!",JOptionPane.WARNING_MESSAGE);
}
}
});
m_endInstanceInput.addFocusListener(new FocusAdapter() {
@Override
public void focusLost(FocusEvent e) {
super.focusLost(e);
if(m_Instances!=null){
int numInst=m_Instances.numInstances();
try {
m_endInstanceInput.commitEdit();
Object o= m_endInstanceInput.getValue();
if(o==null){
m_endInstanceInput.setValue(numInst);//Default is set so this could not happen.
}else {
int inputInt = Integer.parseInt(o.toString());
/**
* m_intEndIndex range: [2, numInstance]
*/
if (inputInt < 2 || inputInt > numInst) {
//set default endIndex
if(numInst<=m_defaultMaxInstanceIndex){
if(numInst<=m_defaultMaxInstanceIndex){
m_endInstanceInput.setValue(numInst);
}else if(numInst>m_defaultMaxInstanceIndex){
m_endInstanceInput.setValue(m_defaultMaxInstanceIndex);
}
}
//warning
Toolkit.getDefaultToolkit().beep();
JOptionPane.showMessageDialog(m_endInstanceInput.getParent(), "The instance end index must be positive integer, \n" +
"more than 1 and not more than total instance number \""+numInst+"\"!",
"Instance startIndex input error prompt!",JOptionPane.WARNING_MESSAGE);
}
}
} catch (ParseException parseException) {
Toolkit.getDefaultToolkit().beep();
JOptionPane.showMessageDialog(m_endInstanceInput.getParent(), "The instance end index must be positive integer, \n" +
"more than 1 and not more than total instance number \""+numInst+"\"!",
"Instance startIndex input error prompt!",JOptionPane.WARNING_MESSAGE);
}
}
}
});
/**
* start index must be positive integer, bigger than 0 and less than instance number.
* numInstance>startIndex>=1
*/
m_startInstanceInput.setToolTipText("Start index must be positive integer, bigger than 0 and less than instance number!");
/**
* numInstance=>endIndex>1
*/
m_endInstanceInput.setToolTipText("End index must be positive integer, bigger than 1 and no than instance number!");
m_plotTypeBox.setEditable(false);
m_plotTypeBox.setToolTipText("The chosen item will determine the feature plot type.");
m_plotTypeBox.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
if(e.getStateChange() == ItemEvent.SELECTED){
if(colorBox.getSelectedItem()!=null){
if(m_Instances!=null){
Object objectStartInstanceInput=m_startInstanceInput.getValue();
Object objectEndInstanceInput=m_endInstanceInput.getValue();
m_intStartIndex=Integer.parseInt(objectStartInstanceInput.toString());
m_intEndIndex=Integer.parseInt(objectEndInstanceInput.toString());
if(m_intEndIndex>m_intStartIndex){
m_graphPanel.setIntStartIndex(m_intStartIndex);
m_graphPanel.setIntEndIndex(m_intEndIndex);
m_selectedPlotTypeIndex=m_plotTypeBox.getSelectedIndex();
String selectedPlotItem=m_plotTypeBox.getSelectedItem().toString();
if(selectedPlotItem.equalsIgnoreCase("No plot type")){
m_plotAmplify.setEnabled(false);
m_visAllGraphBut.setEnabled(false);
}else{
m_plotAmplify.setEnabled(true);
m_visAllGraphBut.setEnabled(true);
}
String attributeName=colorBox.getSelectedItem().toString();
int attributeIndex=colorBox.getSelectedIndex();
if(attributeIndex==0){//
/**
* if the class is "no class",set the first class whose index is 0 as default class index.
*/
m_graphPanel.setSelectedPlotInfo(m_selectedPlotTypeIndex,selectedPlotItem,0,colorBox.getItemAt(1).toString());
}else{
m_graphPanel.setSelectedPlotInfo(m_selectedPlotTypeIndex,selectedPlotItem,attributeIndex-1,attributeName);
}
}else{
Toolkit.getDefaultToolkit().beep();
JOptionPane.showMessageDialog(m_plotTypeBox.getParent(), "EndIndex must be bigger than StartIndex",
"Instance index range error prompt!",JOptionPane.WARNING_MESSAGE);
}
}
}
}
}
});
final JButton visAllBut = new JButton("Visualize All");
visAllBut.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
if (m_Instances != null) {
try {
final weka.gui.beans.AttributeSummarizer as =
new weka.gui.beans.AttributeSummarizer();
as.setColoringIndex(m_AttVisualizePanel.getColoringIndex());
as.setInstances(m_samoaToWekaInstanceConverter.wekaInstances(m_Instances));
final JFrame jf = Utils.getWekaJFrame("All attributes", VisualizeFeaturesPanel.this);
jf.getContentPane().setLayout(new BorderLayout());
jf.getContentPane().add(as, BorderLayout.CENTER);
jf.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
visAllBut.setEnabled(true);
jf.dispose();
}
});
jf.pack();
jf.setSize(1000, 600);
jf.setLocationRelativeTo(SwingUtilities.getWindowAncestor(VisualizeFeaturesPanel.this));
jf.setVisible(true);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
});
m_plotAmplify.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if(m_Instances!=null){
int numIns=m_Instances.numInstances();
Object objectStartInstanceInput=m_startInstanceInput.getValue();
Object objectEndInstanceInput=m_endInstanceInput.getValue();
m_intStartIndex=Integer.parseInt(objectStartInstanceInput.toString());
m_intEndIndex=Integer.parseInt(objectEndInstanceInput.toString());
if(m_intEndIndex>m_intStartIndex){
m_graphPanel.setIntStartIndex(m_intStartIndex);
m_graphPanel.setIntEndIndex(m_intEndIndex);
m_graphPanel.paintAmplifiedPlot();
}else{
Toolkit.getDefaultToolkit().beep();
JOptionPane.showMessageDialog(m_plotAmplify.getParent(), "EndIndex must be bigger than StartIndex",
"Instance index range error prompt!",JOptionPane.WARNING_MESSAGE);
}
}
}
});
m_visAllGraphBut.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if(m_Instances!=null){
Object objectStartInstanceInput=m_startInstanceInput.getValue();
Object objectEndInstanceInput=m_endInstanceInput.getValue();
m_intStartIndex=Integer.parseInt(objectStartInstanceInput.toString());
m_intEndIndex=Integer.parseInt(objectEndInstanceInput.toString());
if(m_intEndIndex>m_intStartIndex){
m_graphPanel.visualizeAll();
}else{
Toolkit.getDefaultToolkit().beep();
JOptionPane.showMessageDialog(m_visAllGraphBut.getParent(), "EndIndex must be bigger than StartIndex",
"Instance index range error prompt!",JOptionPane.WARNING_MESSAGE);
}
}
}
});
/** Histogram includes "dropdown List","visualize all button" and AttVisualizePanel */
JPanel histoHolder = new JPanel();
JPanel histoControls = new JPanel();
histoControls.setLayout(new BorderLayout());
histoControls.add(colorBox, BorderLayout.CENTER);//dropdown List
histoControls.add(visAllBut, BorderLayout.EAST);//visualize all button
histoHolder.setLayout(new BorderLayout());
histoHolder.add(histoControls, BorderLayout.NORTH);
histoHolder.add(m_AttVisualizePanel, BorderLayout.CENTER);
attVis.add(histoHolder);
JPanel lineScatterController = new JPanel();
//lineScatterController.setLayout(new FlowLayout());
/** BoxLayout is better than lowLayout on linux machine. */
lineScatterController.setLayout(new BoxLayout(lineScatterController,BoxLayout.X_AXIS));
lineScatterController.add(m_startIndex);
m_startInstanceInput.setPreferredSize(new Dimension(80, 18));
lineScatterController.add(m_startInstanceInput);
lineScatterController.add(m_endIndex);
m_endInstanceInput.setPreferredSize(new Dimension(80, 18));
lineScatterController.add(m_endInstanceInput);
lineScatterController.add(m_plotTypeBox);
JPanel lineScatterHolder = new JPanel();
lineScatterHolder.setLayout(new BorderLayout());
lineScatterHolder.add(lineScatterController, BorderLayout.NORTH);
lineScatterHolder.add(m_graphPanel, BorderLayout.CENTER);
JPanel graphButtonPanel=new JPanel();
graphButtonPanel.setLayout(new FlowLayout());
graphButtonPanel.add(m_plotAmplify);
m_featureRangeBox=new JComboBox();
graphButtonPanel.add(m_featureRangeBox);
m_featureRangeBox.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
if(e.getStateChange() == ItemEvent.SELECTED){
m_graphPanel.setFeatureRange(e.getItem().toString());
}
}
});
graphButtonPanel.add(m_visAllGraphBut);
lineScatterHolder.add(graphButtonPanel,BorderLayout.SOUTH);
attVis.add(lineScatterHolder);
JPanel lhs = new JPanel();//left
lhs.setLayout(new BorderLayout());
lhs.add(m_InstSummaryPanel, BorderLayout.NORTH);
lhs.add(attInfo, BorderLayout.CENTER);
JPanel rhs = new JPanel();//right
rhs.setLayout(new BorderLayout());
rhs.add(attVis, BorderLayout.CENTER);
JPanel relation = new JPanel();
relation.setLayout(new GridLayout(1, 2));
relation.add(lhs);
relation.add(rhs);
JPanel middle = new JPanel();
middle.setLayout(new BorderLayout());
middle.add(relation, BorderLayout.CENTER);
LogPanel lp = new LogPanel();//Log + Status
this.setLog(lp);
setLayout(new BorderLayout());
add(buttons, BorderLayout.NORTH);
add(middle, BorderLayout.CENTER);
//add(lp,BorderLayout.SOUTH);
}
public boolean startIndexValidation(int startIndex){
if(startIndex>=1){
return true;
}else{
JOptionPane.showMessageDialog(this, "The instance start index must be integer and not less than 1:\n"
, "Instance Index", JOptionPane.ERROR_MESSAGE);
return false;
}
}
public boolean endIndexValidation(int endIndex){
if(endIndex<=m_Instances.numInstances()){
return true;
}else{
JOptionPane.showMessageDialog(this, "The instance end index must be integer and not bigger than \""+m_Instances.numInstances() + "\""
, "Instance Index", JOptionPane.ERROR_MESSAGE);
return false;
}
}
/**
* Sets the Logger to receive informational messages
*
* @param newLog the Logger that will now get info messages
*/
public void setLog(Logger newLog) {
m_Log = newLog;
}
/**
* Tells the panel to use a new base set of instances.
*
* @param inst a set of Instances
*/
public void setInstances(Instances inst) {
m_Instances = inst;
try {
Runnable r = new Runnable() {
public void run() {
boolean first = (m_AttPanel.getTableModel() == null);
m_graphPanel.setInstances(m_Instances);
/**
* When new data is loaded, set default value for m_intStartIndex and m_intEndIndex
*/
if(m_Instances!=null){
/** set default startIndex, endIndex */
m_startInstanceInput.setValue(1);
/** set default endIndex */
int numInstances=m_Instances.numInstances();
if(numInstances<=m_defaultMaxInstanceIndex){
m_endInstanceInput.setValue(numInstances);
m_graphPanel.setIntEndIndex(numInstances);
}else{
m_endInstanceInput.setValue(m_defaultMaxInstanceIndex);
m_graphPanel.setIntEndIndex(m_defaultMaxInstanceIndex);
}
}
/** The suggested best set for maxPlotsNumberInOneScreen is 9 for 3 rows * 3 columns plots. */
int maxPlotsNumberInOneScreen=9;//
if(m_Instances!=null && m_Instances.numAttributes()>0){
m_featureRangeBox.removeAllItems();//when user changes dataset, this code will be used.
featureRangeBoxSet(m_Instances.numAttributes(),maxPlotsNumberInOneScreen);
}
m_InstSummaryPanel.setInstances(m_Instances);
m_AttPanel.setInstances(m_Instances);
if (first) {
TableModel model = m_AttPanel.getTableModel();
model.addTableModelListener(new TableModelListener() {
public void tableChanged(TableModelEvent e) {
if (m_AttPanel.getSelectedAttributes() != null
&& m_AttPanel.getSelectedAttributes().length > 0) {
m_RemoveButton.setEnabled(true);
} else {
m_RemoveButton.setEnabled(false);
}
}
});
}
m_AttSummaryPanel.setInstances(m_Instances);
m_AttVisualizePanel.setInstances(m_samoaToWekaInstanceConverter.wekaInstances(m_Instances));
/** select the first attribute in the list */
m_AttPanel.getSelectionModel().setSelectionInterval(0, 0);
m_AttSummaryPanel.setAttribute(0);
m_AttVisualizePanel.setAttribute(0);
/**
* The default selected item of component colorBox in this class is the class attribute,
* so the default attribute shown in scatter diagram is the class attribute too.
* In other words, the initial attribute shown in histogram and scatter diagram both is the class attribute
* which is always the last attribute in a dataset.
*/
m_graphPanel.setAttributeIndex(m_Instances.classIndex());
m_Log.logMessage("Base relation is now " + m_Instances.getRelationName()
+ " (" + m_Instances.numInstances() + " instances)");
m_SaveBut.setEnabled(true);
m_Log.statusMessage("OK");
// Fire a propertychange event
m_Support.firePropertyChange("", null, null);
fip.setInstances(m_Instances);
}
};
if (SwingUtilities.isEventDispatchThread()) {
r.run();
} else {
SwingUtilities.invokeAndWait(r);
}
} catch (Exception ex) {
ex.printStackTrace();
JOptionPane.showMessageDialog(this, "Problem setting base instances:\n"
+ ex, "Instances", JOptionPane.ERROR_MESSAGE);
}
}
public void featureRangeBoxSet(int numAttributes,int maxFeaturesInOneScreen){
if(numAttributes>=maxFeaturesInOneScreen){
int itemNum= (int) Math.ceil(numAttributes/maxFeaturesInOneScreen);
int remainder=numAttributes % maxFeaturesInOneScreen;
for(int i=0; i0 && remainder==1 ){
m_featureRangeBox.addItem("feature range: "+(itemNum * maxFeaturesInOneScreen+1));
}else if(remainder>1){
m_featureRangeBox.addItem("feature range: "+(itemNum * maxFeaturesInOneScreen+1)+ " -- " + (itemNum * maxFeaturesInOneScreen+remainder));
}
}else if(numAttributes1){
/** Then number of attributes is more than 1 but less than max features whose plots are shown in "visualizeAll" screen.*/
m_featureRangeBox.addItem("feature range: "+1+ " -- " + numAttributes);
}else if(numAttributes==1){
/** There is only one attribute in the dataset */
m_featureRangeBox.addItem("feature range: "+1);
}
}
/**
* Gets the working set of instances.
*
* @return the working instances
*/
public Instances getInstances() {
return m_Instances;
}
/**
* Adds a PropertyChangeListener who will be notified of value changes.
*
* @param l a value of type 'PropertyChangeListener'
*/
@Override
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'
*/
@Override
public void removePropertyChangeListener(PropertyChangeListener l) {
if (m_Support != null && l != null) {
m_Support.removePropertyChangeListener(l);
}
}
/**
* Passes the dataset through the filter that has been configured for use.
*
* @param filter the filter to apply
*/
protected void applyFilter(final Filter filter) {
if (m_IOThread == null) {
m_IOThread = new Thread() {
@Override
public void run() {
try {
if (filter != null) {
if (m_Log instanceof TaskLogger) {
((TaskLogger) m_Log).taskStarted();
}
m_Log.statusMessage("Passing dataset through filter "
+ filter.getClass().getName());
String cmd = filter.getClass().getName();
if (filter instanceof OptionHandler)
cmd +=
" "
+ Utils.joinOptions(((OptionHandler) filter).getOptions());
m_Log.logMessage("Command: " + cmd);
int classIndex = m_AttVisualizePanel.getColoringIndex();
if ((classIndex < 0) && (filter instanceof SupervisedFilter)) {
throw new IllegalArgumentException("Class (colour) needs to "
+ "be set for supervised " + "filter.");
}
Instances copy = new Instances(m_Instances);
copy.setClassIndex(classIndex);
Filter filterCopy = Filter.makeCopy(filter);
weka.core.Instances copyToWeka=m_samoaToWekaInstanceConverter.wekaInstances(copy) ;
filterCopy.setInputFormat(copyToWeka);
weka.core.Instances newInstances = Filter.useFilter(copyToWeka, filterCopy);
if (newInstances == null || newInstances.numAttributes() < 1) {
throw new Exception("Dataset is empty.");
}
m_Log.statusMessage("Saving undo information");
int debugClassIndex=copy.classIndex();
int debugClassIndex2=copyToWeka.classIndex();
m_AttVisualizePanel.setColoringIndex(copy.classIndex());
// if class was not set before, reset it again after use of filter
/* if (m_Instances.classIndex() < 0)
newInstances.setClassIndex(-1); */
m_Instances = m_wekaToSamoaInstanceConverter.samoaInstances(newInstances);
setInstances(m_Instances);
if (m_Log instanceof TaskLogger) {
((TaskLogger) m_Log).taskFinished();
}
}
} catch (Exception ex) {
if (m_Log instanceof TaskLogger) {
((TaskLogger) m_Log).taskFinished();
}
// Pop up an error optionpane
JOptionPane.showMessageDialog(VisualizeFeaturesPanel.this,
"Problem filtering instances:\n" + ex.getMessage(),
"Apply Filter", JOptionPane.ERROR_MESSAGE);
m_Log.logMessage("Problem filtering instances: " + ex.getMessage());
m_Log.statusMessage("Problem filtering instances");
ex.printStackTrace();
}
m_IOThread = null;
}
};
m_IOThread.setPriority(Thread.MIN_PRIORITY); // UI has most priority
m_IOThread.start();
} else {
JOptionPane.showMessageDialog(this, "Can't apply filter at this time,\n"
+ "currently busy with other IO", "Apply Filter",
JOptionPane.WARNING_MESSAGE);
}
}
/**
* 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) {
if (m_FileChooser.getLoader() == null) {
JOptionPane.showMessageDialog(this,
"Cannot determine file loader automatically, please choose one.",
"Load Instances", JOptionPane.ERROR_MESSAGE);
} else {
setInstancesFromFile2(m_FileChooser.getSelectedFile().toString());
}
}
} else {
JOptionPane.showMessageDialog(this, "Can't load at this time,\n"
+ "currently busy with other IO", "Load Instances",
JOptionPane.WARNING_MESSAGE);
}
}
public void setInstancesFromFile2(String selectedFile) {
if (m_IOThread == null) {
m_IOThread = new Thread() {
@Override
public void run() {
try {
m_Log.statusMessage("Reading from file...");
ArffFileStream afs=new ArffFileStream(selectedFile,-1);
Instance instance=null;
java.io.Reader reader = new java.io.BufferedReader(new java.io.FileReader(selectedFile));
Instances insts=new Instances(reader,1,-1);//parameter size is not used.
while(afs.hasMoreInstances()){
instance=afs.nextInstance().getData();
insts.add(instance);
}
setInstances(insts);
} catch (Exception ex) {
}
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 file to save instances as, then saves 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 saveWorkingInstancesToFileQ() {
if (m_IOThread == null) {
m_FileChooser.setAcceptAllFileFilterUsed(false);
int returnVal = m_FileChooser.showSaveDialog(this);
if (returnVal == JFileChooser.APPROVE_OPTION) {
weka.core.Instances inst=m_samoaToWekaInstanceConverter.wekaInstances(m_Instances) ;
inst.setClassIndex(m_AttVisualizePanel.getColoringIndex());
saveInstancesToFile(m_FileChooser.getSaver(), inst);
}
FileFilter temp = m_FileChooser.getFileFilter();
m_FileChooser.setAcceptAllFileFilterUsed(true);
m_FileChooser.setFileFilter(temp);
} else {
JOptionPane.showMessageDialog(this, "Can't save at this time,\n"
+ "currently busy with other IO", "Save Instances",
JOptionPane.WARNING_MESSAGE);
}
}
/**
* saves the data with the specified saver
*
* @param saver the saver to use for storing the data
* @param inst the data to save
*/
public void saveInstancesToFile(final AbstractFileSaver saver,
final weka.core.Instances inst) {
if (m_IOThread == null) {
m_IOThread = new Thread() {
@Override
public void run() {
try {
m_Log.statusMessage("Saving to file...");
saver.setInstances(inst);
saver.writeBatch();
m_Log.statusMessage("OK");
} catch (Exception ex) {
ex.printStackTrace();
m_Log.logMessage(ex.getMessage());
}
m_IOThread = null;
}
};
m_IOThread.setPriority(Thread.MIN_PRIORITY); // UI has most priority
m_IOThread.start();
} else {
JOptionPane.showMessageDialog(this, "Can't save at this time,\n"
+ "currently busy with other IO", "Saving instances",
JOptionPane.WARNING_MESSAGE);
}
}
/**
* We've been instantiated and now have access to the main application and
* PerspectiveManager
*/
@Override
public void instantiationComplete() {
// overridden here so that we know if we're operating within
// a non-legacy UI, and can thus set up our send data to perspective
// menu (if necessary)
boolean sendToAll =
getMainApplication().getApplicationSettings().getSetting(
getPerspectiveID(),
PreprocessPanel.PreprocessDefaults.ALWAYS_SEND_INSTANCES_TO_ALL_KEY,
PreprocessPanel.PreprocessDefaults.ALWAYS_SEND_INSTANCES_TO_ALL,
Environment.getSystemWide());
// install a menu item to allow the user to choose to send to all or
// send to a specific perspective
final List perspectivesThatAcceptInstances =
new ArrayList();
List visiblePerspectives =
getMainApplication().getPerspectiveManager().getVisiblePerspectives();
for (Perspective p : visiblePerspectives) {
if (p.acceptsInstances()
&& !p.getPerspectiveID().equals(getPerspectiveID())) {
perspectivesThatAcceptInstances.add(p);
}
}
if (perspectivesThatAcceptInstances.size() > 0) {
m_sendToPerspective = new JMenu();
m_sendToPerspective.setText("Send to perspective");
if (!sendToAll) {
m_sendToPerspective.setEnabled(false);
}
JMenuItem sendToAllItem = new JMenuItem("All perspectives");
sendToAllItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
for (Perspective p : perspectivesThatAcceptInstances) {
if (getInstances() != null && p.acceptsInstances()) {
p.setInstances(m_samoaToWekaInstanceConverter.wekaInstances(getInstances()));
getMainApplication().getPerspectiveManager()
.setEnablePerspectiveTab(p.getPerspectiveID(), true);
}
}
}
});
m_sendToPerspective.add(sendToAllItem);
for (final Perspective p : perspectivesThatAcceptInstances) {
JMenuItem item = new JMenuItem(p.getPerspectiveTitle());
m_sendToPerspective.add(item);
item.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (getInstances() != null) {
p.setInstances(m_samoaToWekaInstanceConverter.wekaInstances(getInstances()));
getMainApplication().getPerspectiveManager()
.setEnablePerspectiveTab(p.getPerspectiveID(), true);
getMainApplication().getPerspectiveManager()
.setActivePerspective(p.getPerspectiveID());
}
}
});
}
}
}
public static class PreprocessDefaults extends Defaults {
public static final String ID = "weka.gui.explorer.preprocesspanel";
public static final Settings.SettingKey INITIAL_DIR_KEY =
new Settings.SettingKey(ID + ".initialDir",
"Initial directory for opening datasets", "");
public static final File INITIAL_DIR = new File("${user.dir}");
public static final Settings.SettingKey UNDO_DIR_KEY =
new Settings.SettingKey(ID + ".undoDir",
"Directory for storing undo files", "");
public static final File UNDO_DIR = new File("${java.io.tmpdir}");
public static final Settings.SettingKey FILTER_KEY =
new Settings.SettingKey(ID + ".initialFilter", "Initial filter", "");
public static final Filter FILTER = new AllFilter();
public static final Settings.SettingKey ENABLE_UNDO_KEY =
new Settings.SettingKey(ID + ".enableUndo", "Enable undo", "");
public static final Boolean ENABLE_UNDO = true;
public static final Settings.SettingKey ALWAYS_SEND_INSTANCES_TO_ALL_KEY =
new Settings.SettingKey(ID + ".alwaysSendInstancesToAllPerspectives",
"Always send instances to all perspectives", "");
public static boolean ALWAYS_SEND_INSTANCES_TO_ALL = true;
public PreprocessDefaults() {
super(ID);
INITIAL_DIR_KEY.setMetadataElement("java.io.File.fileSelectionMode", ""
+ JFileChooser.DIRECTORIES_ONLY);
INITIAL_DIR_KEY.setMetadataElement("java.io.File.dialogType", ""
+ JFileChooser.OPEN_DIALOG);
UNDO_DIR_KEY.setMetadataElement("java.io.File.fileSelectionMode", ""
+ JFileChooser.DIRECTORIES_ONLY);
UNDO_DIR_KEY.setMetadataElement("java.io.File.dialogType", ""
+ JFileChooser.DIRECTORIES_ONLY);
m_defaults.put(INITIAL_DIR_KEY, INITIAL_DIR);
m_defaults.put(UNDO_DIR_KEY, UNDO_DIR);
m_defaults.put(FILTER_KEY, FILTER);
m_defaults.put(ENABLE_UNDO_KEY, ENABLE_UNDO);
m_defaults.put(ALWAYS_SEND_INSTANCES_TO_ALL_KEY,
ALWAYS_SEND_INSTANCES_TO_ALL);
}
}
/**
* Tests out the instance-preprocessing panel from the command line.
*
* @param args ignored
*/
public static void main(String[] args) {
try {
final JFrame jf = new JFrame("MOA: Data Analysis");
jf.getContentPane().setLayout(new BorderLayout());
final VisualizeFeaturesPanel sp = new VisualizeFeaturesPanel();
jf.getContentPane().add(sp, BorderLayout.CENTER);
LogPanel lp = new LogPanel();
sp.setLog(lp);
jf.getContentPane().add(lp, BorderLayout.SOUTH);
jf.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
jf.dispose();
System.exit(0);
}
});
jf.pack();
jf.setSize(800, 600);
jf.setVisible(true);
} catch (Exception ex) {
ex.printStackTrace();
System.err.println(ex.getMessage());
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy