mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2025-12-06 22:10:54 +03:00
Popup: fixed background flashing effect when drop shadows are disabled (issue #94)
This commit is contained in:
@@ -35,8 +35,8 @@ import com.formdev.flatlaf.FlatClientProperties;
|
|||||||
import com.formdev.flatlaf.util.SystemInfo;
|
import com.formdev.flatlaf.util.SystemInfo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A popup factory that adds drop shadows to popups on Windows and Linux.
|
* A popup factory that adds drop shadows to popups on Windows.
|
||||||
* On macOS, heavy weight popups (without drop shadow) are produced and the
|
* On macOS and Linux, heavy weight popups (without drop shadow) are produced and the
|
||||||
* operating system automatically adds drop shadows.
|
* operating system automatically adds drop shadows.
|
||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
@@ -52,23 +52,18 @@ public class FlatPopupFactory
|
|||||||
throws IllegalArgumentException
|
throws IllegalArgumentException
|
||||||
{
|
{
|
||||||
if( !isDropShadowPainted( owner, contents ) )
|
if( !isDropShadowPainted( owner, contents ) )
|
||||||
return super.getPopup( owner, contents, x, y );
|
return new NonFlashingPopup( super.getPopup( owner, contents, x, y ), contents );
|
||||||
|
|
||||||
// macOS and Linux adds drop shadow to heavy weight popups
|
// macOS and Linux adds drop shadow to heavy weight popups
|
||||||
if( SystemInfo.IS_MAC || SystemInfo.IS_LINUX ) {
|
if( SystemInfo.IS_MAC || SystemInfo.IS_LINUX ) {
|
||||||
Popup popup = getHeavyWeightPopup( owner, contents, x, y );
|
Popup popup = getHeavyWeightPopup( owner, contents, x, y );
|
||||||
if ( popup != null ) {
|
if( popup == null )
|
||||||
// fix background flashing
|
popup = super.getPopup( owner, contents, x, y );
|
||||||
SwingUtilities.windowForComponent( contents ).setBackground( contents.getBackground() );
|
return new NonFlashingPopup( popup, contents );
|
||||||
}
|
|
||||||
return (popup != null) ? popup : super.getPopup( owner, contents, x, y );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// create popup
|
|
||||||
Popup popup = super.getPopup( owner, contents, x, y );
|
|
||||||
|
|
||||||
// create drop shadow popup
|
// create drop shadow popup
|
||||||
return new DropShadowPopup( popup, owner, contents );
|
return new DropShadowPopup( super.getPopup( owner, contents, x, y ), owner, contents );
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isDropShadowPainted( Component owner, Component contents ) {
|
private boolean isDropShadowPainted( Component owner, Component contents ) {
|
||||||
@@ -124,26 +119,69 @@ public class FlatPopupFactory
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//---- class DropShadowPopup ----------------------------------------------
|
//---- class NonFlashingPopup ---------------------------------------------
|
||||||
|
|
||||||
private class DropShadowPopup
|
private class NonFlashingPopup
|
||||||
extends Popup
|
extends Popup
|
||||||
{
|
{
|
||||||
private Popup delegate;
|
private Popup delegate;
|
||||||
|
|
||||||
|
// heavy weight
|
||||||
|
protected Window popupWindow;
|
||||||
|
private Color oldPopupWindowBackground;
|
||||||
|
|
||||||
|
NonFlashingPopup( Popup delegate, Component contents ) {
|
||||||
|
this.delegate = delegate;
|
||||||
|
|
||||||
|
popupWindow = SwingUtilities.windowForComponent( contents );
|
||||||
|
if( popupWindow != null ) {
|
||||||
|
// heavy weight popup
|
||||||
|
|
||||||
|
// fix background flashing which may occur on some platforms
|
||||||
|
// (e.g. macOS and Linux) when using dark theme
|
||||||
|
oldPopupWindowBackground = popupWindow.getBackground();
|
||||||
|
popupWindow.setBackground( contents.getBackground() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void show() {
|
||||||
|
delegate.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void hide() {
|
||||||
|
if( delegate != null ) {
|
||||||
|
delegate.hide();
|
||||||
|
delegate = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( popupWindow != null ) {
|
||||||
|
// restore background so that it can not affect other LaFs (when switching)
|
||||||
|
// because popup windows are cached and reused
|
||||||
|
popupWindow.setBackground( oldPopupWindowBackground );
|
||||||
|
popupWindow = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//---- class DropShadowPopup ----------------------------------------------
|
||||||
|
|
||||||
|
private class DropShadowPopup
|
||||||
|
extends NonFlashingPopup
|
||||||
|
{
|
||||||
// light weight
|
// light weight
|
||||||
private JComponent lightComp;
|
private JComponent lightComp;
|
||||||
private Border oldBorder;
|
private Border oldBorder;
|
||||||
private boolean oldOpaque;
|
private boolean oldOpaque;
|
||||||
|
|
||||||
// heavy weight
|
// heavy weight
|
||||||
private Window popupWindow;
|
|
||||||
private Popup dropShadowDelegate;
|
private Popup dropShadowDelegate;
|
||||||
private Window dropShadowWindow;
|
private Window dropShadowWindow;
|
||||||
private Color oldBackground;
|
private Color oldDropShadowWindowBackground;
|
||||||
|
|
||||||
DropShadowPopup( Popup delegate, Component owner, Component contents ) {
|
DropShadowPopup( Popup delegate, Component owner, Component contents ) {
|
||||||
this.delegate = delegate;
|
super( delegate, contents );
|
||||||
|
|
||||||
// drop shadows on medium weight popups are not supported
|
// drop shadows on medium weight popups are not supported
|
||||||
if( delegate.getClass().getName().endsWith( "MediumWeightPopup" ) )
|
if( delegate.getClass().getName().endsWith( "MediumWeightPopup" ) )
|
||||||
@@ -153,7 +191,6 @@ public class FlatPopupFactory
|
|||||||
if( size.width <= 0 || size.height <= 0 )
|
if( size.width <= 0 || size.height <= 0 )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
popupWindow = SwingUtilities.windowForComponent( contents );
|
|
||||||
if( popupWindow != null ) {
|
if( popupWindow != null ) {
|
||||||
// heavy weight popup
|
// heavy weight popup
|
||||||
|
|
||||||
@@ -175,15 +212,15 @@ public class FlatPopupFactory
|
|||||||
prefSize.width + insets.left + insets.right,
|
prefSize.width + insets.left + insets.right,
|
||||||
prefSize.height + insets.top + insets.bottom ) );
|
prefSize.height + insets.top + insets.bottom ) );
|
||||||
|
|
||||||
// create popup for drop shadow
|
// create heavy weight popup for drop shadow
|
||||||
int x = popupWindow.getX() - insets.left;
|
int x = popupWindow.getX() - insets.left;
|
||||||
int y = popupWindow.getY() - insets.top;
|
int y = popupWindow.getY() - insets.top;
|
||||||
dropShadowDelegate = getHeavyWeightPopup( owner, dropShadowPanel, x, y );
|
dropShadowDelegate = getHeavyWeightPopup( owner, dropShadowPanel, x, y );
|
||||||
|
|
||||||
// make drop shadow popup translucent
|
// make drop shadow popup window translucent
|
||||||
dropShadowWindow = SwingUtilities.windowForComponent( dropShadowPanel );
|
dropShadowWindow = SwingUtilities.windowForComponent( dropShadowPanel );
|
||||||
if( dropShadowWindow != null ) {
|
if( dropShadowWindow != null ) {
|
||||||
oldBackground = dropShadowWindow.getBackground();
|
oldDropShadowWindowBackground = dropShadowWindow.getBackground();
|
||||||
dropShadowWindow.setBackground( new Color( 0, true ) );
|
dropShadowWindow.setBackground( new Color( 0, true ) );
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -213,7 +250,7 @@ public class FlatPopupFactory
|
|||||||
if( dropShadowDelegate != null )
|
if( dropShadowDelegate != null )
|
||||||
dropShadowDelegate.show();
|
dropShadowDelegate.show();
|
||||||
|
|
||||||
delegate.show();
|
super.show();
|
||||||
|
|
||||||
// fix location of light weight popup in case it has left or top drop shadow
|
// fix location of light weight popup in case it has left or top drop shadow
|
||||||
if( lightComp != null ) {
|
if( lightComp != null ) {
|
||||||
@@ -230,13 +267,10 @@ public class FlatPopupFactory
|
|||||||
dropShadowDelegate = null;
|
dropShadowDelegate = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( delegate != null ) {
|
super.hide();
|
||||||
delegate.hide();
|
|
||||||
delegate = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( dropShadowWindow != null ) {
|
if( dropShadowWindow != null ) {
|
||||||
dropShadowWindow.setBackground( oldBackground );
|
dropShadowWindow.setBackground( oldDropShadowWindowBackground );
|
||||||
dropShadowWindow = null;
|
dropShadowWindow = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user