Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JLayeredPane overlaps the title bar with FlatLaf #658

Closed
Chrriis opened this issue Mar 28, 2023 · 6 comments
Closed

JLayeredPane overlaps the title bar with FlatLaf #658

Chrriis opened this issue Mar 28, 2023 · 6 comments
Milestone

Comments

@Chrriis
Copy link
Contributor

Chrriis commented Mar 28, 2023

We have some components in the layered pane which we can move around. I noticed that they could be dragged over the FlatLaf title bar. Worse, once they float over the title bar, they cannot be dragged again! 😉

Here is a test case to show what I mean:
LayeredPaneTest.zip

Note that this does not happen with Windows system look and feel. I think the root cause is that the layered pane overlaps the FlatLaf title bar. I wonder if other components (like glasspane, etc.) have a similar behavior.

@DevCharly
Copy link
Collaborator

The reason is that the FlatLaf window title bar and the menu bar are children of the layered pane.
So the layered pane must fill the whole root pane (or window).

This is normal/expected behavior when using FlatLaf window decorations on Windows 10/11 (or on Linux).

It is the same with Metal L&F when using JFrame.setDefaultLookAndFeelDecorated(true);:

image

Theoretically it would be possible to add the title bar to the root pane and make the layered pane smaller.
But the problem is that then it would be no longer possible to place the menu bar into/over the title bar because the menu bar is always a child of the layered pane. See source of JRootPane.setJMenuBar().

To fix the problem in your application, you could add another JLayeredPane to the content pane and put your movable components there.

I wonder if other components (like glasspane, etc.) have a similar behavior.

Glass pane:

@DevCharly DevCharly closed this as not planned Won't fix, can't repro, duplicate, stale Jul 1, 2023
@Chrriis
Copy link
Contributor Author

Chrriis commented Jul 1, 2023

I understand the technical reasons, I can live with the fact that we can hover over the title bar. But this is not the main issue! Once the component is over the title bar, it cannot be dragged out anymore because the title bar (which is under it) seems to capture the events!
Do try my test case, and let me know if the issue is not clear.

@DevCharly
Copy link
Collaborator

I can live with the fact that we can hover over the title bar ...

If you add another JLayeredPane to the content pane and put your movable components there, you don't have this "problem" 😉

... it cannot be dragged out anymore because the title bar (which is under it) seems to capture the events!

That's because dragging frame/dialog is done by Windows (and not Java). FlatLaf tells Windows that the mouse location is at a HTCAPTION and Windows handles all mouse events and frame/dialog dragging. Java does not receive mouse events for HTCAPTION.

It is possible to specify special areas (e.g. for menu bar and iconfify/maximize/close buttons) that Windows should ignore and pass mouse events to Java.

Following patch also added internal frame to those special areas:

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 93fe344c..a49a5835 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
@@ -57,6 +57,7 @@ import javax.swing.Icon;
 import javax.swing.JButton;
 import javax.swing.JComponent;
 import javax.swing.JDialog;
+import javax.swing.JInternalFrame;
 import javax.swing.JLabel;
 import javax.swing.JMenuBar;
 import javax.swing.JPanel;
@@ -952,6 +953,13 @@ public class FlatTitlePane
 			}
 		}
 
+		// allow internal frames in layered pane to be moved/resized when placed over title bar
+		for( Component c : rootPane.getLayeredPane().getComponents() ) {
+			r = (c instanceof JInternalFrame) ? getNativeHitTestSpot( (JInternalFrame) c ) : null;
+			if( r != null )
+				hitTestSpots.add( r );
+		}
+
 		Rectangle minimizeButtonBounds = boundsInWindow( iconifyButton );
 		Rectangle maximizeButtonBounds = boundsInWindow( maximizeButton.isVisible() ? maximizeButton : restoreButton );
 		Rectangle closeButtonBounds = boundsInWindow( closeButton );

The red rectangle show the special area. It is larger than the internal frame because it includes areas to resize the internal frame:

image

If this helps for your application, we can add this patch. But this works only if your application also uses internal frames...

@Chrriis
Copy link
Contributor Author

Chrriis commented Jul 9, 2023

But this works only if your application also uses internal frames
Yes, our application uses internal frames, this is why I found this bug.
I wonder if this logic should apply to any component that overlaps, but I understand sometimes some invisible components can be placed there too and should not prevent dragging...

@DevCharly
Copy link
Collaborator

Ok, then I'll apply the patch.

I wonder if this logic should apply to any component that overlaps, but I understand sometimes some invisible components can be placed there too and should not prevent dragging...

I've considered this, but I think it is too risky...

@DevCharly DevCharly reopened this Jul 9, 2023
DevCharly added a commit that referenced this issue Jul 9, 2023
…child of `JLayeredPane` and overlaps FlatLaf title bar (issue #658)
@DevCharly
Copy link
Collaborator

fixed in latest 3.2-SNAPSHOT: https://github.com/JFormDesigner/FlatLaf#snapshots

@DevCharly DevCharly added this to the 3.2 milestone Jul 9, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants