apple.awt.fileDialogForDirectories property not working.

Marco Dinacci marco.dinacci at gmail.com
Tue May 29 10:03:27 PDT 2012


Hi Anthony,

> This is a known issue: 7161437. Although it is closed as a duplicate of a
> more general AWT RFE 6927978 that proposes to add public API for
> DirectoryDialogs to AWT.

I understand that 7161437 is closed but since it's more than two years
that the RFE has been submitted and all I need really is just the fix
for the 7161437, here's a patch that actually fixes it. I don't know
if it's the best way to do it but this is certainly good enough for my
application. After the diff there's a test case. I hope it can be
useful.

diff -r 6432464ffec2 src/macosx/classes/sun/lwawt/macosx/CFileDialog.java
--- a/src/macosx/classes/sun/lwawt/macosx/CFileDialog.java	Sat May 26
08:01:40 2012 -0700
+++ b/src/macosx/classes/sun/lwawt/macosx/CFileDialog.java	Tue May 29
17:56:51 2012 +0100
@@ -49,20 +49,28 @@ class CFileDialog implements FileDialogP

                 navigateApps = true;

                 String title = target.getTitle();
                 if (title == null) {
                     title = " ";
                 }

+                String chooseDirectoriesValue =
System.getProperty("apple.awt.fileDialogForDirectories");
+                boolean chooseDirectories = false;
+                if(chooseDirectoriesValue != null &&
+                        chooseDirectoriesValue.equalsIgnoreCase("true")) {
+                    chooseDirectories = true;
+                }
+
                 String[] userFileNames = nativeRunFileDialog(title,
                         dialogMode,
                         target.isMultipleMode(),
                         navigateApps,
+                        chooseDirectories,
                         target.getFilenameFilter() != null,
                         target.getDirectory(),
                         target.getFile());

                 String directory = null;
                 String file = null;
                 File[] files = null;

@@ -137,18 +145,18 @@ class CFileDialog implements FileDialogP
             File directoryObj = new File(fileObj.getParent());
             String nameOnly = fileObj.getName();
             ret = ff.accept(directoryObj, nameOnly);
         }
         return ret;
     }

     private native String[] nativeRunFileDialog(String title, int mode,
-            boolean multipleMode, boolean shouldNavigateApps, boolean
hasFilenameFilter,
-            String directory, String file);
+            boolean multipleMode, boolean shouldNavigateApps, boolean
canChooseDirectories,
+            boolean hasFilenameFilter, String directory, String file);

     @Override
     public void setDirectory(String dir) {
     }

     @Override
     public void setFile(String file) {
     }
diff -r 6432464ffec2 src/macosx/native/sun/awt/CFileDialog.h
--- a/src/macosx/native/sun/awt/CFileDialog.h	Sat May 26 08:01:40 2012 -0700
+++ b/src/macosx/native/sun/awt/CFileDialog.h	Tue May 29 17:56:51 2012 +0100
@@ -47,16 +47,19 @@
     jint fMode;

     // Indicates whether the user can select multiple files
     BOOL fMultipleMode;

     // Should we navigate into apps?
     BOOL fNavigateApps;

+    // Can the dialog choose directories ?
+    BOOL fChooseDirectories;
+
     // Contains the absolute paths of the selected files as URLs
     NSArray *fURLs;
 }

 // Allocator
 - (id) initWithFilter:(jboolean)inHasFilter
            fileDialog:(jobject)inDialog
                 title:(NSString *)inTitle
diff -r 6432464ffec2 src/macosx/native/sun/awt/CFileDialog.m
--- a/src/macosx/native/sun/awt/CFileDialog.m	Sat May 26 08:01:40 2012 -0700
+++ b/src/macosx/native/sun/awt/CFileDialog.m	Tue May 29 17:56:51 2012 +0100
@@ -38,30 +38,32 @@
 - (id)initWithFilter:(jboolean)inHasFilter
           fileDialog:(jobject)inDialog
                title:(NSString *)inTitle
            directory:(NSString *)inPath
                 file:(NSString *)inFile
                 mode:(jint)inMode
         multipleMode:(BOOL)inMultipleMode
       shouldNavigate:(BOOL)inNavigateApps
