Ignore:
Timestamp:
2012-08-13T00:12:48+02:00 (12 years ago)
Author:
Don-vip
Message:

fix #6733 - File Open dialog incorrectly accepts folder selection

Major rework of how the JFileChooser are created in JOSM

  • Simple need: use DiskAccessAction.createAndOpenFileChooser methods
  • Complex need: use directly the new class JFileChooserManager

Concerning the directory selection for geottaged images, this is still possible via:

  • right-click on GPX layer -> Import Photos
Location:
trunk/src/org/openstreetmap/josm/actions
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/actions/DiskAccessAction.java

    r4608 r5438  
    22package org.openstreetmap.josm.actions;
    33
    4 import static org.openstreetmap.josm.tools.I18n.tr;
    5 
    6 import java.io.File;
     4import java.util.Collection;
    75
    86import javax.swing.JFileChooser;
     7import javax.swing.filechooser.FileFilter;
    98
    10 import org.openstreetmap.josm.Main;
    11 import org.openstreetmap.josm.gui.ExtendedDialog;
     9import org.openstreetmap.josm.gui.widgets.JFileChooserManager;
    1210import org.openstreetmap.josm.tools.Shortcut;
    1311
    1412/**
    15  * Helper class for all actions that access the disk
     13 * Helper class for all actions that access the disk.
     14 * @since 78
    1615 */
    1716abstract public class DiskAccessAction extends JosmAction {
    1817
     18    /**
     19     * Constructs a new {@code DiskAccessAction}.
     20     *
     21     * @param name The action's text as displayed on the menu (if it is added to a menu)
     22     * @param iconName The filename of the icon to use
     23     * @param tooltip A longer description of the action that will be displayed in the tooltip
     24     * @param shortcut A ready-created shortcut object or {@code null} if you don't want a shortcut
     25     * @since 1084
     26     */
    1927    public DiskAccessAction(String name, String iconName, String tooltip, Shortcut shortcut) {
    2028        super(name, iconName, tooltip, shortcut, true);
    2129    }
    2230
     31    /**
     32     * Constructs a new {@code DiskAccessAction}.
     33     *
     34     * @param name The action's text as displayed on the menu (if it is added to a menu)
     35     * @param iconName The filename of the icon to use
     36     * @param tooltip  A longer description of the action that will be displayed in the tooltip
     37     * @param shortcut A ready-created shortcut object or null if you don't want a shortcut
     38     * @param register Register this action for the toolbar preferences?
     39     * @param toolbarId Identifier for the toolbar preferences. The iconName is used, if this parameter is null
     40     * @param installAdapters False, if you don't want to install layer changed and selection changed adapters
     41     * @since 5438
     42     */
     43    public DiskAccessAction(String name, String iconName, String tooltip, Shortcut shortcut, boolean register, String toolbarId, boolean installAdapters) {
     44        super(name, iconName, tooltip, shortcut, register, toolbarId, installAdapters);
     45    }
     46
     47    /**
     48     * Creates a new {@link JFileChooser} and makes it visible.
     49     * @param open If true, pops up an "Open File" dialog. If false, pops up a "Save File" dialog
     50     * @param multiple If true, makes the dialog allow multiple file selections
     51     * @param title The string that goes in the dialog window's title bar
     52     * @return The {@code JFileChooser}.
     53     * @since 1646
     54     */
    2355    public static JFileChooser createAndOpenFileChooser(boolean open, boolean multiple, String title) {
    2456        return createAndOpenFileChooser(open, multiple, title, null);
    2557    }
    2658
     59    /**
     60     * Creates a new {@link JFileChooser} and makes it visible.
     61     * @param open If true, pops up an "Open File" dialog. If false, pops up a "Save File" dialog
     62     * @param multiple If true, makes the dialog allow multiple file selections
     63     * @param title The string that goes in the dialog window's title bar
     64     * @param extension The file extension that will be selected as the default file filter
     65     * @return The {@code JFileChooser}.
     66     * @since 2020
     67     */
    2768    public static JFileChooser createAndOpenFileChooser(boolean open, boolean multiple, String title, String extension) {
    28         String curDir = Main.pref.get("lastDirectory");
    29         if (curDir.equals("")) {
    30             curDir = ".";
    31         }
    32         JFileChooser fc = new JFileChooser(new File(curDir));
    33         if (title != null) {
    34             fc.setDialogTitle(title);
    35         }
     69        return createAndOpenFileChooser(open, multiple, title, extension, JFileChooser.FILES_ONLY, true, null);
     70    }
    3671
    37         fc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
    38         fc.setMultiSelectionEnabled(multiple);
    39         fc.setAcceptAllFileFilterUsed(false);
    40         ExtensionFileFilter.applyChoosableImportFileFilters(fc, extension);
     72    /**
     73     * Creates a new {@link JFileChooser} and makes it visible.
     74     * @param open If true, pops up an "Open File" dialog. If false, pops up a "Save File" dialog
     75     * @param multiple If true, makes the dialog allow multiple file selections
     76     * @param title The string that goes in the dialog window's title bar
     77     * @param extension The file extension that will be selected as the default file filter
     78     * @param selectionMode The selection mode that allows the user to:<br/>
     79     *                      <li>just select files ({@code JFileChooser.FILES_ONLY})</li>
     80     *                      <li>just select directories ({@code JFileChooser.DIRECTORIES_ONLY})</li>
     81     *                      <li>select both files and directories ({@code JFileChooser.FILES_AND_DIRECTORIES})</li>
     82     * @param allTypes If true, all the files types known by JOSM will be proposed in the "file type" combobox.
     83     *                 If false, only the file filters that include {@code extension} will be proposed
     84     * @param lastDirProperty The name of the property used to setup the JFileChooser initial directory.
     85     *        This property will then be updated to the new "last directory" chosen by the user. If null, the default property "lastDirectory" will be used.
     86     * @return The {@code JFileChooser}.
     87     * @since 5438
     88     */
     89    public static JFileChooser createAndOpenFileChooser(boolean open, boolean multiple, String title, String extension, int selectionMode, boolean allTypes, String lastDirProperty) {
     90        return new JFileChooserManager(open, lastDirProperty).createFileChooser(multiple, title, extension, allTypes, selectionMode).openFileChooser();
     91    }
    4192
    42         int answer = open ? fc.showOpenDialog(Main.parent) : fc.showSaveDialog(Main.parent);
    43         if (answer != JFileChooser.APPROVE_OPTION)
    44             return null;
     93    /**
     94     * Creates a new {@link JFileChooser} for a single {@link FileFilter} and makes it visible.
     95     * @param open If true, pops up an "Open File" dialog. If false, pops up a "Save File" dialog
     96     * @param multiple If true, makes the dialog allow multiple file selections
     97     * @param title The string that goes in the dialog window's title bar
     98     * @param filter The only file filter that will be proposed by the dialog
     99     * @param selectionMode The selection mode that allows the user to:<br/>
     100     *                      <li>just select files ({@code JFileChooser.FILES_ONLY})</li>
     101     *                      <li>just select directories ({@code JFileChooser.DIRECTORIES_ONLY})</li>
     102     *                      <li>select both files and directories ({@code JFileChooser.FILES_AND_DIRECTORIES})</li>
     103     * @param lastDirProperty The name of the property used to setup the JFileChooser initial directory. This property will then be updated to the new "last directory" chosen by the user
     104     * @return The {@code JFileChooser}.
     105     * @since 5438
     106     */
     107    public static JFileChooser createAndOpenFileChooser(boolean open, boolean multiple, String title, FileFilter filter, int selectionMode, String lastDirProperty) {
     108        return new JFileChooserManager(open, lastDirProperty).createFileChooser(multiple, title, filter, selectionMode).openFileChooser();
     109    }
    45110
    46         if (!fc.getCurrentDirectory().getAbsolutePath().equals(curDir)) {
    47             Main.pref.put("lastDirectory", fc.getCurrentDirectory().getAbsolutePath());
    48         }
    49 
    50         if (!open) {
    51             File file = fc.getSelectedFile();
    52             if (file != null && file.exists()) {
    53                 ExtendedDialog dialog = new ExtendedDialog(
    54                         Main.parent,
    55                         tr("Overwrite"),
    56                         new String[] {tr("Overwrite"), tr("Cancel")}
    57                 );
    58                 dialog.setContent(tr("File exists. Overwrite?"));
    59                 dialog.setButtonIcons(new String[] {"save_as.png", "cancel.png"});
    60                 dialog.showDialog();
    61                 if (dialog.getValue() != 1)
    62                     return null;
    63             }
    64         }
    65 
    66         return fc;
     111    /**
     112     * Creates a new {@link JFileChooser} for several {@link FileFilter}s and makes it visible.
     113     * @param open If true, pops up an "Open File" dialog. If false, pops up a "Save File" dialog
     114     * @param multiple If true, makes the dialog allow multiple file selections
     115     * @param title The string that goes in the dialog window's title bar
     116     * @param filters The file filters that will be proposed by the dialog
     117     * @param defaultFilter The file filter that will be selected by default
     118     * @param selectionMode The selection mode that allows the user to:<br/>
     119     *                      <li>just select files ({@code JFileChooser.FILES_ONLY})</li>
     120     *                      <li>just select directories ({@code JFileChooser.DIRECTORIES_ONLY})</li>
     121     *                      <li>select both files and directories ({@code JFileChooser.FILES_AND_DIRECTORIES})</li>
     122     * @param lastDirProperty The name of the property used to setup the JFileChooser initial directory. This property will then be updated to the new "last directory" chosen by the user
     123     * @return The {@code JFileChooser}.
     124     * @since 5438
     125     */
     126    public static JFileChooser createAndOpenFileChooser(boolean open, boolean multiple, String title,
     127            Collection<? extends FileFilter> filters, FileFilter defaultFilter, int selectionMode, String lastDirProperty) {
     128        return new JFileChooserManager(open, lastDirProperty).createFileChooser(multiple, title, filters, defaultFilter, selectionMode).openFileChooser();
    67129    }
    68130}
  • trunk/src/org/openstreetmap/josm/actions/ExtensionFileFilter.java

    r5266 r5438  
    1919 * A file filter that filters after the extension. Also includes a list of file
    2020 * filters used in JOSM.
    21  *
     21 * @since 32
    2222 */
    2323public class ExtensionFileFilter extends FileFilter {
    2424
    2525    /**
    26      * list of supported formats
     26     * List of supported formats for import.
     27     * @since 4869
    2728     */
    2829    public static final ArrayList<FileImporter> importers;
    2930
     31    /**
     32     * List of supported formats for export.
     33     * @since 4869
     34     */
    3035    public static final ArrayList<FileExporter> exporters;
    3136
     
    95100     * Updates the {@link AllFormatsImporter} that is contained in the importers list. If
    96101     * you do not use the importers variable directly, you don’t need to call this.
     102     * <p>
     103     * Updating the AllFormatsImporter is required when plugins add new importers that
     104     * support new file extensions. The old AllFormatsImporter doesn’t include the new
     105     * extensions and thus will not display these files.
    97106     *
    98      *  Updating the AllFormatsImporter is required when plugins add new importers that
    99      *  support new file extensions. The old AllFormatsImporter doesn’t include the new
    100      *  extensions and thus will not display these files.
     107     * @since 5131
    101108     */
    102109    public static void updateAllFormatsImporter() {
     
    114121     *
    115122     * @return an ordered list of {@link ExtensionFileFilter}s for importing.
     123     * @since 2029
    116124     */
    117125    public static List<ExtensionFileFilter> getImportExtensionFileFilters() {
     
    131139     *
    132140     * @return an ordered list of {@link ExtensionFileFilter}s for exporting.
     141     * @since 2029
    133142     */
    134143    public static List<ExtensionFileFilter> getExportExtensionFileFilters() {
     
    149158     * @param extension the extension
    150159     * @return the default {@link ExtensionFileFilter} for a given extension
     160     * @since 2029
    151161     */
    152162    public static ExtensionFileFilter getDefaultImportExtensionFileFilter(String extension) {
     
    164174     * @param extension the extension
    165175     * @return the default {@link ExtensionFileFilter} for a given extension
     176     * @since 2029
    166177     */
    167178    public static ExtensionFileFilter getDefaultExportExtensionFileFilter(String extension) {
     
    180191     * @param fileChooser the file chooser
    181192     * @param extension the default extension
    182      */
    183     public static void applyChoosableImportFileFilters(JFileChooser fileChooser, String extension) {
     193     * @param allTypes If true, all the files types known by JOSM will be proposed in the "file type" combobox.
     194     *                 If false, only the file filters that include {@code extension} will be proposed
     195     * @since 5438
     196     */
     197    public static void applyChoosableImportFileFilters(JFileChooser fileChooser, String extension, boolean allTypes) {
    184198        for (ExtensionFileFilter filter: getImportExtensionFileFilters()) {
    185             fileChooser.addChoosableFileFilter(filter);
     199            if (allTypes || filter.acceptName("file."+extension)) {
     200                fileChooser.addChoosableFileFilter(filter);
     201            }
    186202        }
    187203        fileChooser.setFileFilter(getDefaultImportExtensionFileFilter(extension));
     
    194210     * @param fileChooser the file chooser
    195211     * @param extension the default extension
    196      */
    197     public static void applyChoosableExportFileFilters(JFileChooser fileChooser, String extension) {
     212     * @param allTypes If true, all the files types known by JOSM will be proposed in the "file type" combobox.
     213     *                 If false, only the file filters that include {@code extension} will be proposed
     214     * @since 5438
     215     */
     216    public static void applyChoosableExportFileFilters(JFileChooser fileChooser, String extension, boolean allTypes) {
    198217        for (ExtensionFileFilter filter: getExportExtensionFileFilters()) {
    199             fileChooser.addChoosableFileFilter(filter);
     218            if (allTypes || filter.acceptName("file."+extension)) {
     219                fileChooser.addChoosableFileFilter(filter);
     220            }
    200221        }
    201222        fileChooser.setFileFilter(getDefaultExportExtensionFileFilter(extension));
     
    204225    /**
    205226     * Construct an extension file filter by giving the extension to check after.
     227     * @param extension The comma-separated list of file extensions
     228     * @param defaultExtension The default extension
     229     * @param description A short textual description of the file type
     230     * @since 1169
    206231     */
    207232    public ExtensionFileFilter(String extension, String defaultExtension, String description) {
     
    211236    }
    212237
     238    /**
     239     * Returns true if this file filter accepts the given filename.
     240     * @param filename The filename to check after
     241     * @return true if this file filter accepts the given filename (i.e if this filename ends with one of the extensions)
     242     * @since 1169
     243     */
    213244    public boolean acceptName(String filename) {
    214245        String name = filename.toLowerCase();
     
    219250    }
    220251
    221     @Override public boolean accept(File pathname) {
     252    @Override
     253    public boolean accept(File pathname) {
    222254        if (pathname.isDirectory())
    223255            return true;
     
    225257    }
    226258
    227     @Override public String getDescription() {
     259    @Override
     260    public String getDescription() {
    228261        return description;
    229262    }
    230263
     264    /**
     265     * Replies the comma-separated list of file extensions of this file filter.
     266     * @return the comma-separated list of file extensions of this file filter, as a String
     267     * @since 5131
     268     */
    231269    public String getExtensions() {
    232270        return extensions;
    233271    }
    234272
     273    /**
     274     * Replies the default file extension of this file filter.
     275     * @return the default file extension of this file filter
     276     * @since 2029
     277     */
    235278    public String getDefaultExtension() {
    236279        return defaultExtension;
  • trunk/src/org/openstreetmap/josm/actions/SaveActionBase.java

    r5014 r5438  
    182182
    183183    public static File createAndOpenSaveFileChooser(String title, String extension) {
    184         String curDir = Main.pref.get("lastDirectory");
    185         if (curDir.equals("")) {
    186             curDir = ".";
    187         }
    188         JFileChooser fc = new JFileChooser(new File(curDir));
    189         if (title != null) {
    190             fc.setDialogTitle(title);
    191         }
    192 
    193         fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
    194         fc.setMultiSelectionEnabled(false);
    195         fc.setAcceptAllFileFilterUsed(false);
    196         ExtensionFileFilter.applyChoosableExportFileFilters(fc, extension);
    197         int answer = fc.showSaveDialog(Main.parent);
    198         if (answer != JFileChooser.APPROVE_OPTION)
    199             return null;
    200 
    201         if (!fc.getCurrentDirectory().getAbsolutePath().equals(curDir)) {
    202             Main.pref.put("lastDirectory", fc.getCurrentDirectory().getAbsolutePath());
    203         }
     184
     185        JFileChooser fc = createAndOpenFileChooser(false, false, title, extension);
     186        if (fc == null) return null;
    204187
    205188        File file = fc.getSelectedFile();
    206189        String fn = file.getPath();
    207         if(fn.indexOf('.') == -1)
     190        if (fn.indexOf('.') == -1)
    208191        {
    209192            FileFilter ff = fc.getFileFilter();
  • trunk/src/org/openstreetmap/josm/actions/SessionLoadAction.java

    r4874 r5438  
    1313import javax.swing.JOptionPane;
    1414import javax.swing.SwingUtilities;
    15 import javax.swing.filechooser.FileFilter;
    1615
    1716import org.openstreetmap.josm.Main;
     
    2322import org.openstreetmap.josm.io.session.SessionReader;
    2423
    25 public class SessionLoadAction extends JosmAction {
     24public class SessionLoadAction extends DiskAccessAction {
     25   
    2626    public SessionLoadAction() {
    2727        super(tr("Load Session"), "open", tr("Load a session from file."), null, true, "load-session", true);
     
    3030
    3131    public void actionPerformed(ActionEvent e) {
    32         String curDir = Main.pref.get("lastDirectory");
    33         if (curDir.equals("")) {
    34             curDir = ".";
    35         }
    36         JFileChooser fc = new JFileChooser(new File(curDir));
    37         fc.setDialogTitle(tr("Open session"));
    38         fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
    39         fc.setMultiSelectionEnabled(false);
    40         fc.setAcceptAllFileFilterUsed(true);
    41         FileFilter ff = new ExtensionFileFilter("jos,joz", "jos", tr("Session file (*.jos, *.joz)"));
    42         fc.addChoosableFileFilter(ff);
    43         int answer = fc.showOpenDialog(Main.parent);
    44         if (answer != JFileChooser.APPROVE_OPTION)
    45             return;
    46 
    47         if (!fc.getCurrentDirectory().getAbsolutePath().equals(curDir)) {
    48             Main.pref.put("lastDirectory", fc.getCurrentDirectory().getAbsolutePath());
    49         }
     32        ExtensionFileFilter ff = new ExtensionFileFilter("jos,joz", "jos", tr("Session file (*.jos, *.joz)"));
     33        JFileChooser fc = createAndOpenFileChooser(true, false, tr("Open session"), ff, JFileChooser.FILES_ONLY, "lastDirectory");
     34        if (fc == null) return;
    5035        File file = fc.getSelectedFile();
    51         boolean zip = true;
    52         if (file.getName().toLowerCase().endsWith(".jos")) {
    53             zip = false;
    54         }
     36        boolean zip = file.getName().toLowerCase().endsWith(".joz");
    5537        Main.worker.submit(new Loader(file, zip));
    5638    }
     
    7254        @Override
    7355        protected void cancel() {
    74             Thread.currentThread().dumpStack();
     56            Thread.dumpStack();
    7557            canceled = true;
    7658        }
  • trunk/src/org/openstreetmap/josm/actions/SessionSaveAsAction.java

    r4910 r5438  
    22package org.openstreetmap.josm.actions;
    33
     4import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
    45import static org.openstreetmap.josm.tools.I18n.tr;
    5 import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
    66
    77import java.awt.Component;
     
    1212import java.io.IOException;
    1313import java.util.ArrayList;
     14import java.util.Arrays;
    1415import java.util.Collection;
     16import java.util.Collections;
    1517import java.util.HashMap;
    1618import java.util.HashSet;
     
    3234
    3335import org.openstreetmap.josm.Main;
    34 import org.openstreetmap.josm.actions.ExtensionFileFilter;
    3536import org.openstreetmap.josm.gui.ExtendedDialog;
    3637import org.openstreetmap.josm.gui.HelpAwareOptionPane;
     
    4243import org.openstreetmap.josm.tools.WindowGeometry;
    4344
    44 public class SessionSaveAsAction extends JosmAction {
     45public class SessionSaveAsAction extends DiskAccessAction {
    4546
    4647    private List<Layer> layers;
     
    5253    /**
    5354     * Construct the action with "Save" as label.
    54      * @param layer Save this layer.
    5555     */
    5656    public SessionSaveAsAction() {
     
    7777            }
    7878        }
    79 
    80         String curDir = Main.pref.get("lastDirectory");
    81         if (curDir.equals("")) {
    82             curDir = ".";
    83         }
    84         JFileChooser fc = new JFileChooser(new File(curDir));
    85         fc.setDialogTitle(tr("Save session"));
    86         fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
     79       
    8780        FileFilter joz = new ExtensionFileFilter("joz", "joz", tr("Session file (archive) (*.joz)"));
    8881        FileFilter jos = new ExtensionFileFilter("jos", "jos", tr("Session file (*.jos)"));
     82
     83        JFileChooser fc;
     84       
    8985        if (zipRequired) {
    90             fc.addChoosableFileFilter(joz);
     86            fc = createAndOpenFileChooser(false, false, tr("Save session"), joz, JFileChooser.FILES_ONLY, "lastDirectory");
    9187        } else {
    92             fc.addChoosableFileFilter(jos);
    93             fc.addChoosableFileFilter(joz);
    94             fc.setFileFilter(jos);
    95         }
    96         int answer = fc.showSaveDialog(Main.parent);
    97         if (answer != JFileChooser.APPROVE_OPTION)
     88            fc = createAndOpenFileChooser(false, false, tr("Save session"), Arrays.asList(new FileFilter[]{jos, joz}), jos, JFileChooser.FILES_ONLY, "lastDirectory");
     89        }
     90
     91        if (fc == null)
    9892            return;
    99 
    100         if (!fc.getCurrentDirectory().getAbsolutePath().equals(curDir)) {
    101             Main.pref.put("lastDirectory", fc.getCurrentDirectory().getAbsolutePath());
    102         }
    10393
    10494        File file = fc.getSelectedFile();
Note: See TracChangeset for help on using the changeset viewer.