mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2026-02-14 07:47:12 -06:00
System File Chooser: support filename extension filters
This commit is contained in:
@@ -112,7 +112,7 @@ public class FlatNativeMacLibrary
|
|||||||
* @param fileTypes file types that the dialog can open or save.
|
* @param fileTypes file types that the dialog can open or save.
|
||||||
* Two or more strings and {@code null} are required for each filter.
|
* Two or more strings and {@code null} are required for each filter.
|
||||||
* First string is the display name of the filter shown in the combobox (e.g. "Text Files").
|
* 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 "*").
|
* Subsequent strings are the filter patterns (e.g. "txt" or "*").
|
||||||
* {@code null} is required to mark end of filter.
|
* {@code null} is required to mark end of filter.
|
||||||
* @return file path(s) that the user selected; an empty array if canceled;
|
* @return file path(s) that the user selected; an empty array if canceled;
|
||||||
* or {@code null} on failures (no dialog shown)
|
* or {@code null} on failures (no dialog shown)
|
||||||
|
|||||||
@@ -204,8 +204,8 @@ public class FlatNativeWindowsLibrary
|
|||||||
* @param owner the owner of the file dialog; or {@code null}
|
* @param owner the owner of the file dialog; or {@code null}
|
||||||
* @param open if {@code true}, shows the open dialog; if {@code false}, shows the save dialog
|
* @param open if {@code true}, shows the open dialog; if {@code false}, shows the save dialog
|
||||||
* @param title text displayed in dialog title; or {@code null}
|
* @param title text displayed in dialog title; or {@code null}
|
||||||
* @param okButtonLabel text displayed in default button; or {@code null}. Use '&' for mnemonics (e.g. "&Choose").
|
* @param okButtonLabel text displayed in default button; or {@code null}. Use '&' for mnemonics (e.g. "&Choose").
|
||||||
* Use '&&' for '&' character (e.g. "Choose && Quit").
|
* Use '&&' for '&' character (e.g. "Choose && Quit").
|
||||||
* @param fileNameLabel text displayed in front of the filename text field; or {@code null}
|
* @param fileNameLabel text displayed in front of the filename text field; or {@code null}
|
||||||
* @param fileName user-editable filename currently shown in the filename field; or {@code null}
|
* @param fileName user-editable filename currently shown in the filename field; or {@code null}
|
||||||
* @param folder current directory shown in the dialog; or {@code null}
|
* @param folder current directory shown in the dialog; or {@code null}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import java.awt.Toolkit;
|
|||||||
import java.awt.Window;
|
import java.awt.Window;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
import javax.swing.JFileChooser;
|
import javax.swing.JFileChooser;
|
||||||
@@ -37,6 +38,12 @@ import com.formdev.flatlaf.ui.FlatNativeWindowsLibrary;
|
|||||||
/**
|
/**
|
||||||
* Gives access to operating system file dialogs.
|
* Gives access to operating system file dialogs.
|
||||||
* <p>
|
* <p>
|
||||||
|
* There are some limitations and incompatibilities to {@link JFileChooser} because
|
||||||
|
* operating system file dialogs do not offer all features that {@code JFileChooser} provides.
|
||||||
|
* On the other hand, operating system file dialogs offer features out of the box
|
||||||
|
* that {@code JFileChooser} do not offer (e.g. ask for overwrite on save).
|
||||||
|
* So this class offers only features that are available on all platforms.
|
||||||
|
* <p>
|
||||||
* The API is (mostly) compatible with {@link JFileChooser}.
|
* The API is (mostly) compatible with {@link JFileChooser}.
|
||||||
* To use this class in existing code, do a string replace from {@code JFileChooser} to {@code SystemFileChooser}.
|
* To use this class in existing code, do a string replace from {@code JFileChooser} to {@code SystemFileChooser}.
|
||||||
* If there are no compile errors, then there is a good chance that it works without further changes.
|
* If there are no compile errors, then there is a good chance that it works without further changes.
|
||||||
@@ -48,8 +55,7 @@ import com.formdev.flatlaf.ui.FlatNativeWindowsLibrary;
|
|||||||
* {@code SystemFileChooser} requires FlatLaf native libraries (usually contained in flatlaf.jar).
|
* {@code SystemFileChooser} requires FlatLaf native libraries (usually contained in flatlaf.jar).
|
||||||
* If not available or disabled (via {@link FlatSystemProperties#USE_NATIVE_LIBRARY}
|
* If not available or disabled (via {@link FlatSystemProperties#USE_NATIVE_LIBRARY}
|
||||||
* or {@link FlatSystemProperties#USE_SYSTEM_FILE_CHOOSER}), then {@code JFileChooser} is used.
|
* or {@link FlatSystemProperties#USE_SYSTEM_FILE_CHOOSER}), then {@code JFileChooser} is used.
|
||||||
* <p>
|
*
|
||||||
* <p>
|
|
||||||
* <h2>Limitations/incompatibilities compared to JFileChooser</h2>
|
* <h2>Limitations/incompatibilities compared to JFileChooser</h2>
|
||||||
*
|
*
|
||||||
* <ul>
|
* <ul>
|
||||||
@@ -67,6 +73,14 @@ import com.formdev.flatlaf.ui.FlatNativeWindowsLibrary;
|
|||||||
* <li>{@link JFileChooser#FILES_AND_DIRECTORIES} is not supported.
|
* <li>{@link JFileChooser#FILES_AND_DIRECTORIES} is not supported.
|
||||||
* <li>{@link #getSelectedFiles()} returns selected file also in single selection mode.
|
* <li>{@link #getSelectedFiles()} returns selected file also in single selection mode.
|
||||||
* {@link JFileChooser#getSelectedFiles()} only in multi selection mode.
|
* {@link JFileChooser#getSelectedFiles()} only in multi selection mode.
|
||||||
|
* <li>Only file name extension filters (see {@link FileNameExtensionFilter}) are supported.
|
||||||
|
* <li>If adding choosable file filters and {@link #isAcceptAllFileFilterUsed()} is {@code true},
|
||||||
|
* then the <b>All Files</b> filter is placed at the end of the combobox list
|
||||||
|
* (as usual in current operating systems) and the first choosable filter is selected by default.
|
||||||
|
* {@code JFileChooser}, on the other hand, adds <b>All Files</b> filter
|
||||||
|
* as first item and selects it by default.
|
||||||
|
* Use {@code chooser.addChoosableFileFilter( chooser.getAcceptAllFileFilter() )}
|
||||||
|
* to place <b>All Files</b> filter somewhere else.
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
@@ -92,17 +106,30 @@ public class SystemFileChooser
|
|||||||
/** @see JFileChooser#DIRECTORIES_ONLY */
|
/** @see JFileChooser#DIRECTORIES_ONLY */
|
||||||
public static final int DIRECTORIES_ONLY = JFileChooser.DIRECTORIES_ONLY;
|
public static final int DIRECTORIES_ONLY = JFileChooser.DIRECTORIES_ONLY;
|
||||||
|
|
||||||
private int dialogType = OPEN_DIALOG;
|
private int dialogType = OPEN_DIALOG;
|
||||||
private String dialogTitle;
|
private String dialogTitle;
|
||||||
private String approveButtonText;
|
private String approveButtonText;
|
||||||
private int approveButtonMnemonic = 0;
|
private int approveButtonMnemonic = 0;
|
||||||
private int fileSelectionMode = FILES_ONLY;
|
private int fileSelectionMode = FILES_ONLY;
|
||||||
private boolean multiSelection;
|
private boolean multiSelection;
|
||||||
private boolean useFileHiding = true;
|
private boolean useFileHiding = true;
|
||||||
|
|
||||||
private File currentDirectory;
|
private File currentDirectory;
|
||||||
private File selectedFile;
|
private File selectedFile;
|
||||||
private File[] selectedFiles;
|
private File[] selectedFiles;
|
||||||
|
|
||||||
|
private final ArrayList<FileFilter> filters = new ArrayList<>();
|
||||||
|
private FileFilter fileFilter;
|
||||||
|
private AcceptAllFileFilter acceptAllFileFilter;
|
||||||
|
private boolean useAcceptAllFileFilter = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If {@code fc.addChoosableFileFilter(fc.getAcceptAllFileFilter())} is invoked from user code,
|
||||||
|
* then this flag is set to {@code false} and subsequent invocations of {@code fc.addChoosableFileFilter(...)}
|
||||||
|
* no longer insert added filters before the "All Files" filter.
|
||||||
|
* This allows custom ordering the "All Files" filter.
|
||||||
|
*/
|
||||||
|
private boolean keepAcceptAllAtEnd = true;
|
||||||
|
|
||||||
/** @see JFileChooser#JFileChooser() */
|
/** @see JFileChooser#JFileChooser() */
|
||||||
public SystemFileChooser() {
|
public SystemFileChooser() {
|
||||||
@@ -111,7 +138,7 @@ public class SystemFileChooser
|
|||||||
|
|
||||||
/** @see JFileChooser#JFileChooser(String) */
|
/** @see JFileChooser#JFileChooser(String) */
|
||||||
public SystemFileChooser( String currentDirectoryPath ) {
|
public SystemFileChooser( String currentDirectoryPath ) {
|
||||||
setCurrentDirectory( (currentDirectoryPath != null)
|
this( (currentDirectoryPath != null)
|
||||||
? FileSystemView.getFileSystemView().createFileObject( currentDirectoryPath )
|
? FileSystemView.getFileSystemView().createFileObject( currentDirectoryPath )
|
||||||
: null );
|
: null );
|
||||||
}
|
}
|
||||||
@@ -119,6 +146,9 @@ public class SystemFileChooser
|
|||||||
/** @see JFileChooser#JFileChooser(File) */
|
/** @see JFileChooser#JFileChooser(File) */
|
||||||
public SystemFileChooser( File currentDirectory ) {
|
public SystemFileChooser( File currentDirectory ) {
|
||||||
setCurrentDirectory( currentDirectory );
|
setCurrentDirectory( currentDirectory );
|
||||||
|
|
||||||
|
addChoosableFileFilter( getAcceptAllFileFilter() );
|
||||||
|
keepAcceptAllAtEnd = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @see JFileChooser#showOpenDialog(Component) */
|
/** @see JFileChooser#showOpenDialog(Component) */
|
||||||
@@ -282,6 +312,101 @@ public class SystemFileChooser
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @see JFileChooser#getChoosableFileFilters() */
|
||||||
|
public FileFilter[] getChoosableFileFilters() {
|
||||||
|
return filters.toArray( new FileFilter[filters.size()] );
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @see JFileChooser#addChoosableFileFilter(javax.swing.filechooser.FileFilter) */
|
||||||
|
public void addChoosableFileFilter( FileFilter filter ) {
|
||||||
|
if( filter == getAcceptAllFileFilter() )
|
||||||
|
keepAcceptAllAtEnd = false;
|
||||||
|
|
||||||
|
if( filter == null || filters.contains( filter ) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if( !(filter instanceof FileNameExtensionFilter) && !(filter instanceof AcceptAllFileFilter) )
|
||||||
|
throw new IllegalArgumentException( "Filter class not supported: " + filter.getClass().getName() );
|
||||||
|
|
||||||
|
// either insert filter before "All Files" filter, or append to the end
|
||||||
|
int size = filters.size();
|
||||||
|
if( keepAcceptAllAtEnd && size > 0 && (filters.get( size - 1 ) == getAcceptAllFileFilter()) )
|
||||||
|
filters.add( size - 1, filter );
|
||||||
|
else
|
||||||
|
filters.add( filter );
|
||||||
|
|
||||||
|
// initialize current filter
|
||||||
|
if( fileFilter == null || (filters.size() == 2 && filters.get( 1 ) == getAcceptAllFileFilter()) )
|
||||||
|
setFileFilter( filter );
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @see JFileChooser#removeChoosableFileFilter(javax.swing.filechooser.FileFilter) */
|
||||||
|
public boolean removeChoosableFileFilter( FileFilter filter ) {
|
||||||
|
if( !filters.remove( filter ) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// update current filter if necessary
|
||||||
|
if( filter == getFileFilter() ) {
|
||||||
|
if( isAcceptAllFileFilterUsed() && filter != getAcceptAllFileFilter() )
|
||||||
|
setFileFilter( getAcceptAllFileFilter() );
|
||||||
|
else
|
||||||
|
setFileFilter( !filters.isEmpty() ? filters.get( 0 ) : null );
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @see JFileChooser#resetChoosableFileFilters() */
|
||||||
|
public void resetChoosableFileFilters() {
|
||||||
|
filters.clear();
|
||||||
|
setFileFilter( null );
|
||||||
|
if( isAcceptAllFileFilterUsed() ) {
|
||||||
|
addChoosableFileFilter( getAcceptAllFileFilter() );
|
||||||
|
keepAcceptAllAtEnd = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @see JFileChooser#getAcceptAllFileFilter() */
|
||||||
|
public FileFilter getAcceptAllFileFilter() {
|
||||||
|
if( acceptAllFileFilter == null )
|
||||||
|
acceptAllFileFilter = new AcceptAllFileFilter();
|
||||||
|
return acceptAllFileFilter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @see JFileChooser#isAcceptAllFileFilterUsed() */
|
||||||
|
public boolean isAcceptAllFileFilterUsed() {
|
||||||
|
return useAcceptAllFileFilter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @see JFileChooser#setAcceptAllFileFilterUsed(boolean) */
|
||||||
|
public void setAcceptAllFileFilterUsed( boolean acceptAll ) {
|
||||||
|
useAcceptAllFileFilter = acceptAll;
|
||||||
|
|
||||||
|
removeChoosableFileFilter( getAcceptAllFileFilter() );
|
||||||
|
if( acceptAll ) {
|
||||||
|
addChoosableFileFilter( getAcceptAllFileFilter() );
|
||||||
|
keepAcceptAllAtEnd = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @see JFileChooser#getFileFilter() */
|
||||||
|
public FileFilter getFileFilter() {
|
||||||
|
return fileFilter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @see JFileChooser#setFileFilter(javax.swing.filechooser.FileFilter) */
|
||||||
|
public void setFileFilter( FileFilter filter ) {
|
||||||
|
this.fileFilter = filter;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int indexOfCurrentFilter() {
|
||||||
|
return filters.indexOf( fileFilter );
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasOnlyAcceptAll() {
|
||||||
|
return filters.size() == 1 && filters.get( 0 ) == getAcceptAllFileFilter();
|
||||||
|
}
|
||||||
|
|
||||||
private int showDialogImpl( Component parent ) {
|
private int showDialogImpl( Component parent ) {
|
||||||
File[] files = getProvider().showDialog( parent, this );
|
File[] files = getProvider().showDialog( parent, this );
|
||||||
setSelectedFiles( files );
|
setSelectedFiles( files );
|
||||||
@@ -401,13 +526,25 @@ public class SystemFileChooser
|
|||||||
// filter
|
// filter
|
||||||
int fileTypeIndex = 0;
|
int fileTypeIndex = 0;
|
||||||
ArrayList<String> fileTypes = new ArrayList<>();
|
ArrayList<String> fileTypes = new ArrayList<>();
|
||||||
// FOS_PICKFOLDERS does not support file types
|
|
||||||
if( !fc.isDirectorySelectionEnabled() ) {
|
if( !fc.isDirectorySelectionEnabled() ) {
|
||||||
|
if( !fc.hasOnlyAcceptAll() ) {
|
||||||
|
fileTypeIndex = fc.indexOfCurrentFilter();
|
||||||
|
for( FileFilter filter : fc.getChoosableFileFilters() ) {
|
||||||
|
if( filter instanceof FileNameExtensionFilter ) {
|
||||||
|
fileTypes.add( filter.getDescription() );
|
||||||
|
fileTypes.add( "*." + String.join( ";*.", ((FileNameExtensionFilter)filter).getExtensions() ) );
|
||||||
|
} else if( filter instanceof AcceptAllFileFilter ) {
|
||||||
|
fileTypes.add( filter.getDescription() );
|
||||||
|
fileTypes.add( "*.*" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// if there are no file types
|
// if there are no file types
|
||||||
// - for Save dialog add "All Files", otherwise Windows would show an empty "Save as type" combobox
|
// - for Save dialog add "All Files", otherwise Windows would show an empty "Save as type" combobox
|
||||||
// - for Open dialog, Windows hides the combobox
|
// - for Open dialog, Windows hides the combobox
|
||||||
if( !open && fileTypes.isEmpty() ) {
|
if( !open && fileTypes.isEmpty() ) {
|
||||||
fileTypes.add( UIManager.getString( "FileChooser.acceptAllFileFilterText" ) );
|
fileTypes.add( fc.getAcceptAllFileFilter().getDescription() );
|
||||||
fileTypes.add( "*.*" );
|
fileTypes.add( "*.*" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -457,11 +594,30 @@ public class SystemFileChooser
|
|||||||
if( !fc.isFileHidingEnabled() )
|
if( !fc.isFileHidingEnabled() )
|
||||||
optionsSet |= FlatNativeMacLibrary.FC_showsHiddenFiles;
|
optionsSet |= FlatNativeMacLibrary.FC_showsHiddenFiles;
|
||||||
|
|
||||||
|
// filter
|
||||||
|
int fileTypeIndex = 0;
|
||||||
|
ArrayList<String> fileTypes = new ArrayList<>();
|
||||||
|
if( !fc.isDirectorySelectionEnabled() && !fc.hasOnlyAcceptAll() ) {
|
||||||
|
fileTypeIndex = fc.indexOfCurrentFilter();
|
||||||
|
for( FileFilter filter : fc.getChoosableFileFilters() ) {
|
||||||
|
if( filter instanceof FileNameExtensionFilter ) {
|
||||||
|
fileTypes.add( filter.getDescription() );
|
||||||
|
for( String ext : ((FileNameExtensionFilter)filter).getExtensions() )
|
||||||
|
fileTypes.add( ext );
|
||||||
|
fileTypes.add( null );
|
||||||
|
} else if( filter instanceof AcceptAllFileFilter ) {
|
||||||
|
fileTypes.add( filter.getDescription() );
|
||||||
|
fileTypes.add( "*" );
|
||||||
|
fileTypes.add( null );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// show system file dialog
|
// show system file dialog
|
||||||
return FlatNativeMacLibrary.showFileChooser( open,
|
return FlatNativeMacLibrary.showFileChooser( open,
|
||||||
fc.getDialogTitle(), fc.getApproveButtonText(), null, null, null,
|
fc.getDialogTitle(), fc.getApproveButtonText(), null, null, null,
|
||||||
nameFieldStringValue, directoryURL,
|
nameFieldStringValue, directoryURL,
|
||||||
optionsSet, optionsClear, 0 );
|
optionsSet, optionsClear, fileTypeIndex, fileTypes.toArray( new String[fileTypes.size()] ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -515,10 +671,46 @@ public class SystemFileChooser
|
|||||||
else // necessary because GTK seems to be remember last state and re-use it for new file dialogs
|
else // necessary because GTK seems to be remember last state and re-use it for new file dialogs
|
||||||
optionsClear |= FlatNativeLinuxLibrary.FC_show_hidden;
|
optionsClear |= FlatNativeLinuxLibrary.FC_show_hidden;
|
||||||
|
|
||||||
|
// filter
|
||||||
|
int fileTypeIndex = 0;
|
||||||
|
ArrayList<String> fileTypes = new ArrayList<>();
|
||||||
|
if( !fc.isDirectorySelectionEnabled() && !fc.hasOnlyAcceptAll() ) {
|
||||||
|
fileTypeIndex = fc.indexOfCurrentFilter();
|
||||||
|
for( FileFilter filter : fc.getChoosableFileFilters() ) {
|
||||||
|
if( filter instanceof FileNameExtensionFilter ) {
|
||||||
|
fileTypes.add( filter.getDescription() );
|
||||||
|
for( String ext : ((FileNameExtensionFilter)filter).getExtensions() )
|
||||||
|
fileTypes.add( caseInsensitiveGlobPattern( ext ) );
|
||||||
|
fileTypes.add( null );
|
||||||
|
} else if( filter instanceof AcceptAllFileFilter ) {
|
||||||
|
fileTypes.add( filter.getDescription() );
|
||||||
|
fileTypes.add( "*" );
|
||||||
|
fileTypes.add( null );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// show system file dialog
|
// show system file dialog
|
||||||
return FlatNativeLinuxLibrary.showFileChooser( owner, open,
|
return FlatNativeLinuxLibrary.showFileChooser( owner, open,
|
||||||
fc.getDialogTitle(), approveButtonText, currentName, currentFolder,
|
fc.getDialogTitle(), approveButtonText, currentName, currentFolder,
|
||||||
optionsSet, optionsClear, 0 );
|
optionsSet, optionsClear, fileTypeIndex, fileTypes.toArray( new String[fileTypes.size()] ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
private String caseInsensitiveGlobPattern( String ext ) {
|
||||||
|
StringBuilder buf = new StringBuilder();
|
||||||
|
buf.append( "*." );
|
||||||
|
int len = ext.length();
|
||||||
|
for( int i = 0; i < len; i++ ) {
|
||||||
|
char ch = ext.charAt( i );
|
||||||
|
if( Character.isLetter( ch ) ) {
|
||||||
|
buf.append( '[' )
|
||||||
|
.append( Character.toLowerCase( ch ) )
|
||||||
|
.append( Character.toUpperCase( ch ) )
|
||||||
|
.append( ']' );
|
||||||
|
} else
|
||||||
|
buf.append( ch );
|
||||||
|
}
|
||||||
|
return buf.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -561,6 +753,27 @@ public class SystemFileChooser
|
|||||||
!chooser.isDirectorySelectionEnabled() )
|
!chooser.isDirectorySelectionEnabled() )
|
||||||
chooser.setMultiSelectionEnabled( false );
|
chooser.setMultiSelectionEnabled( false );
|
||||||
|
|
||||||
|
// filter
|
||||||
|
if( !fc.isDirectorySelectionEnabled() && !fc.hasOnlyAcceptAll() ) {
|
||||||
|
FileFilter currentFilter = fc.getFileFilter();
|
||||||
|
for( FileFilter filter : fc.getChoosableFileFilters() ) {
|
||||||
|
javax.swing.filechooser.FileFilter jfilter = convertFilter( filter, chooser );
|
||||||
|
if( jfilter == null )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
chooser.addChoosableFileFilter( jfilter );
|
||||||
|
if( filter == currentFilter ) {
|
||||||
|
chooser.setFileFilter( jfilter );
|
||||||
|
currentFilter = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( currentFilter != null ) {
|
||||||
|
javax.swing.filechooser.FileFilter jfilter = convertFilter( currentFilter, chooser );
|
||||||
|
if( jfilter != null )
|
||||||
|
chooser.setFileFilter( jfilter );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// paths
|
// paths
|
||||||
chooser.setCurrentDirectory( fc.getCurrentDirectory() );
|
chooser.setCurrentDirectory( fc.getCurrentDirectory() );
|
||||||
chooser.setSelectedFile( fc.getSelectedFile() );
|
chooser.setSelectedFile( fc.getSelectedFile() );
|
||||||
@@ -572,40 +785,111 @@ public class SystemFileChooser
|
|||||||
? chooser.getSelectedFiles()
|
? chooser.getSelectedFiles()
|
||||||
: new File[] { chooser.getSelectedFile() };
|
: new File[] { chooser.getSelectedFile() };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private javax.swing.filechooser.FileFilter convertFilter( FileFilter filter, JFileChooser chooser ) {
|
||||||
|
if( filter instanceof FileNameExtensionFilter ) {
|
||||||
|
return new javax.swing.filechooser.FileNameExtensionFilter(
|
||||||
|
((FileNameExtensionFilter)filter).getDescription(),
|
||||||
|
((FileNameExtensionFilter)filter).getExtensions() );
|
||||||
|
} else if( filter instanceof AcceptAllFileFilter )
|
||||||
|
return chooser.getAcceptAllFileFilter();
|
||||||
|
else
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean checkMustExist( JFileChooser chooser, File[] files ) {
|
||||||
|
for( File file : files ) {
|
||||||
|
if( !file.exists() ) {
|
||||||
|
String title = chooser.getDialogTitle();
|
||||||
|
JOptionPane.showMessageDialog( chooser,
|
||||||
|
file.getName() + (chooser.isDirectorySelectionEnabled()
|
||||||
|
? "\nPath does not exist.\nCheck the path and try again."
|
||||||
|
: "\nFile not found.\nCheck the file name and try again."),
|
||||||
|
(title != null) ? title : "Open",
|
||||||
|
JOptionPane.WARNING_MESSAGE );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean checkOverwrite( JFileChooser chooser, File[] files ) {
|
||||||
|
for( File file : files ) {
|
||||||
|
if( file.exists() ) {
|
||||||
|
String title = chooser.getDialogTitle();
|
||||||
|
Locale l = chooser.getLocale();
|
||||||
|
Object[] options = {
|
||||||
|
UIManager.getString( "OptionPane.yesButtonText", l ),
|
||||||
|
UIManager.getString( "OptionPane.noButtonText", l ), };
|
||||||
|
int result = JOptionPane.showOptionDialog( chooser,
|
||||||
|
file.getName() + " already exists.\nDo you want to replace it?",
|
||||||
|
"Confirm " + (title != null ? title : "Save"),
|
||||||
|
JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE,
|
||||||
|
null, options, options[1] );
|
||||||
|
return (result == 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean checkMustExist( JFileChooser chooser, File[] files ) {
|
//---- class FileFilter ---------------------------------------------------
|
||||||
for( File file : files ) {
|
|
||||||
if( !file.exists() ) {
|
/** @see javax.swing.filechooser.FileFilter */
|
||||||
String title = chooser.getDialogTitle();
|
public static abstract class FileFilter {
|
||||||
JOptionPane.showMessageDialog( chooser,
|
/** @see javax.swing.filechooser.FileFilter#getDescription() */
|
||||||
file.getName() + (chooser.isDirectorySelectionEnabled()
|
public abstract String getDescription();
|
||||||
? "\nPath does not exist.\nCheck the path and try again."
|
|
||||||
: "\nFile not found.\nCheck the file name and try again."),
|
|
||||||
(title != null) ? title : "Open",
|
|
||||||
JOptionPane.WARNING_MESSAGE );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean checkOverwrite( JFileChooser chooser, File[] files ) {
|
//---- class FileNameExtensionFilter --------------------------------------
|
||||||
for( File file : files ) {
|
|
||||||
if( file.exists() ) {
|
/** @see javax.swing.filechooser.FileNameExtensionFilter */
|
||||||
String title = chooser.getDialogTitle();
|
public static final class FileNameExtensionFilter
|
||||||
Locale l = chooser.getLocale();
|
extends FileFilter
|
||||||
Object[] options = {
|
{
|
||||||
UIManager.getString( "OptionPane.yesButtonText", l ),
|
private final String description;
|
||||||
UIManager.getString( "OptionPane.noButtonText", l ), };
|
private final String[] extensions;
|
||||||
int result = JOptionPane.showOptionDialog( chooser,
|
|
||||||
file.getName() + " already exists.\nDo you want to replace it?",
|
/** @see javax.swing.filechooser.FileNameExtensionFilter#FileNameExtensionFilter(String, String...) */
|
||||||
"Confirm " + (title != null ? title : "Save"),
|
public FileNameExtensionFilter( String description, String... extensions ) {
|
||||||
JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE,
|
if( extensions == null || extensions.length == 0 )
|
||||||
null, options, options[1] );
|
throw new IllegalArgumentException( "Missing extensions" );
|
||||||
return (result == 0);
|
for( String extension : extensions ) {
|
||||||
|
if( extension == null || extension.isEmpty() )
|
||||||
|
throw new IllegalArgumentException( "Extension is null or empty string" );
|
||||||
|
if( extension.indexOf( '.' ) >= 0 || extension.indexOf( '*' ) >= 0 )
|
||||||
|
throw new IllegalArgumentException( "Extension must not contain '.' or '*'" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.description = description;
|
||||||
|
this.extensions = extensions.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @see javax.swing.filechooser.FileNameExtensionFilter#getDescription() */
|
||||||
|
@Override
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @see javax.swing.filechooser.FileNameExtensionFilter#getExtensions() */
|
||||||
|
public String[] getExtensions() {
|
||||||
|
return extensions.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return super.toString() + "[description=" + description + " extensions=" + Arrays.toString( extensions ) + "]";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//---- class AcceptAllFileFilter ------------------------------------------
|
||||||
|
|
||||||
|
private static final class AcceptAllFileFilter
|
||||||
|
extends FileFilter
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public String getDescription() {
|
||||||
|
return UIManager.getString( "FileChooser.acceptAllFileFilterText" );
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -175,11 +175,21 @@ class DemoFrame
|
|||||||
|
|
||||||
private void openSystemActionPerformed() {
|
private void openSystemActionPerformed() {
|
||||||
SystemFileChooser chooser = new SystemFileChooser();
|
SystemFileChooser chooser = new SystemFileChooser();
|
||||||
|
chooser.addChoosableFileFilter( new SystemFileChooser.FileNameExtensionFilter(
|
||||||
|
"Text Files", "txt", "md" ) );
|
||||||
|
chooser.addChoosableFileFilter( new SystemFileChooser.FileNameExtensionFilter(
|
||||||
|
"PDF Files", "pdf" ) );
|
||||||
|
chooser.addChoosableFileFilter( new SystemFileChooser.FileNameExtensionFilter(
|
||||||
|
"Archives", "zip", "tar", "jar", "7z" ) );
|
||||||
chooser.showOpenDialog( this );
|
chooser.showOpenDialog( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
private void saveAsSystemActionPerformed() {
|
private void saveAsSystemActionPerformed() {
|
||||||
SystemFileChooser chooser = new SystemFileChooser();
|
SystemFileChooser chooser = new SystemFileChooser();
|
||||||
|
chooser.addChoosableFileFilter( new SystemFileChooser.FileNameExtensionFilter(
|
||||||
|
"Text Files", "txt", "md" ) );
|
||||||
|
chooser.addChoosableFileFilter( new SystemFileChooser.FileNameExtensionFilter(
|
||||||
|
"Images", "png", "gif", "jpg" ) );
|
||||||
chooser.showSaveDialog( this );
|
chooser.showSaveDialog( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -611,11 +621,13 @@ class DemoFrame
|
|||||||
|
|
||||||
//---- openSystemMenuItem ----
|
//---- openSystemMenuItem ----
|
||||||
openSystemMenuItem.setText("Open (System)...");
|
openSystemMenuItem.setText("Open (System)...");
|
||||||
|
openSystemMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()|KeyEvent.SHIFT_DOWN_MASK));
|
||||||
openSystemMenuItem.addActionListener(e -> openSystemActionPerformed());
|
openSystemMenuItem.addActionListener(e -> openSystemActionPerformed());
|
||||||
fileMenu.add(openSystemMenuItem);
|
fileMenu.add(openSystemMenuItem);
|
||||||
|
|
||||||
//---- saveAsSystemMenuItem ----
|
//---- saveAsSystemMenuItem ----
|
||||||
saveAsSystemMenuItem.setText("Save As (System)...");
|
saveAsSystemMenuItem.setText("Save As (System)...");
|
||||||
|
saveAsSystemMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()|KeyEvent.SHIFT_DOWN_MASK));
|
||||||
saveAsSystemMenuItem.addActionListener(e -> saveAsSystemActionPerformed());
|
saveAsSystemMenuItem.addActionListener(e -> saveAsSystemActionPerformed());
|
||||||
fileMenu.add(saveAsSystemMenuItem);
|
fileMenu.add(saveAsSystemMenuItem);
|
||||||
fileMenu.addSeparator();
|
fileMenu.addSeparator();
|
||||||
|
|||||||
@@ -188,11 +188,13 @@ new FormModel {
|
|||||||
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||||
name: "openSystemMenuItem"
|
name: "openSystemMenuItem"
|
||||||
"text": "Open (System)..."
|
"text": "Open (System)..."
|
||||||
|
"accelerator": static javax.swing.KeyStroke getKeyStroke( 79, 4291, false )
|
||||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "openSystemActionPerformed", false ) )
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "openSystemActionPerformed", false ) )
|
||||||
} )
|
} )
|
||||||
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||||
name: "saveAsSystemMenuItem"
|
name: "saveAsSystemMenuItem"
|
||||||
"text": "Save As (System)..."
|
"text": "Save As (System)..."
|
||||||
|
"accelerator": static javax.swing.KeyStroke getKeyStroke( 83, 4291, false )
|
||||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "saveAsSystemActionPerformed", false ) )
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "saveAsSystemActionPerformed", false ) )
|
||||||
} )
|
} )
|
||||||
add( new FormComponent( "javax.swing.JPopupMenu$Separator" ) {
|
add( new FormComponent( "javax.swing.JPopupMenu$Separator" ) {
|
||||||
|
|||||||
@@ -186,7 +186,22 @@ public class FlatSystemFileChooserTest
|
|||||||
else
|
else
|
||||||
System.setProperty( FlatSystemProperties.USE_SYSTEM_FILE_CHOOSER, "false" );
|
System.setProperty( FlatSystemProperties.USE_SYSTEM_FILE_CHOOSER, "false" );
|
||||||
|
|
||||||
//TODO filter
|
// filter
|
||||||
|
String fileTypesStr = n( (String) fileTypesField.getSelectedItem() );
|
||||||
|
String[] fileTypes = {};
|
||||||
|
if( fileTypesStr != null )
|
||||||
|
fileTypes = fileTypesStr.trim().split( "[,]+" );
|
||||||
|
int fileTypeIndex = fileTypeIndexSlider.getValue();
|
||||||
|
if( !useAcceptAllFileFilterCheckBox.isSelected() )
|
||||||
|
fc.setAcceptAllFileFilterUsed( false );
|
||||||
|
for( int i = 0; i < fileTypes.length; i += 2 ) {
|
||||||
|
fc.addChoosableFileFilter( "*".equals( fileTypes[i+1] )
|
||||||
|
? fc.getAcceptAllFileFilter()
|
||||||
|
: new SystemFileChooser.FileNameExtensionFilter( fileTypes[i], fileTypes[i+1].split( ";" ) ) );
|
||||||
|
}
|
||||||
|
SystemFileChooser.FileFilter[] filters = fc.getChoosableFileFilters();
|
||||||
|
if( filters.length > 0 )
|
||||||
|
fc.setFileFilter( filters[Math.min( Math.max( fileTypeIndex, 0 ), filters.length - 1 )] );
|
||||||
}
|
}
|
||||||
|
|
||||||
private void configureSwingFileChooser( JFileChooser fc ) {
|
private void configureSwingFileChooser( JFileChooser fc ) {
|
||||||
|
|||||||
Reference in New Issue
Block a user