/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2002-2008, Open Source Geospatial Foundation (OSGeo) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library 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 * Lesser General Public License for more details. */ package org.geotools.swing.dialog; import java.awt.Component; import java.io.File; import java.util.Set; import java.util.TreeSet; import javax.imageio.ImageIO; import javax.swing.JFileChooser; import javax.swing.JOptionPane; import javax.swing.filechooser.FileFilter; import org.geotools.swing.data.JFileDataStoreChooser; import org.geotools.swing.data.JParameterListWizard; /** * A file chooser dialog for common raster image format files. * It provides static methods to display the dialog for opening or * saving an image file with basic validation of user input. * * <pre><code> * // Prompting for an input image file * File file = JFileImageChooser.showOpenFile(null); * if (file != null) { * ... * } * * // Prompting for a file name to save an image * File file = JFileImageChooser.showSaveFile(null); * if (file != null) { * ... * } * </code></pre> * * The file formats offered by the dialog are a subset of those supported by * {@code ImageIO} on the host system. * <p> * * @see JFileDataStoreChooser * @see JParameterListWizard * @see ImageIO * * @author Michael Bedward * @since 2.6.1 * * * @source $URL$ * @version $Id$ */ public class JFileImageChooser extends JFileChooser { private static enum FormatSpecifier { BMP("bmp", "BMP image", ".bmp"), GIF("gif", "GIF image", ".gif"), JPG("jpg", "JPEG image", ".jpg", ".jpeg"), PNG("png", "PNG image", "png"), TIF("tif", "TIFF image", ".tif", ".tiff"); private String id; private String desc; private String[] suffixes; private FormatSpecifier(String id, String desc, String ...suffixes) { this.id = id; this.desc = desc; this.suffixes = new String[suffixes.length]; for (int i = 0; i < suffixes.length; i++) { this.suffixes[i] = suffixes[i]; } } }; private static final Set<FormatSpecifier> supportedReaders = new TreeSet<FormatSpecifier>(); private static final Set<FormatSpecifier> supportedWriters = new TreeSet<FormatSpecifier>(); static { for (FormatSpecifier format : FormatSpecifier.values()) { if (ImageIO.getImageReadersBySuffix(format.id).hasNext()) { supportedReaders.add(format); } if (ImageIO.getImageWritersBySuffix(format.id).hasNext()) { supportedWriters.add(format); } } } private static class FormatFilter extends FileFilter { private FormatSpecifier format; FormatFilter(FormatSpecifier format) { this.format = format; } @Override public boolean accept(File f) { if (f.isDirectory()) { return true; } for (String suffix : format.suffixes) { if (f.getPath().endsWith(suffix) || f.getPath().endsWith(suffix.toUpperCase())) { return true; } } return false; } @Override public String getDescription() { return format.desc; } public String getDefaultSuffix() { return format.suffixes[0]; } } /* * Create a new image file chooser */ public JFileImageChooser() { this(null); } /** * Create a new image file chooser * * @param workingDir the initial directory to display */ public JFileImageChooser(File workingDir) { super(workingDir); } /** * Overridden method to validate the dialog content prior to closing. */ @Override public void approveSelection() { FormatFilter filter = (FormatFilter) getFileFilter(); File file = getSelectedFile(); String name = file.getAbsolutePath(); int dot = name.lastIndexOf('.'); boolean ok = true; if (dot < 0) { /* * No file extension. Set the default one */ name = name + filter.getDefaultSuffix(); file = new File(name); setSelectedFile(file); } if (this.getDialogType() == JFileImageChooser.SAVE_DIALOG) { if (!filter.accept(getSelectedFile())) { StringBuilder sb = new StringBuilder(); sb.append("'"); sb.append(name.substring(dot + 1)); sb.append("' "); sb.append("is not a standard suffix for a "); sb.append(filter.getDescription()); sb.append("."); sb.append("\nDo you want to save with this name ?"); int answer = JOptionPane.showConfirmDialog( getParent(), sb.toString(), "Incompatible file suffix", JOptionPane.YES_NO_OPTION); ok = answer == JOptionPane.YES_OPTION; } if (ok && file.exists()) { int answer = JOptionPane.showConfirmDialog( this, "Overwrite the existing file ?", "File exists", JOptionPane.YES_NO_OPTION); ok = answer == JOptionPane.YES_OPTION; } } else { if (!file.exists()) { JOptionPane.showMessageDialog( this, "Can't file this file", "File not found", JOptionPane.WARNING_MESSAGE); ok = false; } } if (ok) { super.approveSelection(); } } /** * Set the file filters. This is a helper for the static showXXXXFile methods. * * @param supportedFormats the set of file formats that will be offered */ private void setFilter(Set<FormatSpecifier> supportedFormats) { this.setAcceptAllFileFilterUsed(false); for (final FormatSpecifier format : supportedFormats) { addChoosableFileFilter(new FormatFilter(format)); } } /** * Display a dialog to choose a file name to save an image to * * @param parent parent component (may be {@code null}) * * @return the selected file or {@code null} if the dialog was cancelled */ public static File showSaveFile(Component parent) { return showSaveFile(parent, null); } /** * Display a dialog to choose a file name to save an image to * * @param parent parent component (may be {@code null}) * @param workingDir the initial directory to display * * @return the selected file or {@code null} if the dialog was cancelled */ public static File showSaveFile(Component parent, File workingDir) { JFileImageChooser chooser = new JFileImageChooser(workingDir); chooser.setFilter(supportedWriters); chooser.setDialogTitle("Save image"); File file = null; if (chooser.showSaveDialog(parent) == JFileImageChooser.APPROVE_OPTION) { file = chooser.getSelectedFile(); String name = file.getAbsolutePath(); int dot = name.lastIndexOf('.'); FormatFilter filter = (FormatFilter) chooser.getFileFilter(); if (dot < 0) { name = name + filter.getDefaultSuffix(); file = new File(name); } } return file; } /** * Display a dialog to choose an image file to open * * @param parent parent component (may be {@code null}) * @param workingDir the initial directory to display * * @return the selected file or {@code null} if the dialog was cancelled */ public static File showOpenFile(Component parent) { return showOpenFile(parent, null); } /** * Display a dialog to choose an image file to open * * @param parent parent component (may be {@code null}) * @param workingDir the initial directory to display * * @return the selected file or {@code null} if the dialog was cancelled */ public static File showOpenFile(Component parent, File workingDir) { JFileImageChooser chooser = new JFileImageChooser(workingDir); chooser.setFilter(supportedReaders); chooser.setDialogTitle("Open image file"); File file = null; if (chooser.showOpenDialog(parent) == JFileImageChooser.APPROVE_OPTION) { file = chooser.getSelectedFile(); } return file; } }