📄 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.core.Instances;import weka.core.Undoable;import weka.core.Utils;import weka.gui.ComponentHelper;import weka.gui.JTableHelper;import weka.gui.ListSelectorDialog;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.7 $ */public class ArffPanel extends JPanel implements ActionListener, ChangeListener, MouseListener, Undoable { /** for serialization */ static final long serialVersionUID = -4697041150989513939L; /** the name of the tab for instances that were set directly */ public final static String TAB_INSTANCES = "Instances"; /** the underlying table */ private ArffTable m_TableArff; /** the popup menu for the header row */ private JPopupMenu m_PopupHeader; /** the popup menu for the data rows */ private JPopupMenu m_PopupRows; /** displays the relation name */ private JLabel m_LabelName; // menu items private JMenuItem menuItemMean; private JMenuItem menuItemSetAllValues; private JMenuItem menuItemSetMissingValues; private JMenuItem menuItemReplaceValues; private JMenuItem menuItemRenameAttribute; private JMenuItem menuItemAttributeAsClass; 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 JMenuItem menuItemOptimalColWidth; private JMenuItem menuItemOptimalColWidths; /** the filename used in the title */ private String m_Filename; /** the title prefix */ private String m_Title; /** the currently selected column */ private int m_CurrentCol; /** flag for whether data got changed */ private boolean m_Changed; /** the listeners that listen for modifications */ private HashSet m_ChangeListeners; /** the string used in the last search */ private String m_LastSearch; /** the string used in the last replace */ private String m_LastReplace; /** * initializes the panel with no data */ public ArffPanel() { super(); initialize(); createPanel(); } /** * initializes the panel and loads the specified file * * @param filename the file to load */ public ArffPanel(String filename) { this(); loadFile(filename); } /** * initializes the panel with the given data * * @param data the data to use */ public ArffPanel(Instances data) { this(); m_Filename = ""; setInstances(data); } /** * any member variables are initialized here */ protected void initialize() { m_Filename = ""; m_Title = ""; m_CurrentCol = -1; m_LastSearch = ""; m_LastReplace = ""; m_Changed = false; m_ChangeListeners = new HashSet(); } /** * creates all the components in the frame */ protected void createPanel() { JScrollPane pane; setLayout(new BorderLayout()); menuItemMean = new JMenuItem("Get mean..."); menuItemMean.addActionListener(this); menuItemSetAllValues = new JMenuItem("Set all values to..."); menuItemSetAllValues.addActionListener(this); menuItemSetMissingValues = new JMenuItem("Set missing values to..."); menuItemSetMissingValues.addActionListener(this); menuItemReplaceValues = new JMenuItem("Replace values with..."); menuItemReplaceValues.addActionListener(this); menuItemRenameAttribute = new JMenuItem("Rename attribute..."); menuItemRenameAttribute.addActionListener(this); menuItemAttributeAsClass = new JMenuItem("Attribute as class"); menuItemAttributeAsClass.addActionListener(this); menuItemDeleteAttribute = new JMenuItem("Delete attribute"); menuItemDeleteAttribute.addActionListener(this); menuItemDeleteAttributes = new JMenuItem("Delete attributes..."); menuItemDeleteAttributes.addActionListener(this); menuItemSortInstances = new JMenuItem("Sort data (ascending)"); menuItemSortInstances.addActionListener(this); menuItemOptimalColWidth = new JMenuItem("Optimal column width (current)"); menuItemOptimalColWidth.addActionListener(this); menuItemOptimalColWidths = new JMenuItem("Optimal column width (all)"); menuItemOptimalColWidths.addActionListener(this); // row popup menuItemUndo = new JMenuItem("Undo"); menuItemUndo.addActionListener(this); menuItemCopy = new JMenuItem("Copy"); menuItemCopy.addActionListener(this); menuItemSearch = new JMenuItem("Search..."); menuItemSearch.addActionListener(this); menuItemClearSearch = new JMenuItem("Clear search"); menuItemClearSearch.addActionListener(this); menuItemDeleteSelectedInstance = new JMenuItem("Delete selected instance"); menuItemDeleteSelectedInstance.addActionListener(this); menuItemDeleteAllSelectedInstances = new JMenuItem("Delete ALL selected instances"); menuItemDeleteAllSelectedInstances.addActionListener(this); // table m_TableArff = new ArffTable(); m_TableArff.setToolTipText("Right click (or left+alt) for context menu"); m_TableArff.getTableHeader().addMouseListener(this); m_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>"); m_TableArff.getTableHeader().setDefaultRenderer(new ArffTableCellRenderer()); m_TableArff.addChangeListener(this); m_TableArff.addMouseListener(this); pane = new JScrollPane(m_TableArff); add(pane, BorderLayout.CENTER); // relation name m_LabelName = new JLabel(); add(m_LabelName, BorderLayout.NORTH); } /** * initializes the popup menus */ private void initPopupMenus() { // header popup m_PopupHeader = new JPopupMenu(); m_PopupHeader.addMouseListener(this); m_PopupHeader.add(menuItemMean); if (!isReadOnly()) { m_PopupHeader.addSeparator(); m_PopupHeader.add(menuItemSetAllValues); m_PopupHeader.add(menuItemSetMissingValues); m_PopupHeader.add(menuItemReplaceValues); m_PopupHeader.addSeparator(); m_PopupHeader.add(menuItemRenameAttribute); m_PopupHeader.add(menuItemAttributeAsClass); m_PopupHeader.add(menuItemDeleteAttribute); m_PopupHeader.add(menuItemDeleteAttributes); m_PopupHeader.add(menuItemSortInstances); } m_PopupHeader.addSeparator(); m_PopupHeader.add(menuItemOptimalColWidth); m_PopupHeader.add(menuItemOptimalColWidths); // row popup m_PopupRows = new JPopupMenu(); m_PopupRows.addMouseListener(this); if (!isReadOnly()) { m_PopupRows.add(menuItemUndo); m_PopupRows.addSeparator(); } m_PopupRows.add(menuItemCopy); m_PopupRows.addSeparator(); m_PopupRows.add(menuItemSearch); m_PopupRows.add(menuItemClearSearch); if (!isReadOnly()) { m_PopupRows.addSeparator(); m_PopupRows.add(menuItemDeleteSelectedInstance); m_PopupRows.add(menuItemDeleteAllSelectedInstances); } } /** * sets the enabled/disabled state of the menu items */ private void setMenu() { boolean isNumeric; boolean hasColumns; boolean hasRows; boolean attSelected; ArffSortedTableModel model; boolean isNull; model = (ArffSortedTableModel) m_TableArff.getModel(); isNull = (model.getInstances() == null); hasColumns = !isNull && (model.getInstances().numAttributes() > 0); hasRows = !isNull && (model.getInstances().numInstances() > 0); attSelected = hasColumns && (m_CurrentCol > 0); isNumeric = attSelected && (model.getAttributeAt(m_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 && m_TableArff.getSelectedRow() > -1); menuItemDeleteAllSelectedInstances.setEnabled(hasRows && (m_TableArff.getSelectedRows().length > 0)); } /** * returns the table component * * @return the table */ public ArffTable getTable() { return m_TableArff; } /** * returns the title for the Tab, i.e. the filename * * @return the title for the tab */ public String getTitle() { return m_Title; } /** * returns the filename * * @return the filename */ public String getFilename() { return m_Filename; } /** * sets the filename * * @param filename the new filename */ public void setFilename(String filename) { m_Filename = filename; createTitle(); } /** * returns the instances of the panel, if none then NULL * * @return the instances of the panel */ public Instances getInstances() { Instances result; result = null; if (m_TableArff.getModel() != null) result = ((ArffSortedTableModel) m_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> * * @param data the instances to display * @see #TAB_INSTANCES * @see #clearUndo() */ public void setInstances(Instances data) { ArffSortedTableModel model; m_Filename = TAB_INSTANCES; createTitle(); model = new ArffSortedTableModel(data); m_TableArff.setModel(model); clearUndo(); setChanged(false); createName(); } /** * returns a list with the attributes * * @return a list of 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 * * @param changed if false, resets the changed state */ public void setChanged(boolean changed) { if (!changed) { this.m_Changed = changed; createTitle(); } } /** * returns whether the content of the panel was changed * * @return true if the content was changed */ public boolean isChanged() { return m_Changed; } /** * returns whether the model is read-only * * @return true if model is read-only */ public boolean isReadOnly() { if (m_TableArff == null) return true; else return ((ArffSortedTableModel) m_TableArff.getModel()).isReadOnly(); } /** * sets whether the model is read-only * * @param value if true the model is set to read-only */ public void setReadOnly(boolean value) { if (m_TableArff != null) ((ArffSortedTableModel) m_TableArff.getModel()).setReadOnly(value); } /** * returns whether undo support is enabled * * @return true if undo is enabled */ public boolean isUndoEnabled() { return ((ArffSortedTableModel) m_TableArff.getModel()).isUndoEnabled(); } /** * sets whether undo support is enabled * * @param enabled whether to enable/disable undo support */ public void setUndoEnabled(boolean enabled) { ((ArffSortedTableModel) m_TableArff.getModel()).setUndoEnabled(enabled); } /** * removes the undo history */ public void clearUndo() { ((ArffSortedTableModel) m_TableArff.getModel()).clearUndo(); } /** * returns whether an undo is possible * * @return true if undo is possible */ public boolean canUndo() { return ((ArffSortedTableModel) m_TableArff.getModel()).canUndo(); } /** * performs an undo action */ public void undo() { if (canUndo()) { ((ArffSortedTableModel) m_TableArff.getModel()).undo(); // notify about update notifyListener(); } } /** * adds the current state of the instances to the undolist */ public void addUndoPoint() { ((ArffSortedTableModel) m_TableArff.getModel()).addUndoPoint(); // update menu setMenu(); } /** * sets the title (i.e. filename) */ private void createTitle() { File file; if (m_Filename.equals("")) { m_Title = "-none-"; } else if (m_Filename.equals(TAB_INSTANCES)) { m_Title = TAB_INSTANCES; } else { try { file = new File(m_Filename); m_Title = file.getName(); } catch (Exception e) { m_Title = "-none-"; } } if (isChanged()) m_Title += " *";
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -