package icy.gui.dialog; import java.awt.Dimension; import java.awt.Rectangle; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.File; import java.util.List; import javax.swing.JFileChooser; import javax.swing.filechooser.FileFilter; import icy.file.FileImporter; import icy.file.FileUtil; import icy.file.Loader; import icy.file.SequenceFileImporter; import icy.main.Icy; import icy.preferences.ApplicationPreferences; import icy.preferences.GeneralPreferences; import icy.preferences.XMLPreferences; import icy.type.collection.CollectionUtil; import icy.util.StringUtil; /** * Loader dialog used to load resource or image from the {@link FileImporter} or * {@link SequenceFileImporter}. * * @author Stephane * @see Loader */ public class LoaderDialog extends JFileChooser implements PropertyChangeListener { /** * */ private static final long serialVersionUID = 5162434537949723956L; public static class AllImagesFileFilter extends FileFilter { @Override public boolean accept(File file) { if (file.isDirectory()) return true; return !Loader.canDiscardImageFile(file.getName()); } @Override public String getDescription() { return "All images file"; } } public static class AllFileFilter extends FileFilter { @Override public boolean accept(File file) { return file.exists(); } @Override public String getDescription() { return "All files"; } } public static AllImagesFileFilter allImagesFileFilter = new AllImagesFileFilter(); public static AllFileFilter allFileFilter = new AllFileFilter(); private static final String PREF_ID = "frame/imageLoader"; private static final String ID_WIDTH = "width"; private static final String ID_HEIGTH = "heigth"; private static final String ID_SEPARATE = "separate"; private static final String ID_AUTOORDER = "autoOrder"; private static final String ID_EXTENSION = "extension"; // GUI protected final LoaderOptionPanel optionPanel; protected final List<SequenceFileImporter> sequenceImporters; protected final List<FileImporter> fileImporters; /** * Display a dialog to select image or resource file(s) and load them.<br> * <br> * To only get selected files from the dialog you must do:<br> * <code> LoaderDialog dialog = new LoaderDialog(false);</code><br> * <code> File[] selectedFiles = dialog.getSelectedFiles()</code><br> * <br> * To directly load selected files just use:<br> * <code>new LoaderDialog(true);</code><br> * or<br> * <code>new LoaderDialog();</code> * * @param defaultPath * default file path (can be null) * @param region * default XY region (can be null) * @param autoLoad * If true the selected file(s) are automatically loaded. */ public LoaderDialog(String defaultPath, Rectangle region, boolean autoLoad) { super(); final XMLPreferences preferences = ApplicationPreferences.getPreferences().node(PREF_ID); sequenceImporters = Loader.getSequenceFileImporters(); fileImporters = Loader.getFileImporters(); // create option panel optionPanel = new LoaderOptionPanel(preferences.getBoolean(ID_SEPARATE, false), preferences.getBoolean(ID_AUTOORDER, true)); // we can only store dimension for JFileChooser setPreferredSize(new Dimension(preferences.getInt(ID_WIDTH, 600), preferences.getInt(ID_HEIGTH, 400))); setMultiSelectionEnabled(true); setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); setAcceptAllFileFilterUsed(false); resetChoosableFileFilters(); // add file filter from importers for (SequenceFileImporter importer : sequenceImporters) { final List<FileFilter> filters = importer.getFileFilters(); if (filters != null) { for (FileFilter filter : filters) addChoosableFileFilter(filter); } } for (FileImporter importer : fileImporters) { final List<FileFilter> filters = importer.getFileFilters(); if (filters != null) { for (FileFilter filter : filters) addChoosableFileFilter(filter); } } // add "all files" filter addChoosableFileFilter(allFileFilter); // we use a default path ? if (defaultPath != null) { // set all files filter setFileFilter(allFileFilter); final File file = new File(defaultPath); if (file.isDirectory()) setCurrentDirectory(file); else setSelectedFile(file); } else { // set last used file filter setFileFilter(getFileFilter(preferences.get(ID_EXTENSION, allImagesFileFilter.getDescription()))); // set last used directory setCurrentDirectory(new File(GeneralPreferences.getLoaderFolder())); } // setting GUI updateGUI(); // we use a default path ? if (defaultPath != null) { // refresh preview optionPanel.updatePreview(defaultPath); updateOptionPanel(); } // have a default XY region ? if (region != null) optionPanel.setXYRegion(region); // listen file filter change addPropertyChangeListener(this); // display loader final int value = showOpenDialog(Icy.getMainInterface().getMainFrame()); // action confirmed ? if (value == JFileChooser.APPROVE_OPTION) { // store current path GeneralPreferences.setLoaderFolder(getCurrentDirectory().getAbsolutePath()); preferences.putBoolean(ID_SEPARATE, isSeparateSequenceSelected()); preferences.putBoolean(ID_AUTOORDER, isAutoOrderSelected()); preferences.put(ID_EXTENSION, getFileFilter().getDescription()); // load if requested if (autoLoad) { // get selected paths final List<String> paths = CollectionUtil.asList(FileUtil.toPaths(getSelectedFiles())); // first path final String firstPath = paths.get(0); // get the selected importer from file filter final Object importer = getImporter(getFileFilterIndex()); // multi file or folder loading if ((paths.size() > 1) || FileUtil.isDirectory(firstPath)) { if (importer instanceof FileImporter) { // load selected non image file(s) Loader.load((FileImporter) importer, paths, true); } else if (importer instanceof SequenceFileImporter) { // load selected image file(s) Loader.load((SequenceFileImporter) importer, paths, isSeparateSequenceSelected(), isAutoOrderSelected(), true); } else { // load selected file(s) Loader.load(paths, isSeparateSequenceSelected(), isAutoOrderSelected(), true); } } else { // single file loading if (importer instanceof FileImporter) { // load selected non image file Loader.load((FileImporter) importer, paths, true); } else if (importer instanceof SequenceFileImporter) { // load selected image file with advanced option Loader.load((SequenceFileImporter) importer, firstPath, -1, optionPanel.getResolutionLevel(), optionPanel.getXYRegion(), optionPanel.getZMin(), optionPanel.getZMax(), optionPanel.getTMin(), optionPanel.getTMax(), optionPanel.getChannel(), true, true); } else { // load selected file Loader.load(null, firstPath, -1, optionPanel.getResolutionLevel(), optionPanel.getXYRegion(), optionPanel.getZMin(), optionPanel.getZMax(), optionPanel.getTMin(), optionPanel.getTMax(), optionPanel.getChannel(), true, true); } } } } // store interface option preferences.putInt(ID_WIDTH, getWidth()); preferences.putInt(ID_HEIGTH, getHeight()); } /** * Display a dialog to select image or resource file(s) and load them.<br> * <br> * To only get selected files from the dialog you must do:<br> * <code> LoaderDialog dialog = new LoaderDialog(false);</code><br> * <code> File[] selectedFiles = dialog.getSelectedFiles()</code><br> * <br> * To directly load selected files just use:<br> * <code>new LoaderDialog(true);</code><br> * or<br> * <code>new LoaderDialog();</code> * * @param autoLoad * If true the selected file(s) are automatically loaded. */ public LoaderDialog(boolean autoLoad) { this(null, null, autoLoad); } /** * Display a dialog to select file(s) and load them. */ public LoaderDialog() { this(null, null, true); } protected FileFilter getFileFilter(String description) { final FileFilter[] filters = getChoosableFileFilters(); for (FileFilter filter : filters) if (StringUtil.equals(filter.getDescription(), description)) return filter; // take first filter by default if (filters.length > 0) return filters[0]; return null; } protected int getFileFilterIndex() { final FileFilter[] filters = getChoosableFileFilters(); final FileFilter filter = getFileFilter(); for (int i = 0; i < filters.length; i++) if (filter == filters[i]) return i; return -1; } protected boolean isImageFilter() { return getImporter(getFileFilterIndex()) instanceof SequenceFileImporter; } protected boolean isAllFileFilter() { return getFileFilter() == allFileFilter; } protected Object getImporter(int filterIndex) { int ind = 0; for (SequenceFileImporter importer : sequenceImporters) { final List<FileFilter> filters = importer.getFileFilters(); final int count = (filters != null) ? filters.size() : 0; if (filterIndex < (ind + count)) return importer; ind += count; } for (FileImporter importer : fileImporters) { final List<FileFilter> filters = importer.getFileFilters(); final int count = (filters != null) ? filters.size() : 0; if (filterIndex < (ind + count)) return importer; ind += count; } return null; } /** * Returns true if user checked the "Separate sequence" option. */ public boolean isSeparateSequenceSelected() { return optionPanel.isSeparateSequenceSelected(); } /** * Returns true if user checked the "Auto Ordering" option. */ public boolean isAutoOrderSelected() { return optionPanel.isAutoOrderSelected(); } /** * Get selected resolution level */ public int getResolutionLevel() { return optionPanel.getResolutionLevel(); } /** * Get selected XY region (when region loading is enabled) */ public Rectangle getXYRegion() { return optionPanel.getXYRegion(); } /** * Get minimum Z (Z range selection) */ public int getZMin() { return optionPanel.getZMin(); } /** * Get maximum Z (Z range selection) */ public int getZMax() { return optionPanel.getZMax(); } /** * Get minimum T (T range selection) */ public int getTMin() { return optionPanel.getTMin(); } /** * Get maximum T (T range selection) */ public int getTMax() { return optionPanel.getTMax(); } /** * Get channel selection (-1 for all) */ public int getChannel() { return optionPanel.getChannel(); } @Override public void propertyChange(PropertyChangeEvent evt) { final String prop = evt.getPropertyName(); if (prop.equals(JFileChooser.FILE_FILTER_CHANGED_PROPERTY)) updateGUI(); else if (prop.equals(JFileChooser.SELECTED_FILE_CHANGED_PROPERTY)) { File f = (File) evt.getNewValue(); if ((f != null) && (f.isDirectory() || !f.exists())) f = null; // refresh preview if (f != null) optionPanel.updatePreview(f.getAbsolutePath()); else optionPanel.updatePreview(""); updateOptionPanel(); } // closing ? --> do some final operation on option panel else if (prop.equals("JFileChooserDialogIsClosingProperty")) optionPanel.closingFromEDT(); else updateOptionPanel(); } protected void updateGUI() { if (isImageFilter() || isAllFileFilter()) { setDialogTitle("Load image file(s)"); setAccessory(optionPanel); updateOptionPanel(); revalidate(); } else { setDialogTitle("Load file(s)"); setAccessory(null); revalidate(); } } protected void updateOptionPanel() { final int numFile = getSelectedFiles().length; final boolean multi; if (numFile > 1) multi = true; else { final File file = getSelectedFile(); multi = (file != null) && file.isDirectory(); } optionPanel.setMultiFile(multi); } }