+canChooseDirectories:(BOOL)inChooseDirectories
              withEnv:(JNIEnv*)env;
 {
     if (self == [super init]) {
         fHasFileFilter = inHasFilter;
         fFileDialog = JNFNewGlobalRef(env, inDialog);
         fDirectory = inPath;
         [fDirectory retain];
         fFile = inFile;
         [fFile retain];
         fTitle = inTitle;
         [fTitle retain];
         fMode = inMode;
         fMultipleMode = inMultipleMode;
         fNavigateApps = inNavigateApps;
+        fChooseDirectories = inChooseDirectories;
         fPanelResult = NSCancelButton;
     }

     return self;
 }

 -(void) disposer {
     if (fFileDialog != NULL) {
@@ -104,17 +106,17 @@
         if (fNavigateApps) {
             [thePanel setTreatsFilePackagesAsDirectories:YES];
         }

         if (fMode == java_awt_FileDialog_LOAD) {
             NSOpenPanel *openPanel = (NSOpenPanel *)thePanel;
             [openPanel setAllowsMultipleSelection:fMultipleMode];
             [openPanel setCanChooseFiles:YES];
-            [openPanel setCanChooseDirectories:NO];
+            [openPanel setCanChooseDirectories:fChooseDirectories];
             [openPanel setCanCreateDirectories:YES];
         }

         [thePanel setDelegate:self];
         fPanelResult = [thePanel runModalForDirectory:fDirectory file:fFile];
         [thePanel setDelegate:nil];

         if ([self userClickedOK]) {
@@ -177,17 +179,17 @@
  * Class:     sun_lwawt_macosx_CFileDialog
  * Method:    nativeRunFileDialog
  * Signature: (Ljava/lang/String;ILjava/io/FilenameFilter;
  *             Ljava/lang/String;Ljava/lang/String;)[Ljava/lang/String;
  */
 JNIEXPORT jobjectArray JNICALL
 Java_sun_lwawt_macosx_CFileDialog_nativeRunFileDialog
 (JNIEnv *env, jobject peer, jstring title, jint mode, jboolean multipleMode,
- jboolean navigateApps, jboolean hasFilter, jstring directory, jstring file)
+ jboolean navigateApps, jboolean chooseDirectories, jboolean
hasFilter, jstring directory, jstring file)
 {
     jobjectArray returnValue = NULL;

 JNF_COCOA_ENTER(env);
     NSString *dialogTitle = JNFJavaToNSString(env, title);
     if ([dialogTitle length] == 0) {
         dialogTitle = @" ";
     }
@@ -195,16 +197,17 @@ JNF_COCOA_ENTER(env);
     CFileDialog *dialogDelegate = [[CFileDialog alloc] initWithFilter:hasFilter
                                                            fileDialog:peer

title:dialogTitle

directory:JNFJavaToNSString(env, directory)

file:JNFJavaToNSString(env, file)
                                                                  mode:mode

multipleMode:multipleMode

shouldNavigate:navigateApps
+
canChooseDirectories:chooseDirectories
                                                               withEnv:env];

     [JNFRunLoop performOnMainThread:@selector(safeSaveOrLoad)
                                  on:dialogDelegate
                          withObject:nil
                       waitUntilDone:YES];

     if ([dialogDelegate userClickedOK]) {



Test case:

import java.awt.FileDialog;
import java.io.File;
import javax.swing.JFrame;

public class FileDialogTest extends JFrame {

    public String selectFolder() {
        FileDialog fd = new FileDialog(this, "Select Folder Test",
FileDialog.LOAD);
        fd.setDirectory(System.getProperty("user.home"));
        fd.setLocation(50,50);
        fd.setVisible(true);

        return fd.getFile();
    }

    public static void main(String[] args) {
        System.setProperty("apple.awt.fileDialogForDirectories", "true");

        FileDialogTest fdt = new FileDialogTest();
        String selectedFolder = fdt.selectFolder();

        System.out.println("The selected file was: " + selectedFolder);

        System.setProperty("apple.awt.fileDialogForDirectories", "false");
        System.exit(0);
    }

}


Best,
Marco


More information about the macosx-port-dev mailing list