weka.gui.AttributeSelectionPanel Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of weka-stable Show documentation
Show all versions of weka-stable Show documentation
The Waikato Environment for Knowledge Analysis (WEKA), a machine
learning workbench. This is the stable version. Apart from bugfixes, this version
does not receive any other updates.
/*
* 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.
*/
/*
* AttributeSelectionPanel.java
* Copyright (C) 1999 University of Waikato, Hamilton, New Zealand
*
*/
package weka.gui;
import weka.core.Instances;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.BorderLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.util.regex.Pattern;
import javax.swing.JPanel;
import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.JTable;
import javax.swing.JScrollPane;
import javax.swing.ListSelectionModel;
import javax.swing.table.TableColumnModel;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableModel;
import javax.swing.BorderFactory;
/**
* Creates a panel that displays the attributes contained in a set of
* instances, letting the user toggle whether each attribute is selected
* or not (eg: so that unselected attributes can be removed before
* classification).
* Besides the All, None and Invert button one can also choose attributes which
* names match a regular expression (Pattern button). E.g. for removing all
* attributes that contain an ID and therefore unwanted information, one can
* match all names that contain "id" in the name:
* (.*_id_.*|.*_id$|^id$)
* This does not match e.g. "humidity", which could be an attribute we would
* like to keep.
*
* @author Len Trigg ([email protected])
* @author FracPete (fracpete at waikato dot ac dot nz)
* @version $Revision: 7059 $
*/
public class AttributeSelectionPanel
extends JPanel {
/** for serialization */
private static final long serialVersionUID = 627131485290359194L;
/**
* A table model that looks at the names of attributes and maintains
* a list of attributes that have been "selected".
*/
class AttributeTableModel
extends AbstractTableModel {
/** for serialization */
private static final long serialVersionUID = -4152987434024338064L;
/** The instances who's attribute structure we are reporting */
protected Instances m_Instances;
/** The flag for whether the instance will be included */
protected boolean [] m_Selected;
/**
* Creates the tablemodel with the given set of instances.
*
* @param instances the initial set of Instances
*/
public AttributeTableModel(Instances instances) {
setInstances(instances);
}
/**
* Sets the tablemodel to look at a new set of instances.
*
* @param instances the new set of Instances.
*/
public void setInstances(Instances instances) {
m_Instances = instances;
m_Selected = new boolean [m_Instances.numAttributes()];
}
/**
* Gets the number of attributes.
*
* @return the number of attributes.
*/
public int getRowCount() {
return m_Selected.length;
}
/**
* Gets the number of columns: 3
*
* @return 3
*/
public int getColumnCount() {
return 3;
}
/**
* Gets a table cell
*
* @param row the row index
* @param column the column index
* @return the value at row, column
*/
public Object getValueAt(int row, int column) {
switch (column) {
case 0:
return new Integer(row + 1);
case 1:
return new Boolean(m_Selected[row]);
case 2:
return m_Instances.attribute(row).name();
default:
return null;
}
}
/**
* Gets the name for a column.
*
* @param column the column index.
* @return the name of the column.
*/
public String getColumnName(int column) {
switch (column) {
case 0:
return new String(Messages.getInstance().getString("AttributeSelectionPanel_GetColumnName_Text_First"));
case 1:
return new String(Messages.getInstance().getString("AttributeSelectionPanel_GetColumnName_Text_Second"));
case 2:
return new String(Messages.getInstance().getString("AttributeSelectionPanel_GetColumnName_Text_Third"));
default:
return null;
}
}
/**
* Sets the value at a cell.
*
* @param value the new value.
* @param row the row index.
* @param col the column index.
*/
public void setValueAt(Object value, int row, int col) {
if (col == 1) {
m_Selected[row] = ((Boolean) value).booleanValue();
fireTableRowsUpdated(0, m_Selected.length);
}
}
/**
* Gets the class of elements in a column.
*
* @param col the column index.
* @return the class of elements in the column.
*/
public Class getColumnClass(int col) {
return getValueAt(0, col).getClass();
}
/**
* Returns true if the column is the "selected" column.
*
* @param row ignored
* @param col the column index.
* @return true if col == 1.
*/
public boolean isCellEditable(int row, int col) {
if (col == 1) {
return true;
}
return false;
}
/**
* Gets an array containing the indices of all selected attributes.
*
* @return the array of selected indices.
*/
public int [] getSelectedAttributes() {
int [] r1 = new int[getRowCount()];
int selCount = 0;
for (int i = 0; i < getRowCount(); i++) {
if (m_Selected[i]) {
r1[selCount++] = i;
}
}
int [] result = new int[selCount];
System.arraycopy(r1, 0, result, 0, selCount);
return result;
}
/**
* Sets the state of all attributes to selected.
*/
public void includeAll() {
for (int i = 0; i < m_Selected.length; i++) {
m_Selected[i] = true;
}
fireTableRowsUpdated(0, m_Selected.length);
}
/**
* Deselects all attributes.
*/
public void removeAll() {
for (int i = 0; i < m_Selected.length; i++) {
m_Selected[i] = false;
}
fireTableRowsUpdated(0, m_Selected.length);
}
/**
* Inverts the selected status of each attribute.
*/
public void invert() {
for (int i = 0; i < m_Selected.length; i++) {
m_Selected[i] = !m_Selected[i];
}
fireTableRowsUpdated(0, m_Selected.length);
}
/**
* applies the perl regular expression pattern to select the attribute
* names (expects a valid reg expression!)
* @param pattern a perl reg. expression
*/
public void pattern(String pattern) {
for (int i = 0; i < m_Selected.length; i++)
m_Selected[i] = Pattern.matches(
pattern, m_Instances.attribute(i).name());
fireTableRowsUpdated(0, m_Selected.length);
}
public void setSelectedAttributes(boolean [] selected) throws Exception {
if (selected.length != m_Selected.length) {
throw new Exception("Supplied array does not have the same number " +
"of elements as there are attributes!");
}
for (int i = 0; i < selected.length; i++) {
m_Selected[i] = selected[i];
}
fireTableRowsUpdated(0, m_Selected.length);
}
}
/** Press to select all attributes */
protected JButton m_IncludeAll = new JButton(Messages.getInstance().getString("AttributeSelectionPanel_IncludeAll_JButton_Text"));
/** Press to deselect all attributes */
protected JButton m_RemoveAll = new JButton(Messages.getInstance().getString("AttributeSelectionPanel_RemoveAll_JButton_Text"));
/** Press to invert the current selection */
protected JButton m_Invert = new JButton(Messages.getInstance().getString("AttributeSelectionPanel_Invert_JButton_Text"));
/** Press to enter a perl regular expression for selection */
protected JButton m_Pattern = new JButton(Messages.getInstance().getString("AttributeSelectionPanel_Pattern_JButton_Text"));
/** The table displaying attribute names and selection status */
protected JTable m_Table = new JTable();
/** The table model containing attribute names and selection status */
protected AttributeTableModel m_Model;
/** The current regular expression. */
protected String m_PatternRegEx = "";
/**
* Creates the attribute selection panel with no initial instances.
*/
public AttributeSelectionPanel() {
this(true, true, true, true);
}
/**
* Creates the attribute selection panel with no initial instances.
* @param include true if the include button is to be shown
* @param remove true if the remove button is to be shown
* @param invert true if the invert button is to be shown
* @param patter true if the pattern button is to be shown
*/
public AttributeSelectionPanel(boolean include, boolean remove, boolean invert,
boolean pattern) {
m_IncludeAll.setToolTipText(Messages.getInstance().getString("AttributeSelectionPanel_IncludeAll_SetToolTipText_Text"));
m_IncludeAll.setEnabled(false);
m_IncludeAll.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
m_Model.includeAll();
}
});
m_RemoveAll.setToolTipText(Messages.getInstance().getString("AttributeSelectionPanel_RemoveAll_SetToolTipText_Text"));
m_RemoveAll.setEnabled(false);
m_RemoveAll.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
m_Model.removeAll();
}
});
m_Invert.setToolTipText(Messages.getInstance().getString("AttributeSelectionPanel_Invert_SetToolTipText_Text"));
m_Invert.setEnabled(false);
m_Invert.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
m_Model.invert();
}
});
m_Pattern.setToolTipText(Messages.getInstance().getString("AttributeSelectionPanel_Pattern_SetToolTipText_Text"));
m_Pattern.setEnabled(false);
m_Pattern.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String pattern = JOptionPane.showInputDialog(
m_Pattern.getParent(),
Messages.getInstance().getString("AttributeSelectionPanel_Pattern_JOptionPaneShowInputDialog_Text"),
m_PatternRegEx);
if (pattern != null) {
try {
Pattern.compile(pattern);
m_PatternRegEx = pattern;
m_Model.pattern(pattern);
}
catch (Exception ex) {
JOptionPane.showMessageDialog(
m_Pattern.getParent(),
Messages.getInstance().getString("AttributeSelectionPanel_Exception_JOptionPaneShowMessageDialog_Text_First") + pattern + Messages.getInstance().getString("AttributeSelectionPanel_Exception_JOptionPaneShowMessageDialog_Text_Second") + ex,
Messages.getInstance().getString("AttributeSelectionPanel_Exception_JOptionPaneShowMessageDialog_Text_Third"),
JOptionPane.ERROR_MESSAGE);
}
}
}
});
m_Table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
m_Table.setColumnSelectionAllowed(false);
m_Table.setPreferredScrollableViewportSize(new Dimension(250, 150));
// Set up the layout
JPanel p1 = new JPanel();
p1.setBorder(BorderFactory.createEmptyBorder(10, 5, 10, 5));
p1.setLayout(new GridLayout(1, 4, 5, 5));
if (include) {
p1.add(m_IncludeAll);
}
if (remove) {
p1.add(m_RemoveAll);
}
if (invert) {
p1.add(m_Invert);
}
if (pattern) {
p1.add(m_Pattern);
}
setLayout(new BorderLayout());
if (include || remove || invert || pattern) {
add(p1, BorderLayout.NORTH);
}
add(new JScrollPane(m_Table), BorderLayout.CENTER);
}
public Dimension getPreferredScrollableViewportSize() {
return m_Table.getPreferredScrollableViewportSize();
}
public void setPreferredScrollableViewportSize(Dimension d) {
m_Table.setPreferredScrollableViewportSize(d);
}
/**
* Sets the instances who's attribute names will be displayed.
*
* @param newInstances the new set of instances
*/
public void setInstances(Instances newInstances) {
if (m_Model == null) {
m_Model = new AttributeTableModel(newInstances);
m_Table.setModel(m_Model);
TableColumnModel tcm = m_Table.getColumnModel();
tcm.getColumn(0).setMaxWidth(60);
tcm.getColumn(1).setMaxWidth(tcm.getColumn(1).getMinWidth());
tcm.getColumn(2).setMinWidth(100);
} else {
m_Model.setInstances(newInstances);
m_Table.clearSelection();
}
m_IncludeAll.setEnabled(true);
m_RemoveAll.setEnabled(true);
m_Invert.setEnabled(true);
m_Pattern.setEnabled(true);
m_Table.sizeColumnsToFit(2);
m_Table.revalidate();
m_Table.repaint();
}
/**
* Gets an array containing the indices of all selected attributes.
*
* @return the array of selected indices.
*/
public int [] getSelectedAttributes() {
return (m_Model == null) ? null : m_Model.getSelectedAttributes();
}
/**
* Set the selected attributes in the widget. Note that
* setInstances() must have been called first.
*
* @param selected an array of boolean indicating which attributes
* are to have their check boxes selected.
* @throws Exception if the supplied array of booleans does not have
* the same number of elements as there are attributes.
*/
public void setSelectedAttributes(boolean[] selected) throws Exception {
if (m_Model != null) {
m_Model.setSelectedAttributes(selected);
}
}
/**
* Get the table model in use (or null if no instances
* have been set yet).
*
* @return the table model in use or null if no instances
* have been seen yet.
*/
public TableModel getTableModel() {
return m_Model;
}
/**
* Gets the selection model used by the table.
*
* @return a value of type 'ListSelectionModel'
*/
public ListSelectionModel getSelectionModel() {
return m_Table.getSelectionModel();
}
/**
* Tests the attribute selection panel from the command line.
*
* @param args must contain the name of an arff file to load.
*/
public static void main(String[] args) {
try {
if (args.length == 0) {
throw new Exception(Messages.getInstance().getString("AttributeSelectionPanel_Main_Exception_Text"));
}
Instances i = new Instances(new java.io.BufferedReader(
new java.io.FileReader(args[0])));
AttributeSelectionPanel asp = new AttributeSelectionPanel();
final javax.swing.JFrame jf =
new javax.swing.JFrame(Messages.getInstance().getString("AttributeSelectionPanel_Main_JFrame_Text"));
jf.getContentPane().setLayout(new BorderLayout());
jf.getContentPane().add(asp, BorderLayout.CENTER);
jf.addWindowListener(new java.awt.event.WindowAdapter() {
public void windowClosing(java.awt.event.WindowEvent e) {
jf.dispose();
System.exit(0);
}
});
jf.pack();
jf.setVisible(true);
asp.setInstances(i);
} catch (Exception ex) {
ex.printStackTrace();
System.err.println(ex.getMessage());
}
}
} // AttributeSelectionPanel
© 2015 - 2025 Weber Informatics LLC | Privacy Policy