diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatRootPaneUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatRootPaneUI.java index 3362753b..8a331a5b 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatRootPaneUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatRootPaneUI.java @@ -20,9 +20,12 @@ import java.awt.Color; import java.awt.Component; import java.awt.Container; import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; import java.awt.Insets; import java.awt.LayoutManager; import java.awt.LayoutManager2; +import java.awt.Toolkit; import java.beans.PropertyChangeEvent; import java.util.function.Function; import javax.swing.JComponent; @@ -31,11 +34,14 @@ import javax.swing.JFrame; import javax.swing.JLayeredPane; import javax.swing.JMenuBar; import javax.swing.JRootPane; +import javax.swing.LookAndFeel; import javax.swing.UIManager; +import javax.swing.plaf.BorderUIResource; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.UIResource; import javax.swing.plaf.basic.BasicRootPaneUI; import com.formdev.flatlaf.FlatClientProperties; +import com.formdev.flatlaf.util.HiDPIUtils; import com.formdev.flatlaf.util.SystemInfo; /** @@ -93,6 +99,12 @@ public class FlatRootPaneUI } private void installClientDecorations() { + // install border + if( rootPane.getWindowDecorationStyle() != JRootPane.NONE ) + LookAndFeel.installBorder( rootPane, "RootPane.border" ); + else + LookAndFeel.uninstallBorder( rootPane ); + // install title pane setTitlePane( new FlatTitlePane( rootPane ) ); @@ -102,6 +114,7 @@ public class FlatRootPaneUI } private void uninstallClientDecorations() { + LookAndFeel.uninstallBorder( rootPane ); setTitlePane( null ); if( oldLayout != null ) { @@ -258,4 +271,30 @@ public class FlatRootPaneUI return 0; } } + + //---- class FlatWindowBorder --------------------------------------------- + + public static class FlatWindowBorder + extends BorderUIResource.EmptyBorderUIResource + { + public FlatWindowBorder() { + super( 1, 1, 1, 1 ); + } + + @Override + public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) { + Object borderColorObj = Toolkit.getDefaultToolkit().getDesktopProperty( + "win.frame.activeBorderColor" ); + Color borderColor = (borderColorObj instanceof Color) + ? (Color) borderColorObj + : UIManager.getColor( "windowBorder" ); + + g.setColor( borderColor ); + HiDPIUtils.paintAtScale1x( (Graphics2D) g, x, y, width, height, this::paintImpl ); + } + + private void paintImpl( Graphics2D g, int x, int y, int width, int height, double scaleFactor ) { + g.drawRect( x, y, width - 1, height - 1 ); + } + } } 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 ecac58bd..fdf45e2d 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 @@ -317,8 +317,10 @@ class FlatTitlePane } Rectangle getMenuBarBounds() { - Rectangle bounds = menuBarPlaceholder.getBounds(); - bounds = SwingUtilities.convertRectangle( menuBarPlaceholder.getParent(), bounds, rootPane ); + Insets insets = rootPane.getInsets(); + Rectangle bounds = new Rectangle( + SwingUtilities.convertPoint( menuBarPlaceholder, -insets.left, -insets.top, rootPane ), + menuBarPlaceholder.getSize() ); // add menu bar bottom border insets to bounds so that menu bar overlaps // title pane border (menu bar border is painted over title pane border) diff --git a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties index bb199a39..9d43cd19 100644 --- a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties +++ b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties @@ -423,6 +423,11 @@ RadioButtonMenuItem.borderPainted=true RadioButtonMenuItem.background=@menuBackground +#---- RootPane ---- + +RootPane.border=com.formdev.flatlaf.ui.FlatRootPaneUI$FlatWindowBorder + + #---- ScrollBar ---- ScrollBar.width=10 diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatInspector.java b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatInspector.java index 58a88d4c..8b38a164 100644 --- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatInspector.java +++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatInspector.java @@ -284,8 +284,9 @@ public class FlatInspector highlightFigure.setVisible( c != null ); if( c != null ) { + Insets insets = rootPane.getInsets(); highlightFigure.setBounds( new Rectangle( - SwingUtilities.convertPoint( c, 0, 0, rootPane ), + SwingUtilities.convertPoint( c, -insets.left, -insets.top, rootPane ), c.getSize() ) ); } } diff --git a/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/uidefaults/FlatDarkLaf_1.8.0_202.txt b/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/uidefaults/FlatDarkLaf_1.8.0_202.txt index 957de7b7..0513ce0c 100644 --- a/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/uidefaults/FlatDarkLaf_1.8.0_202.txt +++ b/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/uidefaults/FlatDarkLaf_1.8.0_202.txt @@ -743,6 +743,7 @@ Resizable.resizeBorder [lazy] 4,4,4,4 false com.formdev.flatlaf.ui.F #---- RootPane ---- +RootPane.border [lazy] 1,1,1,1 false com.formdev.flatlaf.ui.FlatRootPaneUI$FlatWindowBorder [UI] RootPane.defaultButtonWindowKeyBindings length=8 [Ljava.lang.Object; [0] ENTER [1] press diff --git a/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/uidefaults/FlatLightLaf_1.8.0_202.txt b/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/uidefaults/FlatLightLaf_1.8.0_202.txt index 8861a633..5f4b56d5 100644 --- a/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/uidefaults/FlatLightLaf_1.8.0_202.txt +++ b/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/uidefaults/FlatLightLaf_1.8.0_202.txt @@ -745,6 +745,7 @@ Resizable.resizeBorder [lazy] 4,4,4,4 false com.formdev.flatlaf.ui.F #---- RootPane ---- +RootPane.border [lazy] 1,1,1,1 false com.formdev.flatlaf.ui.FlatRootPaneUI$FlatWindowBorder [UI] RootPane.defaultButtonWindowKeyBindings length=8 [Ljava.lang.Object; [0] ENTER [1] press