All Downloads are FREE. Search and download functionalities are using the official Maven repository.

weka.gui.ConverterFileChooser Maven / Gradle / Ivy

Go to download

The Waikato Environment for Knowledge Analysis (WEKA), a machine learning workbench. This version represents the developer version, the "bleeding edge" of development, you could say. New functionality gets added to this version.

There is a newer version: 3.9.6
Show 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 .
 */

/*
 * ConverterFileChooser.java
 * Copyright (C) 2006-2012 University of Waikato, Hamilton, New Zealand
 */

package weka.gui;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.util.Vector;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.filechooser.FileFilter;

import weka.core.Capabilities;
import weka.core.Instances;
import weka.core.converters.AbstractFileLoader;
import weka.core.converters.AbstractFileSaver;
import weka.core.converters.AbstractLoader;
import weka.core.converters.AbstractSaver;
import weka.core.converters.ConverterUtils;
import weka.core.converters.FileSourcedConverter;

/**
 * A specialized JFileChooser that lists all available file Loaders and Savers.
 * To list only savers that can handle the data that is about to be saved, one
 * can set a Capabilities filter.
 * 
 * @author fracpete (fracpete at waikato dot ac dot nz)
 * @version $Revision: 10859 $
 * @see #setCapabilitiesFilter(Capabilities)
 */
public class ConverterFileChooser extends JFileChooser {

  /** for serialization. */
  private static final long serialVersionUID = -5373058011025481738L;

  /** unhandled type of dialog. */
  public final static int UNHANDLED_DIALOG = 0;

  /** the loader dialog. */
  public final static int LOADER_DIALOG = 1;

  /** the saver dialog. */
  public final static int SAVER_DIALOG = 2;

  /** the file chooser itself. */
  protected ConverterFileChooser m_Self;

  /** the file filters for the loaders. */
  protected static Vector m_LoaderFileFilters;

  /** the file filters for the savers. */
  protected static Vector m_SaverFileFilters;

  /** the type of dialog to display. */
  protected int m_DialogType;

  /** the converter that was chosen by the user. */
  protected Object m_CurrentConverter;

  /** the configure button. */
  protected JButton m_ConfigureButton;

  /** the propertychangelistener. */
  protected PropertyChangeListener m_Listener;

  /** the last filter that was used for opening/saving. */
  protected FileFilter m_LastFilter;

  /** the Capabilities filter for the savers. */
  protected Capabilities m_CapabilitiesFilter;

  /**
   * whether to popup a dialog in case the file already exists (only save
   * dialog).
   */
  protected boolean m_OverwriteWarning = true;

  /** whether the file to be opened must exist (only open dialog). */
  protected boolean m_FileMustExist = true;

  /** the checkbox for bringing up the GenericObjectEditor. */
  protected JCheckBox m_CheckBoxOptions;

  /** the note about the options dialog. */
  protected JLabel m_LabelOptions;

  /** the GOE for displaying the options of a loader/saver. */
  protected GenericObjectEditor m_Editor = null;

  /** whether the GOE was OKed or Canceled. */
  protected int m_EditorResult;

  /**
   * whether to display only core converters (hardcoded in ConverterUtils).
   * Necessary for RMI/Remote Experiments for instance.
   * 
   * @see ConverterUtils#CORE_FILE_LOADERS
   * @see ConverterUtils#CORE_FILE_SAVERS
   */
  protected boolean m_CoreConvertersOnly = false;

  static {
    initDefaultFilters();
  }

  /**
   * Initialize the default set of filters for loaders and savers
   */
  public static void initDefaultFilters() {
    initFilters(true, ConverterUtils.getFileLoaders());
    initFilters(false, ConverterUtils.getFileSavers());
  }

  /**
   * onstructs a FileChooser pointing to the user's default directory.
   */
  public ConverterFileChooser() {
    super();
    initialize();
  }

  /**
   * Constructs a FileChooser using the given File as the path.
   * 
   * @param currentDirectory the path to start in
   */
  public ConverterFileChooser(File currentDirectory) {
    super(currentDirectory);
    initialize();
  }

