package org.opentrafficsim.demo.ntm.IO; import java.awt.Component; import java.awt.Container; import java.io.File; import javax.swing.Icon; import javax.swing.JButton; import javax.swing.JFileChooser; import javax.swing.JOptionPane; import javax.swing.UIManager; import javax.swing.filechooser.FileFilter; /** * The FileDialog class is (or rather should) be used for all file dialogs in Open Traffic * @author Peter Knoppers */ public class FileDialog { /** * Show a file selector dialog to the user. * @param reading boolean; set to true if only existing files may be selected, set to false if a non-existing file may be * returned and new directories may be created. If reading is false and an existing file is selected that is not * equal to the defaultName, an overwrite warning dialog will be displayed. * @param fileType String; expected file type * @param fileTypeDescription String; description of expected file type * @param defaultName String; path to directory shown initially in the file selector dialog; if it ends on an existing file * name, that file is initially selected * @return String; absolute path of the selected file (or null when the operation was cancelled by the user) */ public static String showFileDialog(boolean reading, String fileType, String fileTypeDescription, String defaultName) { FileFilter filter = new ExtensionFileFilter(fileTypeDescription, fileType); javax.swing.JFileChooser fileChooser = new JFileChooser(); if (!fileType.isEmpty()) { fileChooser.setFileFilter(filter); } File defaultFile = new File(defaultName); fileChooser.setCurrentDirectory(defaultFile); if (defaultFile.isFile()) { fileChooser.setSelectedFile(defaultFile); fileChooser.ensureFileIsVisible(defaultFile); } int result; if (reading) { disableNewFolderButton(fileChooser); fileChooser.setDialogType(JFileChooser.OPEN_DIALOG); result = fileChooser.showOpenDialog(null); } else { fileChooser.setDialogType(JFileChooser.SAVE_DIALOG); result = fileChooser.showSaveDialog(null); } if (JFileChooser.APPROVE_OPTION == result) { String fullName = fileChooser.getSelectedFile().getAbsolutePath(); if (null == fullName) return null; String plainName = fileChooser.getSelectedFile().getName(); int dotPosition = plainName.lastIndexOf("."); if ((dotPosition < 0) && (!reading)) fullName += "." + fileType; if ((!reading) && (!defaultName.equals(fullName)) && (new File(fullName).exists())) if (JOptionPane.showConfirmDialog(null, String.format("Overwrite existing file \"%s\"?", fullName), "Overwrite file", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE) != JOptionPane.YES_OPTION) return null; return fullName; } return null; } // adapted from // http://www.java2s.com/Code/Java/Swing-JFC/DisabletheJFileChoosersNewfolderbutton.htm // Search a tree of Containers recursively for a JButton with the newFolderIcon and // call setEnabled(false) for that/those button(s). There should be a cleaner way... private static void disableNewFolderButton(Container c) { for (Component comp : c.getComponents()) { if (comp instanceof JButton) { JButton b = (JButton) comp; Icon icon = b.getIcon(); if ((null != icon) && (icon == UIManager.getIcon("FileChooser.newFolderIcon"))) b.setEnabled(false); } else if (comp instanceof Container) disableNewFolderButton((Container) comp); } } } // adapted from http://www.java2s.com/Code/JavaAPI/javax.swing/JFileChoosersetFileFilterFileFilterfilter.htm class ExtensionFileFilter extends FileFilter { String description; String extensions[]; public ExtensionFileFilter(String description, String extension) { this(description, new String[] {extension}); } public ExtensionFileFilter(String description, String extensions[]) { if (description == null) this.description = extensions[0]; else this.description = description; this.extensions = extensions.clone(); toLower(this.extensions); } private static void toLower(String array[]) { for (int i = 0, n = array.length; i < n; i++) array[i] = array[i].toLowerCase(); } @Override public String getDescription() { return description; } @Override public boolean accept(File file) { if (file.isDirectory()) return true; String path = file.getAbsolutePath().toLowerCase(); for (int i = 0, n = extensions.length; i < n; i++) { String extension = extensions[i]; if ((path.endsWith(extension) && (path.charAt(path.length() - extension.length() - 1)) == '.')) return true; } return false; } }