mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2026-02-12 23:07:15 -06:00
System File Chooser: update current filter before invoking approve callback and after closing dialog (issue #1065)
This commit is contained in:
@@ -37,7 +37,7 @@ import com.formdev.flatlaf.util.SystemInfo;
|
||||
*/
|
||||
public class FlatNativeLinuxLibrary
|
||||
{
|
||||
private static int API_VERSION_LINUX = 3003;
|
||||
private static int API_VERSION_LINUX = 3004;
|
||||
|
||||
/**
|
||||
* Checks whether native library is loaded/available.
|
||||
@@ -186,8 +186,8 @@ public class FlatNativeLinuxLibrary
|
||||
* Use '__' for '_' character (e.g. "Choose__and__Quit").
|
||||
* @param currentName user-editable filename currently shown in the filename field in save dialog; or {@code null}
|
||||
* @param currentFolder current directory shown in the dialog; or {@code null}
|
||||
* @param optionsSet options to set; see {@code FOS_*} constants
|
||||
* @param optionsClear options to clear; see {@code FOS_*} constants
|
||||
* @param optionsSet options to set; see {@code FC_*} constants
|
||||
* @param optionsClear options to clear; see {@code FC_*} constants
|
||||
* @param callback approve callback; or {@code null}
|
||||
* @param fileTypeIndex the file type that appears as selected (zero-based)
|
||||
* @param fileTypes file types that the dialog can open or save.
|
||||
@@ -195,19 +195,20 @@ public class FlatNativeLinuxLibrary
|
||||
* First string is the display name of the filter shown in the combobox (e.g. "Text Files").
|
||||
* Subsequent strings are the filter patterns (e.g. "*.txt" or "*").
|
||||
* {@code null} is required to mark end of filter.
|
||||
* @param retFileTypeIndex returns selected file type (zero-based); array must be have one element
|
||||
* @return file path(s) that the user selected; an empty array if canceled;
|
||||
* or {@code null} on failures (no dialog shown)
|
||||
*
|
||||
* @since 3.7
|
||||
* @since 3.7.1
|
||||
*/
|
||||
public native static String[] showFileChooser( Window owner, int dark, boolean open,
|
||||
String title, String okButtonLabel, String currentName, String currentFolder,
|
||||
int optionsSet, int optionsClear, FileChooserCallback callback,
|
||||
int fileTypeIndex, String... fileTypes );
|
||||
int fileTypeIndex, String[] fileTypes, int[] retFileTypeIndex );
|
||||
|
||||
/** @since 3.7 */
|
||||
/** @since 3.7.1 */
|
||||
public interface FileChooserCallback {
|
||||
boolean approve( String[] files, long hwndFileDialog );
|
||||
boolean approve( String[] files, int fileTypeIndex, long hwndFileDialog );
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -45,7 +45,7 @@ import com.formdev.flatlaf.util.SystemInfo;
|
||||
*/
|
||||
public class FlatNativeMacLibrary
|
||||
{
|
||||
private static int API_VERSION_MACOS = 2002;
|
||||
private static int API_VERSION_MACOS = 2003;
|
||||
|
||||
/**
|
||||
* Checks whether native library is loaded/available.
|
||||
@@ -117,20 +117,21 @@ public class FlatNativeMacLibrary
|
||||
* First string is the display name of the filter shown in the combobox (e.g. "Text Files").
|
||||
* Subsequent strings are the filter patterns (e.g. "txt" or "*").
|
||||
* {@code null} is required to mark end of filter.
|
||||
* @param retFileTypeIndex returns selected file type (zero-based); array must be have one element
|
||||
* @return file path(s) that the user selected; an empty array if canceled;
|
||||
* or {@code null} on failures (no dialog shown)
|
||||
*
|
||||
* @since 3.7
|
||||
* @since 3.7.1
|
||||
*/
|
||||
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,
|
||||
int fileTypeIndex, String... fileTypes );
|
||||
int fileTypeIndex, String[] fileTypes, int[] retFileTypeIndex );
|
||||
|
||||
/** @since 3.7 */
|
||||
/** @since 3.7.1 */
|
||||
public interface FileChooserCallback {
|
||||
boolean approve( String[] files, long hwndFileDialog );
|
||||
boolean approve( String[] files, int fileTypeIndex, long hwndFileDialog );
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -31,7 +31,7 @@ import com.formdev.flatlaf.util.SystemInfo;
|
||||
*/
|
||||
public class FlatNativeWindowsLibrary
|
||||
{
|
||||
private static int API_VERSION_WINDOWS = 1002;
|
||||
private static int API_VERSION_WINDOWS = 1003;
|
||||
|
||||
private static long osBuildNumber = Long.MIN_VALUE;
|
||||
|
||||
@@ -226,20 +226,21 @@ public class FlatNativeWindowsLibrary
|
||||
* Pairs of strings are required for each filter.
|
||||
* First string is the display name of the filter shown in the combobox (e.g. "Text Files").
|
||||
* Second string is the filter pattern (e.g. "*.txt", "*.exe;*.dll" or "*.*").
|
||||
* @param retFileTypeIndex returns selected file type (zero-based); array must be have one element
|
||||
* @return file path(s) that the user selected; an empty array if canceled;
|
||||
* or {@code null} on failures (no dialog shown)
|
||||
*
|
||||
* @since 3.7
|
||||
* @since 3.7.1
|
||||
*/
|
||||
public native static String[] showFileChooser( Window owner, boolean open,
|
||||
String title, String okButtonLabel, String fileNameLabel, String fileName,
|
||||
String folder, String saveAsItem, String defaultFolder, String defaultExtension,
|
||||
int optionsSet, int optionsClear, FileChooserCallback callback,
|
||||
int fileTypeIndex, String... fileTypes );
|
||||
int fileTypeIndex, String[] fileTypes, int[] retFileTypeIndex );
|
||||
|
||||
/** @since 3.7 */
|
||||
/** @since 3.7.1 */
|
||||
public interface FileChooserCallback {
|
||||
boolean approve( String[] files, long hwndFileDialog );
|
||||
boolean approve( String[] files, int fileTypeIndex, long hwndFileDialog );
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -28,6 +28,7 @@ import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
@@ -607,6 +608,11 @@ public class SystemFileChooser
|
||||
return filters2;
|
||||
}
|
||||
|
||||
private void updateFileFilter( List<FileFilter> filters, int index ) {
|
||||
if( index >= 0 && index < filters.size() )
|
||||
setFileFilter( filters.get( index ) );
|
||||
}
|
||||
|
||||
public ApproveCallback getApproveCallback() {
|
||||
return approveCallback;
|
||||
}
|
||||
@@ -890,6 +896,7 @@ public class SystemFileChooser
|
||||
// filter
|
||||
int fileTypeIndex = 0;
|
||||
ArrayList<String> fileTypes = new ArrayList<>();
|
||||
ArrayList<FileFilter> fileTypeFilters = new ArrayList<>();
|
||||
if( !fc.isDirectorySelectionEnabled() ) {
|
||||
List<FileFilter> filters = fc.getFiltersForDialog();
|
||||
if( !filters.isEmpty() ) {
|
||||
@@ -898,9 +905,11 @@ public class SystemFileChooser
|
||||
if( filter instanceof FileNameExtensionFilter ) {
|
||||
fileTypes.add( filter.getDescription() );
|
||||
fileTypes.add( "*." + String.join( ";*.", ((FileNameExtensionFilter)filter).getExtensions() ) );
|
||||
fileTypeFilters.add( filter );
|
||||
} else if( filter instanceof AcceptAllFileFilter ) {
|
||||
fileTypes.add( filter.getDescription() );
|
||||
fileTypes.add( "*.*" );
|
||||
fileTypeFilters.add( filter );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -916,19 +925,24 @@ public class SystemFileChooser
|
||||
|
||||
// callback
|
||||
FlatNativeWindowsLibrary.FileChooserCallback callback = (fc.getApproveCallback() != null)
|
||||
? (files, hwndFileDialog) -> {
|
||||
? (files, fileTypeIndex2, hwndFileDialog) -> {
|
||||
fc.updateFileFilter( fileTypeFilters, fileTypeIndex2 );
|
||||
return invokeApproveCallback( fc, files, new WindowsApproveContext( hwndFileDialog ) );
|
||||
} : null;
|
||||
|
||||
// show system file dialog
|
||||
return FlatNativeWindowsLibrary.showFileChooser( owner, open,
|
||||
int[] retFileTypeIndex = { -1 };
|
||||
String[] result = FlatNativeWindowsLibrary.showFileChooser( owner, open,
|
||||
fc.getDialogTitle(), approveButtonText,
|
||||
fc.getPlatformProperty( WINDOWS_FILE_NAME_LABEL ),
|
||||
fileName, folder, saveAsItem,
|
||||
fc.getPlatformProperty( WINDOWS_DEFAULT_FOLDER ),
|
||||
fc.getPlatformProperty( WINDOWS_DEFAULT_EXTENSION ),
|
||||
optionsSet, optionsClear, callback,
|
||||
fileTypeIndex, fileTypes.toArray( new String[fileTypes.size()] ) );
|
||||
fileTypeIndex, fileTypes.toArray( new String[fileTypes.size()] ), retFileTypeIndex );
|
||||
if( result != null )
|
||||
fc.updateFileFilter( fileTypeFilters, retFileTypeIndex[0] );
|
||||
return result;
|
||||
}
|
||||
|
||||
//---- class WindowsApproveContext ----
|
||||
@@ -1013,6 +1027,7 @@ public class SystemFileChooser
|
||||
// filter
|
||||
int fileTypeIndex = 0;
|
||||
ArrayList<String> fileTypes = new ArrayList<>();
|
||||
ArrayList<FileFilter> fileTypeFilters = new ArrayList<>();
|
||||
if( !fc.isDirectorySelectionEnabled() ) {
|
||||
List<FileFilter> filters = fc.getFiltersForDialog();
|
||||
if( !filters.isEmpty() ) {
|
||||
@@ -1023,10 +1038,12 @@ public class SystemFileChooser
|
||||
for( String ext : ((FileNameExtensionFilter)filter).getExtensions() )
|
||||
fileTypes.add( ext );
|
||||
fileTypes.add( null );
|
||||
fileTypeFilters.add( filter );
|
||||
} else if( filter instanceof AcceptAllFileFilter ) {
|
||||
fileTypes.add( filter.getDescription() );
|
||||
fileTypes.add( "*" );
|
||||
fileTypes.add( null );
|
||||
fileTypeFilters.add( filter );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1034,18 +1051,23 @@ public class SystemFileChooser
|
||||
|
||||
// callback
|
||||
FlatNativeMacLibrary.FileChooserCallback callback = (fc.getApproveCallback() != null)
|
||||
? (files, hwndFileDialog) -> {
|
||||
? (files, fileTypeIndex2, hwndFileDialog) -> {
|
||||
fc.updateFileFilter( fileTypeFilters, fileTypeIndex2 );
|
||||
return invokeApproveCallback( fc, files, new MacApproveContext( hwndFileDialog ) );
|
||||
} : null;
|
||||
|
||||
// show system file dialog
|
||||
return FlatNativeMacLibrary.showFileChooser( owner, dark, open,
|
||||
int[] retFileTypeIndex = { -1 };
|
||||
String[] result = FlatNativeMacLibrary.showFileChooser( owner, dark, open,
|
||||
fc.getDialogTitle(), fc.getApproveButtonText(),
|
||||
fc.getPlatformProperty( MAC_MESSAGE ),
|
||||
fc.getPlatformProperty( MAC_FILTER_FIELD_LABEL ),
|
||||
fc.getPlatformProperty( MAC_NAME_FIELD_LABEL ),
|
||||
nameFieldStringValue, directoryURL, optionsSet, optionsClear, callback,
|
||||
fileTypeIndex, fileTypes.toArray( new String[fileTypes.size()] ) );
|
||||
fileTypeIndex, fileTypes.toArray( new String[fileTypes.size()] ), retFileTypeIndex );
|
||||
if( result != null )
|
||||
fc.updateFileFilter( fileTypeFilters, retFileTypeIndex[0] );
|
||||
return result;
|
||||
}
|
||||
|
||||
//---- class MacApproveContext ----
|
||||
@@ -1141,6 +1163,7 @@ public class SystemFileChooser
|
||||
// filter
|
||||
int fileTypeIndex = 0;
|
||||
ArrayList<String> fileTypes = new ArrayList<>();
|
||||
ArrayList<FileFilter> fileTypeFilters = new ArrayList<>();
|
||||
if( !fc.isDirectorySelectionEnabled() ) {
|
||||
List<FileFilter> filters = fc.getFiltersForDialog();
|
||||
if( !filters.isEmpty() ) {
|
||||
@@ -1151,10 +1174,12 @@ public class SystemFileChooser
|
||||
for( String ext : ((FileNameExtensionFilter)filter).getExtensions() )
|
||||
fileTypes.add( caseInsensitiveGlobPattern( ext ) );
|
||||
fileTypes.add( null );
|
||||
fileTypeFilters.add( filter );
|
||||
} else if( filter instanceof AcceptAllFileFilter ) {
|
||||
fileTypes.add( filter.getDescription() );
|
||||
fileTypes.add( "*" );
|
||||
fileTypes.add( null );
|
||||
fileTypeFilters.add( filter );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1162,15 +1187,20 @@ public class SystemFileChooser
|
||||
|
||||
// callback
|
||||
FlatNativeLinuxLibrary.FileChooserCallback callback = (fc.getApproveCallback() != null)
|
||||
? (files, hwndFileDialog) -> {
|
||||
? (files, fileTypeIndex2, hwndFileDialog) -> {
|
||||
fc.updateFileFilter( fileTypeFilters, fileTypeIndex2 );
|
||||
return invokeApproveCallback( fc, files, new LinuxApproveContext( hwndFileDialog ) );
|
||||
} : null;
|
||||
|
||||
// show system file dialog
|
||||
return FlatNativeLinuxLibrary.showFileChooser( owner, dark, open,
|
||||
int[] retFileTypeIndex = { -1 };
|
||||
String[] result = FlatNativeLinuxLibrary.showFileChooser( owner, dark, open,
|
||||
fc.getDialogTitle(), approveButtonText, currentName, currentFolder,
|
||||
optionsSet, optionsClear, callback,
|
||||
fileTypeIndex, fileTypes.toArray( new String[fileTypes.size()] ) );
|
||||
fileTypeIndex, fileTypes.toArray( new String[fileTypes.size()] ), retFileTypeIndex );
|
||||
if( result != null )
|
||||
fc.updateFileFilter( fileTypeFilters, retFileTypeIndex[0] );
|
||||
return result;
|
||||
}
|
||||
|
||||
private String caseInsensitiveGlobPattern( String ext ) {
|
||||
@@ -1253,6 +1283,8 @@ public class SystemFileChooser
|
||||
{
|
||||
@Override
|
||||
public File[] showDialog( Window owner, SystemFileChooser fc ) {
|
||||
IdentityHashMap<javax.swing.filechooser.FileFilter, FileFilter> filterMap = new IdentityHashMap<>();
|
||||
|
||||
JFileChooser chooser = new JFileChooser() {
|
||||
@Override
|
||||
public void approveSelection() {
|
||||
@@ -1273,6 +1305,7 @@ public class SystemFileChooser
|
||||
// callback
|
||||
ApproveCallback approveCallback = fc.getApproveCallback();
|
||||
if( approveCallback != null ) {
|
||||
updateFileFilter( fc, this, filterMap );
|
||||
int result = approveCallback.approve( files, new SwingApproveContext( this ) );
|
||||
if( result == CANCEL_OPTION )
|
||||
return;
|
||||
@@ -1313,6 +1346,7 @@ public class SystemFileChooser
|
||||
chooser.addChoosableFileFilter( jfilter );
|
||||
if( filter == currentFilter )
|
||||
chooser.setFileFilter( jfilter );
|
||||
filterMap.put( jfilter, filter );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1340,6 +1374,7 @@ public class SystemFileChooser
|
||||
|
||||
// show dialog
|
||||
int result = chooser.showDialog( owner, null );
|
||||
updateFileFilter( fc, chooser, filterMap );
|
||||
|
||||
// save window size
|
||||
Dimension windowSize = chooser.getSize();
|
||||
@@ -1367,6 +1402,14 @@ public class SystemFileChooser
|
||||
return null;
|
||||
}
|
||||
|
||||
private void updateFileFilter( SystemFileChooser fc, JFileChooser chooser,
|
||||
IdentityHashMap<javax.swing.filechooser.FileFilter, FileFilter> filterMap )
|
||||
{
|
||||
FileFilter fileFilter = filterMap.get( chooser.getFileFilter() );
|
||||
if( fileFilter != null )
|
||||
fc.setFileFilter( fileFilter );
|
||||
}
|
||||
|
||||
private static boolean checkMustExist( JFileChooser chooser, File[] files ) {
|
||||
for( File file : files ) {
|
||||
if( !file.exists() ) {
|
||||
|
||||
Reference in New Issue
Block a user