System File Chooser: support macOS in class SystemFileChooser

This commit is contained in:
Karl Tauber
2025-01-06 19:22:15 +01:00
parent 91e8d04a9f
commit 2e16ded5d4
3 changed files with 69 additions and 9 deletions

View File

@@ -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
*/

View File

@@ -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.
* <li><b>Save File</b> dialog does not support multi-selection.
* <li>For selection mode {@link #DIRECTORIES_ONLY}, dialog type {@link #SAVE_DIALOG} is ignored.
* Operating system file dialogs support folder selection only in "Open" dialogs.
* <li>{@link JFileChooser#FILES_AND_DIRECTORIES} is not supported.
* <li>{@link #getSelectedFiles()} returns selected file also in single selection mode.
* {@link JFileChooser#getSelectedFiles()} only in multi selection mode.
* </ul>
*
* @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

View File

@@ -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()
}