System File Chooser: on Linux when JavaFX is used in application, then always use Swing file chooser because system file dialog does work (PR #988)

with Java 8, some GLib related messages are logged to console and system file dialog is not shown
e.g.: `GLib-GObject-WARNING **: cannot register existing type 'GdkDisplayManager'`

with Java 17, the system file dialog is shown, but then JavaFX no longer works
with Java 21, the application quits/crashes immediately when trying to show system file dialog

also fixed Error Prone warning in `getFiltersForDialog()`
This commit is contained in:
Karl Tauber
2025-12-01 13:41:54 +01:00
parent 1c6e8774cf
commit 58e073a05b
2 changed files with 50 additions and 5 deletions

View File

@@ -22,9 +22,10 @@ import java.awt.SecondaryLoop;
import java.awt.Toolkit;
import java.awt.Window;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
@@ -590,7 +591,7 @@ public class SystemFileChooser
if( filters.size() == 1 &&
filters.get( 0 ) == getAcceptAllFileFilter() &&
(fileFilter == getAcceptAllFileFilter() || fileFilter == null) )
return Collections.emptyList();
return new ArrayList<>();
// check whether current filter is already in list
if( (fileFilter != null && filters.contains( fileFilter )) || fileFilter == null )
@@ -1073,6 +1074,15 @@ public class SystemFileChooser
private static class LinuxFileChooserProvider
extends SystemFileChooserProvider
{
@Override
public File[] showDialog( Window owner, SystemFileChooser fc ) {
// fallback to Swing file chooser if JavaFX is initialized
if( isFXinitialized() )
return new SwingFileChooserProvider().showDialog( owner, fc );
return super.showDialog( owner, fc );
}
@Override
String[] showSystemDialog( Window owner, SystemFileChooser fc ) {
boolean open = (fc.getDialogType() == OPEN_DIALOG);
@@ -1175,6 +1185,41 @@ public class SystemFileChooser
return buf.toString();
}
private static Boolean fxinitialized;
boolean isFXinitialized() {
if( fxinitialized != null )
return fxinitialized;
// check whether JavaFX is available
try {
Class.forName( "javafx.application.Platform", false, getClass().getClassLoader() );
} catch( ClassNotFoundException ex ) {
// JavaFX is not available
fxinitialized = false;
return fxinitialized;
}
// check whether JavaFX is initialized
try {
Class<?> cls = Class.forName( "javafx.application.Platform" );
Method m = cls.getMethod( "runLater", Runnable.class );
m.invoke( null, (Runnable) () -> {} );
fxinitialized = true;
return fxinitialized;
} catch( InvocationTargetException ex ) {
if( ex.getCause() instanceof IllegalStateException )
return false; // JavaFX is available, but not (yet) initialized
} catch( Throwable ex ) {
// ignore
}
// other error --> assume that JavaFX is not initialized
fxinitialized = false;
return fxinitialized;
}
//---- class LinuxApproveContext ----
private static class LinuxApproveContext

View File

@@ -77,7 +77,7 @@ public class FlatSystemFileChooserTest
FlatSystemFileChooserTest() {
initComponents();
if( !NativeJFileChooser.FX_AVAILABLE ) {
if( SystemInfo.isLinux || !NativeJFileChooser.FX_AVAILABLE ) {
javafxOpenButton.setEnabled( false );
javafxSaveButton.setEnabled( false );
}
@@ -231,7 +231,7 @@ public class FlatSystemFileChooserTest
int fileTypeIndex = fileTypeIndexSlider.getValue();
if( !useAcceptAllFileFilterCheckBox.isSelected() )
fc.setAcceptAllFileFilterUsed( false );
for( int i = 0; i < fileTypes.length; i += 2 ) {
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( ";" ) ) );
@@ -282,7 +282,7 @@ public class FlatSystemFileChooserTest
int fileTypeIndex = fileTypeIndexSlider.getValue();
if( !useAcceptAllFileFilterCheckBox.isSelected() )
fc.setAcceptAllFileFilterUsed( false );
for( int i = 0; i < fileTypes.length; i += 2 ) {
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( ";" ) ) );