mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2025-12-06 22:10:54 +03:00
Popup: on Windows 10, update drop shadow of heavy-weight popup if popup moved/resized (issue #942)
Some checks failed
CI / build (11) (push) Has been cancelled
CI / build-on (17, ) (push) Has been cancelled
CI / build-on (21, ) (push) Has been cancelled
CI / build-on (23, ) (push) Has been cancelled
CI / build-on (8, ) (push) Has been cancelled
CI / snapshot (push) Has been cancelled
CI / release (push) Has been cancelled
Some checks failed
CI / build (11) (push) Has been cancelled
CI / build-on (17, ) (push) Has been cancelled
CI / build-on (21, ) (push) Has been cancelled
CI / build-on (23, ) (push) Has been cancelled
CI / build-on (8, ) (push) Has been cancelled
CI / snapshot (push) Has been cancelled
CI / release (push) Has been cancelled
This commit is contained in:
@@ -25,6 +25,8 @@ FlatLaf Change Log
|
|||||||
- FileChooser: Improved performance when navigating to large directories with
|
- FileChooser: Improved performance when navigating to large directories with
|
||||||
thousands of files. (issue #953)
|
thousands of files. (issue #953)
|
||||||
- PopupFactory: Fixed NPE on Windows 10 when `owner` is `null`. (issue #952)
|
- PopupFactory: Fixed NPE on Windows 10 when `owner` is `null`. (issue #952)
|
||||||
|
- Popup: On Windows 10, drop shadow of heavy-weight popup was not updated if
|
||||||
|
popup moved/resized. (issue #942)
|
||||||
- FlatLaf window decorations: Minimize and maximize icons were not shown for
|
- FlatLaf window decorations: Minimize and maximize icons were not shown for
|
||||||
custom scale factors less than 100% (e.g. `-Dflatlaf.uiScale=75%`). (issue
|
custom scale factors less than 100% (e.g. `-Dflatlaf.uiScale=75%`). (issue
|
||||||
#951)
|
#951)
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ public class FlatDropShadowBorder
|
|||||||
|
|
||||||
this.shadowColor = shadowColor;
|
this.shadowColor = shadowColor;
|
||||||
this.shadowInsets = shadowInsets;
|
this.shadowInsets = shadowInsets;
|
||||||
this.shadowOpacity = shadowOpacity;
|
this.shadowOpacity = Math.min( Math.max( shadowOpacity, 0f ), 1f );
|
||||||
|
|
||||||
shadowSize = maxInset( shadowInsets );
|
shadowSize = maxInset( shadowInsets );
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -709,6 +709,7 @@ public class FlatPopupFactory
|
|||||||
|
|
||||||
private class DropShadowPopup
|
private class DropShadowPopup
|
||||||
extends NonFlashingPopup
|
extends NonFlashingPopup
|
||||||
|
implements ComponentListener
|
||||||
{
|
{
|
||||||
// light weight
|
// light weight
|
||||||
private JComponent lightComp;
|
private JComponent lightComp;
|
||||||
@@ -768,7 +769,7 @@ public class FlatPopupFactory
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Windows 11: reset corner preference on reused heavy weight popups
|
// Windows 11: reset corner preference on reused heavy weight popups
|
||||||
if( isWindows11BorderSupported() ) {
|
if( SystemInfo.isWindows_11_orLater && FlatNativeWindowsLibrary.isLoaded() ) {
|
||||||
resetWindows11Border( popupWindow );
|
resetWindows11Border( popupWindow );
|
||||||
if( dropShadowWindow != null )
|
if( dropShadowWindow != null )
|
||||||
resetWindows11Border( dropShadowWindow );
|
resetWindows11Border( dropShadowWindow );
|
||||||
@@ -838,10 +839,18 @@ public class FlatPopupFactory
|
|||||||
if( insets.left != 0 || insets.top != 0 )
|
if( insets.left != 0 || insets.top != 0 )
|
||||||
lightComp.setLocation( lightComp.getX() - insets.left, lightComp.getY() - insets.top );
|
lightComp.setLocation( lightComp.getX() - insets.left, lightComp.getY() - insets.top );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( popupWindow != null ) {
|
||||||
|
removeAllPopupWindowComponentListeners();
|
||||||
|
popupWindow.addComponentListener( this );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void hideImpl() {
|
void hideImpl() {
|
||||||
|
if( popupWindow != null )
|
||||||
|
removeAllPopupWindowComponentListeners();
|
||||||
|
|
||||||
if( dropShadowDelegate != null ) {
|
if( dropShadowDelegate != null ) {
|
||||||
dropShadowDelegate.hide();
|
dropShadowDelegate.hide();
|
||||||
dropShadowDelegate = null;
|
dropShadowDelegate = null;
|
||||||
@@ -941,23 +950,55 @@ public class FlatPopupFactory
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
void reset( Component contents, int ownerX, int ownerY ) {
|
void reset( Component contents, int ownerX, int ownerY ) {
|
||||||
|
if( popupWindow != null )
|
||||||
|
removeAllPopupWindowComponentListeners();
|
||||||
|
|
||||||
super.reset( contents, ownerX, ownerY );
|
super.reset( contents, ownerX, ownerY );
|
||||||
|
|
||||||
if( dropShadowWindow != null ) {
|
updateDropShadowWindowBounds();
|
||||||
// set preferred size of drop shadow panel
|
}
|
||||||
Dimension prefSize = popupWindow.getPreferredSize();
|
|
||||||
Insets insets = dropShadowPanel2.getInsets();
|
|
||||||
int w = prefSize.width + insets.left + insets.right;
|
|
||||||
int h = prefSize.height + insets.top + insets.bottom;
|
|
||||||
dropShadowPanel2.setPreferredSize( new Dimension( w, h ) );
|
|
||||||
dropShadowPanel2.invalidate();
|
|
||||||
dropShadowWindow.pack();
|
|
||||||
|
|
||||||
// update drop shadow popup window location
|
private void updateDropShadowWindowBounds() {
|
||||||
int x = popupWindow.getX() - insets.left;
|
if( dropShadowWindow == null )
|
||||||
int y = popupWindow.getY() - insets.top;
|
return;
|
||||||
dropShadowWindow.setLocation( x, y );
|
|
||||||
|
// calculate size of drop shadow window
|
||||||
|
Dimension size = popupWindow.getSize();
|
||||||
|
Insets insets = dropShadowPanel2.getInsets();
|
||||||
|
int w = size.width + insets.left + insets.right;
|
||||||
|
int h = size.height + insets.top + insets.bottom;
|
||||||
|
|
||||||
|
// update drop shadow popup window bounds
|
||||||
|
int x = popupWindow.getX() - insets.left;
|
||||||
|
int y = popupWindow.getY() - insets.top;
|
||||||
|
dropShadowWindow.setBounds( x, y, w, h );
|
||||||
|
dropShadowWindow.validate();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeAllPopupWindowComponentListeners() {
|
||||||
|
// make sure that there is no old component listener
|
||||||
|
// necessary because this class is cloned if reusing popup windows
|
||||||
|
for( ComponentListener l : popupWindow.getComponentListeners() ) {
|
||||||
|
if( l instanceof DropShadowPopup )
|
||||||
|
popupWindow.removeComponentListener( l );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---- interface ComponentListener ----
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void componentResized( ComponentEvent e ) {
|
||||||
|
if( e.getSource() == popupWindow )
|
||||||
|
updateDropShadowWindowBounds();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void componentMoved( ComponentEvent e ) {
|
||||||
|
if( e.getSource() == popupWindow )
|
||||||
|
updateDropShadowWindowBounds();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public void componentShown( ComponentEvent e ) {}
|
||||||
|
@Override public void componentHidden( ComponentEvent e ) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,10 @@ import java.awt.event.MouseEvent;
|
|||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import javax.swing.border.*;
|
import javax.swing.border.*;
|
||||||
|
import javax.swing.event.PopupMenuEvent;
|
||||||
|
import javax.swing.event.PopupMenuListener;
|
||||||
|
import com.formdev.flatlaf.FlatClientProperties;
|
||||||
|
import com.formdev.flatlaf.FlatSystemProperties;
|
||||||
import com.formdev.flatlaf.util.Animator;
|
import com.formdev.flatlaf.util.Animator;
|
||||||
import com.formdev.flatlaf.util.UIScale;
|
import com.formdev.flatlaf.util.UIScale;
|
||||||
import net.miginfocom.swing.*;
|
import net.miginfocom.swing.*;
|
||||||
@@ -43,6 +47,8 @@ public class FlatPopupTest
|
|||||||
|
|
||||||
FlatPopupTest() {
|
FlatPopupTest() {
|
||||||
initComponents();
|
initComponents();
|
||||||
|
addPopupMenuListener( popupMenu1, "popupMenu1" );
|
||||||
|
addPopupMenuListener( popupMenu2, "popupMenu2" );
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showPopupMenu() {
|
private void showPopupMenu() {
|
||||||
@@ -114,6 +120,46 @@ public class FlatPopupTest
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void showDirectPopup() {
|
||||||
|
DirectPopupContent content = new DirectPopupContent();
|
||||||
|
content.putClientProperty( FlatClientProperties.POPUP_FORCE_HEAVY_WEIGHT, true );
|
||||||
|
Point pt = showDirectPopupButton.getLocationOnScreen();
|
||||||
|
|
||||||
|
System.setProperty( FlatSystemProperties.USE_ROUNDED_POPUP_BORDER, "false" );
|
||||||
|
UIManager.put( "Popup.dropShadowColor", Color.red );
|
||||||
|
UIManager.put( "Popup.dropShadowInsets", new Insets( 5, 5, 5, 5 ) );
|
||||||
|
UIManager.put( "Popup.dropShadowOpacity", 1f );
|
||||||
|
|
||||||
|
Popup popup = PopupFactory.getSharedInstance().getPopup( showDirectPopupButton,
|
||||||
|
content, pt.x, pt.y + showDirectPopupButton.getHeight() + 10 );
|
||||||
|
content.popup = popup;
|
||||||
|
popup.show();
|
||||||
|
|
||||||
|
System.clearProperty( FlatSystemProperties.USE_ROUNDED_POPUP_BORDER );
|
||||||
|
UIManager.put( "Popup.dropShadowColor", null );
|
||||||
|
UIManager.put( "Popup.dropShadowInsets", null );
|
||||||
|
UIManager.put( "Popup.dropShadowOpacity", null );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addPopupMenuListener( JPopupMenu popupMenu, String name ) {
|
||||||
|
popupMenu.addPopupMenuListener( new PopupMenuListener() {
|
||||||
|
@Override
|
||||||
|
public void popupMenuWillBecomeVisible( PopupMenuEvent e ) {
|
||||||
|
System.out.println( "popupMenuWillBecomeVisible " + name );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void popupMenuWillBecomeInvisible( PopupMenuEvent e ) {
|
||||||
|
System.out.println( "popupMenuWillBecomeInvisible " + name );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void popupMenuCanceled( PopupMenuEvent e ) {
|
||||||
|
System.out.println( "popupMenuCanceled " + name );
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateUI() {
|
public void updateUI() {
|
||||||
super.updateUI();
|
super.updateUI();
|
||||||
@@ -128,15 +174,12 @@ public class FlatPopupTest
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void countChanged() {
|
|
||||||
// TODO add your code here
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initComponents() {
|
private void initComponents() {
|
||||||
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
|
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
|
||||||
label1 = new JLabel();
|
label1 = new JLabel();
|
||||||
label2 = new JLabel();
|
label2 = new JLabel();
|
||||||
showPopupMenuButton = new JButton();
|
showPopupMenuButton = new JButton();
|
||||||
|
showDirectPopupButton = new JButton();
|
||||||
showLargePopupMenuButton = new JButton();
|
showLargePopupMenuButton = new JButton();
|
||||||
showPopupButton = new JButton();
|
showPopupButton = new JButton();
|
||||||
hidePopupButton = new JButton();
|
hidePopupButton = new JButton();
|
||||||
@@ -209,6 +252,11 @@ public class FlatPopupTest
|
|||||||
showPopupMenuButton.addActionListener(e -> showPopupMenu());
|
showPopupMenuButton.addActionListener(e -> showPopupMenu());
|
||||||
add(showPopupMenuButton, "cell 0 2");
|
add(showPopupMenuButton, "cell 0 2");
|
||||||
|
|
||||||
|
//---- showDirectPopupButton ----
|
||||||
|
showDirectPopupButton.setText("show direct move/resize popup");
|
||||||
|
showDirectPopupButton.addActionListener(e -> showDirectPopup());
|
||||||
|
add(showDirectPopupButton, "cell 2 2 2 1");
|
||||||
|
|
||||||
//---- showLargePopupMenuButton ----
|
//---- showLargePopupMenuButton ----
|
||||||
showLargePopupMenuButton.setText("show heavy-weight JPopupMenu");
|
showLargePopupMenuButton.setText("show heavy-weight JPopupMenu");
|
||||||
showLargePopupMenuButton.addActionListener(e -> showLargePopupMenu());
|
showLargePopupMenuButton.addActionListener(e -> showLargePopupMenu());
|
||||||
@@ -240,7 +288,6 @@ public class FlatPopupTest
|
|||||||
|
|
||||||
//---- countField ----
|
//---- countField ----
|
||||||
countField.setModel(new SpinnerNumberModel(1, 1, null, 1));
|
countField.setModel(new SpinnerNumberModel(1, 1, null, 1));
|
||||||
countField.addChangeListener(e -> countChanged());
|
|
||||||
add(countField, "cell 5 4");
|
add(countField, "cell 5 4");
|
||||||
|
|
||||||
//---- label4 ----
|
//---- label4 ----
|
||||||
@@ -366,6 +413,7 @@ public class FlatPopupTest
|
|||||||
private JLabel label1;
|
private JLabel label1;
|
||||||
private JLabel label2;
|
private JLabel label2;
|
||||||
private JButton showPopupMenuButton;
|
private JButton showPopupMenuButton;
|
||||||
|
private JButton showDirectPopupButton;
|
||||||
private JButton showLargePopupMenuButton;
|
private JButton showLargePopupMenuButton;
|
||||||
private JButton showPopupButton;
|
private JButton showPopupButton;
|
||||||
private JButton hidePopupButton;
|
private JButton hidePopupButton;
|
||||||
@@ -444,4 +492,69 @@ public class FlatPopupTest
|
|||||||
private JLabel label6;
|
private JLabel label6;
|
||||||
// JFormDesigner - End of variables declaration //GEN-END:variables @formatter:on
|
// JFormDesigner - End of variables declaration //GEN-END:variables @formatter:on
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---- class MyPopupContent -----------------------------------------------
|
||||||
|
|
||||||
|
private static class DirectPopupContent
|
||||||
|
extends JPanel
|
||||||
|
{
|
||||||
|
Popup popup;
|
||||||
|
|
||||||
|
DirectPopupContent() {
|
||||||
|
initComponents();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void resizePopup() {
|
||||||
|
Window popupWindow = SwingUtilities.windowForComponent( this );
|
||||||
|
popupWindow.setSize( popupWindow.getWidth() + 20, popupWindow.getHeight() + 50 );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void movePopup() {
|
||||||
|
Window popupWindow = SwingUtilities.windowForComponent( this );
|
||||||
|
popupWindow.setLocation( popupWindow.getX() + 20, popupWindow.getY() + 50 );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void hidePopup() {
|
||||||
|
popup.hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initComponents() {
|
||||||
|
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents @formatter:off
|
||||||
|
resizeButton = new JButton();
|
||||||
|
moveButton = new JButton();
|
||||||
|
hideButton = new JButton();
|
||||||
|
|
||||||
|
//======== this ========
|
||||||
|
setLayout(new MigLayout(
|
||||||
|
"hidemode 3",
|
||||||
|
// columns
|
||||||
|
"[fill]" +
|
||||||
|
"[fill]" +
|
||||||
|
"[fill]",
|
||||||
|
// rows
|
||||||
|
"[]"));
|
||||||
|
|
||||||
|
//---- resizeButton ----
|
||||||
|
resizeButton.setText("Resize");
|
||||||
|
resizeButton.addActionListener(e -> resizePopup());
|
||||||
|
add(resizeButton, "cell 0 0");
|
||||||
|
|
||||||
|
//---- moveButton ----
|
||||||
|
moveButton.setText("Move");
|
||||||
|
moveButton.addActionListener(e -> movePopup());
|
||||||
|
add(moveButton, "cell 1 0");
|
||||||
|
|
||||||
|
//---- hideButton ----
|
||||||
|
hideButton.setText("Hide");
|
||||||
|
hideButton.addActionListener(e -> hidePopup());
|
||||||
|
add(hideButton, "cell 2 0");
|
||||||
|
// JFormDesigner - End of component initialization //GEN-END:initComponents @formatter:on
|
||||||
|
}
|
||||||
|
|
||||||
|
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables @formatter:off
|
||||||
|
private JButton resizeButton;
|
||||||
|
private JButton moveButton;
|
||||||
|
private JButton hideButton;
|
||||||
|
// JFormDesigner - End of variables declaration //GEN-END:variables @formatter:on
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
JFDML JFormDesigner: "8.2.3.0.386" Java: "21" encoding: "UTF-8"
|
JFDML JFormDesigner: "8.3" encoding: "UTF-8"
|
||||||
|
|
||||||
new FormModel {
|
new FormModel {
|
||||||
contentType: "form/swing"
|
contentType: "form/swing"
|
||||||
@@ -30,6 +30,13 @@ new FormModel {
|
|||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
"value": "cell 0 2"
|
"value": "cell 0 2"
|
||||||
} )
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JButton" ) {
|
||||||
|
name: "showDirectPopupButton"
|
||||||
|
"text": "show direct move/resize popup"
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "showDirectPopup", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 2 2 2 1"
|
||||||
|
} )
|
||||||
add( new FormComponent( "javax.swing.JButton" ) {
|
add( new FormComponent( "javax.swing.JButton" ) {
|
||||||
name: "showLargePopupMenuButton"
|
name: "showLargePopupMenuButton"
|
||||||
"text": "show heavy-weight JPopupMenu"
|
"text": "show heavy-weight JPopupMenu"
|
||||||
@@ -77,7 +84,6 @@ new FormModel {
|
|||||||
minimum: 1
|
minimum: 1
|
||||||
value: 1
|
value: 1
|
||||||
}
|
}
|
||||||
addEvent( new FormEvent( "javax.swing.event.ChangeListener", "stateChanged", "countChanged", false ) )
|
|
||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
"value": "cell 5 4"
|
"value": "cell 5 4"
|
||||||
} )
|
} )
|
||||||
@@ -215,5 +221,39 @@ new FormModel {
|
|||||||
}, new FormLayoutConstraints( null ) {
|
}, new FormLayoutConstraints( null ) {
|
||||||
"location": new java.awt.Point( 5, 505 )
|
"location": new java.awt.Point( 5, 505 )
|
||||||
} )
|
} )
|
||||||
|
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
|
||||||
|
"$layoutConstraints": "hidemode 3"
|
||||||
|
"$columnConstraints": "[fill][fill][fill]"
|
||||||
|
"$rowConstraints": "[]"
|
||||||
|
} ) {
|
||||||
|
name: "panel1"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.className": "DirectPopupContent"
|
||||||
|
}
|
||||||
|
add( new FormComponent( "javax.swing.JButton" ) {
|
||||||
|
name: "resizeButton"
|
||||||
|
"text": "Resize"
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "resizePopup", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 0"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JButton" ) {
|
||||||
|
name: "moveButton"
|
||||||
|
"text": "Move"
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "movePopup", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 0"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JButton" ) {
|
||||||
|
name: "hideButton"
|
||||||
|
"text": "Hide"
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "hidePopup", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 2 0"
|
||||||
|
} )
|
||||||
|
}, new FormLayoutConstraints( null ) {
|
||||||
|
"location": new java.awt.Point( 180, 395 )
|
||||||
|
"size": new java.awt.Dimension( 270, 100 )
|
||||||
|
} )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user