source: src/main/java/weka/gui/arffviewer/ArffViewerMainPanel.java @ 15

Last change on this file since 15 was 4, checked in by gnappo, 14 years ago

Import di weka.

File size: 30.1 KB
Line 
1/*
2 *    This program is free software; you can redistribute it and/or modify
3 *    it under the terms of the GNU General Public License as published by
4 *    the Free Software Foundation; either version 2 of the License, or
5 *    (at your option) any later version.
6 *
7 *    This program is distributed in the hope that it will be useful,
8 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
9 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10 *    GNU General Public License for more details.
11 *
12 *    You should have received a copy of the GNU General Public License
13 *    along with this program; if not, write to the Free Software
14 *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
15 */
16
17/*
18 * ArffViewerMainPanel.java
19 * Copyright (C) 2005 University of Waikato, Hamilton, New Zealand
20 *
21 */
22
23package weka.gui.arffviewer;
24
25import weka.core.Capabilities;
26import weka.core.Instances;
27import weka.core.converters.AbstractSaver;
28import weka.gui.ComponentHelper;
29import weka.gui.ConverterFileChooser;
30import weka.gui.JTableHelper;
31import weka.gui.ListSelectorDialog;
32
33import java.awt.BorderLayout;
34import java.awt.Container;
35import java.awt.Cursor;
36import java.awt.Window;
37import java.awt.event.ActionEvent;
38import java.awt.event.ActionListener;
39import java.awt.event.KeyEvent;
40import java.awt.event.WindowEvent;
41import java.io.File;
42import java.util.Collections;
43import java.util.HashSet;
44import java.util.Iterator;
45import java.util.Vector;
46
47import javax.swing.JComponent;
48import javax.swing.JFrame;
49import javax.swing.JInternalFrame;
50import javax.swing.JList;
51import javax.swing.JMenu;
52import javax.swing.JMenuBar;
53import javax.swing.JMenuItem;
54import javax.swing.JOptionPane;
55import javax.swing.JPanel;
56import javax.swing.JTabbedPane;
57import javax.swing.KeyStroke;
58import javax.swing.event.ChangeEvent;
59import javax.swing.event.ChangeListener;
60
61/**
62 * The main panel of the ArffViewer. It has a reference to the menu, that an
63 * implementing JFrame only needs to add via the setJMenuBar(JMenuBar) method.
64 *
65 *
66 * @author FracPete (fracpete at waikato dot ac dot nz)
67 * @version $Revision: 1.7 $
68 */
69
70public class ArffViewerMainPanel 
71  extends JPanel
72  implements ActionListener, ChangeListener {
73 
74  /** for serialization */
75  static final long serialVersionUID = -8763161167586738753L;
76 
77  /** the default for width */
78  public final static int    DEFAULT_WIDTH     = -1;
79  /** the default for height */
80  public final static int    DEFAULT_HEIGHT    = -1;
81  /** the default for left */
82  public final static int    DEFAULT_LEFT      = -1;
83  /** the default for top */
84  public final static int    DEFAULT_TOP       = -1;
85  /** default width */
86  public final static int    WIDTH             = 800;
87  /** default height */
88  public final static int    HEIGHT            = 600;
89
90  protected Container             parent;
91  protected JTabbedPane           tabbedPane;
92  protected JMenuBar              menuBar;
93  protected JMenu                 menuFile;
94  protected JMenuItem             menuFileOpen;
95  protected JMenuItem             menuFileSave;
96  protected JMenuItem             menuFileSaveAs;
97  protected JMenuItem             menuFileClose;
98  protected JMenuItem             menuFileCloseAll;
99  protected JMenuItem             menuFileProperties;
100  protected JMenuItem             menuFileExit;
101  protected JMenu                 menuEdit;
102  protected JMenuItem             menuEditUndo;
103  protected JMenuItem             menuEditCopy;
104  protected JMenuItem             menuEditSearch;
105  protected JMenuItem             menuEditClearSearch;
106  protected JMenuItem             menuEditDeleteAttribute;
107  protected JMenuItem             menuEditDeleteAttributes;
108  protected JMenuItem             menuEditRenameAttribute;
109  protected JMenuItem             menuEditAttributeAsClass;
110  protected JMenuItem             menuEditDeleteInstance;
111  protected JMenuItem             menuEditDeleteInstances;
112  protected JMenuItem             menuEditSortInstances;
113  protected JMenu                 menuView;
114  protected JMenuItem             menuViewAttributes;
115  protected JMenuItem             menuViewValues;
116  protected JMenuItem             menuViewOptimalColWidths;
117 
118  protected ConverterFileChooser  fileChooser;
119  protected String                frameTitle;
120  protected boolean               confirmExit;
121  protected int                   width;
122  protected int                   height;
123  protected int                   top;
124  protected int                   left;
125  protected boolean               exitOnClose;
126 
127  /**
128   * initializes the object
129   *
130   * @param parentFrame         the parent frame (JFrame or JInternalFrame)
131   */
132  public ArffViewerMainPanel(Container parentFrame) {
133    parent     = parentFrame;
134    frameTitle = "ARFF-Viewer"; 
135    createPanel();
136  }
137 
138  /**
139   * creates all the components in the panel
140   */
141  protected void createPanel() {
142    // basic setup
143    setSize(WIDTH, HEIGHT);
144   
145    setConfirmExit(false);
146    setLayout(new BorderLayout());
147   
148    // file dialog
149    fileChooser = new ConverterFileChooser(new File(System.getProperty("user.dir")));
150    fileChooser.setMultiSelectionEnabled(true);
151   
152    // menu
153    menuBar        = new JMenuBar();
154    menuFile       = new JMenu("File");
155    menuFileOpen   = new JMenuItem("Open...", ComponentHelper.getImageIcon("open.gif"));
156    menuFileOpen.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, KeyEvent.CTRL_MASK));
157    menuFileOpen.addActionListener(this);
158    menuFileSave   = new JMenuItem("Save", ComponentHelper.getImageIcon("save.gif"));
159    menuFileSave.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, KeyEvent.CTRL_MASK));
160    menuFileSave.addActionListener(this);
161    menuFileSaveAs = new JMenuItem("Save as...", ComponentHelper.getImageIcon("empty.gif"));
162    menuFileSaveAs.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, KeyEvent.CTRL_MASK + KeyEvent.SHIFT_MASK));
163    menuFileSaveAs.addActionListener(this);
164    menuFileClose  = new JMenuItem("Close", ComponentHelper.getImageIcon("empty.gif"));
165    menuFileClose.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_W, KeyEvent.CTRL_MASK));
166    menuFileClose.addActionListener(this);
167    menuFileCloseAll = new JMenuItem("Close all", ComponentHelper.getImageIcon("empty.gif"));
168    menuFileCloseAll.addActionListener(this);
169    menuFileProperties  = new JMenuItem("Properties", ComponentHelper.getImageIcon("empty.gif"));
170    menuFileProperties.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, KeyEvent.CTRL_MASK));
171    menuFileProperties.addActionListener(this);
172    menuFileExit   = new JMenuItem("Exit", ComponentHelper.getImageIcon("forward.gif"));
173    menuFileExit.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, KeyEvent.ALT_MASK));
174    menuFileExit.addActionListener(this);
175    menuFile.add(menuFileOpen);
176    menuFile.add(menuFileSave);
177    menuFile.add(menuFileSaveAs);
178    menuFile.add(menuFileClose);
179    menuFile.add(menuFileCloseAll);
180    menuFile.addSeparator();
181    menuFile.add(menuFileProperties);
182    menuFile.addSeparator();
183    menuFile.add(menuFileExit);
184    menuBar.add(menuFile);
185   
186    menuEdit       = new JMenu("Edit");
187    menuEditUndo   = new JMenuItem("Undo", ComponentHelper.getImageIcon("undo.gif"));
188    menuEditUndo.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Z, KeyEvent.CTRL_MASK));
189    menuEditUndo.addActionListener(this);
190    menuEditCopy   = new JMenuItem("Copy", ComponentHelper.getImageIcon("copy.gif"));
191    menuEditCopy.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_INSERT, KeyEvent.CTRL_MASK));
192    menuEditCopy.addActionListener(this);
193    menuEditSearch   = new JMenuItem("Search...", ComponentHelper.getImageIcon("find.gif"));
194    menuEditSearch.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F, KeyEvent.CTRL_MASK));
195    menuEditSearch.addActionListener(this);
196    menuEditClearSearch   = new JMenuItem("Clear search", ComponentHelper.getImageIcon("empty.gif"));
197    menuEditClearSearch.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F, KeyEvent.CTRL_MASK + KeyEvent.SHIFT_MASK));
198    menuEditClearSearch.addActionListener(this);
199    menuEditRenameAttribute = new JMenuItem("Rename attribute", ComponentHelper.getImageIcon("empty.gif"));
200    menuEditRenameAttribute.addActionListener(this);
201    menuEditAttributeAsClass = new JMenuItem("Attribute as class", ComponentHelper.getImageIcon("empty.gif"));
202    menuEditAttributeAsClass.addActionListener(this);
203    menuEditDeleteAttribute = new JMenuItem("Delete attribute", ComponentHelper.getImageIcon("empty.gif"));
204    menuEditDeleteAttribute.addActionListener(this);
205    menuEditDeleteAttributes = new JMenuItem("Delete attributes", ComponentHelper.getImageIcon("empty.gif"));
206    menuEditDeleteAttributes.addActionListener(this);
207    menuEditDeleteInstance = new JMenuItem("Delete instance", ComponentHelper.getImageIcon("empty.gif"));
208    menuEditDeleteInstance.addActionListener(this);
209    menuEditDeleteInstances = new JMenuItem("Delete instances", ComponentHelper.getImageIcon("empty.gif"));
210    menuEditDeleteInstances.addActionListener(this);
211    menuEditSortInstances = new JMenuItem("Sort data (ascending)", ComponentHelper.getImageIcon("sort.gif"));
212    menuEditSortInstances.addActionListener(this);
213    menuEdit.add(menuEditUndo);
214    menuEdit.addSeparator();
215    menuEdit.add(menuEditCopy);
216    menuEdit.addSeparator();
217    menuEdit.add(menuEditSearch);
218    menuEdit.add(menuEditClearSearch);
219    menuEdit.addSeparator();
220    menuEdit.add(menuEditRenameAttribute);
221    menuEdit.add(menuEditAttributeAsClass);
222    menuEdit.add(menuEditDeleteAttribute);
223    menuEdit.add(menuEditDeleteAttributes);
224    menuEdit.addSeparator();
225    menuEdit.add(menuEditDeleteInstance);
226    menuEdit.add(menuEditDeleteInstances);
227    menuEdit.add(menuEditSortInstances);
228    menuBar.add(menuEdit);
229   
230    menuView       = new JMenu("View");
231    menuViewAttributes   = new JMenuItem("Attributes...", ComponentHelper.getImageIcon("objects.gif"));
232    menuViewAttributes.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_A, KeyEvent.CTRL_MASK + KeyEvent.SHIFT_MASK));
233    menuViewAttributes.addActionListener(this);
234    menuViewValues   = new JMenuItem("Values...", ComponentHelper.getImageIcon("properties.gif"));
235    menuViewValues.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V, KeyEvent.CTRL_MASK + KeyEvent.SHIFT_MASK));
236    menuViewValues.addActionListener(this);
237    menuViewOptimalColWidths = new JMenuItem("Optimal column width (all)", ComponentHelper.getImageIcon("resize.gif"));
238    menuViewOptimalColWidths.addActionListener(this);
239    menuView.add(menuViewAttributes);
240    menuView.add(menuViewValues);
241    menuView.addSeparator();
242    menuView.add(menuViewOptimalColWidths);
243    menuBar.add(menuView);
244   
245    // tabbed pane
246    tabbedPane  = new JTabbedPane();
247    tabbedPane.addChangeListener(this);
248    add(tabbedPane, BorderLayout.CENTER);
249   
250    updateMenu();
251    updateFrameTitle();
252  }
253 
254  /**
255   * returns the parent frame, if it's a JFrame, otherwise null
256   *
257   * @return            the parent frame
258   */
259  public JFrame getParentFrame() {
260    if (parent instanceof JFrame)
261      return (JFrame) parent;
262    else
263      return null;
264  }
265 
266  /**
267   * returns the parent frame, if it's a JInternalFrame, otherwise null
268   *
269   * @return            the parent frame
270   */
271  public JInternalFrame getParentInternalFrame() {
272    if (parent instanceof JInternalFrame)
273      return (JInternalFrame) parent;
274    else
275      return null;
276  }
277 
278  /**
279   * sets the new parent frame
280   *
281   * @param value       the parent frame
282   */
283  public void setParent(Container value) {
284    parent = value;
285  }
286 
287  /**
288   * returns the menu bar to be added in a frame
289   *
290   * @return            the menu bar
291   */
292  public JMenuBar getMenu() {
293    return menuBar;
294  }
295 
296  /**
297   * returns the tabbedpane instance
298   *
299   * @return            the tabbed pane
300   */
301  public JTabbedPane getTabbedPane() {
302    return tabbedPane;
303  }
304 
305  /**
306   * whether to present a MessageBox on Exit or not
307   * @param confirm           whether a MessageBox pops up or not to confirm
308   *                          exit
309   */
310  public void setConfirmExit(boolean confirm) {
311    confirmExit = confirm;
312  }
313 
314  /**
315   * returns the setting of whether to display a confirm messagebox or not
316   * on exit
317   * @return                  whether a messagebox is displayed or not
318   */
319  public boolean getConfirmExit() {
320    return confirmExit;
321  }
322
323  /**
324   * whether to do a System.exit(0) on close
325   *
326   * @param value       enables/disables a System.exit(0) on close
327   */
328  public void setExitOnClose(boolean value) {
329    exitOnClose = value;
330  }
331
332  /**
333   * returns TRUE if a System.exit(0) is done on a close
334   *
335   * @return            true if a System.exit(0) is done on close
336   */
337  public boolean getExitOnClose() {
338    return exitOnClose;
339  }
340 
341  /**
342   * validates and repaints the frame
343   */
344  public void refresh() {
345    validate();
346    repaint();
347  }
348 
349  /**
350   * returns the title (incl. filename) for the frame
351   *
352   * @return            the frame title
353   */
354  public String getFrameTitle() {
355    if (getCurrentFilename().equals(""))
356      return frameTitle;
357    else
358      return frameTitle + " - " + getCurrentFilename();
359  }
360 
361  /**
362   * sets the title of the parent frame, if one was provided
363   */
364  public void updateFrameTitle() {
365    if (getParentFrame() != null)
366      getParentFrame().setTitle(getFrameTitle());
367    if (getParentInternalFrame() != null)
368      getParentInternalFrame().setTitle(getFrameTitle());
369  }
370 
371  /**
372   * sets the enabled/disabled state of the menu
373   */
374  protected void updateMenu() {
375    boolean       fileOpen;
376    boolean       isChanged;
377    boolean       canUndo;
378   
379    fileOpen  = (getCurrentPanel() != null);
380    isChanged = fileOpen && (getCurrentPanel().isChanged());
381    canUndo   = fileOpen && (getCurrentPanel().canUndo());
382   
383    // File
384    menuFileOpen.setEnabled(true);
385    menuFileSave.setEnabled(isChanged);
386    menuFileSaveAs.setEnabled(fileOpen);
387    menuFileClose.setEnabled(fileOpen);
388    menuFileCloseAll.setEnabled(fileOpen);
389    menuFileProperties.setEnabled(fileOpen);
390    menuFileExit.setEnabled(true);
391    // Edit
392    menuEditUndo.setEnabled(canUndo);
393    menuEditCopy.setEnabled(fileOpen);
394    menuEditSearch.setEnabled(fileOpen);
395    menuEditClearSearch.setEnabled(fileOpen);
396    menuEditAttributeAsClass.setEnabled(fileOpen);
397    menuEditRenameAttribute.setEnabled(fileOpen);
398    menuEditDeleteAttribute.setEnabled(fileOpen);
399    menuEditDeleteAttributes.setEnabled(fileOpen);
400    menuEditDeleteInstance.setEnabled(fileOpen);
401    menuEditDeleteInstances.setEnabled(fileOpen);
402    menuEditSortInstances.setEnabled(fileOpen);
403    // View
404    menuViewAttributes.setEnabled(fileOpen);
405    menuViewValues.setEnabled(fileOpen);
406    menuViewOptimalColWidths.setEnabled(fileOpen);
407  }
408 
409  /**
410   * sets the title of the tab that contains the given component
411   *
412   * @param component           the component to set the title for
413   */
414  protected void setTabTitle(JComponent component) {
415    int            index;
416   
417    if (!(component instanceof ArffPanel))
418      return;
419   
420    index = tabbedPane.indexOfComponent(component);
421    if (index == -1)
422      return;
423   
424    tabbedPane.setTitleAt(index, ((ArffPanel) component).getTitle());
425    updateFrameTitle();
426  }
427 
428  /**
429   * returns the number of panels currently open
430   *
431   * @return            the number of open panels
432   */
433  public int getPanelCount() {
434    return tabbedPane.getTabCount();
435  }
436 
437  /**
438   * returns the specified panel, <code>null</code> if index is out of bounds 
439   *
440   * @param index       the index of the panel
441   * @return            the panel
442   */
443  public ArffPanel getPanel(int index) {
444    if ((index >= 0) && (index < getPanelCount()))
445      return (ArffPanel) tabbedPane.getComponentAt(index);
446    else
447      return null;
448  }
449 
450  /**
451   * returns the currently selected tab index
452   *
453   * @return            the index of the currently selected tab
454   */
455  public int getCurrentIndex() {
456    return tabbedPane.getSelectedIndex();
457  }
458 
459  /**
460   * returns the currently selected panel
461   *
462   * @return            the currently selected panel
463   */
464  public ArffPanel getCurrentPanel() {
465    return getPanel(getCurrentIndex());
466  }
467 
468  /**
469   * checks whether a panel is currently selected
470   *
471   * @return            true if a panel is currently selected
472   */
473  public boolean isPanelSelected() {
474    return (getCurrentPanel() != null);
475  }
476 
477  /**
478   * returns the filename of the specified panel
479   *
480   * @param index       the index of the panel
481   * @return            the filename for the panel
482   */
483  public String getFilename(int index) {
484    String            result;
485    ArffPanel         panel;
486   
487    result = "";
488    panel  = getPanel(index);
489   
490    if (panel != null)
491      result = panel.getFilename();
492   
493    return result;
494  }
495 
496  /**
497   * returns the filename of the current tab
498   *
499   * @return            the current filename
500   */
501  public String getCurrentFilename() {
502    return getFilename(getCurrentIndex());
503  }
504 
505  /**
506   * sets the filename of the specified panel
507   *
508   * @param index       the index of the panel
509   * @param filename    the new filename
510   */
511  public void setFilename(int index, String filename) {
512    ArffPanel         panel;
513   
514    panel = getPanel(index);
515   
516    if (panel != null) {
517      panel.setFilename(filename);
518      setTabTitle(panel);
519    }
520  }
521 
522  /**
523   * sets the filename of the current tab
524   *
525   * @param filename    the new filename
526   */
527  public void setCurrentFilename(String filename) {
528    setFilename(getCurrentIndex(), filename);
529  }
530 
531  /**
532   * if the file is changed it pops up a dialog whether to change the
533   * settings. if the project wasn't changed or saved it returns TRUE
534   *
535   * @return            true if project wasn't changed or saved
536   */
537  protected boolean saveChanges() {
538    return saveChanges(true);
539  }
540 
541  /**
542   * if the file is changed it pops up a dialog whether to change the
543   * settings. if the project wasn't changed or saved it returns TRUE
544   *
545   * @param showCancel  whether we have YES/NO/CANCEL or only YES/NO
546   * @return            true if project wasn't changed or saved
547   */
548  protected boolean saveChanges(boolean showCancel) {
549    int            button;
550    boolean        result;
551   
552    if (!isPanelSelected())
553      return true;
554   
555    result = !getCurrentPanel().isChanged();
556   
557    if (getCurrentPanel().isChanged()) {
558      try {
559        if (showCancel)
560          button = ComponentHelper.showMessageBox(
561              this,
562              "Changed",
563              "The file is not saved - Do you want to save it?",
564              JOptionPane.YES_NO_CANCEL_OPTION,
565              JOptionPane.QUESTION_MESSAGE );
566        else
567          button = ComponentHelper.showMessageBox(
568              this,
569              "Changed",
570              "The file is not saved - Do you want to save it?",
571              JOptionPane.YES_NO_OPTION,
572              JOptionPane.QUESTION_MESSAGE );
573      }
574      catch (Exception e) {
575        button = JOptionPane.CANCEL_OPTION; 
576      }
577     
578      switch (button) {
579        case JOptionPane.YES_OPTION:
580          saveFile();
581          result = !getCurrentPanel().isChanged();
582          break;
583        case JOptionPane.NO_OPTION:
584          result = true;
585          break;
586        case JOptionPane.CANCEL_OPTION: 
587          result = false;
588          break;
589      }
590    }
591   
592    return result;
593  }
594
595  /**
596   * loads the specified file
597   *
598   * @param filename    the file to load
599   */
600  public void loadFile(String filename) {
601    ArffPanel         panel;
602
603    panel    = new ArffPanel(filename);
604    panel.addChangeListener(this);
605    tabbedPane.addTab(panel.getTitle(), panel);
606    tabbedPane.setSelectedIndex(tabbedPane.getTabCount() - 1);
607  }
608 
609  /**
610   * loads the specified file into the table
611   */
612  public void loadFile() {
613    int               retVal;
614    int               i;
615    String            filename;
616   
617    retVal = fileChooser.showOpenDialog(this);
618    if (retVal != ConverterFileChooser.APPROVE_OPTION)
619      return;
620   
621    setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
622   
623    for (i = 0; i< fileChooser.getSelectedFiles().length; i++) {
624      filename = fileChooser.getSelectedFiles()[i].getAbsolutePath();
625      loadFile(filename);
626    }
627   
628    setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
629  }
630 
631  /**
632   * saves the current data into a file
633   */
634  public void saveFile() {
635    ArffPanel           panel;
636    String              filename;
637    AbstractSaver       saver;
638   
639    // no panel? -> exit
640    panel = getCurrentPanel();
641    if (panel == null)
642      return;
643   
644    filename = panel.getFilename();
645    if (filename.equals(ArffPanel.TAB_INSTANCES)) {
646      saveFileAs();
647    }
648    else {
649      saver = fileChooser.getSaver();
650      try {
651        saver.setInstances(panel.getInstances());
652        saver.writeBatch();
653        panel.setChanged(false);
654        setCurrentFilename(filename);
655      }
656      catch (Exception e) {
657        e.printStackTrace();
658      }
659    }
660  }
661 
662  /**
663   * saves the current data into a new file
664   */
665  public void saveFileAs() {
666    int                  retVal;
667    ArffPanel            panel;
668   
669    // no panel? -> exit
670    panel = getCurrentPanel();
671    if (panel == null) {
672      System.out.println("nothing selected!");
673      return;
674    }
675   
676    if (!getCurrentFilename().equals("")) {
677      try {
678        fileChooser.setSelectedFile(new File(getCurrentFilename()));
679      }
680      catch (Exception e) {
681        // ignore
682      }
683    }
684   
685    // set filter for savers
686    try {
687      fileChooser.setCapabilitiesFilter(Capabilities.forInstances(panel.getInstances()));
688    }
689    catch (Exception e) {
690      fileChooser.setCapabilitiesFilter(null);
691    }
692
693    retVal = fileChooser.showSaveDialog(this);
694    if (retVal != ConverterFileChooser.APPROVE_OPTION)
695      return;
696   
697    panel.setChanged(false);
698    setCurrentFilename(fileChooser.getSelectedFile().getAbsolutePath());
699    saveFile();
700  }
701 
702  /**
703   * closes the current tab
704   */
705  public void closeFile() {
706    closeFile(true);
707  }
708 
709  /**
710   * closes the current tab
711   * @param showCancel           whether to show an additional CANCEL button
712   *                             in the "Want to save changes"-dialog
713   * @see                        #saveChanges(boolean)
714   */
715  public void closeFile(boolean showCancel) {
716    if (getCurrentIndex() == -1)
717      return;
718   
719    if (!saveChanges(showCancel))
720      return;
721   
722    tabbedPane.removeTabAt(getCurrentIndex());
723    updateFrameTitle();
724    System.gc();
725  }
726 
727  /**
728   * closes all open files
729   */
730  public void closeAllFiles() {
731    while (tabbedPane.getTabCount() > 0) {
732      if (!saveChanges(true))
733        return;
734     
735      tabbedPane.removeTabAt(getCurrentIndex());
736      updateFrameTitle();
737      System.gc();
738    }
739  }
740 
741  /**
742   * displays some properties of the instances
743   */
744  public void showProperties() {
745    ArffPanel             panel;
746    ListSelectorDialog    dialog;
747    Vector                props;
748    Instances             inst;
749   
750    panel = getCurrentPanel();
751    if (panel == null)
752      return;
753   
754    inst  = panel.getInstances();
755    if (inst == null)
756      return;
757    if (inst.classIndex() < 0)
758      inst.setClassIndex(inst.numAttributes() - 1);
759   
760    // get some data
761    props = new Vector();
762    props.add("Filename: " + panel.getFilename());
763    props.add("Relation name: " + inst.relationName());
764    props.add("# of instances: " + inst.numInstances());
765    props.add("# of attributes: " + inst.numAttributes());
766    props.add("Class attribute: " + inst.classAttribute().name());
767    props.add("# of class labels: " + inst.numClasses());
768   
769    dialog = new ListSelectorDialog(getParentFrame(), new JList(props));
770    dialog.showDialog();
771  }
772 
773  /**
774   * closes the window, i.e., if the parent is not null and implements
775   * the WindowListener interface it calls the windowClosing method
776   */
777  public void close() {
778    if (getParentInternalFrame() != null)
779      getParentInternalFrame().doDefaultCloseAction();
780    else if (getParentFrame() != null)
781      ((Window) getParentFrame()).dispatchEvent(
782          new WindowEvent(
783              (Window) getParentFrame(), WindowEvent.WINDOW_CLOSING));
784  }
785 
786  /**
787   * undoes the last action
788   */
789  public void undo() {
790    if (!isPanelSelected())
791      return;
792   
793    getCurrentPanel().undo();
794  }
795 
796  /**
797   * copies the content of the selection to the clipboard
798   */
799  public void copyContent() {
800    if (!isPanelSelected())
801      return;
802   
803    getCurrentPanel().copyContent();
804  }
805 
806  /**
807   * searches for a string in the cells
808   */
809  public void search() {
810    if (!isPanelSelected())
811      return;
812
813    getCurrentPanel().search();
814  }
815 
816  /**
817   * clears the search, i.e. resets the found cells
818   */
819  public void clearSearch() {
820    if (!isPanelSelected())
821      return;
822
823    getCurrentPanel().clearSearch();
824  }
825 
826  /**
827   * renames the current selected Attribute
828   */
829  public void renameAttribute() {
830    if (!isPanelSelected())
831      return;
832   
833    getCurrentPanel().renameAttribute();
834  }
835 
836  /**
837   * sets the current selected Attribute as class attribute, i.e. it moves it
838   * to the end of the attributes
839   */
840  public void attributeAsClass() {
841    if (!isPanelSelected())
842      return;
843   
844    getCurrentPanel().attributeAsClass();
845  }
846 
847  /**
848   * deletes the current selected Attribute or several chosen ones
849   *
850   * @param multiple    whether to delete myultiple attributes
851   */
852  public void deleteAttribute(boolean multiple) {
853    if (!isPanelSelected())
854      return;
855   
856    if (multiple)
857      getCurrentPanel().deleteAttributes();
858    else
859      getCurrentPanel().deleteAttribute();
860  }
861 
862  /**
863   * deletes the current selected Instance or several chosen ones
864   *
865   * @param multiple            whether to delete multiple instances
866   */
867  public void deleteInstance(boolean multiple) {
868    if (!isPanelSelected())
869      return;
870   
871    if (multiple)
872      getCurrentPanel().deleteInstances();
873    else
874      getCurrentPanel().deleteInstance();
875  }
876 
877  /**
878   * sorts the current selected attribute
879   */
880  public void sortInstances() {
881    if (!isPanelSelected())
882      return;
883   
884    getCurrentPanel().sortInstances();
885  }
886 
887  /**
888   * displays all the attributes, returns the selected item or NULL if canceled
889   *
890   * @return            the name of the selected attribute
891   */
892  public String showAttributes() {
893    ArffSortedTableModel     model;
894    ListSelectorDialog  dialog;
895    int                 i;
896    JList               list;
897    String              name;
898    int                 result;
899   
900    if (!isPanelSelected())
901      return null;
902   
903    list   = new JList(getCurrentPanel().getAttributes());
904    dialog = new ListSelectorDialog(getParentFrame(), list);
905    result = dialog.showDialog();
906   
907    if (result == ListSelectorDialog.APPROVE_OPTION) {
908      model = (ArffSortedTableModel) getCurrentPanel().getTable().getModel();
909      name  = list.getSelectedValue().toString();
910      i     = model.getAttributeColumn(name);
911      JTableHelper.scrollToVisible(getCurrentPanel().getTable(), 0, i);
912      getCurrentPanel().getTable().setSelectedColumn(i);
913      return name;
914    }
915    else {
916      return null;
917    }
918  }
919 
920  /**
921   * displays all the distinct values for an attribute
922   */
923  public void showValues() {
924    String                attribute;
925    ArffSortedTableModel       model;
926    ArffTable             table;
927    HashSet               values;
928    Vector                items;
929    Iterator              iter;
930    ListSelectorDialog    dialog;
931    int                   i;
932    int                   col;
933   
934    // choose attribute to retrieve values for
935    attribute = showAttributes();
936    if (attribute == null)
937      return;
938   
939    table  = (ArffTable) getCurrentPanel().getTable();
940    model  = (ArffSortedTableModel) table.getModel();
941   
942    // get column index
943    col    = -1;
944    for (i = 0; i < table.getColumnCount(); i++) {
945      if (table.getPlainColumnName(i).equals(attribute)) {
946        col = i;
947        break;
948      }
949    }
950    // not found?
951    if (col == -1)
952      return;
953   
954    // get values
955    values = new HashSet();
956    items  = new Vector();
957    for (i = 0; i < model.getRowCount(); i++)
958      values.add(model.getValueAt(i, col).toString());
959    if (values.isEmpty())
960      return;
961    iter = values.iterator();
962    while (iter.hasNext())
963      items.add(iter.next());
964    Collections.sort(items);
965   
966    dialog = new ListSelectorDialog(getParentFrame(), new JList(items));
967    dialog.showDialog();
968  }
969 
970  /**
971   * sets the optimal column width for all columns
972   */
973  public void setOptimalColWidths() {
974    if (!isPanelSelected())
975      return;
976   
977    getCurrentPanel().setOptimalColWidths();
978  }
979 
980  /**
981   * invoked when an action occurs
982   *
983   * @param e           the action event
984   */
985  public void actionPerformed(ActionEvent e) {
986    Object          o;
987   
988    o = e.getSource();
989   
990    if (o == menuFileOpen)
991      loadFile();
992    else if (o == menuFileSave)
993      saveFile();
994    else if (o == menuFileSaveAs)
995      saveFileAs();
996    else if (o == menuFileClose)
997      closeFile();
998    else if (o == menuFileCloseAll)
999      closeAllFiles();
1000    else if (o == menuFileProperties)
1001      showProperties();
1002    else if (o == menuFileExit)
1003      close();
1004    else if (o == menuEditUndo)
1005      undo();
1006    else if (o == menuEditCopy)
1007      copyContent();
1008    else if (o == menuEditSearch)
1009      search();
1010    else if (o == menuEditClearSearch)
1011      clearSearch();
1012    else if (o == menuEditDeleteAttribute)
1013      deleteAttribute(false);
1014    else if (o == menuEditDeleteAttributes)
1015      deleteAttribute(true);
1016    else if (o == menuEditRenameAttribute)
1017      renameAttribute();
1018    else if (o == menuEditAttributeAsClass)
1019      attributeAsClass();
1020    else if (o == menuEditDeleteInstance)
1021      deleteInstance(false);
1022    else if (o == menuEditDeleteInstances)
1023      deleteInstance(true);
1024    else if (o == menuEditSortInstances)
1025      sortInstances();
1026    else if (o == menuViewAttributes)
1027      showAttributes();
1028    else if (o == menuViewValues)
1029      showValues();
1030    else if (o == menuViewOptimalColWidths)
1031      setOptimalColWidths();
1032   
1033    updateMenu();
1034  }
1035 
1036  /**
1037   * Invoked when the target of the listener has changed its state.
1038   *
1039   * @param e           the change event
1040   */
1041  public void stateChanged(ChangeEvent e) {
1042    updateFrameTitle();
1043    updateMenu();
1044   
1045    // did the content of panel change? -> change title of tab
1046    if (e.getSource() instanceof JComponent)
1047      setTabTitle((JComponent) e.getSource());
1048  }
1049 
1050  /**
1051   * returns only the classname
1052   *
1053   * @return            the classname
1054   */
1055  public String toString() {
1056    return this.getClass().getName();
1057  }
1058}
Note: See TracBrowser for help on using the repository browser.