mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2025-12-06 22:10:54 +03:00
System File Chooser: introduced class SystemFileChooser as replacement for JFileChooser
This commit is contained in:
@@ -16,7 +16,9 @@
|
|||||||
|
|
||||||
package com.formdev.flatlaf;
|
package com.formdev.flatlaf;
|
||||||
|
|
||||||
|
import javax.swing.JFileChooser;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
|
import com.formdev.flatlaf.util.SystemFileChooser;
|
||||||
import com.formdev.flatlaf.util.UIScale;
|
import com.formdev.flatlaf.util.UIScale;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -226,6 +228,17 @@ public interface FlatSystemProperties
|
|||||||
*/
|
*/
|
||||||
String USE_SUB_MENU_SAFE_TRIANGLE = "flatlaf.useSubMenuSafeTriangle";
|
String USE_SUB_MENU_SAFE_TRIANGLE = "flatlaf.useSubMenuSafeTriangle";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies whether {@link SystemFileChooser} uses operating system file dialogs.
|
||||||
|
* If set to {@code false}, the {@link JFileChooser} is used instead.
|
||||||
|
* <p>
|
||||||
|
* <strong>Allowed Values</strong> {@code false} and {@code true}<br>
|
||||||
|
* <strong>Default</strong> {@code true}
|
||||||
|
*
|
||||||
|
* @since 3.6
|
||||||
|
*/
|
||||||
|
String USE_SYSTEM_FILE_CHOOSER = "flatlaf.useSystemFileChooser";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks whether a system property is set and returns {@code true} if its value
|
* Checks whether a system property is set and returns {@code true} if its value
|
||||||
* is {@code "true"} (case-insensitive), otherwise it returns {@code false}.
|
* is {@code "true"} (case-insensitive), otherwise it returns {@code false}.
|
||||||
|
|||||||
@@ -134,6 +134,10 @@ public class FlatNativeLinuxLibrary
|
|||||||
* Shows the Linux system file dialog
|
* Shows the Linux system file dialog
|
||||||
* <a href="https://docs.gtk.org/gtk3/class.FileChooserDialog.html">GtkFileChooserDialog</a>.
|
* <a href="https://docs.gtk.org/gtk3/class.FileChooserDialog.html">GtkFileChooserDialog</a>.
|
||||||
* <p>
|
* <p>
|
||||||
|
* Uses {@code GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER} if {@link #FC_select_folder} is set in parameter {@code optionsSet}.
|
||||||
|
* Otherwise uses {@code GTK_FILE_CHOOSER_ACTION_OPEN} if parameter {@code open} is {@code true},
|
||||||
|
* or {@code GTK_FILE_CHOOSER_ACTION_SAVE} if {@code false}.
|
||||||
|
* <p>
|
||||||
* <b>Note:</b> This method blocks the current thread until the user closes
|
* <b>Note:</b> This method blocks the current thread until the user closes
|
||||||
* the file dialog. It is highly recommended to invoke it from a new thread
|
* the file dialog. It is highly recommended to invoke it from a new thread
|
||||||
* to avoid blocking the AWT event dispatching thread.
|
* to avoid blocking the AWT event dispatching thread.
|
||||||
@@ -142,6 +146,7 @@ public class FlatNativeLinuxLibrary
|
|||||||
* @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__and__Quit").
|
||||||
* @param currentName user-editable filename currently shown in the filename field in save dialog; or {@code null}
|
* @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 currentFolder current directory shown in the dialog; or {@code null}
|
||||||
* @param optionsSet options to set; see {@code FOS_*} constants
|
* @param optionsSet options to set; see {@code FOS_*} constants
|
||||||
|
|||||||
@@ -204,7 +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").
|
||||||
* @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}
|
||||||
|
|||||||
@@ -0,0 +1,559 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2025 FormDev Software GmbH
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.formdev.flatlaf.util;
|
||||||
|
|
||||||
|
import java.awt.Component;
|
||||||
|
import java.awt.SecondaryLoop;
|
||||||
|
import java.awt.Toolkit;
|
||||||
|
import java.awt.Window;
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
import javax.swing.JFileChooser;
|
||||||
|
import javax.swing.JOptionPane;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
|
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.FlatNativeWindowsLibrary;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gives access to operating system file dialogs.
|
||||||
|
* <p>
|
||||||
|
* 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}.
|
||||||
|
* If there are no compile errors, then there is a good chance that it works without further changes.
|
||||||
|
* If there are compile errors, then you're using a feature that {@code SystemFileChooser} does not support.
|
||||||
|
* <p>
|
||||||
|
* Supported platforms are <b>Windows 10+</b>, <b>macOS 10.14+</b> and <b>Linux GTK 3</b>.
|
||||||
|
* {@code JFileChooser} is used on unsupported platforms.
|
||||||
|
* <p>
|
||||||
|
* {@code SystemFileChooser} requires FlatLaf native libraries (usually contained in flatlaf.jar).
|
||||||
|
* If not available or disabled (via {@link FlatSystemProperties#USE_NATIVE_LIBRARY}
|
||||||
|
* or {@link FlatSystemProperties#USE_SYSTEM_FILE_CHOOSER}), then {@code JFileChooser} is used.
|
||||||
|
* <p>
|
||||||
|
* <p>
|
||||||
|
* <h2>Limitations/incompatibilities compared to JFileChooser</h2>
|
||||||
|
*
|
||||||
|
* <ul>
|
||||||
|
* <li><b>Open File</b> and <b>Select Folder</b> dialogs always warn about not existing files/folders.
|
||||||
|
* The operating system shows a warning dialog to inform the user.
|
||||||
|
* It is not possible to customize that warning dialog.
|
||||||
|
* The file chooser stays open.
|
||||||
|
* <li><b>Save File</b> dialog always asks whether an existing file should be overwritten.
|
||||||
|
* The operating system shows a question dialog to ask the user whether he wants to overwrite the file or not.
|
||||||
|
* 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>{@link JFileChooser#FILES_AND_DIRECTORIES} is not supported.
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* @author Karl Tauber
|
||||||
|
* @since 3.6
|
||||||
|
*/
|
||||||
|
public class SystemFileChooser
|
||||||
|
{
|
||||||
|
/** @see JFileChooser#OPEN_DIALOG */
|
||||||
|
public static final int OPEN_DIALOG = JFileChooser.OPEN_DIALOG;
|
||||||
|
|
||||||
|
/** @see JFileChooser#SAVE_DIALOG */
|
||||||
|
public static final int SAVE_DIALOG = JFileChooser.SAVE_DIALOG;
|
||||||
|
|
||||||
|
/** @see JFileChooser#CANCEL_OPTION */
|
||||||
|
public static final int CANCEL_OPTION = JFileChooser.CANCEL_OPTION;
|
||||||
|
|
||||||
|
/** @see JFileChooser#APPROVE_OPTION */
|
||||||
|
public static final int APPROVE_OPTION = JFileChooser.APPROVE_OPTION;
|
||||||
|
|
||||||
|
/** @see JFileChooser#FILES_ONLY */
|
||||||
|
public static final int FILES_ONLY = JFileChooser.FILES_ONLY;
|
||||||
|
|
||||||
|
/** @see JFileChooser#DIRECTORIES_ONLY */
|
||||||
|
public static final int DIRECTORIES_ONLY = JFileChooser.DIRECTORIES_ONLY;
|
||||||
|
|
||||||
|
private int dialogType = OPEN_DIALOG;
|
||||||
|
private String dialogTitle;
|
||||||
|
private String approveButtonText;
|
||||||
|
private int approveButtonMnemonic = 0;
|
||||||
|
private int fileSelectionMode = FILES_ONLY;
|
||||||
|
private boolean multiSelection;
|
||||||
|
private boolean useFileHiding = true;
|
||||||
|
|
||||||
|
private File currentDirectory;
|
||||||
|
private File selectedFile;
|
||||||
|
private File[] selectedFiles;
|
||||||
|
|
||||||
|
/** @see JFileChooser#JFileChooser() */
|
||||||
|
public SystemFileChooser() {
|
||||||
|
this( (File) null );
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @see JFileChooser#JFileChooser(String) */
|
||||||
|
public SystemFileChooser( String currentDirectoryPath ) {
|
||||||
|
setCurrentDirectory( (currentDirectoryPath != null)
|
||||||
|
? FileSystemView.getFileSystemView().createFileObject( currentDirectoryPath )
|
||||||
|
: null );
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @see JFileChooser#JFileChooser(File) */
|
||||||
|
public SystemFileChooser( File currentDirectory ) {
|
||||||
|
setCurrentDirectory( currentDirectory );
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @see JFileChooser#showOpenDialog(Component) */
|
||||||
|
public int showOpenDialog( Component parent ) {
|
||||||
|
setDialogType( OPEN_DIALOG );
|
||||||
|
return showDialogImpl( parent );
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @see JFileChooser#showSaveDialog(Component) */
|
||||||
|
public int showSaveDialog( Component parent ) {
|
||||||
|
setDialogType( SAVE_DIALOG );
|
||||||
|
return showDialogImpl( parent );
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @see JFileChooser#showDialog(Component, String) */
|
||||||
|
public int showDialog( Component parent, String approveButtonText ) {
|
||||||
|
if( approveButtonText != null )
|
||||||
|
setApproveButtonText( approveButtonText );
|
||||||
|
return showDialogImpl( parent );
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @see JFileChooser#getDialogType() */
|
||||||
|
public int getDialogType() {
|
||||||
|
return dialogType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @see JFileChooser#setDialogType(int) */
|
||||||
|
public void setDialogType( int dialogType ) {
|
||||||
|
if( dialogType != OPEN_DIALOG && dialogType != SAVE_DIALOG )
|
||||||
|
throw new IllegalArgumentException( "Invalid dialog type " + dialogType );
|
||||||
|
|
||||||
|
this.dialogType = dialogType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @see JFileChooser#getDialogTitle() */
|
||||||
|
public String getDialogTitle() {
|
||||||
|
return dialogTitle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @see JFileChooser#setDialogTitle(String) */
|
||||||
|
public void setDialogTitle( String dialogTitle ) {
|
||||||
|
this.dialogTitle = dialogTitle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @see JFileChooser#getApproveButtonText() */
|
||||||
|
public String getApproveButtonText() {
|
||||||
|
return approveButtonText;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @see JFileChooser#setApproveButtonText(String) */
|
||||||
|
public void setApproveButtonText( String approveButtonText ) {
|
||||||
|
this.approveButtonText = approveButtonText;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @see JFileChooser#getApproveButtonMnemonic() */
|
||||||
|
public int getApproveButtonMnemonic() {
|
||||||
|
return approveButtonMnemonic;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @see JFileChooser#setApproveButtonMnemonic(int) */
|
||||||
|
public void setApproveButtonMnemonic( int mnemonic ) {
|
||||||
|
approveButtonMnemonic = mnemonic;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @see JFileChooser#setApproveButtonMnemonic(char) */
|
||||||
|
public void setApproveButtonMnemonic( char mnemonic ) {
|
||||||
|
int vk = mnemonic;
|
||||||
|
if( vk >= 'a' && vk <= 'z' )
|
||||||
|
vk -= 'a' - 'A';
|
||||||
|
setApproveButtonMnemonic( vk );
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @see JFileChooser#getFileSelectionMode() */
|
||||||
|
public int getFileSelectionMode() {
|
||||||
|
return fileSelectionMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @see JFileChooser#setFileSelectionMode(int) */
|
||||||
|
public void setFileSelectionMode( int fileSelectionMode ) {
|
||||||
|
if( fileSelectionMode != FILES_ONLY && fileSelectionMode != DIRECTORIES_ONLY )
|
||||||
|
throw new IllegalArgumentException( "Invalid file selection mode " + fileSelectionMode );
|
||||||
|
|
||||||
|
this.fileSelectionMode = fileSelectionMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @see JFileChooser#isFileSelectionEnabled() */
|
||||||
|
public boolean isFileSelectionEnabled() {
|
||||||
|
return fileSelectionMode == FILES_ONLY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @see JFileChooser#isDirectorySelectionEnabled() */
|
||||||
|
public boolean isDirectorySelectionEnabled() {
|
||||||
|
return fileSelectionMode == DIRECTORIES_ONLY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @see JFileChooser#isMultiSelectionEnabled() */
|
||||||
|
public boolean isMultiSelectionEnabled() {
|
||||||
|
return multiSelection;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @see JFileChooser#setMultiSelectionEnabled(boolean) */
|
||||||
|
public void setMultiSelectionEnabled( boolean multiSelection ) {
|
||||||
|
this.multiSelection = multiSelection;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @see JFileChooser#isFileHidingEnabled() */
|
||||||
|
public boolean isFileHidingEnabled() {
|
||||||
|
return useFileHiding;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @see JFileChooser#setFileHidingEnabled(boolean) */
|
||||||
|
public void setFileHidingEnabled( boolean useFileHiding ) {
|
||||||
|
this.useFileHiding = useFileHiding;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @see JFileChooser#getCurrentDirectory() */
|
||||||
|
public File getCurrentDirectory() {
|
||||||
|
return currentDirectory;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @see JFileChooser#setCurrentDirectory(File) */
|
||||||
|
public void setCurrentDirectory( File dir ) {
|
||||||
|
// for compatibility with JFileChooser
|
||||||
|
if( dir != null && !dir.exists() )
|
||||||
|
return;
|
||||||
|
if( dir == null )
|
||||||
|
dir = FileSystemView.getFileSystemView().getDefaultDirectory();
|
||||||
|
|
||||||
|
currentDirectory = dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @see JFileChooser#getSelectedFile() */
|
||||||
|
public File getSelectedFile() {
|
||||||
|
return selectedFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @see JFileChooser#setSelectedFile(File) */
|
||||||
|
public void setSelectedFile( File file ) {
|
||||||
|
selectedFile = file;
|
||||||
|
|
||||||
|
// for compatibility with JFileChooser
|
||||||
|
if( file != null &&
|
||||||
|
file.isAbsolute() &&
|
||||||
|
!FileSystemView.getFileSystemView().isParent( getCurrentDirectory(), file ) )
|
||||||
|
setCurrentDirectory( file.getParentFile() );
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @see JFileChooser#getSelectedFiles() */
|
||||||
|
public File[] getSelectedFiles() {
|
||||||
|
return (selectedFiles != null) ? selectedFiles.clone() : new File[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @see JFileChooser#setSelectedFiles(File[]) */
|
||||||
|
public void setSelectedFiles( File[] selectedFiles ) {
|
||||||
|
if( selectedFiles != null && selectedFiles.length > 0 ) {
|
||||||
|
this.selectedFiles = selectedFiles.clone();
|
||||||
|
setSelectedFile( selectedFiles[0] );
|
||||||
|
} else {
|
||||||
|
this.selectedFiles = null;
|
||||||
|
setSelectedFile( null );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int showDialogImpl( Component parent ) {
|
||||||
|
File[] files = getProvider().showDialog( parent, this );
|
||||||
|
setSelectedFiles( files );
|
||||||
|
return (files != null) ? APPROVE_OPTION : CANCEL_OPTION;
|
||||||
|
}
|
||||||
|
|
||||||
|
private FileChooserProvider getProvider() {
|
||||||
|
if( !FlatSystemProperties.getBoolean( FlatSystemProperties.USE_SYSTEM_FILE_CHOOSER, true ) )
|
||||||
|
return new SwingFileChooserProvider();
|
||||||
|
|
||||||
|
if( SystemInfo.isWindows_10_orLater && FlatNativeWindowsLibrary.isLoaded() )
|
||||||
|
return new WindowsFileChooserProvider();
|
||||||
|
else if( SystemInfo.isLinux && FlatNativeLinuxLibrary.isLoaded() )
|
||||||
|
return new LinuxFileChooserProvider();
|
||||||
|
else // unknown platform or FlatLaf native library not loaded
|
||||||
|
return new SwingFileChooserProvider();
|
||||||
|
}
|
||||||
|
|
||||||
|
//---- interface FileChooserProvider --------------------------------------
|
||||||
|
|
||||||
|
private interface FileChooserProvider {
|
||||||
|
File[] showDialog( Component parent, SystemFileChooser fc );
|
||||||
|
}
|
||||||
|
|
||||||
|
//---- class SystemFileChooserProvider ------------------------------------
|
||||||
|
|
||||||
|
private static abstract class SystemFileChooserProvider
|
||||||
|
implements FileChooserProvider
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public File[] showDialog( Component parent, SystemFileChooser fc ) {
|
||||||
|
Window owner = (parent instanceof Window)
|
||||||
|
? (Window) parent
|
||||||
|
: (parent != null) ? SwingUtilities.windowForComponent( parent ) : null;
|
||||||
|
AtomicReference<String[]> filenamesRef = new AtomicReference<>();
|
||||||
|
|
||||||
|
// create secondary event look and invoke system file dialog on a new thread
|
||||||
|
SecondaryLoop secondaryLoop = Toolkit.getDefaultToolkit().getSystemEventQueue().createSecondaryLoop();
|
||||||
|
new Thread( () -> {
|
||||||
|
filenamesRef.set( showSystemDialog( owner, fc ) );
|
||||||
|
secondaryLoop.exit();
|
||||||
|
} ).start();
|
||||||
|
secondaryLoop.enter();
|
||||||
|
|
||||||
|
String[] filenames = filenamesRef.get();
|
||||||
|
|
||||||
|
// fallback to Swing file chooser if system file dialog failed or is not available
|
||||||
|
if( filenames == null )
|
||||||
|
return new SwingFileChooserProvider().showDialog( parent, fc );
|
||||||
|
|
||||||
|
// canceled?
|
||||||
|
if( filenames.length == 0 )
|
||||||
|
return null;
|
||||||
|
|
||||||
|
// convert file names to file objects
|
||||||
|
FileSystemView fsv = FileSystemView.getFileSystemView();
|
||||||
|
File[] files = new File[filenames.length];
|
||||||
|
for( int i = 0; i < filenames.length; i++ )
|
||||||
|
files[i] = fsv.createFileObject( filenames[i] );
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract String[] showSystemDialog( Window owner, SystemFileChooser fc );
|
||||||
|
}
|
||||||
|
|
||||||
|
//---- class WindowsFileChooserProvider -----------------------------------
|
||||||
|
|
||||||
|
private static class WindowsFileChooserProvider
|
||||||
|
extends SystemFileChooserProvider
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
String[] showSystemDialog( Window owner, SystemFileChooser fc ) {
|
||||||
|
boolean open = (fc.getDialogType() == OPEN_DIALOG);
|
||||||
|
String approveButtonText = fc.getApproveButtonText();
|
||||||
|
int approveButtonMnemonic = fc.getApproveButtonMnemonic();
|
||||||
|
String fileName = null;
|
||||||
|
String folder = null;
|
||||||
|
String saveAsItem = null;
|
||||||
|
|
||||||
|
// approve button text and mnemonic
|
||||||
|
if( approveButtonText != null ) {
|
||||||
|
approveButtonText = approveButtonText.replace( "&", "&&" );
|
||||||
|
if( approveButtonMnemonic > 0 ) {
|
||||||
|
int mnemonicIndex = approveButtonText.toUpperCase( Locale.ENGLISH ).indexOf( approveButtonMnemonic );
|
||||||
|
if( mnemonicIndex >= 0 ) {
|
||||||
|
approveButtonText = approveButtonText.substring( 0, mnemonicIndex )
|
||||||
|
+ '&' + approveButtonText.substring( mnemonicIndex );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// paths
|
||||||
|
File currentDirectory = fc.getCurrentDirectory();
|
||||||
|
File selectedFile = fc.getSelectedFile();
|
||||||
|
if( selectedFile != null ) {
|
||||||
|
if( selectedFile.exists() && !open )
|
||||||
|
saveAsItem = selectedFile.getAbsolutePath();
|
||||||
|
else {
|
||||||
|
fileName = selectedFile.getName();
|
||||||
|
folder = selectedFile.getParent();
|
||||||
|
}
|
||||||
|
} else if( currentDirectory != null )
|
||||||
|
folder = currentDirectory.getAbsolutePath();
|
||||||
|
|
||||||
|
// options
|
||||||
|
int optionsSet = FlatNativeWindowsLibrary.FOS_OVERWRITEPROMPT;
|
||||||
|
int optionsClear = 0;
|
||||||
|
if( fc.isDirectorySelectionEnabled() )
|
||||||
|
optionsSet |= FlatNativeWindowsLibrary.FOS_PICKFOLDERS;
|
||||||
|
if( fc.isMultiSelectionEnabled() )
|
||||||
|
optionsSet |= FlatNativeWindowsLibrary.FOS_ALLOWMULTISELECT;
|
||||||
|
if( !fc.isFileHidingEnabled() )
|
||||||
|
optionsSet |= FlatNativeWindowsLibrary.FOS_FORCESHOWHIDDEN;
|
||||||
|
|
||||||
|
// filter
|
||||||
|
int fileTypeIndex = 0;
|
||||||
|
ArrayList<String> fileTypes = new ArrayList<>();
|
||||||
|
// FOS_PICKFOLDERS does not support file types
|
||||||
|
if( !fc.isDirectorySelectionEnabled() ) {
|
||||||
|
// if there are no file types
|
||||||
|
// - for Save dialog add "All Files", otherwise Windows would show an empty "Save as type" combobox
|
||||||
|
// - for Open dialog, Windows hides the combobox
|
||||||
|
if( !open && fileTypes.isEmpty() ) {
|
||||||
|
fileTypes.add( UIManager.getString( "FileChooser.acceptAllFileFilterText" ) );
|
||||||
|
fileTypes.add( "*.*" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// show system file dialog
|
||||||
|
return FlatNativeWindowsLibrary.showFileChooser( owner, open,
|
||||||
|
fc.getDialogTitle(), approveButtonText, null, fileName,
|
||||||
|
folder, saveAsItem, null, null, optionsSet, optionsClear,
|
||||||
|
fileTypeIndex, fileTypes.toArray( new String[fileTypes.size()] ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//---- class LinuxFileChooserProvider -----------------------------------..
|
||||||
|
|
||||||
|
private static class LinuxFileChooserProvider
|
||||||
|
extends SystemFileChooserProvider
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
String[] showSystemDialog( Window owner, SystemFileChooser fc ) {
|
||||||
|
boolean open = (fc.getDialogType() == OPEN_DIALOG);
|
||||||
|
String approveButtonText = fc.getApproveButtonText();
|
||||||
|
int approveButtonMnemonic = fc.getApproveButtonMnemonic();
|
||||||
|
String currentName = null;
|
||||||
|
String currentFolder = null;
|
||||||
|
|
||||||
|
// approve button text and mnemonic
|
||||||
|
if( approveButtonText != null ) {
|
||||||
|
approveButtonText = approveButtonText.replace( "_", "__" );
|
||||||
|
if( approveButtonMnemonic > 0 ) {
|
||||||
|
int mnemonicIndex = approveButtonText.toUpperCase( Locale.ENGLISH ).indexOf( approveButtonMnemonic );
|
||||||
|
if( mnemonicIndex >= 0 ) {
|
||||||
|
approveButtonText = approveButtonText.substring( 0, mnemonicIndex )
|
||||||
|
+ '_' + approveButtonText.substring( mnemonicIndex );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// paths
|
||||||
|
File currentDirectory = fc.getCurrentDirectory();
|
||||||
|
File selectedFile = fc.getSelectedFile();
|
||||||
|
if( selectedFile != null ) {
|
||||||
|
if( selectedFile.isDirectory() )
|
||||||
|
currentFolder = selectedFile.getAbsolutePath();
|
||||||
|
else {
|
||||||
|
currentName = selectedFile.getName();
|
||||||
|
currentFolder = selectedFile.getParent();
|
||||||
|
}
|
||||||
|
} else if( currentDirectory != null )
|
||||||
|
currentFolder = currentDirectory.getAbsolutePath();
|
||||||
|
|
||||||
|
// options
|
||||||
|
int optionsSet = FlatNativeLinuxLibrary.FC_do_overwrite_confirmation;
|
||||||
|
int optionsClear = 0;
|
||||||
|
if( fc.isDirectorySelectionEnabled() )
|
||||||
|
optionsSet |= FlatNativeLinuxLibrary.FC_select_folder;
|
||||||
|
if( fc.isMultiSelectionEnabled() )
|
||||||
|
optionsSet |= FlatNativeLinuxLibrary.FC_select_multiple;
|
||||||
|
if( !fc.isFileHidingEnabled() )
|
||||||
|
optionsSet |= FlatNativeLinuxLibrary.FC_show_hidden;
|
||||||
|
else // necessary because GTK seems to be remember last state and re-use it for new file dialogs
|
||||||
|
optionsClear |= FlatNativeLinuxLibrary.FC_show_hidden;
|
||||||
|
|
||||||
|
// show system file dialog
|
||||||
|
return FlatNativeLinuxLibrary.showFileChooser( owner, open,
|
||||||
|
fc.getDialogTitle(), approveButtonText, currentName, currentFolder,
|
||||||
|
optionsSet, optionsClear, 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//---- class SwingFileChooserProvider -------------------------------------
|
||||||
|
|
||||||
|
private static class SwingFileChooserProvider
|
||||||
|
implements FileChooserProvider
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public File[] showDialog( Component parent, SystemFileChooser fc ) {
|
||||||
|
JFileChooser chooser = new JFileChooser() {
|
||||||
|
@Override
|
||||||
|
public void approveSelection() {
|
||||||
|
File[] files = isMultiSelectionEnabled()
|
||||||
|
? getSelectedFiles()
|
||||||
|
: new File[] { getSelectedFile() };
|
||||||
|
|
||||||
|
if( getDialogType() == OPEN_DIALOG || isDirectorySelectionEnabled() ) {
|
||||||
|
if( !checkMustExist( this, files ) )
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
if( !checkOverwrite( this, files ) )
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
super.approveSelection();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
chooser.setDialogType( fc.getDialogType() );
|
||||||
|
chooser.setDialogTitle( fc.getDialogTitle() );
|
||||||
|
chooser.setApproveButtonText( fc.getApproveButtonText() );
|
||||||
|
chooser.setApproveButtonMnemonic( fc.getApproveButtonMnemonic() );
|
||||||
|
chooser.setFileSelectionMode( fc.getFileSelectionMode() );
|
||||||
|
chooser.setMultiSelectionEnabled( fc.isMultiSelectionEnabled() );
|
||||||
|
chooser.setFileHidingEnabled( fc.isFileHidingEnabled() );
|
||||||
|
|
||||||
|
// system file dialogs do not support multi-selection for Save File dialogs
|
||||||
|
if( chooser.isMultiSelectionEnabled() &&
|
||||||
|
chooser.getDialogType() == JFileChooser.SAVE_DIALOG &&
|
||||||
|
!chooser.isDirectorySelectionEnabled() )
|
||||||
|
chooser.setMultiSelectionEnabled( false );
|
||||||
|
|
||||||
|
// paths
|
||||||
|
chooser.setCurrentDirectory( fc.getCurrentDirectory() );
|
||||||
|
chooser.setSelectedFile( fc.getSelectedFile() );
|
||||||
|
|
||||||
|
if( chooser.showDialog( parent, null ) != JFileChooser.APPROVE_OPTION )
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return chooser.isMultiSelectionEnabled()
|
||||||
|
? chooser.getSelectedFiles()
|
||||||
|
: new File[] { chooser.getSelectedFile() };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -49,6 +49,7 @@ import com.formdev.flatlaf.extras.FlatSVGUtils;
|
|||||||
import com.formdev.flatlaf.util.ColorFunctions;
|
import com.formdev.flatlaf.util.ColorFunctions;
|
||||||
import com.formdev.flatlaf.util.FontUtils;
|
import com.formdev.flatlaf.util.FontUtils;
|
||||||
import com.formdev.flatlaf.util.LoggingFacade;
|
import com.formdev.flatlaf.util.LoggingFacade;
|
||||||
|
import com.formdev.flatlaf.util.SystemFileChooser;
|
||||||
import com.formdev.flatlaf.util.SystemInfo;
|
import com.formdev.flatlaf.util.SystemInfo;
|
||||||
import net.miginfocom.layout.ConstraintParser;
|
import net.miginfocom.layout.ConstraintParser;
|
||||||
import net.miginfocom.layout.LC;
|
import net.miginfocom.layout.LC;
|
||||||
@@ -172,6 +173,16 @@ class DemoFrame
|
|||||||
chooser.showSaveDialog( this );
|
chooser.showSaveDialog( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void openSystemActionPerformed() {
|
||||||
|
SystemFileChooser chooser = new SystemFileChooser();
|
||||||
|
chooser.showOpenDialog( this );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void saveAsSystemActionPerformed() {
|
||||||
|
SystemFileChooser chooser = new SystemFileChooser();
|
||||||
|
chooser.showSaveDialog( this );
|
||||||
|
}
|
||||||
|
|
||||||
private void exitActionPerformed() {
|
private void exitActionPerformed() {
|
||||||
dispose();
|
dispose();
|
||||||
}
|
}
|
||||||
@@ -496,6 +507,8 @@ class DemoFrame
|
|||||||
JMenuItem newMenuItem = new JMenuItem();
|
JMenuItem newMenuItem = new JMenuItem();
|
||||||
JMenuItem openMenuItem = new JMenuItem();
|
JMenuItem openMenuItem = new JMenuItem();
|
||||||
JMenuItem saveAsMenuItem = new JMenuItem();
|
JMenuItem saveAsMenuItem = new JMenuItem();
|
||||||
|
JMenuItem openSystemMenuItem = new JMenuItem();
|
||||||
|
JMenuItem saveAsSystemMenuItem = new JMenuItem();
|
||||||
JMenuItem closeMenuItem = new JMenuItem();
|
JMenuItem closeMenuItem = new JMenuItem();
|
||||||
exitMenuItem = new JMenuItem();
|
exitMenuItem = new JMenuItem();
|
||||||
JMenu editMenu = new JMenu();
|
JMenu editMenu = new JMenu();
|
||||||
@@ -596,6 +609,17 @@ class DemoFrame
|
|||||||
fileMenu.add(saveAsMenuItem);
|
fileMenu.add(saveAsMenuItem);
|
||||||
fileMenu.addSeparator();
|
fileMenu.addSeparator();
|
||||||
|
|
||||||
|
//---- openSystemMenuItem ----
|
||||||
|
openSystemMenuItem.setText("Open (System)...");
|
||||||
|
openSystemMenuItem.addActionListener(e -> openSystemActionPerformed());
|
||||||
|
fileMenu.add(openSystemMenuItem);
|
||||||
|
|
||||||
|
//---- saveAsSystemMenuItem ----
|
||||||
|
saveAsSystemMenuItem.setText("Save As (System)...");
|
||||||
|
saveAsSystemMenuItem.addActionListener(e -> saveAsSystemActionPerformed());
|
||||||
|
fileMenu.add(saveAsSystemMenuItem);
|
||||||
|
fileMenu.addSeparator();
|
||||||
|
|
||||||
//---- closeMenuItem ----
|
//---- closeMenuItem ----
|
||||||
closeMenuItem.setText("Close");
|
closeMenuItem.setText("Close");
|
||||||
closeMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_W, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
|
closeMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_W, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
JFDML JFormDesigner: "8.2.1.0.348" Java: "21.0.1" encoding: "UTF-8"
|
JFDML JFormDesigner: "8.3" encoding: "UTF-8"
|
||||||
|
|
||||||
new FormModel {
|
new FormModel {
|
||||||
contentType: "form/swing"
|
contentType: "form/swing"
|
||||||
@@ -182,6 +182,19 @@ new FormModel {
|
|||||||
"mnemonic": 83
|
"mnemonic": 83
|
||||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "saveAsActionPerformed", false ) )
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "saveAsActionPerformed", false ) )
|
||||||
} )
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JPopupMenu$Separator" ) {
|
||||||
|
name: "separator9"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||||
|
name: "openSystemMenuItem"
|
||||||
|
"text": "Open (System)..."
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "openSystemActionPerformed", false ) )
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||||
|
name: "saveAsSystemMenuItem"
|
||||||
|
"text": "Save As (System)..."
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "saveAsSystemActionPerformed", false ) )
|
||||||
|
} )
|
||||||
add( new FormComponent( "javax.swing.JPopupMenu$Separator" ) {
|
add( new FormComponent( "javax.swing.JPopupMenu$Separator" ) {
|
||||||
name: "separator2"
|
name: "separator2"
|
||||||
} )
|
} )
|
||||||
|
|||||||
@@ -71,6 +71,17 @@ tasks {
|
|||||||
else -> emptyList()
|
else -> emptyList()
|
||||||
}
|
}
|
||||||
} )
|
} )
|
||||||
|
|
||||||
|
doFirst {
|
||||||
|
// check required Java version
|
||||||
|
if( JavaVersion.current() < JavaVersion.VERSION_11 ) {
|
||||||
|
println()
|
||||||
|
println( "WARNING: Java 11 or later required to build Linux native library (running ${System.getProperty( "java.version" )})" )
|
||||||
|
println( " Native library built with older Java versions throw following exception when running in Java 17+:" )
|
||||||
|
println( " java.lang.UnsatisfiedLinkError: .../libjawt.so: version `SUNWprivate_1.1' not found" )
|
||||||
|
println()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
withType<LinkSharedLibrary>().configureEach {
|
withType<LinkSharedLibrary>().configureEach {
|
||||||
|
|||||||
@@ -177,11 +177,11 @@ JNIEXPORT jobjectArray JNICALL Java_com_formdev_flatlaf_ui_FlatNativeLinuxLibrar
|
|||||||
bool multiSelect = isOptionSet( FC_select_multiple );
|
bool multiSelect = isOptionSet( FC_select_multiple );
|
||||||
GtkWidget* dialog = gtk_file_chooser_dialog_new(
|
GtkWidget* dialog = gtk_file_chooser_dialog_new(
|
||||||
(ctitle != NULL) ? ctitle
|
(ctitle != NULL) ? ctitle
|
||||||
: (open ? (selectFolder ? (multiSelect ? _("Select Folders") : _("Select Folder"))
|
: (selectFolder ? (multiSelect ? _("Select Folders") : _("Select Folder"))
|
||||||
: (multiSelect ? _("Open Files") : _("Open File"))) : _("Save File")),
|
: (open ? ((multiSelect ? _("Open Files") : _("Open File"))) : _("Save File"))),
|
||||||
NULL, // can not use AWT X11 window as parent because GtkWindow is required
|
NULL, // can not use AWT X11 window as parent because GtkWindow is required
|
||||||
open ? (selectFolder ? GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER : GTK_FILE_CHOOSER_ACTION_OPEN)
|
selectFolder ? GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER
|
||||||
: GTK_FILE_CHOOSER_ACTION_SAVE,
|
: (open ? GTK_FILE_CHOOSER_ACTION_OPEN : GTK_FILE_CHOOSER_ACTION_SAVE),
|
||||||
_("_Cancel"), GTK_RESPONSE_CANCEL,
|
_("_Cancel"), GTK_RESPONSE_CANCEL,
|
||||||
(cokButtonLabel != NULL) ? cokButtonLabel : (open ? _("_Open") : _("_Save")), GTK_RESPONSE_ACCEPT,
|
(cokButtonLabel != NULL) ? cokButtonLabel : (open ? _("_Open") : _("_Save")), GTK_RESPONSE_ACCEPT,
|
||||||
NULL ); // marks end of buttons
|
NULL ); // marks end of buttons
|
||||||
|
|||||||
@@ -144,6 +144,7 @@ public:
|
|||||||
|
|
||||||
//---- helper -----------------------------------------------------------------
|
//---- helper -----------------------------------------------------------------
|
||||||
|
|
||||||
|
#define isOptionSet( option ) ((optionsSet & com_formdev_flatlaf_ui_FlatNativeWindowsLibrary_ ## option) != 0)
|
||||||
#define CHECK_HRESULT( code ) { if( (code) != S_OK ) return NULL; }
|
#define CHECK_HRESULT( code ) { if( (code) != S_OK ) return NULL; }
|
||||||
|
|
||||||
jobjectArray newJavaStringArray( JNIEnv* env, jsize count ) {
|
jobjectArray newJavaStringArray( JNIEnv* env, jsize count ) {
|
||||||
@@ -170,12 +171,12 @@ JNIEXPORT jobjectArray JNICALL Java_com_formdev_flatlaf_ui_FlatNativeWindowsLibr
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
// handle limitations (without this, some Win32 method fails and this method returns NULL)
|
// handle limitations (without this, some Win32 method fails and this method returns NULL)
|
||||||
if( (optionsSet & FOS_PICKFOLDERS) != 0 ) {
|
if( isOptionSet( FOS_PICKFOLDERS ) ) {
|
||||||
if( open )
|
open = true; // always use IFileOpenDialog for picking folders
|
||||||
fileTypes = NULL; // no filter allowed for picking folders
|
fileTypes = NULL; // no filter allowed for picking folders
|
||||||
else
|
|
||||||
optionsSet &= ~FOS_PICKFOLDERS; // not allowed for save dialog
|
|
||||||
}
|
}
|
||||||
|
if( !open && isOptionSet( FOS_ALLOWMULTISELECT ) )
|
||||||
|
optionsSet &= ~FOS_ALLOWMULTISELECT;
|
||||||
|
|
||||||
// convert Java strings to C strings
|
// convert Java strings to C strings
|
||||||
AutoReleaseString ctitle( env, title );
|
AutoReleaseString ctitle( env, title );
|
||||||
@@ -219,7 +220,7 @@ JNIEXPORT jobjectArray JNICALL Java_com_formdev_flatlaf_ui_FlatNativeWindowsLibr
|
|||||||
CHECK_HRESULT( dialog->SetOptions ( (existingOptions & ~optionsClear) | optionsSet ) );
|
CHECK_HRESULT( dialog->SetOptions ( (existingOptions & ~optionsClear) | optionsSet ) );
|
||||||
|
|
||||||
// initialize filter
|
// initialize filter
|
||||||
if( specs.count > 0 && (optionsSet & FOS_PICKFOLDERS) == 0 ) {
|
if( specs.count > 0 ) {
|
||||||
CHECK_HRESULT( dialog->SetFileTypes( specs.count, specs.specs ) );
|
CHECK_HRESULT( dialog->SetFileTypes( specs.count, specs.specs ) );
|
||||||
if( fileTypeIndex > 0 )
|
if( fileTypeIndex > 0 )
|
||||||
CHECK_HRESULT( dialog->SetFileTypeIndex( min( fileTypeIndex + 1, specs.count ) ) );
|
CHECK_HRESULT( dialog->SetFileTypeIndex( min( fileTypeIndex + 1, specs.count ) ) );
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ dependencies {
|
|||||||
implementation( libs.jide.oss )
|
implementation( libs.jide.oss )
|
||||||
implementation( libs.glazedlists )
|
implementation( libs.glazedlists )
|
||||||
implementation( libs.netbeans.api.awt )
|
implementation( libs.netbeans.api.awt )
|
||||||
|
implementation( libs.nativejfilechooser )
|
||||||
|
|
||||||
components.all<TargetJvmVersion8Rule>()
|
components.all<TargetJvmVersion8Rule>()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,749 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2025 FormDev Software GmbH
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.formdev.flatlaf.testing;
|
||||||
|
|
||||||
|
import java.awt.Dialog;
|
||||||
|
import java.awt.FileDialog;
|
||||||
|
import java.awt.Frame;
|
||||||
|
import java.awt.Window;
|
||||||
|
import java.awt.event.WindowAdapter;
|
||||||
|
import java.awt.event.WindowEvent;
|
||||||
|
import java.awt.event.WindowFocusListener;
|
||||||
|
import java.awt.event.WindowListener;
|
||||||
|
import java.awt.event.WindowStateListener;
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.prefs.Preferences;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
import javax.swing.*;
|
||||||
|
import javax.swing.filechooser.FileFilter;
|
||||||
|
import javax.swing.filechooser.FileNameExtensionFilter;
|
||||||
|
import com.formdev.flatlaf.FlatSystemProperties;
|
||||||
|
import com.formdev.flatlaf.demo.DemoPrefs;
|
||||||
|
import com.formdev.flatlaf.util.SystemFileChooser;
|
||||||
|
import com.formdev.flatlaf.util.SystemInfo;
|
||||||
|
import li.flor.nativejfilechooser.NativeJFileChooser;
|
||||||
|
import net.miginfocom.swing.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Karl Tauber
|
||||||
|
*/
|
||||||
|
public class FlatSystemFileChooserTest
|
||||||
|
extends FlatTestPanel
|
||||||
|
{
|
||||||
|
public static void main( String[] args ) {
|
||||||
|
// macOS (see https://www.formdev.com/flatlaf/macos/)
|
||||||
|
if( SystemInfo.isMacOS ) {
|
||||||
|
// appearance of window title bars
|
||||||
|
// possible values:
|
||||||
|
// - "system": use current macOS appearance (light or dark)
|
||||||
|
// - "NSAppearanceNameAqua": use light appearance
|
||||||
|
// - "NSAppearanceNameDarkAqua": use dark appearance
|
||||||
|
// (needs to be set on main thread; setting it on AWT thread does not work)
|
||||||
|
System.setProperty( "apple.awt.application.appearance", "system" );
|
||||||
|
}
|
||||||
|
|
||||||
|
SwingUtilities.invokeLater( () -> {
|
||||||
|
FlatTestFrame frame = FlatTestFrame.create( args, "FlatSystemFileChooserTest" );
|
||||||
|
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); // necessary because of JavaFX
|
||||||
|
addListeners( frame );
|
||||||
|
frame.showFrame( FlatSystemFileChooserTest::new );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
FlatSystemFileChooserTest() {
|
||||||
|
initComponents();
|
||||||
|
|
||||||
|
if( !NativeJFileChooser.FX_AVAILABLE ) {
|
||||||
|
javafxOpenButton.setEnabled( false );
|
||||||
|
javafxSaveButton.setEnabled( false );
|
||||||
|
}
|
||||||
|
|
||||||
|
Preferences state = DemoPrefs.getState();
|
||||||
|
currentDirField.setText( state.get( "systemfilechooser.currentdir", "" ) );
|
||||||
|
selectedFileField.setText( state.get( "systemfilechooser.selectedfile", "" ) );
|
||||||
|
selectedFilesField.setText( state.get( "systemfilechooser.selectedfiles", "" ) );
|
||||||
|
currentDirCheckBox.setSelected( state.getBoolean( "systemfilechooser.currentdir.enabled", false ) );
|
||||||
|
selectedFileCheckBox.setSelected( state.getBoolean( "systemfilechooser.selectedfile.enabled", false ) );
|
||||||
|
selectedFilesCheckBox.setSelected( state.getBoolean( "systemfilechooser.selectedfiles.enabled", false ) );
|
||||||
|
|
||||||
|
currentDirChanged();
|
||||||
|
selectedFileChanged();
|
||||||
|
selectedFilesChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void open() {
|
||||||
|
SystemFileChooser fc = new SystemFileChooser();
|
||||||
|
configureSystemFileChooser( fc );
|
||||||
|
showWithOwner( owner -> {
|
||||||
|
int result = fc.showOpenDialog( owner );
|
||||||
|
outputSystemFileChooser( fc, result );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void save() {
|
||||||
|
SystemFileChooser fc = new SystemFileChooser();
|
||||||
|
configureSystemFileChooser( fc );
|
||||||
|
showWithOwner( owner -> {
|
||||||
|
int result = fc.showSaveDialog( owner );
|
||||||
|
outputSystemFileChooser( fc, result );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void swingOpen() {
|
||||||
|
JFileChooser fc = new JFileChooser();
|
||||||
|
configureSwingFileChooser( fc );
|
||||||
|
showWithOwner( owner -> {
|
||||||
|
int result = fc.showOpenDialog( owner );
|
||||||
|
outputSwingFileChooser( "Swing", fc, result );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void swingSave() {
|
||||||
|
JFileChooser fc = new JFileChooser();
|
||||||
|
configureSwingFileChooser( fc );
|
||||||
|
showWithOwner( owner -> {
|
||||||
|
int result = fc.showSaveDialog( owner );
|
||||||
|
outputSwingFileChooser( "Swing", fc, result );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void awtOpen() {
|
||||||
|
showWithOwner( owner -> {
|
||||||
|
FileDialog fc = (owner instanceof Frame)
|
||||||
|
? new FileDialog( (Frame) owner )
|
||||||
|
: new FileDialog( (Dialog) owner );
|
||||||
|
configureAWTFileChooser( fc, true );
|
||||||
|
fc.setVisible( true );
|
||||||
|
outputAWTFileChooser( fc );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void awtSave() {
|
||||||
|
showWithOwner( owner -> {
|
||||||
|
FileDialog fc = (owner instanceof Frame)
|
||||||
|
? new FileDialog( (Frame) owner )
|
||||||
|
: new FileDialog( (Dialog) owner );
|
||||||
|
configureAWTFileChooser( fc, false );
|
||||||
|
fc.setVisible( true );
|
||||||
|
outputAWTFileChooser( fc );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void javafxOpen() {
|
||||||
|
JFileChooser fc = new NativeJFileChooser();
|
||||||
|
configureSwingFileChooser( fc );
|
||||||
|
showWithOwner( owner -> {
|
||||||
|
int result = fc.showOpenDialog( owner );
|
||||||
|
outputSwingFileChooser( "JavaFX", fc, result );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void javafxSave() {
|
||||||
|
JFileChooser fc = new NativeJFileChooser();
|
||||||
|
configureSwingFileChooser( fc );
|
||||||
|
showWithOwner( owner -> {
|
||||||
|
int result = fc.showSaveDialog( owner );
|
||||||
|
outputSwingFileChooser( "JavaFX", fc, result );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void configureSystemFileChooser( SystemFileChooser fc ) {
|
||||||
|
fc.setDialogTitle( n( dialogTitleField.getText() ) );
|
||||||
|
fc.setApproveButtonText( n( approveButtonTextField.getText() ) );
|
||||||
|
fc.setApproveButtonMnemonic( mnemonic( approveButtonMnemonicField.getText() ) );
|
||||||
|
|
||||||
|
// paths
|
||||||
|
if( currentDirCheckBox.isSelected() )
|
||||||
|
fc.setCurrentDirectory( toFile( currentDirField.getText() ) );
|
||||||
|
if( selectedFileCheckBox.isSelected() )
|
||||||
|
fc.setSelectedFile( toFile( selectedFileField.getText() ) );
|
||||||
|
if( selectedFilesCheckBox.isSelected() )
|
||||||
|
fc.setSelectedFiles( toFiles( selectedFilesField.getText() ) );
|
||||||
|
|
||||||
|
// options
|
||||||
|
if( directorySelectionCheckBox.isSelected() )
|
||||||
|
fc.setFileSelectionMode( SystemFileChooser.DIRECTORIES_ONLY );
|
||||||
|
fc.setMultiSelectionEnabled( multiSelectionEnabledCheckBox.isSelected() );
|
||||||
|
fc.setFileHidingEnabled( useFileHidingCheckBox.isSelected() );
|
||||||
|
if( useSystemFileChooserCheckBox.isSelected() )
|
||||||
|
System.clearProperty( FlatSystemProperties.USE_SYSTEM_FILE_CHOOSER );
|
||||||
|
else
|
||||||
|
System.setProperty( FlatSystemProperties.USE_SYSTEM_FILE_CHOOSER, "false" );
|
||||||
|
|
||||||
|
//TODO filter
|
||||||
|
}
|
||||||
|
|
||||||
|
private void configureSwingFileChooser( JFileChooser fc ) {
|
||||||
|
fc.setDialogTitle( n( dialogTitleField.getText() ) );
|
||||||
|
fc.setApproveButtonText( n( approveButtonTextField.getText() ) );
|
||||||
|
fc.setApproveButtonMnemonic( mnemonic( approveButtonMnemonicField.getText() ) );
|
||||||
|
|
||||||
|
// paths
|
||||||
|
if( currentDirCheckBox.isSelected() )
|
||||||
|
fc.setCurrentDirectory( toFile( currentDirField.getText() ) );
|
||||||
|
if( selectedFileCheckBox.isSelected() )
|
||||||
|
fc.setSelectedFile( toFile( selectedFileField.getText() ) );
|
||||||
|
if( selectedFilesCheckBox.isSelected() )
|
||||||
|
fc.setSelectedFiles( toFiles( selectedFilesField.getText() ) );
|
||||||
|
|
||||||
|
// options
|
||||||
|
if( directorySelectionCheckBox.isSelected() )
|
||||||
|
fc.setFileSelectionMode( JFileChooser.DIRECTORIES_ONLY );
|
||||||
|
fc.setMultiSelectionEnabled( multiSelectionEnabledCheckBox.isSelected() );
|
||||||
|
fc.setFileHidingEnabled( useFileHidingCheckBox.isSelected() );
|
||||||
|
|
||||||
|
// 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 FileNameExtensionFilter( fileTypes[i], fileTypes[i+1].split( ";" ) ) );
|
||||||
|
}
|
||||||
|
FileFilter[] filters = fc.getChoosableFileFilters();
|
||||||
|
if( filters.length > 0 )
|
||||||
|
fc.setFileFilter( filters[Math.min( Math.max( fileTypeIndex, 0 ), filters.length - 1 )] );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void configureAWTFileChooser( FileDialog fc, boolean open ) {
|
||||||
|
fc.setMode( open ? FileDialog.LOAD : FileDialog.SAVE );
|
||||||
|
fc.setTitle( n( dialogTitleField.getText() ) );
|
||||||
|
|
||||||
|
// paths
|
||||||
|
if( currentDirCheckBox.isSelected() )
|
||||||
|
fc.setDirectory( n( currentDirField.getText() ) );
|
||||||
|
|
||||||
|
// options
|
||||||
|
fc.setMultipleMode( multiSelectionEnabledCheckBox.isSelected() );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void outputSystemFileChooser( SystemFileChooser fc, int result ) {
|
||||||
|
output( "System", fc.getDialogType() == SystemFileChooser.OPEN_DIALOG,
|
||||||
|
fc.isDirectorySelectionEnabled(), fc.isMultiSelectionEnabled(),
|
||||||
|
"result", result,
|
||||||
|
"currentDirectory", fc.getCurrentDirectory(),
|
||||||
|
"selectedFile", fc.getSelectedFile(),
|
||||||
|
"selectedFiles", fc.getSelectedFiles() );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void outputSwingFileChooser( String type, JFileChooser fc, int result ) {
|
||||||
|
output( type, fc.getDialogType() == JFileChooser.OPEN_DIALOG,
|
||||||
|
fc.isDirectorySelectionEnabled(), fc.isMultiSelectionEnabled(),
|
||||||
|
"result", result,
|
||||||
|
"currentDirectory", fc.getCurrentDirectory(),
|
||||||
|
"selectedFile", fc.getSelectedFile(),
|
||||||
|
"selectedFiles", fc.getSelectedFiles() );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void outputAWTFileChooser( FileDialog fc ) {
|
||||||
|
output( "AWT", fc.getMode() == FileDialog.LOAD, false, fc.isMultipleMode(),
|
||||||
|
"files", fc.getFiles(),
|
||||||
|
"directory", fc.getDirectory(),
|
||||||
|
"file", fc.getFile() );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void output( String type, boolean open, boolean directorySelection,
|
||||||
|
boolean multiSelection, Object... values )
|
||||||
|
{
|
||||||
|
outputField.append( "---- " + type + " " + (open ? "Open " : "Save ")
|
||||||
|
+ (directorySelection ? " directory-sel " : "")
|
||||||
|
+ (multiSelection ? " multi-sel " : "")
|
||||||
|
+ "----\n" );
|
||||||
|
|
||||||
|
for( int i = 0; i < values.length; i += 2 ) {
|
||||||
|
outputField.append( values[i] + " = " );
|
||||||
|
Object value = values[i+1];
|
||||||
|
if( value instanceof File[] )
|
||||||
|
outputField.append( Arrays.toString( (File[]) value ).replace( ",", "\n " ) );
|
||||||
|
else
|
||||||
|
outputField.append( String.valueOf( value ) );
|
||||||
|
outputField.append( "\n" );
|
||||||
|
}
|
||||||
|
outputField.append( "\n" );
|
||||||
|
outputField.setCaretPosition( outputField.getDocument().getLength() );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String n( String s ) {
|
||||||
|
return !s.isEmpty() ? s : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static char mnemonic( String s ) {
|
||||||
|
return !s.isEmpty() ? s.charAt( 0 ) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showWithOwner( Consumer<Window> showConsumer ) {
|
||||||
|
Window frame = SwingUtilities.windowForComponent( this );
|
||||||
|
if( ownerFrameRadioButton.isSelected() )
|
||||||
|
showConsumer.accept( frame );
|
||||||
|
else if( ownerDialogRadioButton.isSelected() ) {
|
||||||
|
JDialog dialog = new JDialog( frame, "Dummy Modal Dialog", Dialog.DEFAULT_MODALITY_TYPE );
|
||||||
|
dialog.setDefaultCloseOperation( JDialog.DISPOSE_ON_CLOSE );
|
||||||
|
dialog.addWindowListener( new WindowAdapter() {
|
||||||
|
@Override
|
||||||
|
public void windowOpened( WindowEvent e ) {
|
||||||
|
showConsumer.accept( dialog );
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
dialog.setSize( 1200, 1000 );
|
||||||
|
dialog.setLocationRelativeTo( this );
|
||||||
|
dialog.setVisible( true );
|
||||||
|
} else
|
||||||
|
showConsumer.accept( null );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void currentDirChanged() {
|
||||||
|
boolean b = currentDirCheckBox.isSelected();
|
||||||
|
currentDirField.setEditable( b );
|
||||||
|
currentDirChooseButton.setEnabled( b );
|
||||||
|
|
||||||
|
DemoPrefs.getState().putBoolean( "systemfilechooser.currentdir.enabled", b );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void selectedFileChanged() {
|
||||||
|
boolean b = selectedFileCheckBox.isSelected();
|
||||||
|
selectedFileField.setEditable( b );
|
||||||
|
selectedFileChooseButton.setEnabled( b );
|
||||||
|
|
||||||
|
DemoPrefs.getState().putBoolean( "systemfilechooser.selectedfile.enabled", b );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void selectedFilesChanged() {
|
||||||
|
boolean b = selectedFilesCheckBox.isSelected();
|
||||||
|
selectedFilesField.setEditable( b );
|
||||||
|
selectedFilesChooseButton.setEnabled( b );
|
||||||
|
|
||||||
|
DemoPrefs.getState().putBoolean( "systemfilechooser.selectedfiles.enabled", b );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void chooseCurrentDir() {
|
||||||
|
JFileChooser chooser = new JFileChooser();
|
||||||
|
chooser.setDialogTitle( "Current Directory" );
|
||||||
|
chooser.setSelectedFile( toFile( currentDirField.getText() ) );
|
||||||
|
chooser.setFileSelectionMode( JFileChooser.DIRECTORIES_ONLY );
|
||||||
|
if( chooser.showOpenDialog( this ) == JFileChooser.APPROVE_OPTION ) {
|
||||||
|
currentDirField.setText( toString( chooser.getSelectedFile() ) );
|
||||||
|
putState( "systemfilechooser.currentdir", currentDirField.getText() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void chooseSelectedFile() {
|
||||||
|
JFileChooser chooser = new JFileChooser();
|
||||||
|
chooser.setDialogTitle( "Selected File" );
|
||||||
|
chooser.setSelectedFile( toFile( selectedFileField.getText() ) );
|
||||||
|
chooser.setFileSelectionMode( JFileChooser.FILES_ONLY );
|
||||||
|
if( chooser.showOpenDialog( this ) == JFileChooser.APPROVE_OPTION ) {
|
||||||
|
selectedFileField.setText( toString( chooser.getSelectedFile() ) );
|
||||||
|
putState( "systemfilechooser.selectedfile", selectedFileField.getText() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void chooseSelectedFiles() {
|
||||||
|
JFileChooser chooser = new JFileChooser();
|
||||||
|
chooser.setDialogTitle( "Selected Files" );
|
||||||
|
chooser.setSelectedFiles( toFiles( selectedFilesField.getText() ) );
|
||||||
|
chooser.setFileSelectionMode( JFileChooser.FILES_ONLY );
|
||||||
|
chooser.setMultiSelectionEnabled( true );
|
||||||
|
if( chooser.showOpenDialog( this ) == JFileChooser.APPROVE_OPTION ) {
|
||||||
|
selectedFilesField.setText( toString( chooser.getSelectedFiles() ) );
|
||||||
|
putState( "systemfilechooser.selectedfiles", selectedFilesField.getText() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static File toFile( String s ) {
|
||||||
|
return !s.isEmpty() ? new File( s ) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String toString( File file ) {
|
||||||
|
return (file != null) ? file.getAbsolutePath() : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static File[] toFiles( String s ) {
|
||||||
|
return !s.isEmpty()
|
||||||
|
? Stream.of( s.split( "," ) ).map( name -> new File( name ) ).toArray( File[]::new )
|
||||||
|
: new File[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String toString( File[] files ) {
|
||||||
|
return (files != null && files.length > 0)
|
||||||
|
? String.join( ",", Stream.of( files ).map( file -> file.getAbsolutePath() ).toArray( String[]::new ) )
|
||||||
|
: "";
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void putState( String key, String value ) {
|
||||||
|
if( value.isEmpty() )
|
||||||
|
DemoPrefs.getState().remove( key );
|
||||||
|
else
|
||||||
|
DemoPrefs.getState().put( key, value );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void addListeners( Window w ) {
|
||||||
|
w.addWindowListener( new WindowListener() {
|
||||||
|
@Override
|
||||||
|
public void windowOpened( WindowEvent e ) {
|
||||||
|
System.out.println( e );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void windowIconified( WindowEvent e ) {
|
||||||
|
System.out.println( e );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void windowDeiconified( WindowEvent e ) {
|
||||||
|
System.out.println( e );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void windowDeactivated( WindowEvent e ) {
|
||||||
|
System.out.println( e );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void windowClosing( WindowEvent e ) {
|
||||||
|
System.out.println( e );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void windowClosed( WindowEvent e ) {
|
||||||
|
System.out.println( e );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void windowActivated( WindowEvent e ) {
|
||||||
|
System.out.println( e );
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
w.addWindowStateListener( new WindowStateListener() {
|
||||||
|
@Override
|
||||||
|
public void windowStateChanged( WindowEvent e ) {
|
||||||
|
System.out.println( e );
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
w.addWindowFocusListener( new WindowFocusListener() {
|
||||||
|
@Override
|
||||||
|
public void windowLostFocus( WindowEvent e ) {
|
||||||
|
System.out.println( e );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void windowGainedFocus( WindowEvent e ) {
|
||||||
|
System.out.println( e );
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initComponents() {
|
||||||
|
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
|
||||||
|
ownerLabel = new JLabel();
|
||||||
|
ownerFrameRadioButton = new JRadioButton();
|
||||||
|
ownerDialogRadioButton = new JRadioButton();
|
||||||
|
ownerNullRadioButton = new JRadioButton();
|
||||||
|
ownerSpacer = new JPanel(null);
|
||||||
|
dialogTitleLabel = new JLabel();
|
||||||
|
dialogTitleField = new JTextField();
|
||||||
|
panel1 = new JPanel();
|
||||||
|
directorySelectionCheckBox = new JCheckBox();
|
||||||
|
multiSelectionEnabledCheckBox = new JCheckBox();
|
||||||
|
useFileHidingCheckBox = new JCheckBox();
|
||||||
|
useSystemFileChooserCheckBox = new JCheckBox();
|
||||||
|
approveButtonTextLabel = new JLabel();
|
||||||
|
approveButtonTextField = new JTextField();
|
||||||
|
approveButtonMnemonicLabel = new JLabel();
|
||||||
|
approveButtonMnemonicField = new JTextField();
|
||||||
|
currentDirCheckBox = new JCheckBox();
|
||||||
|
currentDirField = new JTextField();
|
||||||
|
currentDirChooseButton = new JButton();
|
||||||
|
selectedFileCheckBox = new JCheckBox();
|
||||||
|
selectedFileField = new JTextField();
|
||||||
|
selectedFileChooseButton = new JButton();
|
||||||
|
selectedFilesCheckBox = new JCheckBox();
|
||||||
|
selectedFilesField = new JTextField();
|
||||||
|
selectedFilesChooseButton = new JButton();
|
||||||
|
fileTypesLabel = new JLabel();
|
||||||
|
fileTypesField = new JComboBox<>();
|
||||||
|
fileTypeIndexLabel = new JLabel();
|
||||||
|
fileTypeIndexSlider = new JSlider();
|
||||||
|
useAcceptAllFileFilterCheckBox = new JCheckBox();
|
||||||
|
openButton = new JButton();
|
||||||
|
saveButton = new JButton();
|
||||||
|
swingOpenButton = new JButton();
|
||||||
|
swingSaveButton = new JButton();
|
||||||
|
awtOpenButton = new JButton();
|
||||||
|
awtSaveButton = new JButton();
|
||||||
|
javafxOpenButton = new JButton();
|
||||||
|
javafxSaveButton = new JButton();
|
||||||
|
outputScrollPane = new JScrollPane();
|
||||||
|
outputField = new JTextArea();
|
||||||
|
|
||||||
|
//======== this ========
|
||||||
|
setLayout(new MigLayout(
|
||||||
|
"ltr,insets dialog,hidemode 3",
|
||||||
|
// columns
|
||||||
|
"[left]" +
|
||||||
|
"[grow,fill]" +
|
||||||
|
"[fill]",
|
||||||
|
// rows
|
||||||
|
"[]" +
|
||||||
|
"[]" +
|
||||||
|
"[]" +
|
||||||
|
"[]" +
|
||||||
|
"[]" +
|
||||||
|
"[]" +
|
||||||
|
"[]" +
|
||||||
|
"[]" +
|
||||||
|
"[]" +
|
||||||
|
"[grow,fill]"));
|
||||||
|
|
||||||
|
//---- ownerLabel ----
|
||||||
|
ownerLabel.setText("owner");
|
||||||
|
add(ownerLabel, "cell 0 0");
|
||||||
|
|
||||||
|
//---- ownerFrameRadioButton ----
|
||||||
|
ownerFrameRadioButton.setText("JFrame");
|
||||||
|
ownerFrameRadioButton.setSelected(true);
|
||||||
|
add(ownerFrameRadioButton, "cell 1 0");
|
||||||
|
|
||||||
|
//---- ownerDialogRadioButton ----
|
||||||
|
ownerDialogRadioButton.setText("JDialog");
|
||||||
|
add(ownerDialogRadioButton, "cell 1 0");
|
||||||
|
|
||||||
|
//---- ownerNullRadioButton ----
|
||||||
|
ownerNullRadioButton.setText("null");
|
||||||
|
add(ownerNullRadioButton, "cell 1 0");
|
||||||
|
add(ownerSpacer, "cell 1 0,growx");
|
||||||
|
|
||||||
|
//---- dialogTitleLabel ----
|
||||||
|
dialogTitleLabel.setText("dialogTitle");
|
||||||
|
add(dialogTitleLabel, "cell 0 1");
|
||||||
|
add(dialogTitleField, "cell 1 1");
|
||||||
|
|
||||||
|
//======== panel1 ========
|
||||||
|
{
|
||||||
|
panel1.setLayout(new MigLayout(
|
||||||
|
"insets 2,hidemode 3",
|
||||||
|
// columns
|
||||||
|
"[left]",
|
||||||
|
// rows
|
||||||
|
"[]0" +
|
||||||
|
"[]0" +
|
||||||
|
"[]" +
|
||||||
|
"[]"));
|
||||||
|
|
||||||
|
//---- directorySelectionCheckBox ----
|
||||||
|
directorySelectionCheckBox.setText("directorySelection");
|
||||||
|
panel1.add(directorySelectionCheckBox, "cell 0 0");
|
||||||
|
|
||||||
|
//---- multiSelectionEnabledCheckBox ----
|
||||||
|
multiSelectionEnabledCheckBox.setText("multiSelectionEnabled");
|
||||||
|
panel1.add(multiSelectionEnabledCheckBox, "cell 0 1");
|
||||||
|
|
||||||
|
//---- useFileHidingCheckBox ----
|
||||||
|
useFileHidingCheckBox.setText("useFileHiding");
|
||||||
|
useFileHidingCheckBox.setSelected(true);
|
||||||
|
panel1.add(useFileHidingCheckBox, "cell 0 2");
|
||||||
|
|
||||||
|
//---- useSystemFileChooserCheckBox ----
|
||||||
|
useSystemFileChooserCheckBox.setText("use SystemFileChooser");
|
||||||
|
useSystemFileChooserCheckBox.setSelected(true);
|
||||||
|
panel1.add(useSystemFileChooserCheckBox, "cell 0 3");
|
||||||
|
}
|
||||||
|
add(panel1, "cell 2 1 1 7,aligny top,growy 0");
|
||||||
|
|
||||||
|
//---- approveButtonTextLabel ----
|
||||||
|
approveButtonTextLabel.setText("approveButtonText");
|
||||||
|
add(approveButtonTextLabel, "cell 0 2");
|
||||||
|
add(approveButtonTextField, "cell 1 2,growx");
|
||||||
|
|
||||||
|
//---- approveButtonMnemonicLabel ----
|
||||||
|
approveButtonMnemonicLabel.setText("approveButtonMnemonic");
|
||||||
|
add(approveButtonMnemonicLabel, "cell 1 2");
|
||||||
|
|
||||||
|
//---- approveButtonMnemonicField ----
|
||||||
|
approveButtonMnemonicField.setColumns(3);
|
||||||
|
add(approveButtonMnemonicField, "cell 1 2");
|
||||||
|
|
||||||
|
//---- currentDirCheckBox ----
|
||||||
|
currentDirCheckBox.setText("current directory");
|
||||||
|
currentDirCheckBox.addActionListener(e -> currentDirChanged());
|
||||||
|
add(currentDirCheckBox, "cell 0 3");
|
||||||
|
add(currentDirField, "cell 1 3,growx");
|
||||||
|
|
||||||
|
//---- currentDirChooseButton ----
|
||||||
|
currentDirChooseButton.setText("...");
|
||||||
|
currentDirChooseButton.addActionListener(e -> chooseCurrentDir());
|
||||||
|
add(currentDirChooseButton, "cell 1 3");
|
||||||
|
|
||||||
|
//---- selectedFileCheckBox ----
|
||||||
|
selectedFileCheckBox.setText("selected file");
|
||||||
|
selectedFileCheckBox.addActionListener(e -> selectedFileChanged());
|
||||||
|
add(selectedFileCheckBox, "cell 0 4");
|
||||||
|
add(selectedFileField, "cell 1 4,growx");
|
||||||
|
|
||||||
|
//---- selectedFileChooseButton ----
|
||||||
|
selectedFileChooseButton.setText("...");
|
||||||
|
selectedFileChooseButton.addActionListener(e -> chooseSelectedFile());
|
||||||
|
add(selectedFileChooseButton, "cell 1 4");
|
||||||
|
|
||||||
|
//---- selectedFilesCheckBox ----
|
||||||
|
selectedFilesCheckBox.setText("selected files");
|
||||||
|
selectedFilesCheckBox.addActionListener(e -> selectedFilesChanged());
|
||||||
|
add(selectedFilesCheckBox, "cell 0 5");
|
||||||
|
add(selectedFilesField, "cell 1 5,growx");
|
||||||
|
|
||||||
|
//---- selectedFilesChooseButton ----
|
||||||
|
selectedFilesChooseButton.setText("...");
|
||||||
|
selectedFilesChooseButton.addActionListener(e -> chooseSelectedFiles());
|
||||||
|
add(selectedFilesChooseButton, "cell 1 5");
|
||||||
|
|
||||||
|
//---- fileTypesLabel ----
|
||||||
|
fileTypesLabel.setText("fileTypes");
|
||||||
|
add(fileTypesLabel, "cell 0 6");
|
||||||
|
|
||||||
|
//---- fileTypesField ----
|
||||||
|
fileTypesField.setEditable(true);
|
||||||
|
fileTypesField.setModel(new DefaultComboBoxModel<>(new String[] {
|
||||||
|
"Text Files,txt",
|
||||||
|
"All Files,*",
|
||||||
|
"Text Files,txt,PDF Files,pdf,All Files,*",
|
||||||
|
"Text and PDF Files,txt;pdf"
|
||||||
|
}));
|
||||||
|
add(fileTypesField, "cell 1 6");
|
||||||
|
|
||||||
|
//---- fileTypeIndexLabel ----
|
||||||
|
fileTypeIndexLabel.setText("fileTypeIndex");
|
||||||
|
add(fileTypeIndexLabel, "cell 0 7");
|
||||||
|
|
||||||
|
//---- fileTypeIndexSlider ----
|
||||||
|
fileTypeIndexSlider.setMaximum(10);
|
||||||
|
fileTypeIndexSlider.setMajorTickSpacing(1);
|
||||||
|
fileTypeIndexSlider.setValue(0);
|
||||||
|
fileTypeIndexSlider.setPaintLabels(true);
|
||||||
|
fileTypeIndexSlider.setSnapToTicks(true);
|
||||||
|
add(fileTypeIndexSlider, "cell 1 7,growx");
|
||||||
|
|
||||||
|
//---- useAcceptAllFileFilterCheckBox ----
|
||||||
|
useAcceptAllFileFilterCheckBox.setText("useAcceptAllFileFilter");
|
||||||
|
useAcceptAllFileFilterCheckBox.setSelected(true);
|
||||||
|
add(useAcceptAllFileFilterCheckBox, "cell 1 7");
|
||||||
|
|
||||||
|
//---- openButton ----
|
||||||
|
openButton.setText("Open...");
|
||||||
|
openButton.addActionListener(e -> open());
|
||||||
|
add(openButton, "cell 0 8 3 1");
|
||||||
|
|
||||||
|
//---- saveButton ----
|
||||||
|
saveButton.setText("Save...");
|
||||||
|
saveButton.addActionListener(e -> save());
|
||||||
|
add(saveButton, "cell 0 8 3 1");
|
||||||
|
|
||||||
|
//---- swingOpenButton ----
|
||||||
|
swingOpenButton.setText("Swing Open...");
|
||||||
|
swingOpenButton.addActionListener(e -> swingOpen());
|
||||||
|
add(swingOpenButton, "cell 0 8 3 1");
|
||||||
|
|
||||||
|
//---- swingSaveButton ----
|
||||||
|
swingSaveButton.setText("Swing Save...");
|
||||||
|
swingSaveButton.addActionListener(e -> swingSave());
|
||||||
|
add(swingSaveButton, "cell 0 8 3 1");
|
||||||
|
|
||||||
|
//---- awtOpenButton ----
|
||||||
|
awtOpenButton.setText("AWT Open...");
|
||||||
|
awtOpenButton.addActionListener(e -> awtOpen());
|
||||||
|
add(awtOpenButton, "cell 0 8 3 1");
|
||||||
|
|
||||||
|
//---- awtSaveButton ----
|
||||||
|
awtSaveButton.setText("AWT Save...");
|
||||||
|
awtSaveButton.addActionListener(e -> awtSave());
|
||||||
|
add(awtSaveButton, "cell 0 8 3 1");
|
||||||
|
|
||||||
|
//---- javafxOpenButton ----
|
||||||
|
javafxOpenButton.setText("JavaFX Open...");
|
||||||
|
javafxOpenButton.addActionListener(e -> javafxOpen());
|
||||||
|
add(javafxOpenButton, "cell 0 8 3 1");
|
||||||
|
|
||||||
|
//---- javafxSaveButton ----
|
||||||
|
javafxSaveButton.setText("JavaFX Save...");
|
||||||
|
javafxSaveButton.addActionListener(e -> javafxSave());
|
||||||
|
add(javafxSaveButton, "cell 0 8 3 1");
|
||||||
|
|
||||||
|
//======== outputScrollPane ========
|
||||||
|
{
|
||||||
|
|
||||||
|
//---- outputField ----
|
||||||
|
outputField.setRows(20);
|
||||||
|
outputScrollPane.setViewportView(outputField);
|
||||||
|
}
|
||||||
|
add(outputScrollPane, "cell 0 9 3 1,growx");
|
||||||
|
|
||||||
|
//---- ownerButtonGroup ----
|
||||||
|
ButtonGroup ownerButtonGroup = new ButtonGroup();
|
||||||
|
ownerButtonGroup.add(ownerFrameRadioButton);
|
||||||
|
ownerButtonGroup.add(ownerDialogRadioButton);
|
||||||
|
ownerButtonGroup.add(ownerNullRadioButton);
|
||||||
|
// JFormDesigner - End of component initialization //GEN-END:initComponents
|
||||||
|
}
|
||||||
|
|
||||||
|
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
|
||||||
|
private JLabel ownerLabel;
|
||||||
|
private JRadioButton ownerFrameRadioButton;
|
||||||
|
private JRadioButton ownerDialogRadioButton;
|
||||||
|
private JRadioButton ownerNullRadioButton;
|
||||||
|
private JPanel ownerSpacer;
|
||||||
|
private JLabel dialogTitleLabel;
|
||||||
|
private JTextField dialogTitleField;
|
||||||
|
private JPanel panel1;
|
||||||
|
private JCheckBox directorySelectionCheckBox;
|
||||||
|
private JCheckBox multiSelectionEnabledCheckBox;
|
||||||
|
private JCheckBox useFileHidingCheckBox;
|
||||||
|
private JCheckBox useSystemFileChooserCheckBox;
|
||||||
|
private JLabel approveButtonTextLabel;
|
||||||
|
private JTextField approveButtonTextField;
|
||||||
|
private JLabel approveButtonMnemonicLabel;
|
||||||
|
private JTextField approveButtonMnemonicField;
|
||||||
|
private JCheckBox currentDirCheckBox;
|
||||||
|
private JTextField currentDirField;
|
||||||
|
private JButton currentDirChooseButton;
|
||||||
|
private JCheckBox selectedFileCheckBox;
|
||||||
|
private JTextField selectedFileField;
|
||||||
|
private JButton selectedFileChooseButton;
|
||||||
|
private JCheckBox selectedFilesCheckBox;
|
||||||
|
private JTextField selectedFilesField;
|
||||||
|
private JButton selectedFilesChooseButton;
|
||||||
|
private JLabel fileTypesLabel;
|
||||||
|
private JComboBox<String> fileTypesField;
|
||||||
|
private JLabel fileTypeIndexLabel;
|
||||||
|
private JSlider fileTypeIndexSlider;
|
||||||
|
private JCheckBox useAcceptAllFileFilterCheckBox;
|
||||||
|
private JButton openButton;
|
||||||
|
private JButton saveButton;
|
||||||
|
private JButton swingOpenButton;
|
||||||
|
private JButton swingSaveButton;
|
||||||
|
private JButton awtOpenButton;
|
||||||
|
private JButton awtSaveButton;
|
||||||
|
private JButton javafxOpenButton;
|
||||||
|
private JButton javafxSaveButton;
|
||||||
|
private JScrollPane outputScrollPane;
|
||||||
|
private JTextArea outputField;
|
||||||
|
// JFormDesigner - End of variables declaration //GEN-END:variables
|
||||||
|
}
|
||||||
@@ -0,0 +1,321 @@
|
|||||||
|
JFDML JFormDesigner: "8.3" encoding: "UTF-8"
|
||||||
|
|
||||||
|
new FormModel {
|
||||||
|
contentType: "form/swing"
|
||||||
|
root: new FormRoot {
|
||||||
|
add( new FormContainer( "com.formdev.flatlaf.testing.FlatTestPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
|
||||||
|
"$layoutConstraints": "ltr,insets dialog,hidemode 3"
|
||||||
|
"$columnConstraints": "[left][grow,fill][fill]"
|
||||||
|
"$rowConstraints": "[][][][][][][][][][grow,fill]"
|
||||||
|
} ) {
|
||||||
|
name: "this"
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "ownerLabel"
|
||||||
|
"text": "owner"
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 0"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JRadioButton" ) {
|
||||||
|
name: "ownerFrameRadioButton"
|
||||||
|
"text": "JFrame"
|
||||||
|
"selected": true
|
||||||
|
"$buttonGroup": new FormReference( "ownerButtonGroup" )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 0"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JRadioButton" ) {
|
||||||
|
name: "ownerDialogRadioButton"
|
||||||
|
"text": "JDialog"
|
||||||
|
"$buttonGroup": new FormReference( "ownerButtonGroup" )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 0"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JRadioButton" ) {
|
||||||
|
name: "ownerNullRadioButton"
|
||||||
|
"text": "null"
|
||||||
|
"$buttonGroup": new FormReference( "ownerButtonGroup" )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 0"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "com.jformdesigner.designer.wrapper.HSpacer" ) {
|
||||||
|
name: "ownerSpacer"
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 0,growx"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "dialogTitleLabel"
|
||||||
|
"text": "dialogTitle"
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 1"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JTextField" ) {
|
||||||
|
name: "dialogTitleField"
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 1"
|
||||||
|
} )
|
||||||
|
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
|
||||||
|
"$layoutConstraints": "insets 2,hidemode 3"
|
||||||
|
"$columnConstraints": "[left]"
|
||||||
|
"$rowConstraints": "[]0[]0[][]"
|
||||||
|
} ) {
|
||||||
|
name: "panel1"
|
||||||
|
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||||
|
name: "directorySelectionCheckBox"
|
||||||
|
"text": "directorySelection"
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 0"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||||
|
name: "multiSelectionEnabledCheckBox"
|
||||||
|
"text": "multiSelectionEnabled"
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 1"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||||
|
name: "useFileHidingCheckBox"
|
||||||
|
"text": "useFileHiding"
|
||||||
|
"selected": true
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 2"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||||
|
name: "useSystemFileChooserCheckBox"
|
||||||
|
"text": "use SystemFileChooser"
|
||||||
|
"selected": true
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 3"
|
||||||
|
} )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 2 1 1 7,aligny top,growy 0"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "approveButtonTextLabel"
|
||||||
|
"text": "approveButtonText"
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 2"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JTextField" ) {
|
||||||
|
name: "approveButtonTextField"
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 2,growx"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "approveButtonMnemonicLabel"
|
||||||
|
"text": "approveButtonMnemonic"
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 2"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JTextField" ) {
|
||||||
|
name: "approveButtonMnemonicField"
|
||||||
|
"columns": 3
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 2"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||||
|
name: "currentDirCheckBox"
|
||||||
|
"text": "current directory"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "currentDirChanged", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 3"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JTextField" ) {
|
||||||
|
name: "currentDirField"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 3,growx"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JButton" ) {
|
||||||
|
name: "currentDirChooseButton"
|
||||||
|
"text": "..."
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "chooseCurrentDir", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 3"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||||
|
name: "selectedFileCheckBox"
|
||||||
|
"text": "selected file"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "selectedFileChanged", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 4"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JTextField" ) {
|
||||||
|
name: "selectedFileField"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 4,growx"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JButton" ) {
|
||||||
|
name: "selectedFileChooseButton"
|
||||||
|
"text": "..."
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "chooseSelectedFile", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 4"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||||
|
name: "selectedFilesCheckBox"
|
||||||
|
"text": "selected files"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "selectedFilesChanged", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 5"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JTextField" ) {
|
||||||
|
name: "selectedFilesField"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 5,growx"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JButton" ) {
|
||||||
|
name: "selectedFilesChooseButton"
|
||||||
|
"text": "..."
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "chooseSelectedFiles", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 5"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "fileTypesLabel"
|
||||||
|
"text": "fileTypes"
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 6"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JComboBox" ) {
|
||||||
|
name: "fileTypesField"
|
||||||
|
"editable": true
|
||||||
|
"model": new javax.swing.DefaultComboBoxModel {
|
||||||
|
selectedItem: "Text Files,txt"
|
||||||
|
addElement( "Text Files,txt" )
|
||||||
|
addElement( "All Files,*" )
|
||||||
|
addElement( "Text Files,txt,PDF Files,pdf,All Files,*" )
|
||||||
|
addElement( "Text and PDF Files,txt;pdf" )
|
||||||
|
}
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 6"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "fileTypeIndexLabel"
|
||||||
|
"text": "fileTypeIndex"
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 7"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JSlider" ) {
|
||||||
|
name: "fileTypeIndexSlider"
|
||||||
|
"maximum": 10
|
||||||
|
"majorTickSpacing": 1
|
||||||
|
"value": 0
|
||||||
|
"paintLabels": true
|
||||||
|
"snapToTicks": true
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 7,growx"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||||
|
name: "useAcceptAllFileFilterCheckBox"
|
||||||
|
"text": "useAcceptAllFileFilter"
|
||||||
|
"selected": true
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 7"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JButton" ) {
|
||||||
|
name: "openButton"
|
||||||
|
"text": "Open..."
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "open", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 8 3 1"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JButton" ) {
|
||||||
|
name: "saveButton"
|
||||||
|
"text": "Save..."
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "save", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 8 3 1"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JButton" ) {
|
||||||
|
name: "swingOpenButton"
|
||||||
|
"text": "Swing Open..."
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "swingOpen", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 8 3 1"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JButton" ) {
|
||||||
|
name: "swingSaveButton"
|
||||||
|
"text": "Swing Save..."
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "swingSave", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 8 3 1"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JButton" ) {
|
||||||
|
name: "awtOpenButton"
|
||||||
|
"text": "AWT Open..."
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "awtOpen", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 8 3 1"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JButton" ) {
|
||||||
|
name: "awtSaveButton"
|
||||||
|
"text": "AWT Save..."
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "awtSave", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 8 3 1"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JButton" ) {
|
||||||
|
name: "javafxOpenButton"
|
||||||
|
"text": "JavaFX Open..."
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "javafxOpen", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 8 3 1"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JButton" ) {
|
||||||
|
name: "javafxSaveButton"
|
||||||
|
"text": "JavaFX Save..."
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "javafxSave", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 8 3 1"
|
||||||
|
} )
|
||||||
|
add( new FormContainer( "javax.swing.JScrollPane", new FormLayoutManager( class javax.swing.JScrollPane ) ) {
|
||||||
|
name: "outputScrollPane"
|
||||||
|
add( new FormComponent( "javax.swing.JTextArea" ) {
|
||||||
|
name: "outputField"
|
||||||
|
"rows": 20
|
||||||
|
} )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 9 3 1,growx"
|
||||||
|
} )
|
||||||
|
}, new FormLayoutConstraints( null ) {
|
||||||
|
"location": new java.awt.Point( 0, 0 )
|
||||||
|
"size": new java.awt.Dimension( 825, 465 )
|
||||||
|
} )
|
||||||
|
add( new FormNonVisual( "javax.swing.ButtonGroup" ) {
|
||||||
|
name: "ownerButtonGroup"
|
||||||
|
}, new FormLayoutConstraints( null ) {
|
||||||
|
"location": new java.awt.Point( 0, 475 )
|
||||||
|
} )
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,6 +19,7 @@ package com.formdev.flatlaf.testing;
|
|||||||
import static com.formdev.flatlaf.ui.FlatNativeWindowsLibrary.*;
|
import static com.formdev.flatlaf.ui.FlatNativeWindowsLibrary.*;
|
||||||
import java.awt.Dialog;
|
import java.awt.Dialog;
|
||||||
import java.awt.EventQueue;
|
import java.awt.EventQueue;
|
||||||
|
import java.awt.Font;
|
||||||
import java.awt.SecondaryLoop;
|
import java.awt.SecondaryLoop;
|
||||||
import java.awt.Toolkit;
|
import java.awt.Toolkit;
|
||||||
import java.awt.Window;
|
import java.awt.Window;
|
||||||
@@ -393,6 +394,7 @@ public class FlatSystemFileChooserWindowsTest
|
|||||||
|
|
||||||
//---- pickFoldersCheckBox ----
|
//---- pickFoldersCheckBox ----
|
||||||
pickFoldersCheckBox.setText("pickFolders");
|
pickFoldersCheckBox.setText("pickFolders");
|
||||||
|
pickFoldersCheckBox.setFont(pickFoldersCheckBox.getFont().deriveFont(pickFoldersCheckBox.getFont().getStyle() | Font.BOLD));
|
||||||
panel1.add(pickFoldersCheckBox, "cell 0 3");
|
panel1.add(pickFoldersCheckBox, "cell 0 3");
|
||||||
|
|
||||||
//---- shareAwareCheckBox ----
|
//---- shareAwareCheckBox ----
|
||||||
@@ -401,6 +403,7 @@ public class FlatSystemFileChooserWindowsTest
|
|||||||
|
|
||||||
//---- forceShowHiddenCheckBox ----
|
//---- forceShowHiddenCheckBox ----
|
||||||
forceShowHiddenCheckBox.setText("forceShowHidden");
|
forceShowHiddenCheckBox.setText("forceShowHidden");
|
||||||
|
forceShowHiddenCheckBox.setFont(forceShowHiddenCheckBox.getFont().deriveFont(forceShowHiddenCheckBox.getFont().getStyle() | Font.BOLD));
|
||||||
panel1.add(forceShowHiddenCheckBox, "cell 2 3");
|
panel1.add(forceShowHiddenCheckBox, "cell 2 3");
|
||||||
|
|
||||||
//---- forceFileSystemCheckBox ----
|
//---- forceFileSystemCheckBox ----
|
||||||
@@ -441,6 +444,7 @@ public class FlatSystemFileChooserWindowsTest
|
|||||||
|
|
||||||
//---- allowMultiSelectCheckBox ----
|
//---- allowMultiSelectCheckBox ----
|
||||||
allowMultiSelectCheckBox.setText("allowMultiSelect");
|
allowMultiSelectCheckBox.setText("allowMultiSelect");
|
||||||
|
allowMultiSelectCheckBox.setFont(allowMultiSelectCheckBox.getFont().deriveFont(allowMultiSelectCheckBox.getFont().getStyle() | Font.BOLD));
|
||||||
panel1.add(allowMultiSelectCheckBox, "cell 0 7");
|
panel1.add(allowMultiSelectCheckBox, "cell 0 7");
|
||||||
|
|
||||||
//---- hidePinnedPlacesCheckBox ----
|
//---- hidePinnedPlacesCheckBox ----
|
||||||
|
|||||||
@@ -116,6 +116,7 @@ new FormModel {
|
|||||||
add( new FormComponent( "com.formdev.flatlaf.extras.components.FlatTriStateCheckBox" ) {
|
add( new FormComponent( "com.formdev.flatlaf.extras.components.FlatTriStateCheckBox" ) {
|
||||||
name: "pickFoldersCheckBox"
|
name: "pickFoldersCheckBox"
|
||||||
"text": "pickFolders"
|
"text": "pickFolders"
|
||||||
|
"font": new com.jformdesigner.model.SwingDerivedFont( null, 1, 0, false )
|
||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
"value": "cell 0 3"
|
"value": "cell 0 3"
|
||||||
} )
|
} )
|
||||||
@@ -128,6 +129,7 @@ new FormModel {
|
|||||||
add( new FormComponent( "com.formdev.flatlaf.extras.components.FlatTriStateCheckBox" ) {
|
add( new FormComponent( "com.formdev.flatlaf.extras.components.FlatTriStateCheckBox" ) {
|
||||||
name: "forceShowHiddenCheckBox"
|
name: "forceShowHiddenCheckBox"
|
||||||
"text": "forceShowHidden"
|
"text": "forceShowHidden"
|
||||||
|
"font": new com.jformdesigner.model.SwingDerivedFont( null, 1, 0, false )
|
||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
"value": "cell 2 3"
|
"value": "cell 2 3"
|
||||||
} )
|
} )
|
||||||
@@ -188,6 +190,7 @@ new FormModel {
|
|||||||
add( new FormComponent( "com.formdev.flatlaf.extras.components.FlatTriStateCheckBox" ) {
|
add( new FormComponent( "com.formdev.flatlaf.extras.components.FlatTriStateCheckBox" ) {
|
||||||
name: "allowMultiSelectCheckBox"
|
name: "allowMultiSelectCheckBox"
|
||||||
"text": "allowMultiSelect"
|
"text": "allowMultiSelect"
|
||||||
|
"font": new com.jformdesigner.model.SwingDerivedFont( null, 1, 0, false )
|
||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
"value": "cell 0 7"
|
"value": "cell 0 7"
|
||||||
} )
|
} )
|
||||||
|
|||||||
@@ -242,6 +242,9 @@ public class FlatTestFrame
|
|||||||
super.dispose();
|
super.dispose();
|
||||||
|
|
||||||
FlatUIDefaultsInspector.hide();
|
FlatUIDefaultsInspector.hide();
|
||||||
|
|
||||||
|
if( getDefaultCloseOperation() == JFrame.EXIT_ON_CLOSE )
|
||||||
|
System.exit( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateTitle() {
|
private void updateTitle() {
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ fifesoft-autocomplete = "com.fifesoft:autocomplete:3.3.1"
|
|||||||
# flatlaf-testing
|
# flatlaf-testing
|
||||||
glazedlists = "com.glazedlists:glazedlists:1.11.0"
|
glazedlists = "com.glazedlists:glazedlists:1.11.0"
|
||||||
netbeans-api-awt = "org.netbeans.api:org-openide-awt:RELEASE112"
|
netbeans-api-awt = "org.netbeans.api:org-openide-awt:RELEASE112"
|
||||||
|
nativejfilechooser = "li.flor:native-j-file-chooser:1.6.4"
|
||||||
|
|
||||||
# flatlaf-natives-jna
|
# flatlaf-natives-jna
|
||||||
jna = "net.java.dev.jna:jna:5.15.0"
|
jna = "net.java.dev.jna:jna:5.15.0"
|
||||||
|
|||||||
Reference in New Issue
Block a user