From aecb496142a411211c5dbebed0a10973fead612c Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Tue, 21 Jan 2025 14:33:03 +0100 Subject: [PATCH] System File Chooser: macOS: show file dialog in dark if current FlatLaf theme is dark --- .../java/com/formdev/flatlaf/ui/FlatNativeMacLibrary.java | 4 +++- .../java/com/formdev/flatlaf/util/SystemFileChooser.java | 4 +++- .../headers/com_formdev_flatlaf_ui_FlatNativeMacLibrary.h | 4 ++-- .../src/main/objcpp/MacFileChooser.mm | 8 +++++++- .../src/main/objcpp/MacMessageDialog.mm | 5 +++++ .../flatlaf/testing/FlatSystemFileChooserMacTest.java | 7 +++++-- 6 files changed, 25 insertions(+), 7 deletions(-) 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 362f8ee3..f4d17c01 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 @@ -99,6 +99,8 @@ public class FlatNativeMacLibrary * the file dialog. It is highly recommended to invoke it from a new thread * to avoid blocking the AWT event dispatching thread. * + * @param owner the owner of the file dialog; or {@code null} + * @param dark appearance of the file dialog: {@code 1} = dark, {@code 0} = light, {@code -1} = default * @param open if {@code true}, shows the open dialog; if {@code false}, shows the save dialog * @param title text displayed at top of save dialog (not used in open dialog); or {@code null} * @param prompt text displayed in default button; or {@code null} @@ -120,7 +122,7 @@ public class FlatNativeMacLibrary * * @since 3.6 */ - public native static String[] showFileChooser( boolean open, + public native static String[] showFileChooser( Window owner, int dark, boolean open, String title, String prompt, String message, String filterFieldLabel, String nameFieldLabel, String nameFieldStringValue, String directoryURL, int optionsSet, int optionsClear, FileChooserCallback callback, 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 39fa5a39..79c97f9d 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 @@ -33,6 +33,7 @@ import javax.swing.JOptionPane; import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.filechooser.FileSystemView; +import com.formdev.flatlaf.FlatLaf; import com.formdev.flatlaf.FlatSystemProperties; import com.formdev.flatlaf.ui.FlatNativeLinuxLibrary; import com.formdev.flatlaf.ui.FlatNativeMacLibrary; @@ -837,6 +838,7 @@ public class SystemFileChooser { @Override String[] showSystemDialog( Window owner, SystemFileChooser fc ) { + int dark = FlatLaf.isLafDark() ? 1 : 0; boolean open = (fc.getDialogType() == OPEN_DIALOG); String nameFieldStringValue = null; String directoryURL = null; @@ -901,7 +903,7 @@ public class SystemFileChooser } : null; // show system file dialog - return FlatNativeMacLibrary.showFileChooser( open, + return FlatNativeMacLibrary.showFileChooser( owner, dark, open, fc.getDialogTitle(), fc.getApproveButtonText(), fc.getPlatformProperty( MAC_MESSAGE ), fc.getPlatformProperty( MAC_FILTER_FIELD_LABEL ), diff --git a/flatlaf-natives/flatlaf-natives-macos/src/main/headers/com_formdev_flatlaf_ui_FlatNativeMacLibrary.h b/flatlaf-natives/flatlaf-natives-macos/src/main/headers/com_formdev_flatlaf_ui_FlatNativeMacLibrary.h index 329085b0..301039b2 100644 --- a/flatlaf-natives/flatlaf-natives-macos/src/main/headers/com_formdev_flatlaf_ui_FlatNativeMacLibrary.h +++ b/flatlaf-natives/flatlaf-natives-macos/src/main/headers/com_formdev_flatlaf_ui_FlatNativeMacLibrary.h @@ -82,10 +82,10 @@ JNIEXPORT jboolean JNICALL Java_com_formdev_flatlaf_ui_FlatNativeMacLibrary_togg /* * Class: com_formdev_flatlaf_ui_FlatNativeMacLibrary * Method: showFileChooser - * Signature: (ZLjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;IILcom/formdev/flatlaf/ui/FlatNativeMacLibrary/FileChooserCallback;I[Ljava/lang/String;)[Ljava/lang/String; + * Signature: (Ljava/awt/Window;IZLjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;IILcom/formdev/flatlaf/ui/FlatNativeMacLibrary/FileChooserCallback;I[Ljava/lang/String;)[Ljava/lang/String; */ JNIEXPORT jobjectArray JNICALL Java_com_formdev_flatlaf_ui_FlatNativeMacLibrary_showFileChooser - (JNIEnv *, jclass, jboolean, jstring, jstring, jstring, jstring, jstring, jstring, jstring, jint, jint, jobject, jint, jobjectArray); + (JNIEnv *, jclass, jobject, jint, jboolean, jstring, jstring, jstring, jstring, jstring, jstring, jstring, jint, jint, jobject, jint, jobjectArray); /* * Class: com_formdev_flatlaf_ui_FlatNativeMacLibrary 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 891d97c2..44d83fce 100644 --- a/flatlaf-natives/flatlaf-natives-macos/src/main/objcpp/MacFileChooser.mm +++ b/flatlaf-natives/flatlaf-natives-macos/src/main/objcpp/MacFileChooser.mm @@ -232,7 +232,7 @@ static NSMutableArray* initFilters( JNIEnv* env, jobjectArray fileTypes ) { extern "C" JNIEXPORT jobjectArray JNICALL Java_com_formdev_flatlaf_ui_FlatNativeMacLibrary_showFileChooser - ( JNIEnv* env, jclass cls, jboolean open, + ( JNIEnv* env, jclass cls, jobject owner, jint dark, jboolean open, jstring title, jstring prompt, jstring message, jstring filterFieldLabel, jstring nameFieldLabel, jstring nameFieldStringValue, jstring directoryURL, jint optionsSet, jint optionsClear, jobject callback, jint fileTypeIndex, jobjectArray fileTypes ) @@ -262,6 +262,12 @@ JNIEXPORT jobjectArray JNICALL Java_com_formdev_flatlaf_ui_FlatNativeMacLibrary_ NSSavePanel* dialog = open ? [NSOpenPanel openPanel] : [NSSavePanel savePanel]; + // set appearance + if( dark == 1 ) + dialog.appearance = [NSAppearance appearanceNamed:NSAppearanceNameDarkAqua]; + else if( dark == 0 ) + dialog.appearance = [NSAppearance appearanceNamed:NSAppearanceNameAqua]; + if( nsTitle != NULL ) dialog.title = nsTitle; if( nsPrompt != NULL ) diff --git a/flatlaf-natives/flatlaf-natives-macos/src/main/objcpp/MacMessageDialog.mm b/flatlaf-natives/flatlaf-natives-macos/src/main/objcpp/MacMessageDialog.mm index d186c8e6..b8d3ee9b 100644 --- a/flatlaf-natives/flatlaf-natives-macos/src/main/objcpp/MacMessageDialog.mm +++ b/flatlaf-natives/flatlaf-natives-macos/src/main/objcpp/MacMessageDialog.mm @@ -51,6 +51,11 @@ JNIEXPORT jint JNICALL Java_com_formdev_flatlaf_ui_FlatNativeMacLibrary_showMess [FlatJNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){ NSAlert* alert = [[NSAlert alloc] init]; + // use appearance from parent window + NSWindow* parent = (NSWindow*) hwndParent; + if( parent != NULL ) + alert.window.appearance = parent.appearance; + // use empty string because if alert.messageText is not set it displays "Alert" alert.messageText = (nsMessageText != NULL) ? nsMessageText : @""; if( nsInformativeText != NULL ) diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatSystemFileChooserMacTest.java b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatSystemFileChooserMacTest.java index de339d50..306e90b4 100644 --- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatSystemFileChooserMacTest.java +++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatSystemFileChooserMacTest.java @@ -28,6 +28,7 @@ import java.awt.event.WindowStateListener; import java.util.Arrays; import java.util.concurrent.atomic.AtomicInteger; import javax.swing.*; +import com.formdev.flatlaf.FlatLaf; import com.formdev.flatlaf.extras.components.*; import com.formdev.flatlaf.extras.components.FlatTriStateCheckBox.State; import com.formdev.flatlaf.ui.FlatNativeMacLibrary; @@ -87,6 +88,7 @@ public class FlatSystemFileChooserMacTest } private void openOrSave( boolean open, boolean direct ) { + Window owner = SwingUtilities.windowForComponent( this ); String title = n( titleField.getText() ); String prompt = n( promptField.getText() ); String message = n( messageField.getText() ); @@ -146,8 +148,9 @@ public class FlatSystemFileChooserMacTest return true; }; + int dark = FlatLaf.isLafDark() ? 1 : 0; if( direct ) { - String[] files = FlatNativeMacLibrary.showFileChooser( open, + String[] files = FlatNativeMacLibrary.showFileChooser( owner, dark, open, title, prompt, message, filterFieldLabel, nameFieldLabel, nameFieldStringValue, directoryURL, optionsSet.get(), optionsClear.get(), callback, fileTypeIndex, fileTypes ); @@ -158,7 +161,7 @@ public class FlatSystemFileChooserMacTest String[] fileTypes2 = fileTypes; new Thread( () -> { - String[] files = FlatNativeMacLibrary.showFileChooser( open, + String[] files = FlatNativeMacLibrary.showFileChooser( owner, dark, open, title, prompt, message, filterFieldLabel, nameFieldLabel, nameFieldStringValue, directoryURL, optionsSet.get(), optionsClear.get(), callback, fileTypeIndex, fileTypes2 );