diff --git a/CHANGELOG.md b/CHANGELOG.md
index bbab99e2..c4e46b71 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -15,8 +15,19 @@ FlatLaf Change Log
- Typography defines several font styles for headers and various text sizes,
which makes it easy to use consistent font styles across the application. (PR
#396)
-- Native window decorations: Show Windows 11 snap layouts menu when hovering the
- mouse over the maximize button. (issues #397 and #407)
+- Native window decorations (Windows 10/11 only):
+ - Unified backgrounds for window title bar is now enabled by default (window
+ title bar has now same background color as window content). Bottom separator
+ for menu bars is no longer painted (if unified background is enabled).
+ - Show Windows 11 snap layouts menu when hovering the mouse over the maximize
+ button. (issues #397 and #407)
+ - Possibility to hide window title bar icon (for single window set client
+ property `JRootPane.titleBarShowIcon` to `false`; for all windows set UI
+ value `TitlePane.showIcon` to `false`).
+ - OptionPane: Hide window title bar icon by default. Can be be made visibly by
+ setting UI default `OptionPane.showIcon` to `true`. (issue #416)
+ - No longer show the Java "duke/cup" icon if no window icon image is set.
+ (issue #416)
- TextField, FormattedTextField and PasswordField: Support leading and trailing
icons (set client property `JTextField.leadingIcon` or
`JTextField.trailingIcon` to an `Icon`). (PR #378; issue #368)
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 93e7c6b6..4af43c96 100644
--- a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java
+++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java
@@ -331,6 +331,24 @@ public interface FlatClientProperties
*/
String MENU_BAR_EMBEDDED = "JRootPane.menuBarEmbedded";
+ /**
+ * Specifies whether the window icon should be shown in the window title bar
+ * (requires enabled window decorations).
+ *
+ * Setting this shows/hides the windows icon
+ * for the {@code JFrame} or {@code JDialog} that contains the root pane.
+ *
+ * This client property has higher priority than UI default {@code TitlePane.showIcon}.
+ *
+ * (requires Window 10)
+ *
+ * Component {@link javax.swing.JRootPane}
+ * Value type {@link java.lang.Boolean}
+ *
+ * @since 2
+ */
+ String TITLE_BAR_SHOW_ICON = "JRootPane.titleBarShowIcon";
+
/**
* Background color of window title bar (requires enabled window decorations).
*
diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatLaf.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatLaf.java
index 324c8e8f..eb137bd8 100644
--- a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatLaf.java
+++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatLaf.java
@@ -393,6 +393,7 @@ public abstract class FlatLaf
"EditorPane.inactiveBackground",
"FormattedTextField.disabledBackground",
"PasswordField.disabledBackground",
+ "RootPane.background",
"Spinner.disabledBackground",
"TextArea.disabledBackground",
"TextArea.inactiveBackground",
@@ -411,7 +412,8 @@ public abstract class FlatLaf
"Spinner.disabledForeground",
"ToggleButton.disabledText" );
putDefaults( defaults, defaults.getColor( "textText" ),
- "DesktopIcon.foreground" );
+ "DesktopIcon.foreground",
+ "RootPane.foreground" );
initFonts( defaults );
initIconColors( defaults, isDark() );
@@ -421,7 +423,7 @@ public abstract class FlatLaf
// (using defaults.remove() to avoid that lazy value is resolved and icon loaded here)
Object icon = defaults.remove( "InternalFrame.icon" );
defaults.put( "InternalFrame.icon", icon );
- defaults.put( "TitlePane.icon", icon );
+ defaults.put( "TitlePane.icon", icon ); // no longer used, but keep for compatibility
// get addons and sort them by priority
ServiceLoader addonLoader = ServiceLoader.load( FlatDefaultsAddon.class );
@@ -541,6 +543,9 @@ public abstract class FlatLaf
if( key instanceof String && (((String)key).endsWith( ".font" ) || ((String)key).endsWith( "Font" )) )
defaults.put( key, activeFont );
}
+
+ // add fonts that are not set in BasicLookAndFeel
+ defaults.put( "RootPane.font", activeFont );
}
private void initDefaultFont( UIDefaults defaults ) {
diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatMenuBarBorder.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatMenuBarBorder.java
index cc437a8d..6ba8d159 100644
--- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatMenuBarBorder.java
+++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatMenuBarBorder.java
@@ -53,6 +53,9 @@ public class FlatMenuBarBorder
@Override
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
+ if( !showBottomSeparator( c ) )
+ return;
+
float lineHeight = scale( (float) 1 );
FlatUIUtils.paintFilledRectangle( g, borderColor, x, y + height - lineHeight, width, lineHeight );
}
@@ -68,4 +71,9 @@ public class FlatMenuBarBorder
insets.right = scale( margin.right );
return insets;
}
+
+ /** @since 2 */
+ protected boolean showBottomSeparator( Component c ) {
+ return !FlatMenuBarUI.useUnifiedBackground( c );
+ }
}
diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatMenuBarUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatMenuBarUI.java
index b2ffd44f..f1d9e038 100644
--- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatMenuBarUI.java
+++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatMenuBarUI.java
@@ -17,6 +17,7 @@
package com.formdev.flatlaf.ui;
import java.awt.Color;
+import java.awt.Component;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Window;
@@ -189,10 +190,8 @@ public class FlatMenuBarUI
return background;
// use parent background for unified title pane
- // (not storing value of "TitlePane.unifiedBackground" in class to allow changing at runtime)
- if( UIManager.getBoolean( "TitlePane.unifiedBackground" ) &&
- FlatNativeWindowBorder.hasCustomDecoration( (Window) rootPane.getParent() ) )
- background = FlatUIUtils.getParentBackground( c );
+ if( useUnifiedBackground( c ) )
+ background = FlatUIUtils.getParentBackground( c );
// paint background in full screen mode
if( FlatUIUtils.isFullScreen( rootPane ) )
@@ -202,6 +201,22 @@ public class FlatMenuBarUI
return FlatRootPaneUI.isMenuBarEmbedded( rootPane ) ? null : background;
}
+ /**@since 2 */
+ static boolean useUnifiedBackground( Component c ) {
+ // check whether:
+ // - TitlePane.unifiedBackground is true and
+ // - menu bar is the "main" menu bar and
+ // - window has custom decorations enabled
+
+ JRootPane rootPane;
+ // (not storing value of "TitlePane.unifiedBackground" in class to allow changing at runtime)
+ return UIManager.getBoolean( "TitlePane.unifiedBackground" ) &&
+ (rootPane = SwingUtilities.getRootPane( c )) != null &&
+ rootPane.getParent() instanceof Window &&
+ rootPane.getJMenuBar() == c &&
+ FlatNativeWindowBorder.hasCustomDecoration( (Window) rootPane.getParent() );
+ }
+
//---- class TakeFocus ----------------------------------------------------
/**
diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatOptionPaneUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatOptionPaneUI.java
index d0413691..ae36668f 100644
--- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatOptionPaneUI.java
+++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatOptionPaneUI.java
@@ -22,18 +22,22 @@ import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.Insets;
+import java.beans.PropertyChangeListener;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
+import javax.swing.JRootPane;
+import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.UIResource;
import javax.swing.plaf.basic.BasicHTML;
import javax.swing.plaf.basic.BasicOptionPaneUI;
+import com.formdev.flatlaf.FlatClientProperties;
import com.formdev.flatlaf.util.UIScale;
/**
@@ -79,6 +83,7 @@ import com.formdev.flatlaf.util.UIScale;
*
*
*
+ * @uiDefault OptionPane.showIcon boolean
* @uiDefault OptionPane.iconMessageGap int
* @uiDefault OptionPane.messagePadding int
* @uiDefault OptionPane.maxCharactersPerLine int
@@ -88,6 +93,7 @@ import com.formdev.flatlaf.util.UIScale;
public class FlatOptionPaneUI
extends BasicOptionPaneUI
{
+ /** @since 2 */ protected boolean showIcon;
protected int iconMessageGap;
protected int messagePadding;
protected int maxCharactersPerLine;
@@ -102,6 +108,7 @@ public class FlatOptionPaneUI
protected void installDefaults() {
super.installDefaults();
+ showIcon = UIManager.getBoolean( "OptionPane.showIcon" );
iconMessageGap = UIManager.getInt( "OptionPane.iconMessageGap" );
messagePadding = UIManager.getInt( "OptionPane.messagePadding" );
maxCharactersPerLine = UIManager.getInt( "OptionPane.maxCharactersPerLine" );
@@ -116,6 +123,24 @@ public class FlatOptionPaneUI
updateChildPanels( optionPane );
}
+ @Override
+ protected PropertyChangeListener createPropertyChangeListener() {
+ PropertyChangeListener superListener = super.createPropertyChangeListener();
+ return e -> {
+ superListener.propertyChange( e );
+
+ // hide window title bar icon
+ // (only if showIcon is false, otherwise the default behavior is used)
+ if( !showIcon && "ancestor".equals( e.getPropertyName() ) && e.getNewValue() != null ) {
+ JRootPane rootPane = SwingUtilities.getRootPane( optionPane );
+ if( rootPane != null &&
+ rootPane.getContentPane().getComponentCount() > 0 &&
+ rootPane.getContentPane().getComponent( 0 ) == optionPane )
+ rootPane.putClientProperty( FlatClientProperties.TITLE_BAR_SHOW_ICON, false );
+ }
+ };
+ }
+
@Override
public Dimension getMinimumOptionPaneSize() {
return UIScale.scale( super.getMinimumOptionPaneSize() );
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 b5d0cfee..61569936 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
@@ -66,6 +66,9 @@ import com.formdev.flatlaf.util.UIScale;
*
*
*
+ * @uiDefault RootPane.font Font unused
+ * @uiDefault RootPane.background Color
+ * @uiDefault RootPane.foreground Color unused
* @uiDefault RootPane.borderDragThickness int
* @uiDefault RootPane.cornerDragWidth int
* @uiDefault RootPane.honorFrameMinimumSizeOnResize boolean
@@ -126,8 +129,23 @@ public class FlatRootPaneUI
protected void installDefaults( JRootPane c ) {
super.installDefaults( c );
+ // Give the root pane useful background, foreground and font.
+ // Background is used for title bar and menu bar if native window decorations
+ // and unified background are enabled.
+ // Foreground and font are usually not used, but set for completeness.
+ // Not using LookAndFeel.installColorsAndFont() here because it will not work
+ // because the properties are null by default but inherit non-null values from parent.
+ if( !c.isBackgroundSet() || c.getBackground() instanceof UIResource )
+ c.setBackground( UIManager.getColor( "RootPane.background" ) );
+ if( !c.isForegroundSet() || c.getForeground() instanceof UIResource )
+ c.setForeground( UIManager.getColor( "RootPane.foreground" ) );
+ if( !c.isFontSet() || c.getFont() instanceof UIResource )
+ c.setFont( UIManager.getFont( "RootPane.font" ) );
+
// Update background color of JFrame or JDialog parent to avoid bad border
// on HiDPI screens when switching from light to dark Laf.
+ // Window background color is also used in native window decorations
+ // to fill background when window is initially shown or when resizing window.
// The background of JFrame is initialized in JFrame.frameInit() and
// the background of JDialog in JDialog.dialogInit(),
// but it was not updated when switching Laf.
@@ -313,6 +331,11 @@ public class FlatRootPaneUI
}
break;
+ case FlatClientProperties.TITLE_BAR_SHOW_ICON:
+ if( titlePane != null )
+ titlePane.updateIcon();
+ 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 38a45cf5..8b2384fd 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
@@ -50,8 +50,6 @@ import javax.accessibility.AccessibleContext;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
-import javax.swing.Icon;
-import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
@@ -66,7 +64,6 @@ import javax.swing.border.Border;
import com.formdev.flatlaf.FlatClientProperties;
import com.formdev.flatlaf.FlatSystemProperties;
import com.formdev.flatlaf.ui.FlatNativeWindowBorder.WindowTopBorder;
-import com.formdev.flatlaf.util.ScaledImageIcon;
import com.formdev.flatlaf.util.SystemInfo;
import com.formdev.flatlaf.util.UIScale;
@@ -80,6 +77,8 @@ import com.formdev.flatlaf.util.UIScale;
* @uiDefault TitlePane.embeddedForeground Color
* @uiDefault TitlePane.borderColor Color optional
* @uiDefault TitlePane.unifiedBackground boolean
+ * @uiDefault TitlePane.showIcon boolean
+ * @uiDefault TitlePane.noIconLeftGap int
* @uiDefault TitlePane.iconSize Dimension
* @uiDefault TitlePane.iconMargins Insets
* @uiDefault TitlePane.titleMargins Insets
@@ -88,7 +87,6 @@ import com.formdev.flatlaf.util.UIScale;
* @uiDefault TitlePane.centerTitle boolean
* @uiDefault TitlePane.centerTitleIfMenuBarEmbedded boolean
* @uiDefault TitlePane.menuBarTitleGap int
- * @uiDefault TitlePane.icon Icon
* @uiDefault TitlePane.closeIcon Icon
* @uiDefault TitlePane.iconifyIcon Icon
* @uiDefault TitlePane.maximizeIcon Icon
@@ -106,6 +104,8 @@ public class FlatTitlePane
protected final Color embeddedForeground = UIManager.getColor( "TitlePane.embeddedForeground" );
protected final Color borderColor = UIManager.getColor( "TitlePane.borderColor" );
+ /** @since 2 */ protected final boolean showIcon = FlatUIUtils.getUIBoolean( "TitlePane.showIcon", true );
+ /** @since 2 */ protected final int noIconLeftGap = FlatUIUtils.getUIInt( "TitlePane.noIconLeftGap", 8 );
protected final Dimension iconSize = UIManager.getDimension( "TitlePane.iconSize" );
protected final int buttonMaximizedHeight = UIManager.getInt( "TitlePane.buttonMaximizedHeight" );
protected final boolean centerTitle = UIManager.getBoolean( "TitlePane.centerTitle" );
@@ -340,36 +340,27 @@ public class FlatTitlePane
protected void updateIcon() {
// get window images
- List images = window.getIconImages();
- if( images.isEmpty() ) {
- // search in owners
- for( Window owner = window.getOwner(); owner != null; owner = owner.getOwner() ) {
- images = owner.getIconImages();
- if( !images.isEmpty() )
- break;
+ List images = null;
+ if( clientPropertyBoolean( rootPane, TITLE_BAR_SHOW_ICON, showIcon ) ) {
+ images = window.getIconImages();
+ if( images.isEmpty() ) {
+ // search in owners
+ for( Window owner = window.getOwner(); owner != null; owner = owner.getOwner() ) {
+ images = owner.getIconImages();
+ if( !images.isEmpty() )
+ break;
+ }
}
}
- boolean hasIcon = true;
+ boolean hasIcon = (images != null && !images.isEmpty());
// set icon
- if( !images.isEmpty() )
- iconLabel.setIcon( new FlatTitlePaneIcon( images, iconSize ) );
- else {
- // no icon set on window --> use default icon
- Icon defaultIcon = UIManager.getIcon( "TitlePane.icon" );
- if( defaultIcon != null && (defaultIcon.getIconWidth() == 0 || defaultIcon.getIconHeight() == 0) )
- defaultIcon = null;
- if( defaultIcon != null ) {
- if( defaultIcon instanceof ImageIcon )
- defaultIcon = new ScaledImageIcon( (ImageIcon) defaultIcon, iconSize.width, iconSize.height );
- iconLabel.setIcon( defaultIcon );
- } else
- hasIcon = false;
- }
+ iconLabel.setIcon( hasIcon ? new FlatTitlePaneIcon( images, iconSize ) : null );
// show/hide icon
iconLabel.setVisible( hasIcon );
+ leftPanel.setBorder( hasIcon ? null : new FlatEmptyBorder( 0, noIconLeftGap, 0, 0 ) );
updateNativeTitleBarHeightAndHitTestSpotsLater();
}
@@ -529,8 +520,8 @@ public class FlatTitlePane
}
paintRect( g, Color.cyan, debugCloseButtonBounds );
paintRect( g, Color.blue, debugAppIconBounds );
- paintRect( g, Color.magenta, debugMinimizeButtonBounds );
- paintRect( g, Color.blue, debugMaximizeButtonBounds );
+ paintRect( g, Color.blue, debugMinimizeButtonBounds );
+ paintRect( g, Color.magenta, debugMaximizeButtonBounds );
paintRect( g, Color.cyan, debugCloseButtonBounds );
}
@@ -739,7 +730,7 @@ debug*/
Rectangle appIconBounds = null;
if( iconLabel.isVisible() ) {
- // compute real icon size (without insets; 1px wider for easier hitting)
+ // compute real icon size (without insets; 1px larger for easier hitting)
Point location = SwingUtilities.convertPoint( iconLabel, 0, 0, window );
Insets iconInsets = iconLabel.getInsets();
Rectangle iconBounds = new Rectangle(
@@ -775,7 +766,7 @@ debug*/
JMenuBar menuBar = rootPane.getJMenuBar();
if( hasVisibleEmbeddedMenuBar( menuBar ) ) {
- r = getNativeHitTestSpot( menuBarPlaceholder );
+ r = getNativeHitTestSpot( menuBar );
if( r != null ) {
Component horizontalGlue = findHorizontalGlue( menuBar );
if( horizontalGlue != null ) {
@@ -784,18 +775,18 @@ debug*/
// the glue component area can used to move the window.
Point glueLocation = SwingUtilities.convertPoint( horizontalGlue, 0, 0, window );
+ int x2 = glueLocation.x + horizontalGlue.getWidth();
Rectangle r2;
if( getComponentOrientation().isLeftToRight() ) {
- int trailingWidth = (r.x + r.width - HIT_TEST_SPOT_GROW) - glueLocation.x;
- r.width -= trailingWidth;
- r2 = new Rectangle( glueLocation.x + horizontalGlue.getWidth(), r.y, trailingWidth, r.height );
+ r2 = new Rectangle( x2, r.y, (r.x + r.width) - x2, r.height );
+
+ r.width = glueLocation.x - r.x;
} else {
- int leadingWidth = (glueLocation.x + horizontalGlue.getWidth()) - (r.x + HIT_TEST_SPOT_GROW);
- r.x += leadingWidth;
- r.width -= leadingWidth;
- r2 = new Rectangle( glueLocation.x -leadingWidth, r.y, leadingWidth, r.height );
+ r2 = new Rectangle( r.x, r.y, glueLocation.x - r.x, r.height );
+
+ r.width = (r.x + r.width) - x2;
+ r.x = x2;
}
- r2.grow( HIT_TEST_SPOT_GROW, HIT_TEST_SPOT_GROW );
hitTestSpots.add( r2 );
}
@@ -834,13 +825,9 @@ debug*/
Point location = SwingUtilities.convertPoint( c, 0, 0, window );
Rectangle r = new Rectangle( location, size );
- // slightly increase rectangle so that component receives mouseExit events
- r.grow( HIT_TEST_SPOT_GROW, HIT_TEST_SPOT_GROW );
return r;
}
- private static final int HIT_TEST_SPOT_GROW = 2;
-
/*debug
private int debugTitleBarHeight;
private List debugHitTestSpots;
@@ -879,7 +866,7 @@ debug*/
Border menuBarBorder = getMenuBarBorder();
if( menuBarBorder != null ) {
// if menu bar is embedded, paint menu bar border
- menuBarBorder.paintBorder( c, g, x, y, width, height );
+ menuBarBorder.paintBorder( rootPane.getJMenuBar(), g, x, y, width, height );
} else if( borderColor != null && (rootPane.getJMenuBar() == null || !rootPane.getJMenuBar().isVisible()) ) {
// paint border between title pane and content if border color is specified
float lineHeight = UIScale.scale( (float) 1 );
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 eb5c8018..002fd997 100644
--- a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties
+++ b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties
@@ -456,6 +456,7 @@ OptionPane.messageAreaBorder = 0,0,0,0
OptionPane.buttonAreaBorder = 12,0,0,0
OptionPane.messageForeground = null
+OptionPane.showIcon = false
OptionPane.maxCharactersPerLine = 80
OptionPane.iconMessageGap = 16
OptionPane.messagePadding = 3
@@ -775,7 +776,9 @@ TitledBorder.border = 1,1,1,1,$Separator.foreground
TitlePane.useWindowDecorations = true
TitlePane.menuBarEmbedded = true
-TitlePane.unifiedBackground = false
+TitlePane.unifiedBackground = true
+TitlePane.showIcon = true
+TitlePane.noIconLeftGap = 8
TitlePane.iconSize = 16,16
TitlePane.iconMargins = 3,8,3,8
TitlePane.titleMargins = 3,0,3,0
diff --git a/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/DemoFrame.java b/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/DemoFrame.java
index c37891c7..678ed225 100644
--- a/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/DemoFrame.java
+++ b/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/DemoFrame.java
@@ -215,6 +215,7 @@ class DemoFrame
menuBarEmbeddedCheckBoxMenuItem.setEnabled( windowDecorations );
unifiedTitleBarMenuItem.setEnabled( windowDecorations );
+ showTitleBarIconMenuItem.setEnabled( windowDecorations );
}
private void menuBarEmbeddedChanged() {
@@ -227,6 +228,16 @@ class DemoFrame
FlatLaf.repaintAllFramesAndDialogs();
}
+ private void showTitleBarIcon() {
+ boolean showIcon = showTitleBarIconMenuItem.isSelected();
+
+ // for main frame (because already created)
+ getRootPane().putClientProperty( FlatClientProperties.TITLE_BAR_SHOW_ICON, showIcon );
+
+ // for other not yet created frames/dialogs
+ UIManager.put( "TitlePane.showIcon", showIcon );
+ }
+
private void underlineMenuSelection() {
UIManager.put( "MenuItem.selectionType", underlineMenuSelectionMenuItem.isSelected() ? "underline" : null );
}
@@ -466,6 +477,7 @@ class DemoFrame
windowDecorationsCheckBoxMenuItem = new JCheckBoxMenuItem();
menuBarEmbeddedCheckBoxMenuItem = new JCheckBoxMenuItem();
unifiedTitleBarMenuItem = new JCheckBoxMenuItem();
+ showTitleBarIconMenuItem = new JCheckBoxMenuItem();
underlineMenuSelectionMenuItem = new JCheckBoxMenuItem();
alwaysShowMnemonicsMenuItem = new JCheckBoxMenuItem();
animatedLafChangeMenuItem = new JCheckBoxMenuItem();
@@ -717,13 +729,11 @@ class DemoFrame
//---- windowDecorationsCheckBoxMenuItem ----
windowDecorationsCheckBoxMenuItem.setText("Window decorations");
- windowDecorationsCheckBoxMenuItem.setSelected(true);
windowDecorationsCheckBoxMenuItem.addActionListener(e -> windowDecorationsChanged());
optionsMenu.add(windowDecorationsCheckBoxMenuItem);
//---- menuBarEmbeddedCheckBoxMenuItem ----
menuBarEmbeddedCheckBoxMenuItem.setText("Embedded menu bar");
- menuBarEmbeddedCheckBoxMenuItem.setSelected(true);
menuBarEmbeddedCheckBoxMenuItem.addActionListener(e -> menuBarEmbeddedChanged());
optionsMenu.add(menuBarEmbeddedCheckBoxMenuItem);
@@ -732,6 +742,11 @@ class DemoFrame
unifiedTitleBarMenuItem.addActionListener(e -> unifiedTitleBar());
optionsMenu.add(unifiedTitleBarMenuItem);
+ //---- showTitleBarIconMenuItem ----
+ showTitleBarIconMenuItem.setText("Show window title bar icon");
+ showTitleBarIconMenuItem.addActionListener(e -> showTitleBarIcon());
+ optionsMenu.add(showTitleBarIconMenuItem);
+
//---- underlineMenuSelectionMenuItem ----
underlineMenuSelectionMenuItem.setText("Use underline menu selection");
underlineMenuSelectionMenuItem.addActionListener(e -> underlineMenuSelection());
@@ -875,6 +890,11 @@ class DemoFrame
pasteMenuItem.addActionListener( new DefaultEditorKit.PasteAction() );
if( FlatLaf.supportsNativeWindowDecorations() ) {
+ windowDecorationsCheckBoxMenuItem.setSelected( FlatLaf.isUseNativeWindowDecorations() );
+ menuBarEmbeddedCheckBoxMenuItem.setSelected( UIManager.getBoolean( "TitlePane.menuBarEmbedded" ) );
+ unifiedTitleBarMenuItem.setSelected( UIManager.getBoolean( "TitlePane.unifiedBackground" ) );
+ showTitleBarIconMenuItem.setSelected( UIManager.getBoolean( "TitlePane.showIcon" ) );
+
if( JBRCustomDecorations.isSupported() ) {
// If the JetBrains Runtime is used, it forces the use of it's own custom
// window decoration, which can not disabled.
@@ -884,6 +904,7 @@ class DemoFrame
unsupported( windowDecorationsCheckBoxMenuItem );
unsupported( menuBarEmbeddedCheckBoxMenuItem );
unsupported( unifiedTitleBarMenuItem );
+ unsupported( showTitleBarIconMenuItem );
}
if( SystemInfo.isMacOS )
@@ -916,6 +937,7 @@ class DemoFrame
private JCheckBoxMenuItem windowDecorationsCheckBoxMenuItem;
private JCheckBoxMenuItem menuBarEmbeddedCheckBoxMenuItem;
private JCheckBoxMenuItem unifiedTitleBarMenuItem;
+ private JCheckBoxMenuItem showTitleBarIconMenuItem;
private JCheckBoxMenuItem underlineMenuSelectionMenuItem;
private JCheckBoxMenuItem alwaysShowMnemonicsMenuItem;
private JCheckBoxMenuItem animatedLafChangeMenuItem;
diff --git a/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/DemoFrame.jfd b/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/DemoFrame.jfd
index 326c9828..65bb5670 100644
--- a/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/DemoFrame.jfd
+++ b/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/DemoFrame.jfd
@@ -354,7 +354,6 @@ new FormModel {
add( new FormComponent( "javax.swing.JCheckBoxMenuItem" ) {
name: "windowDecorationsCheckBoxMenuItem"
"text": "Window decorations"
- "selected": true
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
@@ -363,7 +362,6 @@ new FormModel {
add( new FormComponent( "javax.swing.JCheckBoxMenuItem" ) {
name: "menuBarEmbeddedCheckBoxMenuItem"
"text": "Embedded menu bar"
- "selected": true
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
@@ -377,6 +375,14 @@ new FormModel {
}
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "unifiedTitleBar", false ) )
} )
+ add( new FormComponent( "javax.swing.JCheckBoxMenuItem" ) {
+ name: "showTitleBarIconMenuItem"
+ "text": "Show window title bar icon"
+ auxiliary() {
+ "JavaCodeGenerator.variableLocal": false
+ }
+ addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "showTitleBarIcon", false ) )
+ } )
add( new FormComponent( "javax.swing.JCheckBoxMenuItem" ) {
name: "underlineMenuSelectionMenuItem"
"text": "Use underline menu selection"
diff --git a/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/OptionPanePanel.java b/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/OptionPanePanel.java
index 98de9d00..d1622644 100644
--- a/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/OptionPanePanel.java
+++ b/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/OptionPanePanel.java
@@ -21,6 +21,7 @@ import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;
import javax.swing.border.*;
+import com.formdev.flatlaf.FlatLaf;
import net.miginfocom.swing.*;
/**
@@ -44,6 +45,29 @@ class OptionPanePanel
"OK",
"Cancel",
} );
+
+ if( FlatLaf.supportsNativeWindowDecorations() ) {
+ updateShowTitleBarIcon();
+
+ UIManager.getDefaults().addPropertyChangeListener( e -> {
+ switch( e.getPropertyName() ) {
+ case "TitlePane.showIcon":
+ case "TitlePane.useWindowDecorations":
+ updateShowTitleBarIcon();
+ break;
+ }
+ } );
+ } else
+ showTitleBarIconCheckBox.setEnabled( false );
+ }
+
+ private void updateShowTitleBarIcon() {
+ showTitleBarIconCheckBox.setEnabled( UIManager.getBoolean( "TitlePane.showIcon" ) &&
+ FlatLaf.isUseNativeWindowDecorations() );
+ }
+
+ private void showTitleBarIcon() {
+ UIManager.put( "OptionPane.showIcon", showTitleBarIconCheckBox.isSelected() );
}
private void initComponents() {
@@ -54,6 +78,7 @@ class OptionPanePanel
JPanel panel1 = new JPanel();
JOptionPane plainOptionPane = new JOptionPane();
plainShowDialogLabel = new OptionPanePanel.ShowDialogLinkLabel();
+ showTitleBarIconCheckBox = new JCheckBox();
JLabel errorLabel = new JLabel();
JPanel panel2 = new JPanel();
JOptionPane errorOptionPane = new JOptionPane();
@@ -93,7 +118,7 @@ class OptionPanePanel
//======== panel9 ========
{
panel9.setLayout(new MigLayout(
- "flowy,insets dialog,hidemode 3",
+ "insets dialog,hidemode 3",
// columns
"[]" +
"[]" +
@@ -126,7 +151,12 @@ class OptionPanePanel
//---- plainShowDialogLabel ----
plainShowDialogLabel.setOptionPane(plainOptionPane);
plainShowDialogLabel.setTitleLabel(plainLabel);
- panel9.add(plainShowDialogLabel, "cell 2 0");
+ panel9.add(plainShowDialogLabel, "cell 1 0");
+
+ //---- showTitleBarIconCheckBox ----
+ showTitleBarIconCheckBox.setText("Show window title bar icon");
+ showTitleBarIconCheckBox.addActionListener(e -> showTitleBarIcon());
+ panel9.add(showTitleBarIconCheckBox, "cell 2 0");
//---- errorLabel ----
errorLabel.setText("Error");
@@ -148,7 +178,7 @@ class OptionPanePanel
//---- errorShowDialogLabel ----
errorShowDialogLabel.setTitleLabel(errorLabel);
errorShowDialogLabel.setOptionPane(errorOptionPane);
- panel9.add(errorShowDialogLabel, "cell 2 1");
+ panel9.add(errorShowDialogLabel, "cell 1 1");
//---- informationLabel ----
informationLabel.setText("Information");
@@ -170,7 +200,7 @@ class OptionPanePanel
//---- informationShowDialogLabel ----
informationShowDialogLabel.setOptionPane(informationOptionPane);
informationShowDialogLabel.setTitleLabel(informationLabel);
- panel9.add(informationShowDialogLabel, "cell 2 2");
+ panel9.add(informationShowDialogLabel, "cell 1 2");
//---- questionLabel ----
questionLabel.setText("Question");
@@ -214,7 +244,7 @@ class OptionPanePanel
//---- warningShowDialogLabel ----
warningShowDialogLabel.setOptionPane(warningOptionPane);
warningShowDialogLabel.setTitleLabel(warningLabel);
- panel9.add(warningShowDialogLabel, "cell 2 4");
+ panel9.add(warningShowDialogLabel, "cell 1 4");
//---- inputLabel ----
inputLabel.setText("Input");
@@ -236,7 +266,7 @@ class OptionPanePanel
//---- inputShowDialogLabel ----
inputShowDialogLabel.setOptionPane(inputOptionPane);
inputShowDialogLabel.setTitleLabel(inputLabel);
- panel9.add(inputShowDialogLabel, "cell 2 5");
+ panel9.add(inputShowDialogLabel, "cell 1 5");
//---- inputIconLabel ----
inputIconLabel.setText("Input + icon");
@@ -259,7 +289,7 @@ class OptionPanePanel
//---- inputIconShowDialogLabel ----
inputIconShowDialogLabel.setTitleLabel(inputIconLabel);
inputIconShowDialogLabel.setOptionPane(inputIconOptionPane);
- panel9.add(inputIconShowDialogLabel, "cell 2 6");
+ panel9.add(inputIconShowDialogLabel, "cell 1 6");
//---- customLabel ----
customLabel.setText("Custom");
@@ -279,7 +309,7 @@ class OptionPanePanel
//---- customShowDialogLabel ----
customShowDialogLabel.setOptionPane(customOptionPane);
customShowDialogLabel.setTitleLabel(customLabel);
- panel9.add(customShowDialogLabel, "cell 2 7");
+ panel9.add(customShowDialogLabel, "cell 1 7");
}
scrollPane1.setViewportView(panel9);
}
@@ -289,6 +319,7 @@ class OptionPanePanel
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
private OptionPanePanel.ShowDialogLinkLabel plainShowDialogLabel;
+ private JCheckBox showTitleBarIconCheckBox;
private OptionPanePanel.ShowDialogLinkLabel errorShowDialogLabel;
private OptionPanePanel.ShowDialogLinkLabel informationShowDialogLabel;
private JOptionPane customOptionPane;
@@ -304,6 +335,7 @@ class OptionPanePanel
ShowDialogLinkLabel() {
setText( "Show dialog" );
+ setCursor( Cursor.getPredefinedCursor( Cursor.HAND_CURSOR ) );
addMouseListener( new MouseAdapter() {
@Override
diff --git a/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/OptionPanePanel.jfd b/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/OptionPanePanel.jfd
index 23905510..7d58e157 100644
--- a/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/OptionPanePanel.jfd
+++ b/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/OptionPanePanel.jfd
@@ -12,7 +12,7 @@ new FormModel {
name: "scrollPane1"
"border": new javax.swing.border.EmptyBorder( 0, 0, 0, 0 )
add( new FormContainer( "com.formdev.flatlaf.demo.ScrollablePanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
- "$layoutConstraints": "flowy,insets dialog,hidemode 3"
+ "$layoutConstraints": "insets dialog,hidemode 3"
"$columnConstraints": "[][][fill]"
"$rowConstraints": "[top][top][top][top][top][top][top][top]"
} ) {
@@ -42,6 +42,16 @@ new FormModel {
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
+ }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
+ "value": "cell 1 0"
+ } )
+ add( new FormComponent( "javax.swing.JCheckBox" ) {
+ name: "showTitleBarIconCheckBox"
+ "text": "Show window title bar icon"
+ auxiliary() {
+ "JavaCodeGenerator.variableLocal": false
+ }
+ addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "showTitleBarIcon", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 0"
} )
@@ -73,7 +83,7 @@ new FormModel {
"JavaCodeGenerator.variableLocal": false
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
- "value": "cell 2 1"
+ "value": "cell 1 1"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "informationLabel"
@@ -103,7 +113,7 @@ new FormModel {
"JavaCodeGenerator.variableLocal": false
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
- "value": "cell 2 2"
+ "value": "cell 1 2"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "questionLabel"
@@ -157,7 +167,7 @@ new FormModel {
"optionPane": new FormReference( "warningOptionPane" )
"titleLabel": new FormReference( "warningLabel" )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
- "value": "cell 2 4"
+ "value": "cell 1 4"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "inputLabel"
@@ -184,7 +194,7 @@ new FormModel {
"optionPane": new FormReference( "inputOptionPane" )
"titleLabel": new FormReference( "inputLabel" )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
- "value": "cell 2 5"
+ "value": "cell 1 5"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "inputIconLabel"
@@ -212,7 +222,7 @@ new FormModel {
"titleLabel": new FormReference( "inputIconLabel" )
"optionPane": new FormReference( "inputIconOptionPane" )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
- "value": "cell 2 6"
+ "value": "cell 1 6"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "customLabel"
@@ -240,7 +250,7 @@ new FormModel {
"optionPane": new FormReference( "customOptionPane" )
"titleLabel": new FormReference( "customLabel" )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
- "value": "cell 2 7"
+ "value": "cell 1 7"
} )
} )
}, new FormLayoutConstraints( class java.lang.String ) {
@@ -248,7 +258,7 @@ new FormModel {
} )
}, new FormLayoutConstraints( null ) {
"location": new java.awt.Point( 0, 0 )
- "size": new java.awt.Dimension( 840, 900 )
+ "size": new java.awt.Dimension( 955, 900 )
} )
}
}
diff --git a/flatlaf-extras/src/main/java/com/formdev/flatlaf/extras/FlatInspector.java b/flatlaf-extras/src/main/java/com/formdev/flatlaf/extras/FlatInspector.java
index 48b3f3ef..da5efbad 100644
--- a/flatlaf-extras/src/main/java/com/formdev/flatlaf/extras/FlatInspector.java
+++ b/flatlaf-extras/src/main/java/com/formdev/flatlaf/extras/FlatInspector.java
@@ -474,9 +474,9 @@ public class FlatInspector
if( c instanceof JComponent )
appendRow( buf, "Border", toString( ((JComponent)c).getBorder(), classHierarchy ) );
- appendRow( buf, "Background", toString( c.getBackground() ) );
- appendRow( buf, "Foreground", toString( c.getForeground() ) );
- appendRow( buf, "Font", toString( c.getFont() ) );
+ appendRow( buf, "Background", toString( c.getBackground() ) + (c.isBackgroundSet() ? "" : " NOT SET") );
+ appendRow( buf, "Foreground", toString( c.getForeground() ) + (c.isBackgroundSet() ? "" : " NOT SET") );
+ appendRow( buf, "Font", toString( c.getFont() ) + (c.isFontSet() ? "" : " NOT SET") );
if( c instanceof JComponent ) {
try {
diff --git a/flatlaf-testing/dumps/uidefaults/FlatDarkLaf_1.8.0.txt b/flatlaf-testing/dumps/uidefaults/FlatDarkLaf_1.8.0.txt
index fdc94768..fca8199d 100644
--- a/flatlaf-testing/dumps/uidefaults/FlatDarkLaf_1.8.0.txt
+++ b/flatlaf-testing/dumps/uidefaults/FlatDarkLaf_1.8.0.txt
@@ -671,6 +671,7 @@ OptionPane.minimumSize 262,90 javax.swing.plaf.DimensionUIResource [U
OptionPane.questionIcon [lazy] 32,32 com.formdev.flatlaf.icons.FlatOptionPaneQuestionIcon [UI]
OptionPane.sameSizeButtons true
OptionPane.setButtonMargin false
+OptionPane.showIcon false
OptionPane.warningIcon [lazy] 32,32 com.formdev.flatlaf.icons.FlatOptionPaneWarningIcon [UI]
OptionPane.windowBindings length=2 [Ljava.lang.Object;
[0] ESCAPE
@@ -818,6 +819,7 @@ Resizable.resizeBorder [lazy] 4,4,4,4 false com.formdev.flatlaf.ui.F
#---- RootPane ----
RootPane.activeBorderColor #4d5154 HSL 206 4 32 com.formdev.flatlaf.util.DerivedColor [UI] lighten(7% autoInverse)
+RootPane.background #3c3f41 HSL 204 4 25 javax.swing.plaf.ColorUIResource [UI]
RootPane.border [lazy] 1,1,1,1 false com.formdev.flatlaf.ui.FlatRootPaneUI$FlatWindowBorder [UI]
RootPane.borderDragThickness 5
RootPane.cornerDragWidth 16
@@ -830,6 +832,8 @@ RootPane.defaultButtonWindowKeyBindings length=8 [Ljava.lang.Object;
[5] press
[6] ctrl released ENTER
[7] release
+RootPane.font [active] $defaultFont [UI]
+RootPane.foreground #bbbbbb HSL 0 0 73 javax.swing.plaf.ColorUIResource [UI]
RootPane.honorDialogMinimumSizeOnResize true
RootPane.honorFrameMinimumSizeOnResize false
RootPane.inactiveBorderColor #484c4e HSL 200 4 29 com.formdev.flatlaf.util.DerivedColor [UI] lighten(5% autoInverse)
@@ -1215,9 +1219,11 @@ TitlePane.inactiveForeground #8c8c8c HSL 0 0 55 javax.swing.plaf.Colo
TitlePane.maximizeIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowMaximizeIcon [UI]
TitlePane.menuBarEmbedded true
TitlePane.menuBarTitleGap 20
+TitlePane.noIconLeftGap 8
TitlePane.restoreIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowRestoreIcon [UI]
+TitlePane.showIcon true
TitlePane.titleMargins 3,0,3,0 javax.swing.plaf.InsetsUIResource [UI]
-TitlePane.unifiedBackground false
+TitlePane.unifiedBackground true
TitlePane.useWindowDecorations true
diff --git a/flatlaf-testing/dumps/uidefaults/FlatLightLaf_1.8.0.txt b/flatlaf-testing/dumps/uidefaults/FlatLightLaf_1.8.0.txt
index a1eb2677..e2162462 100644
--- a/flatlaf-testing/dumps/uidefaults/FlatLightLaf_1.8.0.txt
+++ b/flatlaf-testing/dumps/uidefaults/FlatLightLaf_1.8.0.txt
@@ -676,6 +676,7 @@ OptionPane.minimumSize 262,90 javax.swing.plaf.DimensionUIResource [U
OptionPane.questionIcon [lazy] 32,32 com.formdev.flatlaf.icons.FlatOptionPaneQuestionIcon [UI]
OptionPane.sameSizeButtons true
OptionPane.setButtonMargin false
+OptionPane.showIcon false
OptionPane.warningIcon [lazy] 32,32 com.formdev.flatlaf.icons.FlatOptionPaneWarningIcon [UI]
OptionPane.windowBindings length=2 [Ljava.lang.Object;
[0] ESCAPE
@@ -823,6 +824,7 @@ Resizable.resizeBorder [lazy] 4,4,4,4 false com.formdev.flatlaf.ui.F
#---- RootPane ----
RootPane.activeBorderColor #737373 HSL 0 0 45 com.formdev.flatlaf.util.DerivedColor [UI] darken(50% autoInverse)
+RootPane.background #f2f2f2 HSL 0 0 95 javax.swing.plaf.ColorUIResource [UI]
RootPane.border [lazy] 1,1,1,1 false com.formdev.flatlaf.ui.FlatRootPaneUI$FlatWindowBorder [UI]
RootPane.borderDragThickness 5
RootPane.cornerDragWidth 16
@@ -835,6 +837,8 @@ RootPane.defaultButtonWindowKeyBindings length=8 [Ljava.lang.Object;
[5] press
[6] ctrl released ENTER
[7] release
+RootPane.font [active] $defaultFont [UI]
+RootPane.foreground #000000 HSL 0 0 0 javax.swing.plaf.ColorUIResource [UI]
RootPane.honorDialogMinimumSizeOnResize true
RootPane.honorFrameMinimumSizeOnResize false
RootPane.inactiveBorderColor #a6a6a6 HSL 0 0 65 com.formdev.flatlaf.util.DerivedColor [UI] darken(30% autoInverse)
@@ -1220,9 +1224,11 @@ TitlePane.inactiveForeground #8c8c8c HSL 0 0 55 javax.swing.plaf.Colo
TitlePane.maximizeIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowMaximizeIcon [UI]
TitlePane.menuBarEmbedded true
TitlePane.menuBarTitleGap 20
+TitlePane.noIconLeftGap 8
TitlePane.restoreIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowRestoreIcon [UI]
+TitlePane.showIcon true
TitlePane.titleMargins 3,0,3,0 javax.swing.plaf.InsetsUIResource [UI]
-TitlePane.unifiedBackground false
+TitlePane.unifiedBackground true
TitlePane.useWindowDecorations true
diff --git a/flatlaf-testing/dumps/uidefaults/FlatTestLaf_1.8.0.txt b/flatlaf-testing/dumps/uidefaults/FlatTestLaf_1.8.0.txt
index df202d17..aff78d85 100644
--- a/flatlaf-testing/dumps/uidefaults/FlatTestLaf_1.8.0.txt
+++ b/flatlaf-testing/dumps/uidefaults/FlatTestLaf_1.8.0.txt
@@ -687,6 +687,7 @@ OptionPane.minimumSize 262,90 javax.swing.plaf.DimensionUIResource [U
OptionPane.questionIcon [lazy] 32,32 com.formdev.flatlaf.icons.FlatOptionPaneQuestionIcon [UI]
OptionPane.sameSizeButtons true
OptionPane.setButtonMargin false
+OptionPane.showIcon false
OptionPane.warningIcon [lazy] 32,32 com.formdev.flatlaf.icons.FlatOptionPaneWarningIcon [UI]
OptionPane.windowBindings length=2 [Ljava.lang.Object;
[0] ESCAPE
@@ -833,6 +834,7 @@ Resizable.resizeBorder [lazy] 4,4,4,4 false com.formdev.flatlaf.ui.F
#---- RootPane ----
+RootPane.background #ccffcc HSL 120 100 90 javax.swing.plaf.ColorUIResource [UI]
RootPane.border [lazy] 1,1,1,1 false com.formdev.flatlaf.ui.FlatRootPaneUI$FlatWindowBorder [UI]
RootPane.borderDragThickness 5
RootPane.cornerDragWidth 16
@@ -845,6 +847,8 @@ RootPane.defaultButtonWindowKeyBindings length=8 [Ljava.lang.Object;
[5] press
[6] ctrl released ENTER
[7] release
+RootPane.font [active] $defaultFont [UI]
+RootPane.foreground #ff0000 HSL 0 100 50 javax.swing.plaf.ColorUIResource [UI]
RootPane.honorDialogMinimumSizeOnResize true
RootPane.honorFrameMinimumSizeOnResize false
RootPaneUI com.formdev.flatlaf.ui.FlatRootPaneUI
@@ -1235,9 +1239,11 @@ TitlePane.inactiveForeground #ffffff HSL 0 0 100 javax.swing.plaf.Colo
TitlePane.maximizeIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowMaximizeIcon [UI]
TitlePane.menuBarEmbedded true
TitlePane.menuBarTitleGap 20
+TitlePane.noIconLeftGap 8
TitlePane.restoreIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowRestoreIcon [UI]
+TitlePane.showIcon true
TitlePane.titleMargins 3,0,3,0 javax.swing.plaf.InsetsUIResource [UI]
-TitlePane.unifiedBackground false
+TitlePane.unifiedBackground true
TitlePane.useWindowDecorations true
diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatOptionPaneTest.java b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatOptionPaneTest.java
index 3c3cda88..4a832fcf 100644
--- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatOptionPaneTest.java
+++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatOptionPaneTest.java
@@ -33,6 +33,7 @@ public class FlatOptionPaneTest
public static void main( String[] args ) {
SwingUtilities.invokeLater( () -> {
FlatTestFrame frame = FlatTestFrame.create( args, "FlatOptionPaneTest" );
+ frame.setIconImage( new ImageIcon( FlatOptionPaneTest.class.getResource( "/com/formdev/flatlaf/testing/test16.png" ) ).getImage() );
frame.showFrame( FlatOptionPaneTest::new );
} );
}
@@ -54,6 +55,10 @@ public class FlatOptionPaneTest
} );
}
+ private void showTitleBarIcon() {
+ UIManager.put( "OptionPane.showIcon", showTitleBarIconCheckBox.isSelected() );
+ }
+
private void initComponents() {
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
ScrollablePanel panel9 = new ScrollablePanel();
@@ -61,6 +66,7 @@ public class FlatOptionPaneTest
JPanel panel1 = new JPanel();
JOptionPane plainOptionPane = new JOptionPane();
plainShowDialogLabel = new FlatOptionPaneTest.ShowDialogLinkLabel();
+ showTitleBarIconCheckBox = new JCheckBox();
JLabel errorLabel = new JLabel();
JPanel panel2 = new JPanel();
JOptionPane errorOptionPane = new JOptionPane();
@@ -100,7 +106,7 @@ public class FlatOptionPaneTest
//======== panel9 ========
{
panel9.setLayout(new MigLayout(
- "flowy,ltr,insets dialog,hidemode 3",
+ "ltr,insets dialog,hidemode 3",
// columns
"[]" +
"[]" +
@@ -134,7 +140,12 @@ public class FlatOptionPaneTest
//---- plainShowDialogLabel ----
plainShowDialogLabel.setOptionPane(plainOptionPane);
plainShowDialogLabel.setTitleLabel(plainLabel);
- panel9.add(plainShowDialogLabel, "cell 2 0");
+ panel9.add(plainShowDialogLabel, "cell 1 0");
+
+ //---- showTitleBarIconCheckBox ----
+ showTitleBarIconCheckBox.setText("Show window title bar icon");
+ showTitleBarIconCheckBox.addActionListener(e -> showTitleBarIcon());
+ panel9.add(showTitleBarIconCheckBox, "cell 2 0");
//---- errorLabel ----
errorLabel.setText("Error");
@@ -156,7 +167,7 @@ public class FlatOptionPaneTest
//---- errorShowDialogLabel ----
errorShowDialogLabel.setTitleLabel(errorLabel);
errorShowDialogLabel.setOptionPane(errorOptionPane);
- panel9.add(errorShowDialogLabel, "cell 2 1");
+ panel9.add(errorShowDialogLabel, "cell 1 1");
//---- informationLabel ----
informationLabel.setText("Information");
@@ -178,7 +189,7 @@ public class FlatOptionPaneTest
//---- informationShowDialogLabel ----
informationShowDialogLabel.setOptionPane(informationOptionPane);
informationShowDialogLabel.setTitleLabel(informationLabel);
- panel9.add(informationShowDialogLabel, "cell 2 2");
+ panel9.add(informationShowDialogLabel, "cell 1 2");
//---- questionLabel ----
questionLabel.setText("Question");
@@ -222,7 +233,7 @@ public class FlatOptionPaneTest
//---- warningShowDialogLabel ----
warningShowDialogLabel.setOptionPane(warningOptionPane);
warningShowDialogLabel.setTitleLabel(warningLabel);
- panel9.add(warningShowDialogLabel, "cell 2 4");
+ panel9.add(warningShowDialogLabel, "cell 1 4");
//---- inputLabel ----
inputLabel.setText("Input");
@@ -244,7 +255,7 @@ public class FlatOptionPaneTest
//---- inputShowDialogLabel ----
inputShowDialogLabel.setOptionPane(inputOptionPane);
inputShowDialogLabel.setTitleLabel(inputLabel);
- panel9.add(inputShowDialogLabel, "cell 2 5");
+ panel9.add(inputShowDialogLabel, "cell 1 5");
//---- inputIconLabel ----
inputIconLabel.setText("Input + icon");
@@ -267,7 +278,7 @@ public class FlatOptionPaneTest
//---- inputIconShowDialogLabel ----
inputIconShowDialogLabel.setTitleLabel(inputIconLabel);
inputIconShowDialogLabel.setOptionPane(inputIconOptionPane);
- panel9.add(inputIconShowDialogLabel, "cell 2 6");
+ panel9.add(inputIconShowDialogLabel, "cell 1 6");
//---- customLabel ----
customLabel.setText("Custom");
@@ -287,7 +298,7 @@ public class FlatOptionPaneTest
//---- customShowDialogLabel ----
customShowDialogLabel.setOptionPane(customOptionPane);
customShowDialogLabel.setTitleLabel(customLabel);
- panel9.add(customShowDialogLabel, "cell 2 7");
+ panel9.add(customShowDialogLabel, "cell 1 7");
//---- rightToLeftLabel ----
rightToLeftLabel.setText("Right-to-left:");
@@ -317,6 +328,7 @@ public class FlatOptionPaneTest
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
private FlatOptionPaneTest.ShowDialogLinkLabel plainShowDialogLabel;
+ private JCheckBox showTitleBarIconCheckBox;
private FlatOptionPaneTest.ShowDialogLinkLabel errorShowDialogLabel;
private FlatOptionPaneTest.ShowDialogLinkLabel informationShowDialogLabel;
private JOptionPane customOptionPane;
@@ -333,6 +345,7 @@ public class FlatOptionPaneTest
ShowDialogLinkLabel() {
setText( "Show dialog" );
+ setCursor( Cursor.getPredefinedCursor( Cursor.HAND_CURSOR ) );
addMouseListener( new MouseAdapter() {
@Override
diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatOptionPaneTest.jfd b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatOptionPaneTest.jfd
index 78d9bf17..26deae19 100644
--- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatOptionPaneTest.jfd
+++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatOptionPaneTest.jfd
@@ -10,7 +10,7 @@ new FormModel {
name: "this"
"border": new javax.swing.border.EmptyBorder( 0, 0, 0, 0 )
add( new FormContainer( "com.formdev.flatlaf.demo.ScrollablePanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
- "$layoutConstraints": "flowy,ltr,insets dialog,hidemode 3"
+ "$layoutConstraints": "ltr,insets dialog,hidemode 3"
"$columnConstraints": "[][][fill]"
"$rowConstraints": "[top][top][top][top][top][top][top][top][top]"
} ) {
@@ -40,6 +40,16 @@ new FormModel {
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
+ }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
+ "value": "cell 1 0"
+ } )
+ add( new FormComponent( "javax.swing.JCheckBox" ) {
+ name: "showTitleBarIconCheckBox"
+ "text": "Show window title bar icon"
+ auxiliary() {
+ "JavaCodeGenerator.variableLocal": false
+ }
+ addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "showTitleBarIcon", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 0"
} )
@@ -71,7 +81,7 @@ new FormModel {
"JavaCodeGenerator.variableLocal": false
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
- "value": "cell 2 1"
+ "value": "cell 1 1"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "informationLabel"
@@ -101,7 +111,7 @@ new FormModel {
"JavaCodeGenerator.variableLocal": false
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
- "value": "cell 2 2"
+ "value": "cell 1 2"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "questionLabel"
@@ -155,7 +165,7 @@ new FormModel {
"optionPane": new FormReference( "warningOptionPane" )
"titleLabel": new FormReference( "warningLabel" )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
- "value": "cell 2 4"
+ "value": "cell 1 4"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "inputLabel"
@@ -182,7 +192,7 @@ new FormModel {
"optionPane": new FormReference( "inputOptionPane" )
"titleLabel": new FormReference( "inputLabel" )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
- "value": "cell 2 5"
+ "value": "cell 1 5"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "inputIconLabel"
@@ -210,7 +220,7 @@ new FormModel {
"titleLabel": new FormReference( "inputIconLabel" )
"optionPane": new FormReference( "inputIconOptionPane" )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
- "value": "cell 2 6"
+ "value": "cell 1 6"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "customLabel"
@@ -238,7 +248,7 @@ new FormModel {
"optionPane": new FormReference( "customOptionPane" )
"titleLabel": new FormReference( "customLabel" )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
- "value": "cell 2 7"
+ "value": "cell 1 7"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "rightToLeftLabel"
@@ -273,7 +283,7 @@ new FormModel {
} )
}, new FormLayoutConstraints( null ) {
"location": new java.awt.Point( 0, 0 )
- "size": new java.awt.Dimension( 895, 1080 )
+ "size": new java.awt.Dimension( 995, 1080 )
} )
}
}
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 e1621235..c8f99783 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
@@ -27,6 +27,7 @@ import java.util.List;
import java.util.Random;
import javax.swing.*;
import com.formdev.flatlaf.FlatClientProperties;
+import com.formdev.flatlaf.extras.components.FlatTriStateCheckBox;
import com.formdev.flatlaf.ui.FlatUIUtils;
import com.formdev.flatlaf.util.MultiResolutionImageSupport;
import net.miginfocom.swing.*;
@@ -73,6 +74,9 @@ public class FlatWindowDecorationsTest
menuBarCheckBox.setSelected( window instanceof JFrame );
maximizedBoundsCheckBox.setEnabled( window instanceof Frame );
+ menuBarEmbeddedCheckBox.setSelected( UIManager.getBoolean( "TitlePane.menuBarEmbedded" ) );
+ unifiedBackgroundCheckBox.setSelected( UIManager.getBoolean( "TitlePane.unifiedBackground" ) );
+
addMenuButton.setEnabled( menuBarCheckBox.isEnabled() );
addGlueButton.setEnabled( menuBarCheckBox.isEnabled() );
removeMenuButton.setEnabled( menuBarCheckBox.isEnabled() );
@@ -402,6 +406,12 @@ public class FlatWindowDecorationsTest
}
}
+ private void showIconChanged() {
+ JRootPane rootPane = getWindowRootPane();
+ if( rootPane != null )
+ rootPane.putClientProperty( FlatClientProperties.TITLE_BAR_SHOW_ICON, showIconCheckBox.getChecked() );
+ }
+
private JRootPane getWindowRootPane() {
Window window = SwingUtilities.windowForComponent( this );
if( window instanceof JFrame )
@@ -450,6 +460,7 @@ public class FlatWindowDecorationsTest
iconTestRandomRadioButton = new JRadioButton();
iconTestMRIRadioButton = new JRadioButton();
iconTestDynMRIRadioButton = new JRadioButton();
+ showIconCheckBox = new FlatTriStateCheckBox();
JButton openDialogButton = new JButton();
JButton openFrameButton = new JButton();
menuBar = new JMenuBar();
@@ -685,12 +696,13 @@ public class FlatWindowDecorationsTest
panel2.setLayout(new MigLayout(
"ltr,insets 0,hidemode 3,gap 0 0",
// columns
- "[fill]",
+ "[left]",
// rows
"[]" +
"[]" +
"[]" +
"[]" +
+ "[]rel" +
"[]"));
//---- iconNoneRadioButton ----
@@ -718,6 +730,11 @@ public class FlatWindowDecorationsTest
iconTestDynMRIRadioButton.setText("test dynamic multi-resolution (Java 9+)");
iconTestDynMRIRadioButton.addActionListener(e -> iconChanged());
panel2.add(iconTestDynMRIRadioButton, "cell 0 4");
+
+ //---- showIconCheckBox ----
+ showIconCheckBox.setText("show icon");
+ showIconCheckBox.addActionListener(e -> showIconChanged());
+ panel2.add(showIconCheckBox, "cell 0 5");
}
add(panel2, "cell 1 8");
@@ -955,6 +972,7 @@ public class FlatWindowDecorationsTest
private JRadioButton iconTestRandomRadioButton;
private JRadioButton iconTestMRIRadioButton;
private JRadioButton iconTestDynMRIRadioButton;
+ private FlatTriStateCheckBox showIconCheckBox;
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 bc655f8e..c5aa442e 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
@@ -327,8 +327,8 @@ new FormModel {
"value": "cell 0 8"
} )
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
- "$columnConstraints": "[fill]"
- "$rowConstraints": "[][][][][]"
+ "$columnConstraints": "[left]"
+ "$rowConstraints": "[][][][][]rel[]"
"$layoutConstraints": "ltr,insets 0,hidemode 3,gap 0 0"
} ) {
name: "panel2"
@@ -388,6 +388,16 @@ new FormModel {
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 4"
} )
+ add( new FormComponent( "com.formdev.flatlaf.extras.components.FlatTriStateCheckBox" ) {
+ name: "showIconCheckBox"
+ "text": "show icon"
+ auxiliary() {
+ "JavaCodeGenerator.variableLocal": false
+ }
+ addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "showIconChanged", false ) )
+ }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
+ "value": "cell 0 5"
+ } )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 8"
} )
diff --git a/flatlaf-theme-editor/src/main/resources/com/formdev/flatlaf/themeeditor/FlatLafUIKeys.txt b/flatlaf-theme-editor/src/main/resources/com/formdev/flatlaf/themeeditor/FlatLafUIKeys.txt
index a0d743ca..7a884b68 100644
--- a/flatlaf-theme-editor/src/main/resources/com/formdev/flatlaf/themeeditor/FlatLafUIKeys.txt
+++ b/flatlaf-theme-editor/src/main/resources/com/formdev/flatlaf/themeeditor/FlatLafUIKeys.txt
@@ -531,6 +531,7 @@ OptionPane.minimumSize
OptionPane.questionIcon
OptionPane.sameSizeButtons
OptionPane.setButtonMargin
+OptionPane.showIcon
OptionPane.warningIcon
OptionPane.windowBindings
OptionPaneUI
@@ -631,10 +632,13 @@ RangeSliderUI
Resizable.resizeBorder
RootPane.activeBorderColor
RootPane.ancestorInputMap
+RootPane.background
RootPane.border
RootPane.borderDragThickness
RootPane.cornerDragWidth
RootPane.defaultButtonWindowKeyBindings
+RootPane.font
+RootPane.foreground
RootPane.honorDialogMinimumSizeOnResize
RootPane.honorFrameMinimumSizeOnResize
RootPane.inactiveBorderColor
@@ -971,7 +975,9 @@ TitlePane.inactiveForeground
TitlePane.maximizeIcon
TitlePane.menuBarEmbedded
TitlePane.menuBarTitleGap
+TitlePane.noIconLeftGap
TitlePane.restoreIcon
+TitlePane.showIcon
TitlePane.titleMargins
TitlePane.unifiedBackground
TitlePane.useWindowDecorations