diff --git a/CHANGELOG.md b/CHANGELOG.md index fec8d763..01386b3d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,12 @@ FlatLaf Change Log ## 1.2-SNAPSHOT +#### New features and improvements + +- Native window decorations: Support disabling native window decorations per + window. (set client property `JRootPane.useWindowDecorations` to `false` on + root pane). + #### Fixed bugs - Native window decorations: Fixed double window title bar when first disposing diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java index 9e198fda..6a82e2ac 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java @@ -231,10 +231,28 @@ public interface FlatClientProperties //---- JRootPane ---------------------------------------------------------- + /** + * Specifies whether FlatLaf native window decorations should be used + * when creating {@code JFrame} or {@code JDialog}. + *
+ * Setting this to {@code false} disables using FlatLaf native window decorations + * for the window that contains the root pane. Needs to be set before showing the window. + *
+ * (requires Window 10) + *
+ * Component {@link javax.swing.JRootPane}
+ * Value type {@link java.lang.Boolean}
+ *
+ * @since 1.1.1
+ */
+ String USE_WINDOW_DECORATIONS = "JRootPane.useWindowDecorations";
+
/**
* Specifies whether the menu bar is embedded into the title pane if custom
* window decorations are enabled. Default is {@code true}.
*
+ * (requires Window 10) + *
* Component {@link javax.swing.JRootPane}
* Value type {@link java.lang.Boolean}
*/
diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatNativeWindowBorder.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatNativeWindowBorder.java
index 4a720492..1c21a5de 100644
--- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatNativeWindowBorder.java
+++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatNativeWindowBorder.java
@@ -27,6 +27,7 @@ import javax.swing.JRootPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.event.ChangeListener;
+import com.formdev.flatlaf.FlatClientProperties;
import com.formdev.flatlaf.FlatLaf;
import com.formdev.flatlaf.FlatSystemProperties;
import com.formdev.flatlaf.ui.JBRCustomDecorations.JBRWindowTopBorder;
@@ -99,6 +100,10 @@ public class FlatNativeWindowBorder
if( window instanceof JFrame ) {
JFrame frame = (JFrame) window;
+ // check whether disabled via client property
+ if( !FlatClientProperties.clientPropertyBoolean( frame.getRootPane(), FlatClientProperties.USE_WINDOW_DECORATIONS, true ) )
+ return;
+
// do not enable native window border if JFrame should use system window decorations
// and if not forced to use FlatLaf/JBR native window decorations
if( !JFrame.isDefaultLookAndFeelDecorated() &&
@@ -119,6 +124,10 @@ public class FlatNativeWindowBorder
} else if( window instanceof JDialog ) {
JDialog dialog = (JDialog) window;
+ // check whether disabled via client property
+ if( !FlatClientProperties.clientPropertyBoolean( dialog.getRootPane(), FlatClientProperties.USE_WINDOW_DECORATIONS, true ) )
+ return;
+
// do not enable native window border if JDialog should use system window decorations
// and if not forced to use FlatLaf/JBR native window decorations
if( !JDialog.isDefaultLookAndFeelDecorated() &&
diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatNativeWindowBorderTest.java b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatNativeWindowBorderTest.java
index 307c6ba2..d41adbc0 100644
--- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatNativeWindowBorderTest.java
+++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatNativeWindowBorderTest.java
@@ -28,6 +28,7 @@ import java.util.WeakHashMap;
import javax.swing.*;
import javax.swing.plaf.metal.MetalLookAndFeel;
import javax.swing.plaf.nimbus.NimbusLookAndFeel;
+import com.formdev.flatlaf.FlatClientProperties;
import com.formdev.flatlaf.FlatDarculaLaf;
import com.formdev.flatlaf.FlatDarkLaf;
import com.formdev.flatlaf.FlatIntelliJLaf;
@@ -303,6 +304,12 @@ public class FlatNativeWindowBorderTest
FlatNativeWindowBorder.setHasCustomDecoration( window, nativeCheckBox.isSelected() );
}
+ private void native2Changed() {
+ ((RootPaneContainer)window).getRootPane().putClientProperty( FlatClientProperties.USE_WINDOW_DECORATIONS, native2CheckBox.isSelected() );
+ window.dispose();
+ window.setVisible( true );
+ }
+
private void revalidateLayout() {
window.revalidate();
}
@@ -372,6 +379,7 @@ public class FlatNativeWindowBorderTest
undecoratedCheckBox = new JCheckBox();
fullScreenCheckBox = new JCheckBox();
nativeCheckBox = new JCheckBox();
+ native2CheckBox = new JCheckBox();
openDialogButton = new JButton();
hideWindowButton = new JButton();
reopenButton = new JButton();
@@ -433,6 +441,12 @@ public class FlatNativeWindowBorderTest
nativeCheckBox.addActionListener(e -> nativeChanged());
add(nativeCheckBox, "cell 0 3 3 1");
+ //---- native2CheckBox ----
+ native2CheckBox.setText("JRootPane.useWindowDecorations");
+ native2CheckBox.setSelected(true);
+ native2CheckBox.addActionListener(e -> native2Changed());
+ add(native2CheckBox, "cell 0 3 3 1");
+
//---- openDialogButton ----
openDialogButton.setText("Open Dialog");
openDialogButton.setMnemonic('D');
@@ -490,6 +504,7 @@ public class FlatNativeWindowBorderTest
private JCheckBox undecoratedCheckBox;
private JCheckBox fullScreenCheckBox;
private JCheckBox nativeCheckBox;
+ private JCheckBox native2CheckBox;
private JButton openDialogButton;
private JButton hideWindowButton;
private JButton reopenButton;
diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatNativeWindowBorderTest.jfd b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatNativeWindowBorderTest.jfd
index dcf543c0..56f5faa3 100644
--- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatNativeWindowBorderTest.jfd
+++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatNativeWindowBorderTest.jfd
@@ -65,6 +65,14 @@ new FormModel {
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 3 3 1"
} )
+ add( new FormComponent( "javax.swing.JCheckBox" ) {
+ name: "native2CheckBox"
+ "text": "JRootPane.useWindowDecorations"
+ "selected": true
+ addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "native2Changed", false ) )
+ }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
+ "value": "cell 0 3 3 1"
+ } )
add( new FormComponent( "javax.swing.JButton" ) {
name: "openDialogButton"
"text": "Open Dialog"