From a9ea9daec39d12b32cb15e7f2a29f58a860b4c09 Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Mon, 8 Jan 2024 20:29:20 +0100 Subject: [PATCH] FileChooser: catch NPE in Java 21 when getting icon for `.exe` files that use default Windows exe icon (see https://bugs.openjdk.org/browse/JDK-8320692) --- CHANGELOG.md | 7 ++- .../formdev/flatlaf/ui/FlatFileChooserUI.java | 53 +++++++++++-------- 2 files changed, 36 insertions(+), 24 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 81594703..0377e840 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,12 +19,15 @@ FlatLaf Change Log - Button and ToggleButton: Selected buttons did not use explicitly set foreground color. (issue 756) -- Table: Switching theme looses table grid and intercell spacing. (issues #733 - and #750) +- FileChooser: Catch NPE in Java 21 when getting icon for `.exe` files that use + default Windows exe icon. (see + [JDK-8320692](https://bugs.openjdk.org/browse/JDK-8320692)) - OptionPane: Fixed styling custom panel background in `JOptionPane`. (issue #761) - ScrollPane: Styling ScrollPane border properties did not work if view component is a Table. +- Table: Switching theme looses table grid and intercell spacing. (issues #733 + and #750) - Table: Fixed background of `boolean` columns when using alternating row colors. (issue #780) - TableHeader: No longer temporary replace header cell renderer while painting. diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatFileChooserUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatFileChooserUI.java index 8f45ec10..1fe8caec 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatFileChooserUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatFileChooserUI.java @@ -370,7 +370,11 @@ public class FlatFileChooserUI // get system icon if( f != null ) { - icon = getFileChooser().getFileSystemView().getSystemIcon( f ); + try { + icon = getFileChooser().getFileSystemView().getSystemIcon( f ); + } catch( NullPointerException ex ) { + // Java 21 may throw a NPE for exe files that use default Windows exe icon + } if( icon != null ) { if( icon instanceof ImageIcon ) @@ -540,31 +544,36 @@ public class FlatFileChooserUI if( doNotUseSystemIcons() ) return new FlatFileViewDirectoryIcon(); - // Java 17+ supports getting larger system icons try { - if( SystemInfo.isJava_17_orLater ) { - Method m = fsv.getClass().getMethod( "getSystemIcon", File.class, int.class, int.class ); - return (Icon) m.invoke( fsv, file, iconSize.width, iconSize.height ); - } else if( iconSize.width > 16 || iconSize.height > 16 ) { - Class cls = Class.forName( "sun.awt.shell.ShellFolder" ); - if( cls.isInstance( file ) ) { - Method m = file.getClass().getMethod( "getIcon", boolean.class ); - m.setAccessible( true ); - Image image = (Image) m.invoke( file, true ); - if( image != null ) - return new ImageIcon( image ); + // Java 17+ supports getting larger system icons + try { + if( SystemInfo.isJava_17_orLater ) { + Method m = fsv.getClass().getMethod( "getSystemIcon", File.class, int.class, int.class ); + return (Icon) m.invoke( fsv, file, iconSize.width, iconSize.height ); + } else if( iconSize.width > 16 || iconSize.height > 16 ) { + Class cls = Class.forName( "sun.awt.shell.ShellFolder" ); + if( cls.isInstance( file ) ) { + Method m = file.getClass().getMethod( "getIcon", boolean.class ); + m.setAccessible( true ); + Image image = (Image) m.invoke( file, true ); + if( image != null ) + return new ImageIcon( image ); + } } + } catch( Exception ex ) { + // do not log InaccessibleObjectException because access + // may be denied via VM option '--illegal-access=deny' (default in Java 16) + // (not catching InaccessibleObjectException here because it is new in Java 9, but FlatLaf also runs on Java 8) + if( !"java.lang.reflect.InaccessibleObjectException".equals( ex.getClass().getName() ) ) + LoggingFacade.INSTANCE.logSevere( null, ex ); } - } catch( Exception ex ) { - // do not log InaccessibleObjectException because access - // may be denied via VM option '--illegal-access=deny' (default in Java 16) - // (not catching InaccessibleObjectException here because it is new in Java 9, but FlatLaf also runs on Java 8) - if( !"java.lang.reflect.InaccessibleObjectException".equals( ex.getClass().getName() ) ) - LoggingFacade.INSTANCE.logSevere( null, ex ); - } - // get system icon in default size 16x16 - return fsv.getSystemIcon( file ); + // get system icon in default size 16x16 + return fsv.getSystemIcon( file ); + } catch( NullPointerException ex ) { + // Java 21 may throw a NPE for exe files that use default Windows exe icon + return new FlatFileViewDirectoryIcon(); + } } protected void directoryChanged( File file ) {