  /**
   * Constructs a FileChooser using the given path.
   * 
   * @param currentDirectory the path to start in
   */
  public ConverterFileChooser(String currentDirectory) {
    super(currentDirectory);
    initialize();
  }

  /**
   * Further initializations.
   */
  protected void initialize() {
    JPanel panel;
    JPanel panel2;

    m_Self = this;

    m_CheckBoxOptions = new JCheckBox("Invoke options dialog");
    m_CheckBoxOptions.setMnemonic('I');
    m_LabelOptions = new JLabel(
      "
Note:

Some file formats offer additional
options which can be customized
when invoking the options dialog."); panel = new JPanel(new BorderLayout()); panel.add(m_CheckBoxOptions, BorderLayout.NORTH); panel2 = new JPanel(new BorderLayout()); panel2.add(m_LabelOptions, BorderLayout.NORTH); panel2.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); panel.add(panel2, BorderLayout.CENTER); setAccessory(panel); m_Editor = new GenericObjectEditor(false); ((GenericObjectEditor.GOEPanel) m_Editor.getCustomEditor()) .addOkListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { m_EditorResult = JFileChooser.APPROVE_OPTION; m_CurrentConverter = m_Editor.getValue(); // thanks to serialization and transient readers/streams, we have // to set the file again to initialize the converter again try { ((FileSourcedConverter) m_CurrentConverter) .setFile(((FileSourcedConverter) m_CurrentConverter) .retrieveFile()); } catch (Exception ex) { // ignored } } }); ((GenericObjectEditor.GOEPanel) m_Editor.getCustomEditor()) .addCancelListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { m_EditorResult = JFileChooser.CANCEL_OPTION; } }); } /** * filters out all non-core loaders if only those should be displayed. * * @param list the list of filters to check * @return the filtered list of filters * @see #m_CoreConvertersOnly */ protected Vector filterNonCoreLoaderFileFilters( Vector list) { Vector result; int i; ExtensionFileFilter filter; AbstractLoader loader; if (!getCoreConvertersOnly()) { result = list; } else { result = new Vector(); for (i = 0; i < list.size(); i++) { filter = list.get(i); loader = ConverterUtils .getLoaderForExtension(filter.getExtensions()[0]); if (ConverterUtils.isCoreFileLoader(loader.getClass().getName())) { result.add(filter); } } } return result; } /** * filters out all non-core savers if only those should be displayed. * * @param list the list of filters to check * @return the filtered list of filters * @see #m_CoreConvertersOnly */ protected Vector filterNonCoreSaverFileFilters( Vector list) { Vector result; int i; ExtensionFileFilter filter; AbstractSaver saver; if (!getCoreConvertersOnly()) { result = list; } else { result = new Vector(); for (i = 0; i < list.size(); i++) { filter = list.get(i); saver = ConverterUtils.getSaverForExtension(filter.getExtensions()[0]); if (ConverterUtils.isCoreFileSaver(saver.getClass().getName())) { result.add(filter); } } } return result; } /** * filters the list of file filters according to the currently set. * Capabilities * * @param list the filters to check * @return the filtered list of filters */ protected Vector filterSaverFileFilters( Vector list) { Vector result; int i; ExtensionFileFilter filter; AbstractSaver saver; if (m_CapabilitiesFilter == null) { result = list; } else { result = new Vector(); for (i = 0; i < list.size(); i++) { filter = list.get(i); saver = ConverterUtils.getSaverForExtension(filter.getExtensions()[0]); if (saver.getCapabilities().supports(m_CapabilitiesFilter)) { result.add(filter); } } } return result; } /** * initializes the ExtensionFileFilters. * * @param loader if true then the loader filter are initialized * @param classnames the classnames of the converters */ protected static void initFilters(boolean loader, Vector classnames) { int i; int n; String classname; Class cls; String[] ext; String desc; FileSourcedConverter converter; ExtensionFileFilter filter; if (loader) { m_LoaderFileFilters = new Vector(); } else { m_SaverFileFilters = new Vector(); } for (i = 0; i < classnames.size(); i++) { classname = classnames.get(i); // get data from converter try { cls = Class.forName(classname); converter = (FileSourcedConverter) cls.newInstance(); ext = converter.getFileExtensions(); desc = converter.getFileDescription(); } catch (Exception e) { cls = null; converter = null; ext = new String[0]; desc = ""; } if (converter == null) { continue; } // loader? if (loader) { for (n = 0; n < ext.length; n++) { filter = new ExtensionFileFilter(ext[n], desc + " (*" + ext[n] + ")"); m_LoaderFileFilters.add(filter); } } else { for (n = 0; n < ext.length; n++) { filter = new ExtensionFileFilter(ext[n], desc + " (*" + ext[n] + ")"); m_SaverFileFilters.add(filter); } } } } /** * initializes the GUI. * * @param dialogType the type of dialog to setup the GUI for */ protected void initGUI(int dialogType) { Vector list; int i; boolean acceptAll; // backup current state acceptAll = isAcceptAllFileFilterUsed(); // setup filters resetChoosableFileFilters(); setAcceptAllFileFilterUsed(acceptAll); if (dialogType == LOADER_DIALOG) { list = filterNonCoreLoaderFileFilters(m_LoaderFileFilters); } else { list = filterSaverFileFilters(filterNonCoreSaverFileFilters(m_SaverFileFilters)); } for (i = 0; i < list.size(); i++) { addChoosableFileFilter(list.get(i)); } if (list.size() > 0) { if ((m_LastFilter == null) || (!list.contains(m_LastFilter))) { setFileFilter(list.get(0)); } else { setFileFilter(m_LastFilter); } } // listener if (m_Listener != null) { removePropertyChangeListener(m_Listener); } m_Listener = new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { // filter changed if (evt.getPropertyName().equals(FILE_FILTER_CHANGED_PROPERTY)) { updateCurrentConverter(); } } }; addPropertyChangeListener(m_Listener); // initial setup if (dialogType == LOADER_DIALOG) { m_Editor.setClassType(AbstractFileLoader.class); m_Editor.setValue(new weka.core.converters.ArffLoader()); } else { m_Editor.setClassType(AbstractFileSaver.class); m_Editor.setValue(new weka.core.converters.ArffSaver()); } updateCurrentConverter(); } /** * sets the capabilities that the savers must have. use null if all should be * listed. * * @param value the minimum Capabilities the savers must have */ public void setCapabilitiesFilter(Capabilities value) { m_CapabilitiesFilter = (Capabilities) value.clone(); } /** * returns the capabilities filter for the savers, can be null if all are * listed. * * @return the minimum Capabilities the savers must have */ public Capabilities getCapabilitiesFilter() { if (m_CapabilitiesFilter != null) { return (Capabilities) m_CapabilitiesFilter.clone(); } else { return null; } } /** * Whether a warning is popped up if the file that is to be saved already * exists (only save dialog). * * @param value if true a warning will be popup */ public void setOverwriteWarning(boolean value) { m_OverwriteWarning = value; } /** * Returns whether a popup appears with a warning that the file already exists * (only save dialog). * * @return true if a warning pops up */ public boolean getOverwriteWarning() { return m_OverwriteWarning; } /** * Whether the selected file must exst (only open dialog). * * @param value if true the file must exist */ public void setFileMustExist(boolean value) { m_FileMustExist = value; } /** * Returns whether the selected file must exist (only open dialog). * * @return true if the file must exist */ public boolean getFileMustExist() { return m_FileMustExist; } /** * Whether to display only the hardocded core converters. Necessary for * RMI/Remote Experiments (dynamic class discovery doesn't work there!). * * @param value if true only the core converters will be displayed * @see #m_CoreConvertersOnly */ public void setCoreConvertersOnly(boolean value) { m_CoreConvertersOnly = value; } /** * Returns whether only the hardcoded core converters are displayed. Necessary * for RMI/REmote Experiments (dynamic class discovery doesn't work there!). * * @return true if the file must exist * @see #m_CoreConvertersOnly */ public boolean getCoreConvertersOnly() { return m_CoreConvertersOnly; } /** * Pops a custom file chooser dialog with a custom approve button. Throws an * exception, if the dialog type is UNHANDLED_DIALOG. * * @param parent the parent of this dialog * @param approveButtonText the text for the OK button * @return the user's action */ @Override public int showDialog(Component parent, String approveButtonText) { if (m_DialogType == UNHANDLED_DIALOG) { throw new IllegalStateException( "Either use showOpenDialog or showSaveDialog!"); } else { return super.showDialog(parent, approveButtonText); } } /** * Pops up an "Open File" file chooser dialog. * * @param parent the parent of this file chooser * @return the result of the user's action */ @Override public int showOpenDialog(Component parent) { m_DialogType = LOADER_DIALOG; m_CurrentConverter = null; initGUI(LOADER_DIALOG); int result = super.showOpenDialog(parent); m_DialogType = UNHANDLED_DIALOG; removePropertyChangeListener(m_Listener); // do we have to add the extension? if ((result == APPROVE_OPTION) && (getSelectedFile().isFile())) { if (getFileFilter() instanceof ExtensionFileFilter) { String filename = getSelectedFile().getAbsolutePath(); String[] extensions = ((ExtensionFileFilter) getFileFilter()) .getExtensions(); if (!filename.endsWith(extensions[0])) { filename += extensions[0]; setSelectedFile(new File(filename)); } } } // does file exist? if ((result == APPROVE_OPTION) && (getFileMustExist()) && (getSelectedFile().isFile()) && (!getSelectedFile().exists())) { int retVal = JOptionPane.showConfirmDialog(parent, "The file '" + getSelectedFile() + "' does not exist - please select again!"); if (retVal == JOptionPane.OK_OPTION) { result = showOpenDialog(parent); } else { result = CANCEL_OPTION; } } if (result == APPROVE_OPTION) { m_LastFilter = getFileFilter(); configureCurrentConverter(LOADER_DIALOG); // bring up options dialog? if (m_CheckBoxOptions.isSelected() && m_CurrentConverter != null) { m_EditorResult = JFileChooser.CANCEL_OPTION; m_Editor.setValue(m_CurrentConverter); PropertyDialog pd; if (PropertyDialog.getParentDialog(this) != null) { pd = new PropertyDialog(PropertyDialog.getParentDialog(this), m_Editor); } else { pd = new PropertyDialog(PropertyDialog.getParentFrame(this), m_Editor); } pd.setVisible(true); result = m_EditorResult; } } return result; } /** * Pops up an "Save File" file chooser dialog. * * @param parent the parent of this file chooser * @return the result of the user's action */ @Override public int showSaveDialog(Component parent) { m_DialogType = SAVER_DIALOG; m_CurrentConverter = null; initGUI(SAVER_DIALOG); boolean acceptAll = isAcceptAllFileFilterUsed(); // using "setAcceptAllFileFilterUsed" messes up the currently selected // file filter/file, hence backup/restore of currently selected // file filter/file FileFilter currentFilter = getFileFilter(); File currentFile = getSelectedFile(); setAcceptAllFileFilterUsed(false); setFileFilter(currentFilter); setSelectedFile(currentFile); int result = super.showSaveDialog(parent); // do we have to add the extension? if (result == APPROVE_OPTION) { if (getFileFilter() instanceof ExtensionFileFilter) { String filename = getSelectedFile().getAbsolutePath(); String[] extensions = ((ExtensionFileFilter) getFileFilter()) .getExtensions(); if (!filename.endsWith(extensions[0])) { filename += extensions[0]; setSelectedFile(new File(filename)); } } } // using "setAcceptAllFileFilterUsed" messes up the currently selected // file filter/file, hence backup/restore of currently selected // file filter/file currentFilter = getFileFilter(); currentFile = getSelectedFile(); setAcceptAllFileFilterUsed(acceptAll); setFileFilter(currentFilter); setSelectedFile(currentFile); m_DialogType = UNHANDLED_DIALOG; removePropertyChangeListener(m_Listener); // overwrite the file? if ((result == APPROVE_OPTION) && (getOverwriteWarning()) && (getSelectedFile().exists())) { int retVal = JOptionPane.showConfirmDialog(parent, "The file '" + getSelectedFile() + "' already exists - overwrite it?"); if (retVal == JOptionPane.OK_OPTION) { result = APPROVE_OPTION; } else if (retVal == JOptionPane.NO_OPTION) { result = showSaveDialog(parent); } else { result = CANCEL_OPTION; } } if (result == APPROVE_OPTION) { m_LastFilter = getFileFilter(); configureCurrentConverter(SAVER_DIALOG); // bring up options dialog? if (m_CheckBoxOptions.isSelected()) { m_EditorResult = JFileChooser.CANCEL_OPTION; m_Editor.setValue(m_CurrentConverter); PropertyDialog pd; if (PropertyDialog.getParentDialog(this) != null) { pd = new PropertyDialog(PropertyDialog.getParentDialog(this), m_Editor); } else { pd = new PropertyDialog(PropertyDialog.getParentFrame(this), m_Editor); } pd.setVisible(true); result = m_EditorResult; } } return result; } /** * returns the loader that was chosen by the user, can be null in case the * user aborted the dialog or the save dialog was shown. * * @return the chosen loader, if any */ public AbstractFileLoader getLoader() { configureCurrentConverter(LOADER_DIALOG); if (m_CurrentConverter instanceof AbstractFileSaver) { return null; } else { return (AbstractFileLoader) m_CurrentConverter; } } /** * returns the saver that was chosen by the user, can be null in case the user * aborted the dialog or the open dialog was shown. * * @return the chosen saver, if any */ public AbstractFileSaver getSaver() { configureCurrentConverter(SAVER_DIALOG); if (m_CurrentConverter instanceof AbstractFileLoader) { return null; } else { return (AbstractFileSaver) m_CurrentConverter; } } /** * sets the current converter according to the current filefilter. */ protected void updateCurrentConverter() { String[] extensions; Object newConverter; if (getFileFilter() == null) { return; } if (!isAcceptAllFileFilterUsed()) { // determine current converter extensions = ((ExtensionFileFilter) getFileFilter()).getExtensions(); if (m_DialogType == LOADER_DIALOG) { newConverter = ConverterUtils.getLoaderForExtension(extensions[0]); } else { newConverter = ConverterUtils.getSaverForExtension(extensions[0]); } try { if (m_CurrentConverter == null) { m_CurrentConverter = newConverter; } else { if (!m_CurrentConverter.getClass().equals(newConverter.getClass())) { m_CurrentConverter = newConverter; } } } catch (Exception e) { m_CurrentConverter = null; e.printStackTrace(); } } else { m_CurrentConverter = null; } } /** * configures the current converter. * * @param dialogType the type of dialog to configure for */ protected void configureCurrentConverter(int dialogType) { String filename; File currFile; if ((getSelectedFile() == null) || (getSelectedFile().isDirectory())) { return; } filename = getSelectedFile().getAbsolutePath(); if (m_CurrentConverter == null) { if (dialogType == LOADER_DIALOG) { m_CurrentConverter = ConverterUtils.getLoaderForFile(filename); } else if (dialogType == SAVER_DIALOG) { m_CurrentConverter = ConverterUtils.getSaverForFile(filename); } else { throw new IllegalStateException("Cannot determine loader/saver!"); } // none found? if (m_CurrentConverter == null) { return; } } try { currFile = ((FileSourcedConverter) m_CurrentConverter).retrieveFile(); if ((currFile == null) || (!currFile.getAbsolutePath().equals(filename))) { ((FileSourcedConverter) m_CurrentConverter).setFile(new File(filename)); } } catch (Exception e) { e.printStackTrace(); } } /** * For testing the file chooser. * * @param args the commandline options - ignored * @throws Exception if something goes wrong with loading/saving */ public static void main(String[] args) throws Exception { ConverterFileChooser fc; int retVal; AbstractFileLoader loader; AbstractFileSaver saver; Instances data; fc = new ConverterFileChooser(); retVal = fc.showOpenDialog(null); // load file if (retVal == ConverterFileChooser.APPROVE_OPTION) { loader = fc.getLoader(); data = loader.getDataSet(); retVal = fc.showSaveDialog(null); // save file if (retVal == ConverterFileChooser.APPROVE_OPTION) { saver = fc.getSaver(); saver.setInstances(data); saver.writeBatch(); } else { System.out.println("Saving aborted!"); } } else { System.out.println("Loading aborted!"); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy