diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatNativeMacLibrary.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatNativeMacLibrary.java
index 5ceb2f61..73bef9b7 100644
--- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatNativeMacLibrary.java
+++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatNativeMacLibrary.java
@@ -72,7 +72,7 @@ public class FlatNativeMacLibrary
/** @since 3.6 */
public static final int
- // NSOpenPanel
+ // NSOpenPanel (extends NSSavePanel)
FC_canChooseFiles = 1 << 0, // default
FC_canChooseDirectories = 1 << 1,
FC_resolvesAliases = 1 << 2, // default
@@ -105,7 +105,8 @@ public class FlatNativeMacLibrary
* @param optionsSet options to set; see {@code FC_*} constants
* @param optionsClear options to clear; see {@code FC_*} constants
* @param allowedFileTypes allowed filename extensions (e.g. "txt")
- * @return file path(s) that the user selected, or {@code null} if canceled
+ * @return file path(s) that the user selected; an empty array if canceled;
+ * or {@code null} on failures (no dialog shown)
*
* @since 3.6
*/
diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/util/SystemFileChooser.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/util/SystemFileChooser.java
index d5d6d773..23f6a2d6 100644
--- a/flatlaf-core/src/main/java/com/formdev/flatlaf/util/SystemFileChooser.java
+++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/util/SystemFileChooser.java
@@ -31,6 +31,7 @@ import javax.swing.UIManager;
import javax.swing.filechooser.FileSystemView;
import com.formdev.flatlaf.FlatSystemProperties;
import com.formdev.flatlaf.ui.FlatNativeLinuxLibrary;
+import com.formdev.flatlaf.ui.FlatNativeMacLibrary;
import com.formdev.flatlaf.ui.FlatNativeWindowsLibrary;
/**
@@ -61,7 +62,11 @@ import com.formdev.flatlaf.ui.FlatNativeWindowsLibrary;
* If user selects "Yes", the file chooser closes. If user selects "No", the file chooser stays open.
* It is not possible to customize that question dialog.
*
Save File dialog does not support multi-selection.
+ * For selection mode {@link #DIRECTORIES_ONLY}, dialog type {@link #SAVE_DIALOG} is ignored.
+ * Operating system file dialogs support folder selection only in "Open" dialogs.
* {@link JFileChooser#FILES_AND_DIRECTORIES} is not supported.
+ * {@link #getSelectedFiles()} returns selected file also in single selection mode.
+ * {@link JFileChooser#getSelectedFiles()} only in multi selection mode.
*
*
* @author Karl Tauber
@@ -289,6 +294,8 @@ public class SystemFileChooser
if( SystemInfo.isWindows_10_orLater && FlatNativeWindowsLibrary.isLoaded() )
return new WindowsFileChooserProvider();
+ else if( SystemInfo.isMacOS && FlatNativeMacLibrary.isLoaded() )
+ return new MacFileChooserProvider();
else if( SystemInfo.isLinux && FlatNativeLinuxLibrary.isLoaded() )
return new LinuxFileChooserProvider();
else // unknown platform or FlatLaf native library not loaded
@@ -413,7 +420,52 @@ public class SystemFileChooser
}
}
- //---- class LinuxFileChooserProvider -----------------------------------..
+ //---- class MacFileChooserProvider ---------------------------------------
+
+ private static class MacFileChooserProvider
+ extends SystemFileChooserProvider
+ {
+ @Override
+ String[] showSystemDialog( Window owner, SystemFileChooser fc ) {
+ boolean open = (fc.getDialogType() == OPEN_DIALOG);
+ String nameFieldStringValue = null;
+ String directoryURL = null;
+
+ // paths
+ File currentDirectory = fc.getCurrentDirectory();
+ File selectedFile = fc.getSelectedFile();
+ if( selectedFile != null ) {
+ if( selectedFile.isDirectory() )
+ directoryURL = selectedFile.getAbsolutePath();
+ else {
+ nameFieldStringValue = selectedFile.getName();
+ directoryURL = selectedFile.getParent();
+ }
+ } else if( currentDirectory != null )
+ directoryURL = currentDirectory.getAbsolutePath();
+
+ // options
+ int optionsSet = 0;
+ int optionsClear = 0;
+ if( fc.isDirectorySelectionEnabled() ) {
+ optionsSet |= FlatNativeMacLibrary.FC_canChooseDirectories;
+ optionsClear |= FlatNativeMacLibrary.FC_canChooseFiles;
+ open = true;
+ }
+ if( fc.isMultiSelectionEnabled() )
+ optionsSet |= FlatNativeMacLibrary.FC_allowsMultipleSelection;
+ if( !fc.isFileHidingEnabled() )
+ optionsSet |= FlatNativeMacLibrary.FC_showsHiddenFiles;
+
+ // show system file dialog
+ return FlatNativeMacLibrary.showFileChooser( open,
+ fc.getDialogTitle(), fc.getApproveButtonText(), null, null,
+ nameFieldStringValue, directoryURL,
+ optionsSet, optionsClear );
+ }
+ }
+
+ //---- class LinuxFileChooserProvider -------------------------------------
private static class LinuxFileChooserProvider
extends SystemFileChooserProvider
diff --git a/flatlaf-natives/flatlaf-natives-macos/src/main/objcpp/MacFileChooser.mm b/flatlaf-natives/flatlaf-natives-macos/src/main/objcpp/MacFileChooser.mm
index 05fd3d67..9755c5ab 100644
--- a/flatlaf-natives/flatlaf-natives-macos/src/main/objcpp/MacFileChooser.mm
+++ b/flatlaf-natives/flatlaf-natives-macos/src/main/objcpp/MacFileChooser.mm
@@ -23,15 +23,23 @@
/**
* @author Karl Tauber
+ * @since 3.6
*/
+//---- helper -----------------------------------------------------------------
+
#define isOptionSet( option ) ((optionsSet & com_formdev_flatlaf_ui_FlatNativeMacLibrary_ ## option) != 0)
#define isOptionClear( option ) ((optionsClear & com_formdev_flatlaf_ui_FlatNativeMacLibrary_ ## option) != 0)
#define isOptionSetOrClear( option ) isOptionSet( option ) || isOptionClear( option )
-// declare internal methods
+// declare methods
NSWindow* getNSWindow( JNIEnv* env, jclass cls, jobject window );
+jobjectArray newJavaStringArray( JNIEnv* env, jsize count ) {
+ jclass stringClass = env->FindClass( "java/lang/String" );
+ return env->NewObjectArray( count, stringClass, NULL );
+}
+
//---- JNI methods ------------------------------------------------------------
extern "C"
@@ -135,19 +143,18 @@ JNIEXPORT jobjectArray JNICALL Java_com_formdev_flatlaf_ui_FlatNativeMacLibrary_
urls = @[url];
if( urls == NULL )
- return NULL;
+ return newJavaStringArray( env, 0 );
// convert URLs to Java string array
jsize count = urls.count;
- jclass stringClass = env->FindClass( "java/lang/String" );
- jobjectArray result = env->NewObjectArray( count, stringClass, NULL );
+ jobjectArray array = newJavaStringArray( env, count );
for( int i = 0; i < count; i++ ) {
jstring filename = NormalizedPathJavaFromNSString( env, [urls[i] path] );
- env->SetObjectArrayElement( result, i, filename );
+ env->SetObjectArrayElement( array, i, filename );
env->DeleteLocalRef( filename );
}
- return result;
+ return array;
JNI_COCOA_EXIT()
}