mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2026-02-11 06:27:13 -06:00
Drop shadows on Windows: support medium-weight popups (issue #94)
This commit is contained in:
@@ -21,13 +21,20 @@ import java.awt.Component;
|
|||||||
import java.awt.Container;
|
import java.awt.Container;
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.awt.Insets;
|
import java.awt.Insets;
|
||||||
|
import java.awt.Panel;
|
||||||
|
import java.awt.Point;
|
||||||
|
import java.awt.Rectangle;
|
||||||
import java.awt.Window;
|
import java.awt.Window;
|
||||||
|
import java.awt.event.ComponentEvent;
|
||||||
|
import java.awt.event.ComponentListener;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
|
import javax.swing.JLayeredPane;
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
import javax.swing.Popup;
|
import javax.swing.Popup;
|
||||||
import javax.swing.PopupFactory;
|
import javax.swing.PopupFactory;
|
||||||
|
import javax.swing.RootPaneContainer;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import javax.swing.border.Border;
|
import javax.swing.border.Border;
|
||||||
@@ -170,11 +177,18 @@ public class FlatPopupFactory
|
|||||||
private class DropShadowPopup
|
private class DropShadowPopup
|
||||||
extends NonFlashingPopup
|
extends NonFlashingPopup
|
||||||
{
|
{
|
||||||
|
private final Component owner;
|
||||||
|
|
||||||
// light weight
|
// light weight
|
||||||
private JComponent lightComp;
|
private JComponent lightComp;
|
||||||
private Border oldBorder;
|
private Border oldBorder;
|
||||||
private boolean oldOpaque;
|
private boolean oldOpaque;
|
||||||
|
|
||||||
|
// medium weight
|
||||||
|
private Panel mediumWeightPanel;
|
||||||
|
private JPanel dropShadowPanel;
|
||||||
|
private ComponentListener mediumPanelListener;
|
||||||
|
|
||||||
// heavy weight
|
// heavy weight
|
||||||
private Popup dropShadowDelegate;
|
private Popup dropShadowDelegate;
|
||||||
private Window dropShadowWindow;
|
private Window dropShadowWindow;
|
||||||
@@ -182,10 +196,7 @@ public class FlatPopupFactory
|
|||||||
|
|
||||||
DropShadowPopup( Popup delegate, Component owner, Component contents ) {
|
DropShadowPopup( Popup delegate, Component owner, Component contents ) {
|
||||||
super( delegate, contents );
|
super( delegate, contents );
|
||||||
|
this.owner = owner;
|
||||||
// drop shadows on medium weight popups are not supported
|
|
||||||
if( delegate.getClass().getName().endsWith( "MediumWeightPopup" ) )
|
|
||||||
return;
|
|
||||||
|
|
||||||
Dimension size = contents.getPreferredSize();
|
Dimension size = contents.getPreferredSize();
|
||||||
if( size.width <= 0 || size.height <= 0 )
|
if( size.width <= 0 || size.height <= 0 )
|
||||||
@@ -224,17 +235,26 @@ public class FlatPopupFactory
|
|||||||
dropShadowWindow.setBackground( new Color( 0, true ) );
|
dropShadowWindow.setBackground( new Color( 0, true ) );
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// light weight popup
|
mediumWeightPanel = (Panel) SwingUtilities.getAncestorOfClass( Panel.class, contents );
|
||||||
Container p = contents.getParent();
|
if( mediumWeightPanel != null ) {
|
||||||
if( !(p instanceof JComponent) )
|
// medium weight popup
|
||||||
return;
|
dropShadowPanel = new JPanel();
|
||||||
|
dropShadowPanel.setBorder( createDropShadowBorder() );
|
||||||
|
dropShadowPanel.setOpaque( false );
|
||||||
|
dropShadowPanel.setSize( FlatUIUtils.addInsets( mediumWeightPanel.getSize(), dropShadowPanel.getInsets() ) );
|
||||||
|
} else {
|
||||||
|
// light weight popup
|
||||||
|
Container p = contents.getParent();
|
||||||
|
if( !(p instanceof JComponent) )
|
||||||
|
return;
|
||||||
|
|
||||||
lightComp = (JComponent) p;
|
lightComp = (JComponent) p;
|
||||||
oldBorder = lightComp.getBorder();
|
oldBorder = lightComp.getBorder();
|
||||||
oldOpaque = lightComp.isOpaque();
|
oldOpaque = lightComp.isOpaque();
|
||||||
lightComp.setBorder( createDropShadowBorder() );
|
lightComp.setBorder( createDropShadowBorder() );
|
||||||
lightComp.setOpaque( false );
|
lightComp.setOpaque( false );
|
||||||
lightComp.setSize( lightComp.getPreferredSize() );
|
lightComp.setSize( lightComp.getPreferredSize() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -250,6 +270,9 @@ public class FlatPopupFactory
|
|||||||
if( dropShadowDelegate != null )
|
if( dropShadowDelegate != null )
|
||||||
dropShadowDelegate.show();
|
dropShadowDelegate.show();
|
||||||
|
|
||||||
|
if( mediumWeightPanel != null )
|
||||||
|
showMediumWeightDropShadow();
|
||||||
|
|
||||||
super.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
|
||||||
@@ -267,6 +290,12 @@ public class FlatPopupFactory
|
|||||||
dropShadowDelegate = null;
|
dropShadowDelegate = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( mediumWeightPanel != null ) {
|
||||||
|
hideMediumWeightDropShadow();
|
||||||
|
dropShadowPanel = null;
|
||||||
|
mediumWeightPanel = null;
|
||||||
|
}
|
||||||
|
|
||||||
super.hide();
|
super.hide();
|
||||||
|
|
||||||
if( dropShadowWindow != null ) {
|
if( dropShadowWindow != null ) {
|
||||||
@@ -280,5 +309,55 @@ public class FlatPopupFactory
|
|||||||
lightComp = null;
|
lightComp = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void showMediumWeightDropShadow() {
|
||||||
|
Window window = SwingUtilities.windowForComponent( owner );
|
||||||
|
if( window == null )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if( !(window instanceof RootPaneContainer) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
dropShadowPanel.setVisible( false );
|
||||||
|
|
||||||
|
JLayeredPane layeredPane = ((RootPaneContainer)window).getLayeredPane();
|
||||||
|
layeredPane.add( dropShadowPanel, JLayeredPane.POPUP_LAYER, 0 );
|
||||||
|
|
||||||
|
mediumPanelListener = new ComponentListener() {
|
||||||
|
@Override
|
||||||
|
public void componentShown( ComponentEvent e ) {
|
||||||
|
dropShadowPanel.setVisible( true );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void componentHidden( ComponentEvent e ) {
|
||||||
|
dropShadowPanel.setVisible( false );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void componentMoved( ComponentEvent e ) {
|
||||||
|
Point location = mediumWeightPanel.getLocation();
|
||||||
|
Insets insets = dropShadowPanel.getInsets();
|
||||||
|
dropShadowPanel.setLocation( location.x - insets.left, location.y - insets.top );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void componentResized( ComponentEvent e ) {
|
||||||
|
dropShadowPanel.setSize( FlatUIUtils.addInsets( mediumWeightPanel.getSize(), dropShadowPanel.getInsets() ) );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
mediumWeightPanel.addComponentListener( mediumPanelListener );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void hideMediumWeightDropShadow() {
|
||||||
|
mediumWeightPanel.removeComponentListener( mediumPanelListener );
|
||||||
|
|
||||||
|
Container parent = dropShadowPanel.getParent();
|
||||||
|
if( parent != null ) {
|
||||||
|
Rectangle bounds = dropShadowPanel.getBounds();
|
||||||
|
parent.remove( dropShadowPanel );
|
||||||
|
parent.repaint( bounds.x, bounds.y, bounds.width, bounds.height );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user