From 8fc335db4614d8e259ec0b9567b47b2a662dfbc9 Mon Sep 17 00:00:00 2001 From: Dennis Fabri Date: Sat, 30 Nov 2019 20:30:44 +0100 Subject: [PATCH 1/4] Updated dependencies --- demo/pom.xml | 2 +- win32/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/demo/pom.xml b/demo/pom.xml index bebc7f0..37cef69 100644 --- a/demo/pom.xml +++ b/demo/pom.xml @@ -40,7 +40,7 @@ com.miglayout miglayout - 3.7.3.1 + 3.7.4 jar swing compile diff --git a/win32/pom.xml b/win32/pom.xml index 698eb10..e2227b1 100644 --- a/win32/pom.xml +++ b/win32/pom.xml @@ -13,7 +13,7 @@ net.java.dev.jna jna - 4.5.1 + 5.4.0 compile From 821301d7fb2ad4ade7869d513f43681f4677c118 Mon Sep 17 00:00:00 2001 From: Dennis Fabri Date: Sat, 30 Nov 2019 20:31:18 +0100 Subject: [PATCH 2/4] Added ignores for eclipse --- .gitignore | 3 ++- api/.gitignore | 2 ++ api/.settings/.gitignore | 1 + demo/.gitignore | 2 ++ demo/.settings/.gitignore | 1 + win32/.gitignore | 2 ++ win32/.settings/.gitignore | 1 + 7 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 api/.gitignore create mode 100644 api/.settings/.gitignore create mode 100644 demo/.gitignore create mode 100644 demo/.settings/.gitignore create mode 100644 win32/.gitignore create mode 100644 win32/.settings/.gitignore diff --git a/.gitignore b/.gitignore index 9f97022..6166a2a 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -target/ \ No newline at end of file +target/ +/.project diff --git a/api/.gitignore b/api/.gitignore new file mode 100644 index 0000000..88b8d07 --- /dev/null +++ b/api/.gitignore @@ -0,0 +1,2 @@ +/.classpath +/.project diff --git a/api/.settings/.gitignore b/api/.settings/.gitignore new file mode 100644 index 0000000..3b1537c --- /dev/null +++ b/api/.settings/.gitignore @@ -0,0 +1 @@ +/org.eclipse.jdt.core.prefs diff --git a/demo/.gitignore b/demo/.gitignore new file mode 100644 index 0000000..88b8d07 --- /dev/null +++ b/demo/.gitignore @@ -0,0 +1,2 @@ +/.classpath +/.project diff --git a/demo/.settings/.gitignore b/demo/.settings/.gitignore new file mode 100644 index 0000000..3b1537c --- /dev/null +++ b/demo/.settings/.gitignore @@ -0,0 +1 @@ +/org.eclipse.jdt.core.prefs diff --git a/win32/.gitignore b/win32/.gitignore new file mode 100644 index 0000000..88b8d07 --- /dev/null +++ b/win32/.gitignore @@ -0,0 +1,2 @@ +/.classpath +/.project diff --git a/win32/.settings/.gitignore b/win32/.settings/.gitignore new file mode 100644 index 0000000..3b1537c --- /dev/null +++ b/win32/.settings/.gitignore @@ -0,0 +1 @@ +/org.eclipse.jdt.core.prefs From c9d5ac0ff26174ec7a9b026128e9881f17b3f2dc Mon Sep 17 00:00:00 2001 From: Dennis Fabri Date: Sat, 30 Nov 2019 20:31:43 +0100 Subject: [PATCH 3/4] Fixed some little bugs and warnings --- .../jnafilechooser/api/JnaFileChooser.java | 427 +++++++++--------- .../api/WindowsFileChooser.java | 23 +- .../api/WindowsFolderBrowser.java | 2 +- .../jnafilechooser/demo/PlumbingDemo.java | 4 +- .../demo/PortablePorcelainDemo.java | 4 +- 5 files changed, 230 insertions(+), 230 deletions(-) diff --git a/api/src/main/java/jnafilechooser/api/JnaFileChooser.java b/api/src/main/java/jnafilechooser/api/JnaFileChooser.java index e6e1a21..912c8ba 100644 --- a/api/src/main/java/jnafilechooser/api/JnaFileChooser.java +++ b/api/src/main/java/jnafilechooser/api/JnaFileChooser.java @@ -11,8 +11,7 @@ import java.awt.Window; import java.io.File; -import java.util.ArrayList; -import java.util.Arrays; +import java.util.*; import javax.swing.JFileChooser; import javax.swing.filechooser.FileNameExtensionFilter; @@ -20,22 +19,18 @@ import com.sun.jna.Platform; /** - * JnaFileChooser is a wrapper around the native Windows file chooser - * and folder browser that falls back to the Swing JFileChooser on platforms - * other than Windows or if the user chooses a combination of features - * that are not supported by the native dialogs (for example multiple - * selection of directories). + * JnaFileChooser is a wrapper around the native Windows file chooser and folder + * browser that falls back to the Swing JFileChooser on platforms other than + * Windows or if the user chooses a combination of features that are not + * supported by the native dialogs (for example multiple selection of + * directories). * - * Example: - * JnaFileChooser fc = new JnaFileChooser(); - * fc.setFilter("All Files", "*"); - * fc.setFilter("Pictures", "jpg", "jpeg", "gif", "png", "bmp"); + * Example: JnaFileChooser fc = new JnaFileChooser(); fc.setFilter("All Files", + * "*"); fc.setFilter("Pictures", "jpg", "jpeg", "gif", "png", "bmp"); * fc.setMultiSelectionEnabled(true); - * fc.setMode(JnaFileChooser.Mode.FilesAndDirectories); - * if (fc.showOpenDialog(parent)) { - * Files[] selected = fc.getSelectedFiles(); - * // do something with selected - * } + * fc.setMode(JnaFileChooser.Mode.FilesAndDirectories); if + * (fc.showOpenDialog(parent)) { Files[] selected = fc.getSelectedFiles(); // do + * something with selected } * * @see JFileChooser, WindowsFileChooser, WindowsFileBrowser */ @@ -43,226 +38,228 @@ public class JnaFileChooser { private static enum Action { Open, Save } - /** - * the availabe selection modes of the dialog - */ - public static enum Mode { - Files(JFileChooser.FILES_ONLY), - Directories(JFileChooser.DIRECTORIES_ONLY), - FilesAndDirectories(JFileChooser.FILES_AND_DIRECTORIES); - private int jFileChooserValue; - private Mode(int jfcv) { - this.jFileChooserValue = jfcv; - } - public int getJFileChooserValue() { - return jFileChooserValue; - } - } + /** + * the availabe selection modes of the dialog + */ + public static enum Mode { + Files(JFileChooser.FILES_ONLY), + Directories(JFileChooser.DIRECTORIES_ONLY), + FilesAndDirectories(JFileChooser.FILES_AND_DIRECTORIES); - protected File[] selectedFiles; - protected File currentDirectory; - protected ArrayList filters; - protected boolean multiSelectionEnabled; - protected Mode mode; + private int jFileChooserValue; - /** - * creates a new file chooser with multiselection disabled and mode set - * to allow file selection only. - */ - public JnaFileChooser() { - filters = new ArrayList(); - multiSelectionEnabled = false; - mode = Mode.Files; - selectedFiles = new File[] { null }; - } + private Mode(int jfcv) { + this.jFileChooserValue = jfcv; + } - /** - * creates a new file chooser with the specified initial directory - * - * @param currentDirectory the initial directory - */ - public JnaFileChooser(File currentDirectory) { - this(); - this.currentDirectory = currentDirectory.isDirectory() ? - currentDirectory : currentDirectory.getParentFile(); - } + public int getJFileChooserValue() { + return jFileChooserValue; + } + } - /** - * creates a new file chooser with the specified initial directory - * - * @param currentDirectory the initial directory - */ - public JnaFileChooser(String currentDirectoryPath) { - this(currentDirectoryPath != null ? - new File(currentDirectoryPath) : null); - } + protected File[] selectedFiles; + protected File currentDirectory; + protected ArrayList filters; + protected boolean multiSelectionEnabled; + protected Mode mode; - /** - * shows a dialog for opening files - * - * @param parent the parent window - * - * @return true if the user clicked OK - */ - public boolean showOpenDialog(Window parent) { - return showDialog(parent, Action.Open); - } + /** + * creates a new file chooser with multiselection disabled and mode set to allow + * file selection only. + */ + public JnaFileChooser() { + filters = new ArrayList(); + multiSelectionEnabled = false; + mode = Mode.Files; + selectedFiles = new File[] { null }; + } - /** - * shows a dialog for saving files - * - * @param parent the parent window - * - * @return true if the user clicked OK - */ - public boolean showSaveDialog(Window parent) { - return showDialog(parent, Action.Save); - } + /** + * creates a new file chooser with the specified initial directory + * + * @param currentDirectory the initial directory + */ + public JnaFileChooser(File currentDirectory) { + this(); + if (currentDirectory != null) { + this.currentDirectory = currentDirectory.isDirectory() ? currentDirectory + : currentDirectory.getParentFile(); + } + } - private boolean showDialog(Window parent, Action action) { - // native windows filechooser doesn't support mixed selection mode - if (Platform.isWindows() && mode != Mode.FilesAndDirectories) { - // windows filechooser can only multiselect files - if (multiSelectionEnabled && mode == Mode.Files) { - // TODO Here we would use the native windows dialog - // to choose multiple files. However I haven't been able - // to get it to work properly yet because it requires - // tricky callback magic and somehow this didn't work for me - // quite as documented (probably because I messed something up). - // Because I don't need this feature right now I've put it on - // hold to get on with stuff. - // Example code: http://support.microsoft.com/kb/131462/en-us - // GetOpenFileName: http://msdn.microsoft.com/en-us/library/ms646927.aspx - // OFNHookProc: http://msdn.microsoft.com/en-us/library/ms646931.aspx - // CDN_SELCHANGE: http://msdn.microsoft.com/en-us/library/ms646865.aspx - // SendMessage: http://msdn.microsoft.com/en-us/library/ms644950.aspx - } - else if (!multiSelectionEnabled) { - if (mode == Mode.Files) { - return showWindowsFileChooser(parent, action); - } - else if (mode == Mode.Directories) { - return showWindowsFolderBrowser(parent); - } - } - } + /** + * creates a new file chooser with the specified initial directory + * + * @param currentDirectory the initial directory + */ + public JnaFileChooser(String currentDirectoryPath) { + this(currentDirectoryPath != null ? new File(currentDirectoryPath) : null); + } - // fallback to Swing - return showSwingFileChooser(parent, action); - } + /** + * shows a dialog for opening files + * + * @param parent the parent window + * + * @return true if the user clicked OK + */ + public boolean showOpenDialog(Window parent) { + return showDialog(parent, Action.Open); + } - private boolean showSwingFileChooser(Window parent, Action action) { - final JFileChooser fc = new JFileChooser(currentDirectory); - fc.setMultiSelectionEnabled(multiSelectionEnabled); - fc.setFileSelectionMode(mode.getJFileChooserValue()); + /** + * shows a dialog for saving files + * + * @param parent the parent window + * + * @return true if the user clicked OK + */ + public boolean showSaveDialog(Window parent) { + return showDialog(parent, Action.Save); + } - // build filters - if (filters.size() > 0) { - boolean useAcceptAllFilter = false; - for (final String[] spec : filters) { - // the "All Files" filter is handled specially by JFileChooser - if (spec[1].equals("*")) { - useAcceptAllFilter = true; - continue; - } - fc.addChoosableFileFilter(new FileNameExtensionFilter( - spec[0], Arrays.copyOfRange(spec, 1, spec.length))); - } - fc.setAcceptAllFileFilterUsed(useAcceptAllFilter); - } + private boolean showDialog(Window parent, Action action) { + // native windows filechooser doesn't support mixed selection mode + if (Platform.isWindows() && mode != Mode.FilesAndDirectories) { + // windows filechooser can only multiselect files + if (multiSelectionEnabled && mode == Mode.Files) { + // TODO Here we would use the native windows dialog + // to choose multiple files. However I haven't been able + // to get it to work properly yet because it requires + // tricky callback magic and somehow this didn't work for me + // quite as documented (probably because I messed something up). + // Because I don't need this feature right now I've put it on + // hold to get on with stuff. + // Example code: http://support.microsoft.com/kb/131462/en-us + // GetOpenFileName: http://msdn.microsoft.com/en-us/library/ms646927.aspx + // OFNHookProc: http://msdn.microsoft.com/en-us/library/ms646931.aspx + // CDN_SELCHANGE: http://msdn.microsoft.com/en-us/library/ms646865.aspx + // SendMessage: http://msdn.microsoft.com/en-us/library/ms644950.aspx + } + else if (!multiSelectionEnabled) { + if (mode == Mode.Files) { + return showWindowsFileChooser(parent, action); + } + else if (mode == Mode.Directories) { + return showWindowsFolderBrowser(parent); + } + } + } - int result = -1; - if (action == Action.Open) { - result = fc.showOpenDialog(parent); - } - else { - result = fc.showSaveDialog(parent); - } - if (result == JFileChooser.APPROVE_OPTION) { - selectedFiles = multiSelectionEnabled ? - fc.getSelectedFiles() : new File[] { fc.getSelectedFile() }; - currentDirectory = fc.getCurrentDirectory(); - return true; - } + // fallback to Swing + return showSwingFileChooser(parent, action); + } - return false; - } + private boolean showSwingFileChooser(Window parent, Action action) { + final JFileChooser fc = new JFileChooser(currentDirectory); + fc.setMultiSelectionEnabled(multiSelectionEnabled); + fc.setFileSelectionMode(mode.getJFileChooserValue()); - private boolean showWindowsFileChooser(Window parent, Action action) { - final WindowsFileChooser fc = new WindowsFileChooser(currentDirectory); - fc.setFilters(filters); - final boolean result = fc.showDialog(parent, action == Action.Open); - if (result) { - selectedFiles = new File[] { fc.getSelectedFile() }; - currentDirectory = fc.getCurrentDirectory(); - } - return result; - } + // build filters + if (filters.size() > 0) { + boolean useAcceptAllFilter = false; + for (final String[] spec : filters) { + // the "All Files" filter is handled specially by JFileChooser + if (spec[1].equals("*")) { + useAcceptAllFilter = true; + continue; + } + fc.addChoosableFileFilter( + new FileNameExtensionFilter(spec[0], Arrays.copyOfRange(spec, 1, spec.length))); + } + fc.setAcceptAllFileFilterUsed(useAcceptAllFilter); + } - private boolean showWindowsFolderBrowser(Window parent) { - final WindowsFolderBrowser fb = new WindowsFolderBrowser(); - final File file = fb.showDialog(parent); - if (file != null) { - selectedFiles = new File[] { file }; - currentDirectory = file.getParentFile() != null ? - file.getParentFile() : file; - return true; - } + int result = -1; + if (action == Action.Open) { + result = fc.showOpenDialog(parent); + } else { + result = fc.showSaveDialog(parent); + } + if (result == JFileChooser.APPROVE_OPTION) { + selectedFiles = multiSelectionEnabled ? fc.getSelectedFiles() : new File[] { fc.getSelectedFile() }; + currentDirectory = fc.getCurrentDirectory(); + return true; + } - return false; - } + return false; + } - /** - * add a filter to the user-selectable list of file filters - * - * @param filter you must pass at least 2 arguments, the first argument - * is the name of this filter and the remaining arguments - * are the file extensions. - * - * @throws IllegalArgumentException if less than 2 arguments are passed - */ - public void addFilter(String ... values) { - if (values.length < 2) { - throw new IllegalArgumentException(); - } - filters.add(values); - } + private boolean showWindowsFileChooser(Window parent, Action action) { + final WindowsFileChooser fc = new WindowsFileChooser(currentDirectory); + fc.setFilters(filters); + final boolean result = fc.showDialog(parent, action == Action.Open); + if (result) { + selectedFiles = new File[] { fc.getSelectedFile() }; + currentDirectory = fc.getCurrentDirectory(); + } + return result; + } - /** - * sets the selection mode - * - * @param mode the selection mode - */ - public void setMode(Mode mode) { - this.mode = mode; - } + private boolean showWindowsFolderBrowser(Window parent) { + final WindowsFolderBrowser fb = new WindowsFolderBrowser(); + final File file = fb.showDialog(parent); + if (file != null) { + selectedFiles = new File[] { file }; + currentDirectory = file.getParentFile() != null ? file.getParentFile() : file; + return true; + } - public Mode getMode() { - return mode; - } + return false; + } - /** - * sets whether to enable multiselection - * - * @param enabled true to enable multiselection, false to disable it - */ - public void setMultiSelectionEnabled(boolean enabled) { - this.multiSelectionEnabled = enabled; - } + /** + * add a filter to the user-selectable list of file filters + * + * @param name name of the filter + * @param filter you must pass at least 1 argument, the arguments are the file + * extensions. + */ + public void addFilter(String name, String... filter) { + if (filter.length < 1) { + throw new IllegalArgumentException(); + } + ArrayList parts = new ArrayList(); + parts.add(name); + Collections.addAll(parts, filter); + filters.add(parts.toArray(new String[parts.size()])); + } - public boolean isMultiSelectionEnabled() { - return multiSelectionEnabled; - } + /** + * sets the selection mode + * + * @param mode the selection mode + */ + public void setMode(Mode mode) { + this.mode = mode; + } - public File[] getSelectedFiles() { - return selectedFiles; - } + public Mode getMode() { + return mode; + } - public File getSelectedFile() { - return selectedFiles[0]; - } + /** + * sets whether to enable multiselection + * + * @param enabled true to enable multiselection, false to disable it + */ + public void setMultiSelectionEnabled(boolean enabled) { + this.multiSelectionEnabled = enabled; + } - public File getCurrentDirectory() { - return currentDirectory; - } + public boolean isMultiSelectionEnabled() { + return multiSelectionEnabled; + } + + public File[] getSelectedFiles() { + return selectedFiles; + } + + public File getSelectedFile() { + return selectedFiles[0]; + } + + public File getCurrentDirectory() { + return currentDirectory; + } } diff --git a/api/src/main/java/jnafilechooser/api/WindowsFileChooser.java b/api/src/main/java/jnafilechooser/api/WindowsFileChooser.java index 052340b..71ed4f3 100644 --- a/api/src/main/java/jnafilechooser/api/WindowsFileChooser.java +++ b/api/src/main/java/jnafilechooser/api/WindowsFileChooser.java @@ -11,7 +11,7 @@ import java.awt.Window; import java.io.File; -import java.util.ArrayList; +import java.util.*; import jnafilechooser.win32.Comdlg32; @@ -121,15 +121,18 @@ void setFilters(ArrayList filters) { /** * add a filter to the user-selectable list of file filters * - * @param filter you must pass at least 2 arguments, the first argument - * is the name of this filter and the remaining arguments + * @param name name of the filter + * @param filter you must pass at least 1 argument, the arguments * are the file extensions. */ - public void addFilter(String ... filter) { - if (filter.length < 2) { - throw new IllegalArgumentException(); - } - filters.add(filter); + public void addFilter(String name, String... filter) { + if (filter.length < 1) { + throw new IllegalArgumentException(); + } + ArrayList parts = new ArrayList(); + parts.add(name); + Collections.addAll(parts, filter); + filters.add(parts.toArray(new String[parts.size()])); } /** @@ -176,7 +179,7 @@ boolean showDialog(Window parent, boolean open) { // enable resizing of the dialog | Comdlg32.OFN_ENABLESIZING; - params.hwndOwner = Native.getWindowPointer(parent); + params.hwndOwner = parent == null ? null : Native.getWindowPointer(parent); // lpstrFile contains the selection path after the dialog // returns. It must be big enough for the path to fit or @@ -216,7 +219,7 @@ boolean showDialog(Window parent, boolean open) { Comdlg32.GetSaveFileNameW(params); if (approved) { - final String filePath = params.lpstrFile.getString(0, true); + final String filePath = params.lpstrFile.getWideString(0); selectedFile = new File(filePath); final File dir = selectedFile.getParentFile(); currentDirectory = dir; diff --git a/api/src/main/java/jnafilechooser/api/WindowsFolderBrowser.java b/api/src/main/java/jnafilechooser/api/WindowsFolderBrowser.java index 77cdb03..51a686d 100644 --- a/api/src/main/java/jnafilechooser/api/WindowsFolderBrowser.java +++ b/api/src/main/java/jnafilechooser/api/WindowsFolderBrowser.java @@ -78,7 +78,7 @@ public File showDialog(Window parent) { // be more than big enough final Pointer path = new Memory(1024 * 4); Shell32.SHGetPathFromIDListW(pidl, path); - final String filePath = path.getString(0, true); + final String filePath = path.getWideString(0); final File file = new File(filePath); Ole32.CoTaskMemFree(pidl); return file; diff --git a/demo/src/main/java/jnafilechooser/demo/PlumbingDemo.java b/demo/src/main/java/jnafilechooser/demo/PlumbingDemo.java index 92036ed..e48acde 100644 --- a/demo/src/main/java/jnafilechooser/demo/PlumbingDemo.java +++ b/demo/src/main/java/jnafilechooser/demo/PlumbingDemo.java @@ -50,7 +50,7 @@ public void actionPerformed(ActionEvent e) { final Pointer path = new Memory(260); path.clear(260); SHGetPathFromIDListW(pidl, path); - final String pathStr = path.getString(0, true); + final String pathStr = path.getWideString(0); System.out.println(pathStr); } CoTaskMemFree(pidl); @@ -74,7 +74,7 @@ public void actionPerformed(ActionEvent e) { | OFN_NOCHANGEDIR | OFN_HIDEREADONLY; if (GetOpenFileNameW(params)) { - System.out.println(params.lpstrFile.getString(0, true)); + System.out.println(params.lpstrFile.getWideString(0)); } else { int err = CommDlgExtendedError(); diff --git a/demo/src/main/java/jnafilechooser/demo/PortablePorcelainDemo.java b/demo/src/main/java/jnafilechooser/demo/PortablePorcelainDemo.java index 2d6ed56..19e3119 100644 --- a/demo/src/main/java/jnafilechooser/demo/PortablePorcelainDemo.java +++ b/demo/src/main/java/jnafilechooser/demo/PortablePorcelainDemo.java @@ -33,8 +33,8 @@ public static void main(String[] args) throws Exception { } final JCheckBox enableMultiSelect = new JCheckBox(); - final JComboBox selectionMode = new JComboBox(JnaFileChooser.Mode.values()); - final JComboBox dialogType = new JComboBox(new String[] { "Open", "Save" }); + final JComboBox selectionMode = new JComboBox(JnaFileChooser.Mode.values()); + final JComboBox dialogType = new JComboBox(new String[] { "Open", "Save" }); final JCheckBox useFilter = new JCheckBox(); final JButton choose = new JButton("Choose"); final JFrame frame = new JFrame(PortablePorcelainDemo.class.getName()); From a5430da4f0b1e9b5a209d3ce4e08feecdfcf255b Mon Sep 17 00:00:00 2001 From: Dennis Fabri Date: Sun, 5 Apr 2020 08:17:14 +0200 Subject: [PATCH 4/4] Fixed code formatting --- .gitignore | 4 +- api/.gitignore | 2 - api/.settings/.gitignore | 1 - .../jnafilechooser/api/JnaFileChooser.java | 423 +++++++++--------- .../api/WindowsFileChooser.java | 17 +- demo/.gitignore | 2 - demo/.settings/.gitignore | 1 - win32/.gitignore | 2 - win32/.settings/.gitignore | 1 - 9 files changed, 227 insertions(+), 226 deletions(-) delete mode 100644 api/.gitignore delete mode 100644 api/.settings/.gitignore delete mode 100644 demo/.gitignore delete mode 100644 demo/.settings/.gitignore delete mode 100644 win32/.gitignore delete mode 100644 win32/.settings/.gitignore diff --git a/.gitignore b/.gitignore index 6166a2a..e9ca771 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ target/ -/.project +.project +.settings +.classpath \ No newline at end of file diff --git a/api/.gitignore b/api/.gitignore deleted file mode 100644 index 88b8d07..0000000 --- a/api/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/.classpath -/.project diff --git a/api/.settings/.gitignore b/api/.settings/.gitignore deleted file mode 100644 index 3b1537c..0000000 --- a/api/.settings/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/org.eclipse.jdt.core.prefs diff --git a/api/src/main/java/jnafilechooser/api/JnaFileChooser.java b/api/src/main/java/jnafilechooser/api/JnaFileChooser.java index 912c8ba..66ef6b1 100644 --- a/api/src/main/java/jnafilechooser/api/JnaFileChooser.java +++ b/api/src/main/java/jnafilechooser/api/JnaFileChooser.java @@ -11,7 +11,9 @@ import java.awt.Window; import java.io.File; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; import javax.swing.JFileChooser; import javax.swing.filechooser.FileNameExtensionFilter; @@ -19,18 +21,22 @@ import com.sun.jna.Platform; /** - * JnaFileChooser is a wrapper around the native Windows file chooser and folder - * browser that falls back to the Swing JFileChooser on platforms other than - * Windows or if the user chooses a combination of features that are not - * supported by the native dialogs (for example multiple selection of - * directories). + * JnaFileChooser is a wrapper around the native Windows file chooser + * and folder browser that falls back to the Swing JFileChooser on platforms + * other than Windows or if the user chooses a combination of features + * that are not supported by the native dialogs (for example multiple + * selection of directories). * - * Example: JnaFileChooser fc = new JnaFileChooser(); fc.setFilter("All Files", - * "*"); fc.setFilter("Pictures", "jpg", "jpeg", "gif", "png", "bmp"); + * Example: + * JnaFileChooser fc = new JnaFileChooser(); + * fc.setFilter("All Files", "*"); + * fc.setFilter("Pictures", "jpg", "jpeg", "gif", "png", "bmp"); * fc.setMultiSelectionEnabled(true); - * fc.setMode(JnaFileChooser.Mode.FilesAndDirectories); if - * (fc.showOpenDialog(parent)) { Files[] selected = fc.getSelectedFiles(); // do - * something with selected } + * fc.setMode(JnaFileChooser.Mode.FilesAndDirectories); + * if (fc.showOpenDialog(parent)) { + * Files[] selected = fc.getSelectedFiles(); + * // do something with selected + * } * * @see JFileChooser, WindowsFileChooser, WindowsFileBrowser */ @@ -38,228 +44,229 @@ public class JnaFileChooser { private static enum Action { Open, Save } - /** - * the availabe selection modes of the dialog - */ - public static enum Mode { - Files(JFileChooser.FILES_ONLY), - Directories(JFileChooser.DIRECTORIES_ONLY), - FilesAndDirectories(JFileChooser.FILES_AND_DIRECTORIES); + /** + * the availabe selection modes of the dialog + */ + public static enum Mode { + Files(JFileChooser.FILES_ONLY), + Directories(JFileChooser.DIRECTORIES_ONLY), + FilesAndDirectories(JFileChooser.FILES_AND_DIRECTORIES); + private int jFileChooserValue; + private Mode(int jfcv) { + this.jFileChooserValue = jfcv; + } + public int getJFileChooserValue() { + return jFileChooserValue; + } + } - private int jFileChooserValue; + protected File[] selectedFiles; + protected File currentDirectory; + protected ArrayList filters; + protected boolean multiSelectionEnabled; + protected Mode mode; - private Mode(int jfcv) { - this.jFileChooserValue = jfcv; - } + /** + * creates a new file chooser with multiselection disabled and mode set + * to allow file selection only. + */ + public JnaFileChooser() { + filters = new ArrayList(); + multiSelectionEnabled = false; + mode = Mode.Files; + selectedFiles = new File[] { null }; + } - public int getJFileChooserValue() { - return jFileChooserValue; - } - } - - protected File[] selectedFiles; - protected File currentDirectory; - protected ArrayList filters; - protected boolean multiSelectionEnabled; - protected Mode mode; - - /** - * creates a new file chooser with multiselection disabled and mode set to allow - * file selection only. - */ - public JnaFileChooser() { - filters = new ArrayList(); - multiSelectionEnabled = false; - mode = Mode.Files; - selectedFiles = new File[] { null }; - } - - /** - * creates a new file chooser with the specified initial directory - * - * @param currentDirectory the initial directory - */ - public JnaFileChooser(File currentDirectory) { - this(); + /** + * creates a new file chooser with the specified initial directory + * + * @param currentDirectory the initial directory + */ + public JnaFileChooser(File currentDirectory) { + this(); if (currentDirectory != null) { - this.currentDirectory = currentDirectory.isDirectory() ? currentDirectory - : currentDirectory.getParentFile(); - } - } + this.currentDirectory = currentDirectory.isDirectory() ? + currentDirectory : currentDirectory.getParentFile(); + } + } - /** - * creates a new file chooser with the specified initial directory - * - * @param currentDirectory the initial directory - */ - public JnaFileChooser(String currentDirectoryPath) { - this(currentDirectoryPath != null ? new File(currentDirectoryPath) : null); - } + /** + * creates a new file chooser with the specified initial directory + * + * @param currentDirectory the initial directory + */ + public JnaFileChooser(String currentDirectoryPath) { + this(currentDirectoryPath != null ? + new File(currentDirectoryPath) : null); + } - /** - * shows a dialog for opening files - * - * @param parent the parent window - * - * @return true if the user clicked OK - */ - public boolean showOpenDialog(Window parent) { - return showDialog(parent, Action.Open); - } + /** + * shows a dialog for opening files + * + * @param parent the parent window + * + * @return true if the user clicked OK + */ + public boolean showOpenDialog(Window parent) { + return showDialog(parent, Action.Open); + } - /** - * shows a dialog for saving files - * - * @param parent the parent window - * - * @return true if the user clicked OK - */ - public boolean showSaveDialog(Window parent) { - return showDialog(parent, Action.Save); - } + /** + * shows a dialog for saving files + * + * @param parent the parent window + * + * @return true if the user clicked OK + */ + public boolean showSaveDialog(Window parent) { + return showDialog(parent, Action.Save); + } - private boolean showDialog(Window parent, Action action) { - // native windows filechooser doesn't support mixed selection mode - if (Platform.isWindows() && mode != Mode.FilesAndDirectories) { - // windows filechooser can only multiselect files - if (multiSelectionEnabled && mode == Mode.Files) { - // TODO Here we would use the native windows dialog - // to choose multiple files. However I haven't been able - // to get it to work properly yet because it requires - // tricky callback magic and somehow this didn't work for me - // quite as documented (probably because I messed something up). - // Because I don't need this feature right now I've put it on - // hold to get on with stuff. - // Example code: http://support.microsoft.com/kb/131462/en-us - // GetOpenFileName: http://msdn.microsoft.com/en-us/library/ms646927.aspx - // OFNHookProc: http://msdn.microsoft.com/en-us/library/ms646931.aspx - // CDN_SELCHANGE: http://msdn.microsoft.com/en-us/library/ms646865.aspx - // SendMessage: http://msdn.microsoft.com/en-us/library/ms644950.aspx - } - else if (!multiSelectionEnabled) { - if (mode == Mode.Files) { - return showWindowsFileChooser(parent, action); - } - else if (mode == Mode.Directories) { - return showWindowsFolderBrowser(parent); - } - } - } + private boolean showDialog(Window parent, Action action) { + // native windows filechooser doesn't support mixed selection mode + if (Platform.isWindows() && mode != Mode.FilesAndDirectories) { + // windows filechooser can only multiselect files + if (multiSelectionEnabled && mode == Mode.Files) { + // TODO Here we would use the native windows dialog + // to choose multiple files. However I haven't been able + // to get it to work properly yet because it requires + // tricky callback magic and somehow this didn't work for me + // quite as documented (probably because I messed something up). + // Because I don't need this feature right now I've put it on + // hold to get on with stuff. + // Example code: http://support.microsoft.com/kb/131462/en-us + // GetOpenFileName: http://msdn.microsoft.com/en-us/library/ms646927.aspx + // OFNHookProc: http://msdn.microsoft.com/en-us/library/ms646931.aspx + // CDN_SELCHANGE: http://msdn.microsoft.com/en-us/library/ms646865.aspx + // SendMessage: http://msdn.microsoft.com/en-us/library/ms644950.aspx + } + else if (!multiSelectionEnabled) { + if (mode == Mode.Files) { + return showWindowsFileChooser(parent, action); + } + else if (mode == Mode.Directories) { + return showWindowsFolderBrowser(parent); + } + } + } - // fallback to Swing - return showSwingFileChooser(parent, action); - } + // fallback to Swing + return showSwingFileChooser(parent, action); + } - private boolean showSwingFileChooser(Window parent, Action action) { - final JFileChooser fc = new JFileChooser(currentDirectory); - fc.setMultiSelectionEnabled(multiSelectionEnabled); - fc.setFileSelectionMode(mode.getJFileChooserValue()); + private boolean showSwingFileChooser(Window parent, Action action) { + final JFileChooser fc = new JFileChooser(currentDirectory); + fc.setMultiSelectionEnabled(multiSelectionEnabled); + fc.setFileSelectionMode(mode.getJFileChooserValue()); - // build filters - if (filters.size() > 0) { - boolean useAcceptAllFilter = false; - for (final String[] spec : filters) { - // the "All Files" filter is handled specially by JFileChooser - if (spec[1].equals("*")) { - useAcceptAllFilter = true; - continue; - } - fc.addChoosableFileFilter( - new FileNameExtensionFilter(spec[0], Arrays.copyOfRange(spec, 1, spec.length))); - } - fc.setAcceptAllFileFilterUsed(useAcceptAllFilter); - } + // build filters + if (filters.size() > 0) { + boolean useAcceptAllFilter = false; + for (final String[] spec : filters) { + // the "All Files" filter is handled specially by JFileChooser + if (spec[1].equals("*")) { + useAcceptAllFilter = true; + continue; + } + fc.addChoosableFileFilter(new FileNameExtensionFilter( + spec[0], Arrays.copyOfRange(spec, 1, spec.length))); + } + fc.setAcceptAllFileFilterUsed(useAcceptAllFilter); + } - int result = -1; - if (action == Action.Open) { - result = fc.showOpenDialog(parent); - } else { - result = fc.showSaveDialog(parent); - } - if (result == JFileChooser.APPROVE_OPTION) { - selectedFiles = multiSelectionEnabled ? fc.getSelectedFiles() : new File[] { fc.getSelectedFile() }; - currentDirectory = fc.getCurrentDirectory(); - return true; - } + int result = -1; + if (action == Action.Open) { + result = fc.showOpenDialog(parent); + } + else { + result = fc.showSaveDialog(parent); + } + if (result == JFileChooser.APPROVE_OPTION) { + selectedFiles = multiSelectionEnabled ? + fc.getSelectedFiles() : new File[] { fc.getSelectedFile() }; + currentDirectory = fc.getCurrentDirectory(); + return true; + } - return false; - } + return false; + } - private boolean showWindowsFileChooser(Window parent, Action action) { - final WindowsFileChooser fc = new WindowsFileChooser(currentDirectory); - fc.setFilters(filters); - final boolean result = fc.showDialog(parent, action == Action.Open); - if (result) { - selectedFiles = new File[] { fc.getSelectedFile() }; - currentDirectory = fc.getCurrentDirectory(); - } - return result; - } + private boolean showWindowsFileChooser(Window parent, Action action) { + final WindowsFileChooser fc = new WindowsFileChooser(currentDirectory); + fc.setFilters(filters); + final boolean result = fc.showDialog(parent, action == Action.Open); + if (result) { + selectedFiles = new File[] { fc.getSelectedFile() }; + currentDirectory = fc.getCurrentDirectory(); + } + return result; + } - private boolean showWindowsFolderBrowser(Window parent) { - final WindowsFolderBrowser fb = new WindowsFolderBrowser(); - final File file = fb.showDialog(parent); - if (file != null) { - selectedFiles = new File[] { file }; - currentDirectory = file.getParentFile() != null ? file.getParentFile() : file; - return true; - } + private boolean showWindowsFolderBrowser(Window parent) { + final WindowsFolderBrowser fb = new WindowsFolderBrowser(); + final File file = fb.showDialog(parent); + if (file != null) { + selectedFiles = new File[] { file }; + currentDirectory = file.getParentFile() != null ? + file.getParentFile() : file; + return true; + } - return false; - } + return false; + } - /** - * add a filter to the user-selectable list of file filters - * + /** + * add a filter to the user-selectable list of file filters + * * @param name name of the filter * @param filter you must pass at least 1 argument, the arguments are the file * extensions. - */ - public void addFilter(String name, String... filter) { - if (filter.length < 1) { - throw new IllegalArgumentException(); - } - ArrayList parts = new ArrayList(); - parts.add(name); - Collections.addAll(parts, filter); - filters.add(parts.toArray(new String[parts.size()])); - } + */ + public void addFilter(String name, String... filter) { + if (filter.length < 1) { + throw new IllegalArgumentException(); + } + ArrayList parts = new ArrayList(); + parts.add(name); + Collections.addAll(parts, filter); + filters.add(parts.toArray(new String[parts.size()])); + } - /** - * sets the selection mode - * - * @param mode the selection mode - */ - public void setMode(Mode mode) { - this.mode = mode; - } + /** + * sets the selection mode + * + * @param mode the selection mode + */ + public void setMode(Mode mode) { + this.mode = mode; + } - public Mode getMode() { - return mode; - } + public Mode getMode() { + return mode; + } - /** - * sets whether to enable multiselection - * - * @param enabled true to enable multiselection, false to disable it - */ - public void setMultiSelectionEnabled(boolean enabled) { - this.multiSelectionEnabled = enabled; - } + /** + * sets whether to enable multiselection + * + * @param enabled true to enable multiselection, false to disable it + */ + public void setMultiSelectionEnabled(boolean enabled) { + this.multiSelectionEnabled = enabled; + } - public boolean isMultiSelectionEnabled() { - return multiSelectionEnabled; - } + public boolean isMultiSelectionEnabled() { + return multiSelectionEnabled; + } - public File[] getSelectedFiles() { - return selectedFiles; - } + public File[] getSelectedFiles() { + return selectedFiles; + } - public File getSelectedFile() { - return selectedFiles[0]; - } + public File getSelectedFile() { + return selectedFiles[0]; + } - public File getCurrentDirectory() { - return currentDirectory; - } + public File getCurrentDirectory() { + return currentDirectory; + } } diff --git a/api/src/main/java/jnafilechooser/api/WindowsFileChooser.java b/api/src/main/java/jnafilechooser/api/WindowsFileChooser.java index 71ed4f3..bd4d726 100644 --- a/api/src/main/java/jnafilechooser/api/WindowsFileChooser.java +++ b/api/src/main/java/jnafilechooser/api/WindowsFileChooser.java @@ -11,7 +11,8 @@ import java.awt.Window; import java.io.File; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; import jnafilechooser.win32.Comdlg32; @@ -126,13 +127,13 @@ void setFilters(ArrayList filters) { * are the file extensions. */ public void addFilter(String name, String... filter) { - if (filter.length < 1) { - throw new IllegalArgumentException(); - } - ArrayList parts = new ArrayList(); - parts.add(name); - Collections.addAll(parts, filter); - filters.add(parts.toArray(new String[parts.size()])); + if (filter.length < 1) { + throw new IllegalArgumentException(); + } + ArrayList parts = new ArrayList(); + parts.add(name); + Collections.addAll(parts, filter); + filters.add(parts.toArray(new String[parts.size()])); } /** diff --git a/demo/.gitignore b/demo/.gitignore deleted file mode 100644 index 88b8d07..0000000 --- a/demo/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/.classpath -/.project diff --git a/demo/.settings/.gitignore b/demo/.settings/.gitignore deleted file mode 100644 index 3b1537c..0000000 --- a/demo/.settings/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/org.eclipse.jdt.core.prefs diff --git a/win32/.gitignore b/win32/.gitignore deleted file mode 100644 index 88b8d07..0000000 --- a/win32/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/.classpath -/.project diff --git a/win32/.settings/.gitignore b/win32/.settings/.gitignore deleted file mode 100644 index 3b1537c..0000000 --- a/win32/.settings/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/org.eclipse.jdt.core.prefs