diff --git a/CHANGELOG.md b/CHANGELOG.md index 625ef98d..95a308db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ FlatLaf Change Log when window is maximized. (issue #296) - Button and ToggleButton: Do not paint background of disabled (and unselected) toolBar buttons. (issue #292; regression since fixing #112) +- TabbedPane: Fixed NPE when creating/modifying in another thread. (issue #299) - Fixed crash when running in Webswing. (issue #290) diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTabbedPaneUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTabbedPaneUI.java index 9c45ca11..d67579b3 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTabbedPaneUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTabbedPaneUI.java @@ -722,6 +722,13 @@ public class FlatTabbedPaneUI } protected Insets getRealTabAreaInsets( int tabPlacement ) { + // this is to avoid potential NPE in ensureSelectedTabIsVisible() + // (see https://github.com/JFormDesigner/FlatLaf/issues/299) + // but now should actually never occur because added more checks to + // ensureSelectedTabIsVisibleLater() and ensureSelectedTabIsVisible() + if( tabAreaInsets == null ) + tabAreaInsets = new Insets( 0, 0, 0, 0 ); + Insets currentTabAreaInsets = super.getTabAreaInsets( tabPlacement ); Insets insets = (Insets) currentTabAreaInsets.clone(); @@ -1386,13 +1393,18 @@ public class FlatTabbedPaneUI } protected void ensureSelectedTabIsVisibleLater() { + // do nothing if not yet displayable or if not invoked from dispatch thread, + // which may be the case when creating/modifying in another thread + if( !tabPane.isDisplayable() || !EventQueue.isDispatchThread() ) + return; + EventQueue.invokeLater( () -> { ensureSelectedTabIsVisible(); } ); } protected void ensureSelectedTabIsVisible() { - if( tabPane == null || tabViewport == null ) + if( tabPane == null || tabViewport == null || !tabPane.isDisplayable() ) return; ensureCurrentLayout();