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 e7e0812ec..3e591a442 100644
--- a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java
+++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java
@@ -346,7 +346,7 @@ public interface FlatClientProperties
/**
* Specifies whether the window icon should be shown in the window title bar
- * (requires enabled window decorations).
+ * (requires enabled window decorations). Default is UI property {@code TitlePane.showIcon}.
*
* Setting this shows/hides the windows icon
* for the {@code JFrame} or {@code JDialog} that contains the root pane.
@@ -362,6 +362,62 @@ public interface FlatClientProperties
*/
String TITLE_BAR_SHOW_ICON = "JRootPane.titleBarShowIcon";
+ /**
+ * Specifies whether the window title should be shown in the window title bar
+ * (requires enabled window decorations). Default is {@code true}.
+ *
+ * Setting this shows/hides the windows title
+ * for the {@code JFrame} or {@code JDialog} that contains the root pane.
+ *
+ * Component {@link javax.swing.JRootPane}
+ * Value type {@link java.lang.Boolean}
+ *
+ * @since 3
+ */
+ String TITLE_BAR_SHOW_TITLE = "JRootPane.titleBarShowTitle";
+
+ /**
+ * Specifies whether the "iconfify" button should be shown in the window title bar
+ * (requires enabled window decorations). Default is {@code true}.
+ *
+ * Setting this shows/hides the "iconfify" button
+ * for the {@code JFrame} that contains the root pane.
+ *
+ * Component {@link javax.swing.JRootPane}
+ * Value type {@link java.lang.Boolean}
+ *
+ * @since 3
+ */
+ String TITLE_BAR_SHOW_ICONIFFY = "JRootPane.titleBarShowIconify";
+
+ /**
+ * Specifies whether the "maximize/restore" button should be shown in the window title bar
+ * (requires enabled window decorations). Default is {@code true}.
+ *
+ * Setting this shows/hides the "maximize/restore" button
+ * for the {@code JFrame} that contains the root pane.
+ *
+ * Component {@link javax.swing.JRootPane}
+ * Value type {@link java.lang.Boolean}
+ *
+ * @since 3
+ */
+ String TITLE_BAR_SHOW_MAXIMIZE = "JRootPane.titleBarShowMaximize";
+
+ /**
+ * Specifies whether the "close" button should be shown in the window title bar
+ * (requires enabled window decorations). Default is {@code true}.
+ *
+ * Setting this shows/hides the "close" button
+ * for the {@code JFrame} or {@code JDialog} that contains the root pane.
+ *
+ * Component {@link javax.swing.JRootPane}
+ * Value type {@link java.lang.Boolean}
+ *
+ * @since 3
+ */
+ String TITLE_BAR_SHOW_CLOSE = "JRootPane.titleBarShowClose";
+
/**
* Background color of window title bar (requires enabled window decorations).
*
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 54640afd6..8177c4fe4 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
@@ -349,6 +349,14 @@ public void propertyChange( PropertyChangeEvent e ) {
titlePane.updateIcon();
break;
+ case FlatClientProperties.TITLE_BAR_SHOW_TITLE:
+ case FlatClientProperties.TITLE_BAR_SHOW_ICONIFFY:
+ case FlatClientProperties.TITLE_BAR_SHOW_MAXIMIZE:
+ case FlatClientProperties.TITLE_BAR_SHOW_CLOSE:
+ if( titlePane != null )
+ titlePane.updateVisibility();
+ break;
+
case FlatClientProperties.TITLE_BAR_BACKGROUND:
case FlatClientProperties.TITLE_BAR_FOREGROUND:
if( titlePane != null )
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 7194bee32..86d652fe4 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
@@ -107,6 +107,8 @@
public class FlatTitlePane
extends JComponent
{
+ private static final String KEY_DEBUG_SHOW_RECTANGLES = "FlatLaf.debug.titlebar.showRectangles";
+
/** @since 2.5 */ protected final Font titleFont = UIManager.getFont( "TitlePane.font" );
protected final Color activeBackground = UIManager.getColor( "TitlePane.background" );
protected final Color inactiveBackground = UIManager.getColor( "TitlePane.inactiveBackground" );
@@ -354,15 +356,12 @@ protected void frameStateChanged() {
if( window == null || rootPane.getWindowDecorationStyle() != JRootPane.FRAME )
return;
+ updateVisibility();
+
if( window instanceof Frame ) {
Frame frame = (Frame) window;
- boolean resizable = frame.isResizable();
boolean maximized = ((frame.getExtendedState() & Frame.MAXIMIZED_BOTH) != 0);
- iconifyButton.setVisible( true );
- maximizeButton.setVisible( resizable && !maximized );
- restoreButton.setVisible( resizable && maximized );
-
if( maximized &&
!(SystemInfo.isLinux && FlatNativeLinuxLibrary.isWMUtilsSupported( window )) &&
rootPane.getClientProperty( "_flatlaf.maximizedBoundsUpToDate" ) == null )
@@ -383,14 +382,27 @@ protected void frameStateChanged() {
frame.setExtendedState( oldExtendedState );
}
}
+ }
+ }
+
+ /** @since 3 */
+ protected void updateVisibility() {
+ titleLabel.setVisible( clientPropertyBoolean( rootPane, TITLE_BAR_SHOW_TITLE, true ) );
+ closeButton.setVisible( clientPropertyBoolean( rootPane, TITLE_BAR_SHOW_CLOSE, true ) );
+
+ if( window instanceof Frame ) {
+ Frame frame = (Frame) window;
+ boolean maximizable = frame.isResizable() && clientPropertyBoolean( rootPane, TITLE_BAR_SHOW_MAXIMIZE, true );
+ boolean maximized = ((frame.getExtendedState() & Frame.MAXIMIZED_BOTH) != 0);
+
+ iconifyButton.setVisible( clientPropertyBoolean( rootPane, TITLE_BAR_SHOW_ICONIFFY, true ) );
+ maximizeButton.setVisible( maximizable && !maximized );
+ restoreButton.setVisible( maximizable && maximized );
} else {
// hide buttons because they are only supported in frames
iconifyButton.setVisible( false );
maximizeButton.setVisible( false );
restoreButton.setVisible( false );
-
- revalidate();
- repaint();
}
}
@@ -566,11 +578,13 @@ protected void menuBarLayouted() {
doLayout();
}
-/*debug
@Override
public void paint( Graphics g ) {
super.paint( g );
+ if( !UIManager.getBoolean( KEY_DEBUG_SHOW_RECTANGLES ) )
+ return;
+
if( debugTitleBarHeight > 0 ) {
g.setColor( Color.green );
g.drawLine( 0, debugTitleBarHeight, getWidth(), debugTitleBarHeight );
@@ -594,7 +608,6 @@ private void paintRect( Graphics g, Color color, Rectangle r ) {
Point offset = SwingUtilities.convertPoint( this, 0, 0, window );
g.drawRect( r.x - offset.x, r.y - offset.y, r.width - 1, r.height - 1 );
}
-debug*/
@Override
protected void paintComponent( Graphics g ) {
@@ -923,15 +936,14 @@ protected void updateNativeTitleBarHeightAndHitTestSpots() {
FlatNativeWindowBorder.setTitleBarHeightAndHitTestSpots( window, titleBarHeight,
hitTestSpots, appIconBounds, minimizeButtonBounds, maximizeButtonBounds, closeButtonBounds );
-/*debug
debugTitleBarHeight = titleBarHeight;
debugHitTestSpots = hitTestSpots;
debugAppIconBounds = appIconBounds;
debugMinimizeButtonBounds = minimizeButtonBounds;
debugMaximizeButtonBounds = maximizeButtonBounds;
debugCloseButtonBounds = closeButtonBounds;
- repaint();
-debug*/
+ if( UIManager.getBoolean( KEY_DEBUG_SHOW_RECTANGLES ) )
+ repaint();
}
private Rectangle boundsInWindow( JComponent c ) {
@@ -950,14 +962,12 @@ protected Rectangle getNativeHitTestSpot( JComponent c ) {
return r;
}
-/*debug
private int debugTitleBarHeight;
private List debugHitTestSpots;
private Rectangle debugAppIconBounds;
private Rectangle debugMinimizeButtonBounds;
private Rectangle debugMaximizeButtonBounds;
private Rectangle debugCloseButtonBounds;
-debug*/
//---- class FlatTitlePaneBorder ------------------------------------------
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 8e82f57e5..e59784fd7 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
@@ -57,6 +57,7 @@ public static void main( String[] args ) {
SwingUtilities.invokeLater( () -> {
FlatLightLaf.setup();
FlatInspector.install( "ctrl shift alt X" );
+ UIManager.put( "FlatLaf.debug.titlebar.showRectangles", true );
mainFrame = showFrame();
} );
diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatWindowDecorationsTest.java b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatWindowDecorationsTest.java
index aeec1663e..203ebd403 100644
--- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatWindowDecorationsTest.java
+++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatWindowDecorationsTest.java
@@ -49,6 +49,7 @@ public static void main( String[] args ) {
FlatTestFrame frame = FlatTestFrame.create( args, "FlatWindowDecorationsTest" );
frame.applyComponentOrientationToFrame = true;
+ UIManager.put( "FlatLaf.debug.titlebar.showRectangles", true );
Class> cls = FlatWindowDecorationsTest.class;
List images = Arrays.asList(
@@ -446,6 +447,30 @@ private void showIconChanged() {
rootPane.putClientProperty( FlatClientProperties.TITLE_BAR_SHOW_ICON, showIconCheckBox.getChecked() );
}
+ private void showTitleChanged() {
+ JRootPane rootPane = getWindowRootPane();
+ if( rootPane != null )
+ rootPane.putClientProperty( FlatClientProperties.TITLE_BAR_SHOW_TITLE, showTitleCheckBox.isSelected() ? null : false );
+ }
+
+ private void showIconifyChanged() {
+ JRootPane rootPane = getWindowRootPane();
+ if( rootPane != null )
+ rootPane.putClientProperty( FlatClientProperties.TITLE_BAR_SHOW_ICONIFFY, showIconifyCheckBox.isSelected() ? null : false );
+ }
+
+ private void showMaximizeChanged() {
+ JRootPane rootPane = getWindowRootPane();
+ if( rootPane != null )
+ rootPane.putClientProperty( FlatClientProperties.TITLE_BAR_SHOW_MAXIMIZE, showMaximizeCheckBox.isSelected() ? null : false );
+ }
+
+ private void showCloseChanged() {
+ JRootPane rootPane = getWindowRootPane();
+ if( rootPane != null )
+ rootPane.putClientProperty( FlatClientProperties.TITLE_BAR_SHOW_CLOSE, showCloseCheckBox.isSelected() ? null : false );
+ }
+
private JRootPane getWindowRootPane() {
Window window = SwingUtilities.windowForComponent( this );
if( window instanceof JFrame )
@@ -495,7 +520,12 @@ private void initComponents() {
iconTestRandomRadioButton = new JRadioButton();
iconTestMRIRadioButton = new JRadioButton();
iconTestDynMRIRadioButton = new JRadioButton();
+ JPanel panel4 = new JPanel();
showIconCheckBox = new FlatTriStateCheckBox();
+ showTitleCheckBox = new JCheckBox();
+ showIconifyCheckBox = new JCheckBox();
+ showMaximizeCheckBox = new JCheckBox();
+ showCloseCheckBox = new JCheckBox();
JButton openDialogButton = new JButton();
JButton openFrameButton = new JButton();
menuBar = new JMenuBar();
@@ -771,13 +801,52 @@ private void initComponents() {
iconTestDynMRIRadioButton.setText("test dynamic multi-resolution (Java 9+)");
iconTestDynMRIRadioButton.addActionListener(e -> iconChanged());
panel2.add(iconTestDynMRIRadioButton, "cell 0 4");
+ }
+ add(panel2, "cell 1 8");
+
+ //======== panel4 ========
+ {
+ panel4.setLayout(new MigLayout(
+ "ltr,insets 0,hidemode 3,gap 0 0",
+ // columns
+ "[grow,left]",
+ // rows
+ "[]" +
+ "[]" +
+ "[]" +
+ "[]" +
+ "[]"));
//---- showIconCheckBox ----
showIconCheckBox.setText("show icon");
showIconCheckBox.addActionListener(e -> showIconChanged());
- panel2.add(showIconCheckBox, "cell 0 5");
+ panel4.add(showIconCheckBox, "cell 0 0");
+
+ //---- showTitleCheckBox ----
+ showTitleCheckBox.setText("show title");
+ showTitleCheckBox.setSelected(true);
+ showTitleCheckBox.addActionListener(e -> showTitleChanged());
+ panel4.add(showTitleCheckBox, "cell 0 1");
+
+ //---- showIconifyCheckBox ----
+ showIconifyCheckBox.setText("show iconfiy");
+ showIconifyCheckBox.setSelected(true);
+ showIconifyCheckBox.addActionListener(e -> showIconifyChanged());
+ panel4.add(showIconifyCheckBox, "cell 0 2");
+
+ //---- showMaximizeCheckBox ----
+ showMaximizeCheckBox.setText("show maximize");
+ showMaximizeCheckBox.setSelected(true);
+ showMaximizeCheckBox.addActionListener(e -> showMaximizeChanged());
+ panel4.add(showMaximizeCheckBox, "cell 0 3");
+
+ //---- showCloseCheckBox ----
+ showCloseCheckBox.setText("show close");
+ showCloseCheckBox.setSelected(true);
+ showCloseCheckBox.addActionListener(e -> showCloseChanged());
+ panel4.add(showCloseCheckBox, "cell 0 4");
}
- add(panel2, "cell 1 8");
+ add(panel4, "cell 2 8");
//---- openDialogButton ----
openDialogButton.setText("Open Dialog");
@@ -1015,6 +1084,10 @@ private void initComponents() {
private JRadioButton iconTestMRIRadioButton;
private JRadioButton iconTestDynMRIRadioButton;
private FlatTriStateCheckBox showIconCheckBox;
+ private JCheckBox showTitleCheckBox;
+ private JCheckBox showIconifyCheckBox;
+ private JCheckBox showMaximizeCheckBox;
+ private JCheckBox showCloseCheckBox;
private JMenuBar menuBar;
// JFormDesigner - End of variables declaration //GEN-END:variables
}
diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatWindowDecorationsTest.jfd b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatWindowDecorationsTest.jfd
index 048d768fe..3287cbd29 100644
--- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatWindowDecorationsTest.jfd
+++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatWindowDecorationsTest.jfd
@@ -1,4 +1,4 @@
-JFDML JFormDesigner: "7.0.3.1.342" Java: "16" encoding: "UTF-8"
+JFDML JFormDesigner: "8.0.0.0.194" Java: "17.0.2" encoding: "UTF-8"
new FormModel {
contentType: "form/swing"
@@ -398,6 +398,15 @@ new FormModel {
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 4"
} )
+ }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
+ "value": "cell 1 8"
+ } )
+ add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
+ "$layoutConstraints": "ltr,insets 0,hidemode 3,gap 0 0"
+ "$columnConstraints": "[grow,left]"
+ "$rowConstraints": "[][][][][]"
+ } ) {
+ name: "panel4"
add( new FormComponent( "com.formdev.flatlaf.extras.components.FlatTriStateCheckBox" ) {
name: "showIconCheckBox"
"text": "show icon"
@@ -406,10 +415,54 @@ new FormModel {
}
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "showIconChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
- "value": "cell 0 5"
+ "value": "cell 0 0"
+ } )
+ add( new FormComponent( "javax.swing.JCheckBox" ) {
+ name: "showTitleCheckBox"
+ "text": "show title"
+ "selected": true
+ auxiliary() {
+ "JavaCodeGenerator.variableLocal": false
+ }
+ addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "showTitleChanged", false ) )
+ }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
+ "value": "cell 0 1"
+ } )
+ add( new FormComponent( "javax.swing.JCheckBox" ) {
+ name: "showIconifyCheckBox"
+ "text": "show iconfiy"
+ "selected": true
+ auxiliary() {
+ "JavaCodeGenerator.variableLocal": false
+ }
+ addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "showIconifyChanged", false ) )
+ }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
+ "value": "cell 0 2"
+ } )
+ add( new FormComponent( "javax.swing.JCheckBox" ) {
+ name: "showMaximizeCheckBox"
+ "text": "show maximize"
+ "selected": true
+ auxiliary() {
+ "JavaCodeGenerator.variableLocal": false
+ }
+ addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "showMaximizeChanged", false ) )
+ }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
+ "value": "cell 0 3"
+ } )
+ add( new FormComponent( "javax.swing.JCheckBox" ) {
+ name: "showCloseCheckBox"
+ "text": "show close"
+ "selected": true
+ auxiliary() {
+ "JavaCodeGenerator.variableLocal": false
+ }
+ addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "showCloseChanged", false ) )
+ }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
+ "value": "cell 0 4"
} )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
- "value": "cell 1 8"
+ "value": "cell 2 8"
} )
add( new FormComponent( "javax.swing.JButton" ) {
name: "openDialogButton"