Class FlatPopupFactory
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionprivate classprivate classFixes popup background flashing effect when using dark theme on light platform theme, where the light popup background is shown for a fraction of a second before the dark popup content is shown. -
Field Summary
FieldsModifier and TypeFieldDescriptionprivate MethodHandleprivate MethodHandle(package private) static final Stringprivate final ArrayList<FlatPopupFactory.NonFlashingPopup> -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionprivate static voidOn Linux with Wayland, since Java 21, Swing adds a window focus listener to popup owner/invoker window, which hides the popup as soon as the owner/invoker window looses focus.private PointfixToolTipLocation(Component owner, Component contents, int x, int y) Usually ToolTipManager places a tooltip at (mouseLocation.x, mouseLocation.y + 20).private static intgetBorderCornerRadius(Component owner, Component contents) private PopupgetHeavyWeightPopup(Component owner, Component contents, int x, int y) There is no API in Java 8 to force creation of heavy weight popups, but it is possible with reflection.private static ObjectGet option from: client propertyclientKeyofownerclient propertyclientKeyofcontentsUI propertyuiKeyprivate PopupgetPopupForScreenOfOwner(Component owner, Component contents, int x, int y, boolean forceHeavyWeight) Creates a popup for the screen that the owner component is on.private static floatgetRoundedBorderWidth(Component owner, Component contents) private booleanhasTipLocation(Component owner) Checks whether the owner component returns a tooltip location in JComponent.getToolTipLocation(MouseEvent).private static booleanprivate static booleanisOptionEnabled(Component owner, Component contents, String clientKey, String uiKey) private static booleanprivate static booleanoverlapsHeavyWeightComponent(Component owner, Component contents, int x, int y) private static booleanoverlapsHeavyWeightComponent(Component parent, Rectangle r) private static voidresetWindows11Border(Window popupWindow) private static FlatPopupFactory.NonFlashingPopupreuseStillShownHeavyWeightPopups(FlatPopupFactory.NonFlashingPopup reusePopup, Component contents, int ownerX, int ownerY) Reuse a heavy weight popup window, which is still shown on screen, by updating window location and contents.private static voidsetupRoundedBorder(Window popupWindow, Component owner, Component contents) private static voidsetupRoundedBorderImpl(Window popupWindow, int borderCornerRadius, float borderWidth, Color borderColor) private static voidshowPopupAndFixLocation(Popup popup, Window popupWindow) Shows the given popup and, if necessary, fixes the location of a heavy weight popup window.private booleanMethods inherited from class PopupFactory
getPopup, getSharedInstance, setSharedInstance
-
Field Details
-
KEY_POPUP_USES_NATIVE_BORDER
- See Also:
-
java8getPopupMethod
-
java9getPopupMethod
-
stillShownHeavyWeightPopups
-
-
Constructor Details
-
FlatPopupFactory
public FlatPopupFactory()
-
-
Method Details
-
getPopup
public Popup getPopup(Component owner, Component contents, int x, int y) throws IllegalArgumentException - Overrides:
getPopupin classPopupFactory- Throws:
IllegalArgumentException
-
getPopupForScreenOfOwner
private Popup getPopupForScreenOfOwner(Component owner, Component contents, int x, int y, boolean forceHeavyWeight) throws IllegalArgumentException Creates a popup for the screen that the owner component is on.PopupFactory caches heavy weight popup windows and reuses them. On a dual screen setup, if the popup owner has moved from one screen to the other one, then the cached heavy weight popup window may be connected to the wrong screen. If the two screens use different scaling factors, then the popup location and size is scaled when the popup becomes visible, which shows the popup in the wrong location (or on wrong screen). The re-scaling is done in WWindowPeer.setBounds() (Java 9+).
To fix this, dispose popup windows that are on wrong screen and get new popup.
This is a workaround for https://bugs.openjdk.java.net/browse/JDK-8224608
- Throws:
IllegalArgumentException
-
getHeavyWeightPopup
private Popup getHeavyWeightPopup(Component owner, Component contents, int x, int y) throws IllegalArgumentException There is no API in Java 8 to force creation of heavy weight popups, but it is possible with reflection. Java 9 provides a new method. When changing FlatLaf system requirements to Java 9+, then this method can be replaced with: return getPopup( owner, contents, x, y, true );- Throws:
IllegalArgumentException
-
isOptionEnabled
-
getOption
-
reuseStillShownHeavyWeightPopups
private static FlatPopupFactory.NonFlashingPopup reuseStillShownHeavyWeightPopups(FlatPopupFactory.NonFlashingPopup reusePopup, Component contents, int ownerX, int ownerY) Reuse a heavy weight popup window, which is still shown on screen, by updating window location and contents. This avoid flicker when popup (e.g. a tooltip) is moving while mouse is moved. E.g. overridden JComponent.getToolTipLocation(MouseEvent). See ToolTipManager.checkForTipChange(MouseEvent). -
fixToolTipLocation
Usually ToolTipManager places a tooltip at (mouseLocation.x, mouseLocation.y + 20). In case that the tooltip would be partly outside of the screen, the ToolTipManager changes the location so that the entire tooltip fits on screen. But this can place the tooltip under the mouse location and hide the owner component.This method checks whether the current mouse location is within tooltip bounds and corrects the y-location so that the tooltip is placed above the mouse location.
-
wasInvokedFromToolTipManager
private boolean wasInvokedFromToolTipManager() -
hasTipLocation
Checks whether the owner component returns a tooltip location in JComponent.getToolTipLocation(MouseEvent). -
isWindows11BorderSupported
private static boolean isWindows11BorderSupported() -
isMacOSBorderSupported
private static boolean isMacOSBorderSupported() -
setupRoundedBorder
-
setupRoundedBorderImpl
-
resetWindows11Border
-
getBorderCornerRadius
-
getRoundedBorderWidth
-
overlapsHeavyWeightComponent
-
overlapsHeavyWeightComponent
-
fixLinuxWaylandJava21focusIssue
On Linux with Wayland, since Java 21, Swing adds a window focus listener to popup owner/invoker window, which hides the popup as soon as the owner/invoker window looses focus. This works fine for light-weight popups. It also works for heavy-weight popups if they do not request focus. Because FlatLaf always uses heavy-weight popups, all popups that request focus are broken since Java 21. This method removes the problematic window focus listener. https://bugs.openjdk.org/browse/JDK-8280993 https://github.com/openjdk/jdk/pull/13830 -
showPopupAndFixLocation
Shows the given popup and, if necessary, fixes the location of a heavy weight popup window.On a dual screen setup, where screens use different scale factors, it may happen that the window location changes when showing a heavy weight popup window. E.g. when opening a dialog on the secondary screen and making combobox popup visible.
This is a workaround for https://bugs.openjdk.java.net/browse/JDK-8224608
-