--- a/openide.filesystems/apichanges.xml +++ a/openide.filesystems/apichanges.xml @@ -46,6 +46,34 @@ Filesystems API + + + Added FileChooserBuilder.setSelectionApprover(FileChooserBuilder.SelectionApprover) and FileChooserBuilder.addFileFilter() + + + + +

+ Added FileChooserBuilder.setSelectionApprover(), + FileChooserBuilder.addFileFilter() and the interface + FileChooserBuilder.SelectionApprover. +

+
+ +

+ Added FileChooserBuilder.setSelectionApprover() which enables + JFileChoosers created by a FileChooserBuilder to intercept + JFileChooser.approveSelection() (for example, to ask the user + if it is ok to overwrite a file); added + FileChooserBuilder.addFileFilter() which operates similarly + to JFileChooser.addChoosableFileFilter(), so JFileChoosers + created by a FileChooserBuilder can be given user-selectable + file filters. +

+
+ + +
System filesystem label/icon annotations work without full module system --- a/openide.filesystems/nbproject/project.properties +++ a/openide.filesystems/nbproject/project.properties @@ -44,4 +44,4 @@ javadoc.main.page=org/openide/filesystems/doc-files/api.html javadoc.arch=${basedir}/arch.xml javadoc.apichanges=${basedir}/apichanges.xml -spec.version.base=7.25.0 +spec.version.base=7.26.0 --- a/openide.filesystems/src/org/openide/filesystems/FileChooserBuilder.java +++ a/openide.filesystems/src/org/openide/filesystems/FileChooserBuilder.java @@ -46,6 +46,8 @@ import java.awt.HeadlessException; import java.awt.KeyboardFocusManager; import java.io.File; +import java.util.ArrayList; +import java.util.List; import javax.swing.Icon; import javax.swing.JFileChooser; import javax.swing.filechooser.FileFilter; @@ -113,6 +115,8 @@ private boolean filesOnly; private static final boolean DONT_STORE_DIRECTORIES = Boolean.getBoolean("forget.recent.dirs"); + private SelectionApprover approver; + private final List filters = new ArrayList(3); /** * Create a new FileChooserBuilder using the name of the passed class * as the metadata for looking up a starting directory from previous @@ -248,7 +252,8 @@ * @return A file chooser */ public JFileChooser createFileChooser() { - JFileChooser result = new SavedDirFileChooser(dirKey, failoverDir, force); + JFileChooser result = new SavedDirFileChooser(dirKey, failoverDir, + force, approver); prepareFileChooser(result); return result; } @@ -362,12 +367,69 @@ if (aDescription != null) { chooser.getAccessibleContext().setAccessibleDescription(aDescription); } + if (!filters.isEmpty()) { + for (FileFilter f : filters) { + chooser.addChoosableFileFilter(f); + } + } + } + + /** + * Equivalent to calling JFileChooser.addChoosableFileFilter(filter). + * Adds another file filter that can be displayed in the file filters combo + * box in the file chooser. + * + * @param filter The file filter to add + * @return this + * @since 7.26.0 + */ + public FileChooserBuilder addFileFilter (FileFilter filter) { + filters.add (filter); + return this; + } + + /** + * Set a selection approver which can display an "Overwrite file?" + * or similar dialog if necessary, when the user presses the accept button + * in the file chooser dialog. + * + * @param approver A SelectionApprover which will determine if the selection + * is valid + * @return this + * @since 7.26.0 + */ + public FileChooserBuilder setSelectionApprover (SelectionApprover approver) { + this.approver = approver; + return this; + } + + /** + * Object which can approve the selection (enabling the OK button or + * equivalent) in a JFileChooser. Equivalent to overriding + * JFileChooser.approveSelection() + * @since 7.26.0 + */ + public interface SelectionApprover { + /** + * Approve the selection, enabling the dialog to be closed. Called by + * the JFileChooser's approveSelection() method. Use this + * interface if you want to, for example, show a dialog asking + * "Overwrite File X?" or similar. + * + * @param selection The selected file(s) at the time the user presses + * the Open, Save or OK button + * @return true if the selection is accepted, false if it is not and + * the dialog should not be closed + */ + public boolean approve (File[] selection); } private static final class SavedDirFileChooser extends JFileChooser { private final String dirKey; - SavedDirFileChooser(String dirKey, File failoverDir, boolean force) { + private final SelectionApprover approver; + SavedDirFileChooser(String dirKey, File failoverDir, boolean force, SelectionApprover approver) { this.dirKey = dirKey; + this.approver = approver; if (force && failoverDir != null && failoverDir.exists() && failoverDir.isDirectory()) { setCurrentDirectory(failoverDir); } else { @@ -387,6 +449,18 @@ } @Override + public void approveSelection() { + if (approver != null) { + boolean approved = approver.approve(getSelectedFiles()); + if (approved) { + super.approveSelection(); + } + } else { + super.approveSelection(); + } + } + + @Override public int showOpenDialog(Component parent) throws HeadlessException { int result = super.showOpenDialog(parent); if (result == APPROVE_OPTION) { --- a/openide.filesystems/test/unit/src/org/openide/filesystems/FileChooserBuilderTest.java +++ a/openide.filesystems/test/unit/src/org/openide/filesystems/FileChooserBuilderTest.java @@ -44,6 +44,9 @@ import java.awt.EventQueue; import java.io.File; import java.io.IOException; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; import javax.swing.AbstractButton; import javax.swing.JButton; import javax.swing.JFileChooser; @@ -178,6 +181,66 @@ assertNotNull(instance.createFileChooser()); } + public void testSetSelectionApprover() throws Exception { + FileChooserBuilder instance = new FileChooserBuilder("i"); + File tmp = new File(System.getProperty("java.io.tmpdir")); + assertTrue ("Environment is insane", tmp.exists() && tmp.isDirectory()); + File sel = new File("tmp" + System.currentTimeMillis()); + if (!sel.exists()) { + assertTrue (sel.createNewFile()); + } + instance.setDefaultWorkingDirectory(tmp); + SA sa = new SA(); + instance.setSelectionApprover(sa); + JFileChooser ch = instance.createFileChooser(); + ch.approveSelection(); + sa.assertApproveInvoked(); + } + + public void testAddFileFilter() { + FileChooserBuilder instance = new FileChooserBuilder("j"); + FF one = new FF ("a"); + FF two = new FF ("b"); + instance.addFileFilter(one); + instance.addFileFilter(two); + JFileChooser ch = instance.createFileChooser(); + Set ff = new HashSet(Arrays.asList(one, two)); + Set actual = new HashSet(Arrays.asList(ch.getChoosableFileFilters())); + assertTrue (actual.containsAll(ff)); + //actual should also contain JFileChooser.getAcceptAllFileFilter() + assertEquals (ff.size() + 1, actual.size()); + } + + private static final class FF extends FileFilter { + private String x; + FF(String x) { + this.x = x; + } + + @Override + public boolean accept(File f) { + return f.getName().endsWith(x); + } + + @Override + public String getDescription() { + return x; + } + + } + + private static final class SA implements FileChooserBuilder.SelectionApprover { + private boolean approveInvoked; + public boolean approve(File[] selection) { + approveInvoked = true; + return true; + } + + void assertApproveInvoked() { + assertTrue (approveInvoked); + } + } + private static AbstractButton findDefaultButton(Container c) { if (c instanceof AbstractButton && "Snorkelbreath".equals(((AbstractButton) c).getText())) { return (JButton) c;