mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2026-02-12 15:07:11 -06:00
System File Chooser: Fixed: system and Swing file dialogs were shown at the same time if application has no other displayable window (issue #1078)
also require that `SystemFileChooser.show*Dialog()` methods are invoked on AWT thread
This commit is contained in:
@@ -6,6 +6,8 @@ FlatLaf Change Log
|
|||||||
- System File Chooser:
|
- System File Chooser:
|
||||||
- Update current filter before invoking approve callback and after closing
|
- Update current filter before invoking approve callback and after closing
|
||||||
dialog. (issue #1065)
|
dialog. (issue #1065)
|
||||||
|
- Fixed: System and Swing file dialogs were shown at the same time if
|
||||||
|
application has no other displayable window. (issue #1078)
|
||||||
- On Linux: Check whether required GSettings schemas are installed to avoid
|
- On Linux: Check whether required GSettings schemas are installed to avoid
|
||||||
application crash (occurred on NixOS with Plasma/KDE desktop). (issue #1069)
|
application crash (occurred on NixOS with Plasma/KDE desktop). (issue #1069)
|
||||||
- ComboBox: Added UI property `ComboBox.buttonFocusedEditableBackground`. (issue
|
- ComboBox: Added UI property `ComboBox.buttonFocusedEditableBackground`. (issue
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ package com.formdev.flatlaf.util;
|
|||||||
|
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
|
import java.awt.EventQueue;
|
||||||
|
import java.awt.Frame;
|
||||||
import java.awt.KeyboardFocusManager;
|
import java.awt.KeyboardFocusManager;
|
||||||
import java.awt.SecondaryLoop;
|
import java.awt.SecondaryLoop;
|
||||||
import java.awt.Toolkit;
|
import java.awt.Toolkit;
|
||||||
@@ -743,6 +745,9 @@ public class SystemFileChooser
|
|||||||
}
|
}
|
||||||
|
|
||||||
private int showDialogImpl( Component parent ) {
|
private int showDialogImpl( Component parent ) {
|
||||||
|
if( !EventQueue.isDispatchThread() )
|
||||||
|
throw new IllegalStateException( "Must be invoked from the AWT/Swing event dispatch thread" );
|
||||||
|
|
||||||
Window owner = (parent instanceof Window)
|
Window owner = (parent instanceof Window)
|
||||||
? (Window) parent
|
? (Window) parent
|
||||||
: (parent != null) ? SwingUtilities.windowForComponent( parent ) : null;
|
: (parent != null) ? SwingUtilities.windowForComponent( parent ) : null;
|
||||||
@@ -791,6 +796,16 @@ public class SystemFileChooser
|
|||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public File[] showDialog( Window owner, SystemFileChooser fc ) {
|
public File[] showDialog( Window owner, SystemFileChooser fc ) {
|
||||||
|
// if there is no displayable window, then AWT's auto-shutdown feature
|
||||||
|
// quits our secondary event loop (see below) immediately
|
||||||
|
// https://docs.oracle.com/en/java/javase/25/docs/api/java.desktop/java/awt/doc-files/AWTThreadIssues.html#Autoshutdown
|
||||||
|
Window dummyWindow = null;
|
||||||
|
if( !hasDisplayableWindow( owner ) ) {
|
||||||
|
// create a (not visible) displayable window to avoid AWT auto-shutdown
|
||||||
|
dummyWindow = new Window( (Frame) null );
|
||||||
|
dummyWindow.addNotify();
|
||||||
|
}
|
||||||
|
|
||||||
AtomicReference<String[]> filenamesRef = new AtomicReference<>();
|
AtomicReference<String[]> filenamesRef = new AtomicReference<>();
|
||||||
|
|
||||||
// create secondary event look and invoke system file dialog on a new thread
|
// create secondary event look and invoke system file dialog on a new thread
|
||||||
@@ -801,6 +816,10 @@ public class SystemFileChooser
|
|||||||
}, "FlatLaf SystemFileChooser" ).start();
|
}, "FlatLaf SystemFileChooser" ).start();
|
||||||
secondaryLoop.enter();
|
secondaryLoop.enter();
|
||||||
|
|
||||||
|
// dispose dummy window to allow AWT to auto-shutdown
|
||||||
|
if( dummyWindow != null )
|
||||||
|
dummyWindow.dispose();
|
||||||
|
|
||||||
String[] filenames = filenamesRef.get();
|
String[] filenames = filenamesRef.get();
|
||||||
|
|
||||||
// fallback to Swing file chooser if system file dialog failed or is not available
|
// fallback to Swing file chooser if system file dialog failed or is not available
|
||||||
@@ -837,6 +856,17 @@ public class SystemFileChooser
|
|||||||
files[i] = fsv.createFileObject( filenames[i] );
|
files[i] = fsv.createFileObject( filenames[i] );
|
||||||
return files;
|
return files;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean hasDisplayableWindow( Window owner ) {
|
||||||
|
if( owner != null && owner.isDisplayable() )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
for( Window window : Window.getWindows() ) {
|
||||||
|
if( window.isDisplayable() )
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//---- class WindowsFileChooserProvider -----------------------------------
|
//---- class WindowsFileChooserProvider -----------------------------------
|
||||||
|
|||||||
Reference in New Issue
Block a user