diff --git a/CHANGELOG.md b/CHANGELOG.md index 37ed6891..dc88bb42 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ FlatLaf Change Log when resizing window. (issue #907) - Popup: On Windows 10, fixed misplaced popup drop shadow. (issue #911; regression in 3.5) +- Popup: Fixed NPE if `GraphicsConfiguration` is `null` on Windows. (issue #921) - Theme Editor: Fixed using color picker on secondary screen. diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatNativeLinuxLibrary.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatNativeLinuxLibrary.java index 8f0ee8b3..952d0ece 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatNativeLinuxLibrary.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatNativeLinuxLibrary.java @@ -16,6 +16,7 @@ package com.formdev.flatlaf.ui; +import java.awt.GraphicsConfiguration; import java.awt.Point; import java.awt.Toolkit; import java.awt.Window; @@ -96,7 +97,11 @@ class FlatNativeLinuxLibrary } private static Point scale( Window window, Point pt ) { - AffineTransform transform = window.getGraphicsConfiguration().getDefaultTransform(); + GraphicsConfiguration gc = window.getGraphicsConfiguration(); + if( gc == null ) + return pt; + + AffineTransform transform = gc.getDefaultTransform(); int x = (int) Math.round( pt.x * transform.getScaleX() ); int y = (int) Math.round( pt.y * transform.getScaleY() ); return new Point( x, y ); diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatPopupFactory.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatPopupFactory.java index bb362106..c5621132 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatPopupFactory.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatPopupFactory.java @@ -138,7 +138,8 @@ public class FlatPopupFactory // create drop shadow popup Popup popupForScreenOfOwner = getPopupForScreenOfOwner( owner, contents, x, y, forceHeavyWeight ); - return owner.getGraphicsConfiguration().isTranslucencyCapable() + GraphicsConfiguration gc = owner.getGraphicsConfiguration(); + return (gc != null && gc.isTranslucencyCapable()) ? new DropShadowPopup( popupForScreenOfOwner, owner, contents ) : new NonFlashingPopup( popupForScreenOfOwner, owner, contents ); } diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatPopupMenuUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatPopupMenuUI.java index f6d3af4f..69fc6ec4 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatPopupMenuUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatPopupMenuUI.java @@ -239,11 +239,13 @@ public class FlatPopupMenuUI if( gc == null && popupMenu.getInvoker() != null ) gc = popupMenu.getInvoker().getGraphicsConfiguration(); - // compute screen height + if( gc == null ) + return new Rectangle( Toolkit.getDefaultToolkit().getScreenSize() ); + + // compute screen bounds // (always subtract screen insets because there is no API to detect whether // the popup can overlap the taskbar; see JPopupMenu.canPopupOverlapTaskBar()) - Toolkit toolkit = Toolkit.getDefaultToolkit(); - Rectangle screenBounds = (gc != null) ? gc.getBounds() : new Rectangle( toolkit.getScreenSize() ); + Rectangle screenBounds = gc.getBounds(); Insets screenInsets = Toolkit.getDefaultToolkit().getScreenInsets( gc ); return FlatUIUtils.subtractInsets( screenBounds, screenInsets ); } diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTitlePane.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTitlePane.java index 42695588..6a9d9983 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTitlePane.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTitlePane.java @@ -824,7 +824,8 @@ public class FlatTitlePane Rectangle oldMaximizedBounds = frame.getMaximizedBounds(); if( !hasNativeCustomDecoration() && (oldMaximizedBounds == null || - Objects.equals( oldMaximizedBounds, rootPane.getClientProperty( "_flatlaf.maximizedBounds" ) )) ) + Objects.equals( oldMaximizedBounds, rootPane.getClientProperty( "_flatlaf.maximizedBounds" ) )) && + window.getGraphicsConfiguration() != null ) { GraphicsConfiguration gc = window.getGraphicsConfiguration(); diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatWindowResizer.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatWindowResizer.java index 35fbb5e7..c466ecf8 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatWindowResizer.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatWindowResizer.java @@ -329,20 +329,17 @@ public abstract class FlatWindowResizer @Override protected boolean limitToParentBounds() { - return limitResizeToScreenBounds && window != null; + return limitResizeToScreenBounds && window != null && window.getGraphicsConfiguration() != null; } @Override protected Rectangle getParentBounds() { - if( limitResizeToScreenBounds && window != null ) { - GraphicsConfiguration gc = window.getGraphicsConfiguration(); - Rectangle bounds = gc.getBounds(); - Insets insets = window.getToolkit().getScreenInsets( gc ); - return new Rectangle( bounds.x + insets.left, bounds.y + insets.top, - bounds.width - insets.left - insets.right, - bounds.height - insets.top - insets.bottom ); - } - return null; + GraphicsConfiguration gc = window.getGraphicsConfiguration(); + Rectangle bounds = gc.getBounds(); + Insets insets = window.getToolkit().getScreenInsets( gc ); + return new Rectangle( bounds.x + insets.left, bounds.y + insets.top, + bounds.width - insets.left - insets.right, + bounds.height - insets.top - insets.bottom ); } @Override diff --git a/flatlaf-extras/src/main/java/com/formdev/flatlaf/extras/FlatInspector.java b/flatlaf-extras/src/main/java/com/formdev/flatlaf/extras/FlatInspector.java index 29f91e67..4f4dcc0f 100644 --- a/flatlaf-extras/src/main/java/com/formdev/flatlaf/extras/FlatInspector.java +++ b/flatlaf-extras/src/main/java/com/formdev/flatlaf/extras/FlatInspector.java @@ -24,6 +24,7 @@ import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Font; import java.awt.Graphics; +import java.awt.GraphicsConfiguration; import java.awt.Insets; import java.awt.KeyboardFocusManager; import java.awt.LayoutManager; @@ -450,15 +451,18 @@ public class FlatInspector Dimension size = tip.getPreferredSize(); // position the tip in the visible area - Rectangle visibleRect = rootPane.getGraphicsConfiguration().getBounds(); - if( tx + size.width > visibleRect.x + visibleRect.width ) - tx -= size.width + UIScale.scale( 16 ); - if( ty + size.height > visibleRect.y + visibleRect.height ) - ty -= size.height + UIScale.scale( 32 ); - if( tx < visibleRect.x ) - tx = visibleRect.x; - if( ty < visibleRect.y ) - ty = visibleRect.y; + GraphicsConfiguration gc = rootPane.getGraphicsConfiguration(); + if( gc != null ) { + Rectangle visibleRect = gc.getBounds(); + if( tx + size.width > visibleRect.x + visibleRect.width ) + tx -= size.width + UIScale.scale( 16 ); + if( ty + size.height > visibleRect.y + visibleRect.height ) + ty -= size.height + UIScale.scale( 32 ); + if( tx < visibleRect.x ) + tx = visibleRect.x; + if( ty < visibleRect.y ) + ty = visibleRect.y; + } PopupFactory popupFactory = PopupFactory.getSharedInstance(); popup = popupFactory.getPopup( c, tip, tx, ty );