📄 arffpanel.java
字号:
/*
* 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.
*/
/*
* ArffPanel.java
* Copyright (C) 2005 FracPete
*
*/
package weka.gui.arffviewer;
import weka.gui.ComponentHelper;
import weka.gui.ListSelectorDialog;
import weka.gui.arffviewer.ArffTable;
import weka.gui.arffviewer.ArffTableCellRenderer;
import weka.gui.arffviewer.ArffTableSorter;
import weka.core.Instances;
import weka.core.Utils;
import weka.core.Undoable;
import java.awt.BorderLayout;
import java.awt.Cursor;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.File;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Vector;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.TableModelEvent;
/**
* A Panel representing an ARFF-Table and the associated filename.
*
*
* @author FracPete (fracpete at waikato dot ac dot nz)
* @version $Revision: 1.1 $
*/
public class ArffPanel
extends JPanel
implements ActionListener, ChangeListener, MouseListener, Undoable
{
/** the name of the tab for instances that were set directly */
public final static String TAB_INSTANCES = "Instances";
private ArffTable tableArff;
private JPopupMenu popupHeader;
private JPopupMenu popupRows;
private JLabel labelName;
private JMenuItem menuItemMean;
private JMenuItem menuItemSetAllValues;
private JMenuItem menuItemSetMissingValues;
private JMenuItem menuItemReplaceValues;
private JMenuItem menuItemRenameAttribute;
private JMenuItem menuItemDeleteAttribute;
private JMenuItem menuItemDeleteAttributes;
private JMenuItem menuItemSortInstances;
private JMenuItem menuItemDeleteSelectedInstance;
private JMenuItem menuItemDeleteAllSelectedInstances;
private JMenuItem menuItemSearch;
private JMenuItem menuItemClearSearch;
private JMenuItem menuItemUndo;
private JMenuItem menuItemCopy;
private String filename;
private String title;
private int currentCol;
private boolean changed;
private HashSet changeListeners;
private String lastSearch;
private String lastReplace;
/**
* initializes the panel with no data
*/
public ArffPanel() {
super();
initialize();
createPanel();
}
/**
* initializes the panel and loads the specified file
*/
public ArffPanel(String filename) {
this();
loadFile(filename);
}
/**
* initializes the panel with the given data
*/
public ArffPanel(Instances data) {
this();
filename = "";
setInstances(data);
}
/**
* any member variables are initialized here
*/
protected void initialize() {
filename = "";
title = "";
currentCol = -1;
lastSearch = "";
lastReplace = "";
changed = false;
changeListeners = new HashSet();
}
/**
* creates all the components in the frame
*/
protected void createPanel() {
JScrollPane pane;
setLayout(new BorderLayout());
// header popup
popupHeader = new JPopupMenu();
popupHeader.addMouseListener(this);
menuItemMean = new JMenuItem("Get mean...");
menuItemMean.addActionListener(this);
popupHeader.add(menuItemMean);
popupHeader.addSeparator();
menuItemSetAllValues = new JMenuItem("Set all values to...");
menuItemSetAllValues.addActionListener(this);
popupHeader.add(menuItemSetAllValues);
menuItemSetMissingValues = new JMenuItem("Set missing values to...");
menuItemSetMissingValues.addActionListener(this);
popupHeader.add(menuItemSetMissingValues);
menuItemReplaceValues = new JMenuItem("Replace values with...");
menuItemReplaceValues.addActionListener(this);
popupHeader.add(menuItemReplaceValues);
popupHeader.addSeparator();
menuItemRenameAttribute = new JMenuItem("Rename attribute...");
menuItemRenameAttribute.addActionListener(this);
popupHeader.add(menuItemRenameAttribute);
menuItemDeleteAttribute = new JMenuItem("Delete attribute");
menuItemDeleteAttribute.addActionListener(this);
popupHeader.add(menuItemDeleteAttribute);
menuItemDeleteAttributes = new JMenuItem("Delete attributes...");
menuItemDeleteAttributes.addActionListener(this);
popupHeader.add(menuItemDeleteAttributes);
menuItemSortInstances = new JMenuItem("Sort data (ascending)");
menuItemSortInstances.addActionListener(this);
popupHeader.add(menuItemSortInstances);
// row popup
popupRows = new JPopupMenu();
popupRows.addMouseListener(this);
menuItemUndo = new JMenuItem("Undo");
menuItemUndo.addActionListener(this);
popupRows.add(menuItemUndo);
popupRows.addSeparator();
menuItemCopy = new JMenuItem("Copy");
menuItemCopy.addActionListener(this);
popupRows.add(menuItemCopy);
popupRows.addSeparator();
menuItemSearch = new JMenuItem("Search...");
menuItemSearch.addActionListener(this);
popupRows.add(menuItemSearch);
menuItemClearSearch = new JMenuItem("Clear search");
menuItemClearSearch.addActionListener(this);
popupRows.add(menuItemClearSearch);
popupRows.addSeparator();
menuItemDeleteSelectedInstance = new JMenuItem("Delete selected instance");
menuItemDeleteSelectedInstance.addActionListener(this);
popupRows.add(menuItemDeleteSelectedInstance);
menuItemDeleteAllSelectedInstances = new JMenuItem("Delete ALL selected instances");
menuItemDeleteAllSelectedInstances.addActionListener(this);
popupRows.add(menuItemDeleteAllSelectedInstances);
// table
tableArff = new ArffTable();
tableArff.setToolTipText("Right click (or left+alt) for context menu");
tableArff.getTableHeader().addMouseListener(this);
tableArff.getTableHeader().setToolTipText("<html><b>Sort view:</b> left click = ascending / Shift + left click = descending<br><b>Menu:</b> right click (or left+alt)</html>");
tableArff.getTableHeader().setDefaultRenderer(new ArffTableCellRenderer());
tableArff.addChangeListener(this);
tableArff.addMouseListener(this);
pane = new JScrollPane(tableArff);
add(pane, BorderLayout.CENTER);
// relation name
labelName = new JLabel();
add(labelName, BorderLayout.NORTH);
}
/**
* sets the enabled/disabled state of the menu items
*/
private void setMenu() {
boolean isNumeric;
boolean hasColumns;
boolean hasRows;
boolean attSelected;
ArffTableSorter model;
model = (ArffTableSorter) tableArff.getModel();
hasColumns = (model.getInstances().numAttributes() > 0);
hasRows = (model.getInstances().numInstances() > 0);
attSelected = hasColumns && (currentCol > 0);
isNumeric = attSelected && (model.getAttributeAt(currentCol).isNumeric());
menuItemUndo.setEnabled(canUndo());
menuItemCopy.setEnabled(true);
menuItemSearch.setEnabled(true);
menuItemClearSearch.setEnabled(true);
menuItemMean.setEnabled(isNumeric);
menuItemSetAllValues.setEnabled(attSelected);
menuItemSetMissingValues.setEnabled(attSelected);
menuItemReplaceValues.setEnabled(attSelected);
menuItemRenameAttribute.setEnabled(attSelected);
menuItemDeleteAttribute.setEnabled(attSelected);
menuItemDeleteAttributes.setEnabled(attSelected);
menuItemSortInstances.setEnabled(hasRows && attSelected);
menuItemDeleteSelectedInstance.setEnabled(hasRows && tableArff.getSelectedRow() > -1);
menuItemDeleteAllSelectedInstances.setEnabled(hasRows && (tableArff.getSelectedRows().length > 0));
}
/**
* returns the table component
*/
public ArffTable getTable() {
return tableArff;
}
/**
* returns the title for the Tab, i.e. the filename
*/
public String getTitle() {
return title;
}
/**
* returns the filename
*/
public String getFilename() {
return filename;
}
/**
* sets the filename
*/
public void setFilename(String filename) {
this.filename = filename;
createTitle();
}
/**
* returns the instances of the panel, if none then NULL
*/
public Instances getInstances() {
Instances result;
result = null;
if (tableArff.getModel() != null)
result = ((ArffTableSorter) tableArff.getModel()).getInstances();
return result;
}
/**
* displays the given instances, i.e. creates a tab with the title
* TAB_INSTANCES. if one already exists it closes it.<br>
* if a different instances object is used here, don't forget to clear
* the undo-history by calling <code>clearUndo()</code>
*
* @see #TAB_INSTANCES
* @see #clearUndo()
*/
public void setInstances(Instances data) {
ArffTableSorter model;
this.filename = TAB_INSTANCES;
createTitle();
if (data == null)
model = null;
else
model = new ArffTableSorter(data);
tableArff.setModel(model);
clearUndo();
setChanged(false);
createName();
}
/**
* returns a list with the attributes
*/
public Vector getAttributes() {
Vector result;
int i;
result = new Vector();
for (i = 0; i < getInstances().numAttributes(); i++)
result.add(getInstances().attribute(i).name());
Collections.sort(result);
return result;
}
/**
* can only reset the changed state to FALSE
*/
public void setChanged(boolean changed) {
if (!changed)
{
this.changed = changed;
createTitle();
}
}
/**
* returns whether the content of the panel was changed
*/
public boolean isChanged() {
return changed;
}
/**
* returns whether undo support is enabled
*/
public boolean isUndoEnabled() {
return ((ArffTableSorter) tableArff.getModel()).isUndoEnabled();
}
/**
* sets whether undo support is enabled
*/
public void setUndoEnabled(boolean enabled) {
((ArffTableSorter) tableArff.getModel()).setUndoEnabled(enabled);
}
/**
* removes the undo history
*/
public void clearUndo() {
((ArffTableSorter) tableArff.getModel()).clearUndo();
}
/**
* returns whether an undo is possible
*/
public boolean canUndo() {
return ((ArffTableSorter) tableArff.getModel()).canUndo();
}
/**
* performs an undo action
*/
public void undo() {
if (canUndo()) {
((ArffTableSorter) tableArff.getModel()).undo();
// notify about update
notifyListener();
}
}
/**
* adds the current state of the instances to the undolist
*/
public void addUndoPoint() {
((ArffTableSorter) tableArff.getModel()).addUndoPoint();
// update menu
setMenu();
}
/**
* sets the title (i.e. filename)
*/
private void createTitle() {
File file;
if (filename.equals("")) {
title = "-none-";
}
else if (filename.equals(TAB_INSTANCES)) {
title = TAB_INSTANCES;
}
else {
try {
file = new File(filename);
title = file.getName();
}
catch (Exception e) {
title = "-none-";
}
}
if (isChanged())
title += " *";
}
/**
* sets the relation name
*/
private void createName() {
ArffTableSorter model;
model = (ArffTableSorter) tableArff.getModel();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -