content: /*
   *    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.
   */
  
  /*
   * ConverterFileChooser.java
   * Copyright (C) 2006 University of Waikato, Hamilton, New Zealand
   */
  
  package weka.gui;
  
  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;
  
  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;
  
  /**
   * 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: 7008 $
   * @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<ExtensionFileFilter> m_LoaderFileFilters;
  
    /** the file filters for the savers. */
    protected static Vector<ExtensionFileFilter> 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("<html><br>Note:<br><br>Some file formats offer additional<br>options which can be customized<br>when invoking the options dialog.</html>");
      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() {
        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() {
        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<ExtensionFileFilter> filterNonCoreLoaderFileFilters(Vector<ExtensionFileFilter> list) {
      Vector<ExtensionFileFilter> result;
      int				i;
      ExtensionFileFilter		filter;
      AbstractLoader		loader;
      
      if (!getCoreConvertersOnly()) {
        result = list;
      }
      else {
        result = new Vector<ExtensionFileFilter>();
        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<ExtensionFileFilter> filterNonCoreSaverFileFilters(Vector<ExtensionFileFilter> list) {
      Vector<ExtensionFileFilter> result;
      int				i;
      ExtensionFileFilter		filter;
      AbstractSaver		saver;
      
      if (!getCoreConvertersOnly()) {
        result = list;
      }
      else {
        result = new Vector<ExtensionFileFilter>();
        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<ExtensionFileFilter> filterSaverFileFilters(Vector<ExtensionFileFilter> list) {
      Vector<ExtensionFileFilter>	result;
      int				i;
      ExtensionFileFilter		filter;
      AbstractSaver		saver;
      
      if (m_CapabilitiesFilter == null) {
        result = list;
      }
      else {
        result = new Vector<ExtensionFileFilter>();
        
        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<String> classnames) {
      int				i;
      int				n;
      String 			classname;
      Class 			cls;
      String[] 			ext;
      String 			desc;
      FileSourcedConverter 	converter;
      ExtensionFileFilter 	filter;
      
      if (loader)
        m_LoaderFileFilters = new Vector<ExtensionFileFilter>();
      else
        m_SaverFileFilters  = new Vector<ExtensionFileFilter>();
  
      for (i = 0; i < classnames.size(); i++) {
        classname = (String) 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<ExtensionFileFilter>	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() {
        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
     */
    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
     */
    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_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
     */
    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!");
      }
    }
  }
  