diff --git a/CHANGELOG.md b/CHANGELOG.md index 344f67167..cd90e1579 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,10 +5,20 @@ FlatLaf Change Log #### New features and improvements -- Native window decorations for Windows 10 enables dark frame/dialog title bar - and embedded menu bar with all JREs, while still having native Windows 10 - border drop shadows, resize behavior, window snapping and system window menu. - (PR #267) +- Windows 10 only: + - Native window decorations for Windows 10 enables dark frame/dialog title bar + and embedded menu bar with all JREs, while still having native Windows 10 + border drop shadows, resize behavior, window snapping and system window + menu. (PR #267) + - Custom window decorations: Support right aligned components in `JFrame` + title bar with embedded menu bar (using `Box.createHorizontalGlue()`). (PR + #268) + - Custom window decorations: Improved centering of window title with embedded + menu bar. (PR #268; issue #252) + - Custom window decorations: Support unified backgrounds for window title bar, + menu bar and main content. If enabled with `UIManager.put( + "TitlePane.unifiedBackground", true );` then window title bar and menu bar + use same background color as main content. (PR #268; issue #254) #### Fixed bugs 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 09af41dd6..d6aa88b1a 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 @@ -16,17 +16,22 @@ package com.formdev.flatlaf.ui; +import java.awt.Graphics; import java.awt.event.ActionEvent; import javax.swing.AbstractAction; import javax.swing.ActionMap; import javax.swing.JComponent; import javax.swing.JMenu; import javax.swing.JMenuBar; +import javax.swing.JRootPane; +import javax.swing.LookAndFeel; import javax.swing.MenuElement; import javax.swing.MenuSelectionManager; import javax.swing.SwingUtilities; +import javax.swing.UIManager; import javax.swing.plaf.ActionMapUIResource; import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.UIResource; import javax.swing.plaf.basic.BasicMenuBarUI; import com.formdev.flatlaf.FlatLaf; import com.formdev.flatlaf.util.SystemInfo; @@ -40,12 +45,15 @@ * @uiDefault MenuBar.background Color * @uiDefault MenuBar.foreground Color * @uiDefault MenuBar.border Border + * @uiDefault TitlePane.unifiedBackground boolean * * @author Karl Tauber */ public class FlatMenuBarUI extends BasicMenuBarUI { + protected boolean unifiedBackground; + public static ComponentUI createUI( JComponent c ) { return new FlatMenuBarUI(); } @@ -55,6 +63,15 @@ public static ComponentUI createUI( JComponent c ) { * Do not add any functionality here. */ + @Override + protected void installDefaults() { + super.installDefaults(); + + LookAndFeel.installProperty( menuBar, "opaque", false ); + + unifiedBackground = UIManager.getBoolean( "TitlePane.unifiedBackground" ); + } + @Override protected void installKeyboardActions() { super.installKeyboardActions(); @@ -67,6 +84,35 @@ protected void installKeyboardActions() { map.put( "takeFocus", new TakeFocus() ); } + @Override + public void update( Graphics g, JComponent c ) { + // do not fill background if menubar is embedded into title pane + if( isFillBackground( c ) ) { + g.setColor( c.getBackground() ); + g.fillRect( 0, 0, c.getWidth(), c.getHeight() ); + } + + paint( g, c ); + } + + protected boolean isFillBackground( JComponent c ) { + // paint background in opaque or having custom background color + if( c.isOpaque() || !(c.getBackground() instanceof UIResource) ) + return true; + + // do not paint background for unified title pane + if( unifiedBackground ) + return false; + + // paint background in full screen mode + JRootPane rootPane = SwingUtilities.getRootPane( c ); + if( rootPane == null || FlatUIUtils.isFullScreen( rootPane ) ) + return true; + + // do not paint background if menu bar is embedded into title pane + return rootPane.getJMenuBar() != c || !FlatRootPaneUI.isMenuBarEmbedded( rootPane ); + } + //---- class TakeFocus ---------------------------------------------------- /** 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 40ca3e986..417cd1e5b 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 @@ -40,6 +40,7 @@ import javax.swing.border.Border; import javax.swing.plaf.BorderUIResource; import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.RootPaneUI; import javax.swing.plaf.UIResource; import javax.swing.plaf.basic.BasicRootPaneUI; import com.formdev.flatlaf.FlatClientProperties; @@ -227,6 +228,13 @@ public void propertyChange( PropertyChangeEvent e ) { } } + protected static boolean isMenuBarEmbedded( JRootPane rootPane ) { + RootPaneUI ui = rootPane.getUI(); + return ui instanceof FlatRootPaneUI && + ((FlatRootPaneUI)ui).titlePane != null && + ((FlatRootPaneUI)ui).titlePane.isMenuBarEmbedded(); + } + //---- class FlatRootLayout ----------------------------------------------- protected class FlatRootLayout @@ -297,15 +305,16 @@ public void layoutContainer( Container parent ) { rootPane.getGlassPane().setBounds( x, y, width, height ); int nextY = 0; - if( !isFullScreen && titlePane != null ) { - Dimension prefSize = titlePane.getPreferredSize(); - titlePane.setBounds( 0, 0, width, prefSize.height ); - nextY += prefSize.height; + if( titlePane != null ) { + int prefHeight = !isFullScreen ? titlePane.getPreferredSize().height : 0; + titlePane.setBounds( 0, 0, width, prefHeight ); + nextY += prefHeight; } JMenuBar menuBar = rootPane.getJMenuBar(); if( menuBar != null && menuBar.isVisible() ) { - if( !isFullScreen && titlePane != null && titlePane.isMenuBarEmbedded() ) { + boolean embedded = !isFullScreen && titlePane != null && titlePane.isMenuBarEmbedded(); + if( embedded ) { titlePane.validate(); menuBar.setBounds( titlePane.getMenuBarBounds() ); } else { @@ -342,6 +351,9 @@ public float getLayoutAlignmentY( Container target ) { //---- class FlatWindowBorder --------------------------------------------- + /** + * Window border used for non-native window decorations. + */ public static class FlatWindowBorder extends BorderUIResource.EmptyBorderUIResource { @@ -356,7 +368,7 @@ public FlatWindowBorder() { @Override public Insets getBorderInsets( Component c, Insets insets ) { if( isWindowMaximized( c ) || FlatUIUtils.isFullScreen( c ) ) { - // hide border if window is maximized + // hide border if window is maximized or full screen insets.top = insets.left = insets.bottom = insets.right = 0; return insets; } else 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 52d7a82f0..af53d8b6d 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 @@ -47,6 +47,7 @@ import java.util.Objects; import javax.accessibility.AccessibleContext; import javax.swing.BorderFactory; +import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.Icon; import javax.swing.ImageIcon; @@ -77,12 +78,15 @@ * @uiDefault TitlePane.inactiveForeground Color * @uiDefault TitlePane.embeddedForeground Color * @uiDefault TitlePane.borderColor Color optional + * @uiDefault TitlePane.unifiedBackground boolean * @uiDefault TitlePane.iconSize Dimension * @uiDefault TitlePane.iconMargins Insets * @uiDefault TitlePane.titleMargins Insets - * @uiDefault TitlePane.menuBarMargins Insets * @uiDefault TitlePane.menuBarEmbedded boolean * @uiDefault TitlePane.buttonMaximizedHeight int + * @uiDefault TitlePane.centerTitle boolean + * @uiDefault TitlePane.centerTitleIfMenuBarEmbedded boolean + * @uiDefault TitlePane.menuBarTitleGap int * @uiDefault TitlePane.closeIcon Icon * @uiDefault TitlePane.iconifyIcon Icon * @uiDefault TitlePane.maximizeIcon Icon @@ -100,9 +104,12 @@ public class FlatTitlePane protected final Color embeddedForeground = UIManager.getColor( "TitlePane.embeddedForeground" ); protected final Color borderColor = UIManager.getColor( "TitlePane.borderColor" ); - protected final Insets menuBarMargins = UIManager.getInsets( "TitlePane.menuBarMargins" ); + protected final boolean unifiedBackground = UIManager.getBoolean( "TitlePane.unifiedBackground" ); protected final Dimension iconSize = UIManager.getDimension( "TitlePane.iconSize" ); protected final int buttonMaximizedHeight = UIManager.getInt( "TitlePane.buttonMaximizedHeight" ); + protected final boolean centerTitle = UIManager.getBoolean( "TitlePane.centerTitle" ); + protected final boolean centerTitleIfMenuBarEmbedded = FlatUIUtils.getUIBoolean( "TitlePane.centerTitleIfMenuBarEmbedded", true ); + protected final int menuBarTitleGap = FlatUIUtils.getUIInt( "TitlePane.menuBarTitleGap", 20 ); protected final JRootPane rootPane; @@ -147,9 +154,15 @@ protected Handler createHandler() { protected void addSubComponents() { leftPanel = new JPanel(); iconLabel = new JLabel(); - titleLabel = new JLabel(); + titleLabel = new JLabel() { + @Override + public void updateUI() { + setUI( new FlatTitleLabelUI() ); + } + }; iconLabel.setBorder( new FlatEmptyBorder( UIManager.getInsets( "TitlePane.iconMargins" ) ) ); titleLabel.setBorder( new FlatEmptyBorder( UIManager.getInsets( "TitlePane.titleMargins" ) ) ); + titleLabel.setHorizontalAlignment( SwingConstants.CENTER ); leftPanel.setLayout( new BoxLayout( leftPanel, BoxLayout.LINE_AXIS ) ); leftPanel.setOpaque( false ); @@ -159,9 +172,7 @@ protected void addSubComponents() { @Override public Dimension getPreferredSize() { JMenuBar menuBar = rootPane.getJMenuBar(); - return (menuBar != null && menuBar.isVisible() && isMenuBarEmbedded()) - ? FlatUIUtils.addInsets( menuBar.getPreferredSize(), UIScale.scale( menuBarMargins ) ) - : new Dimension(); + return hasVisibleEmbeddedMenuBar( menuBar ) ? menuBar.getPreferredSize() : new Dimension(); } }; leftPanel.add( menuBarPlaceholder ); @@ -184,6 +195,18 @@ public void layoutContainer( Container target ) { if( !getComponentOrientation().isLeftToRight() ) leftPanel.setLocation( leftPanel.getX() + (oldWidth - newWidth), leftPanel.getY() ); } + + // If menu bar is embedded and contains a horizontal glue component, + // then move the title label to the same location as the glue component. + // This allows placing any component on the trailing side of the title pane. + JMenuBar menuBar = rootPane.getJMenuBar(); + if( hasVisibleEmbeddedMenuBar( menuBar ) ) { + Component horizontalGlue = findHorizontalGlue( menuBar ); + if( horizontalGlue != null ) { + Point glueLocation = SwingUtilities.convertPoint( horizontalGlue, 0, 0, titleLabel ); + titleLabel.setLocation( titleLabel.getX() + glueLocation.x, titleLabel.getY() ); + } + } } } ); @@ -240,7 +263,7 @@ protected JButton createButton( String iconKey, String accessibleName, ActionLis } protected void activeChanged( boolean active ) { - boolean hasEmbeddedMenuBar = rootPane.getJMenuBar() != null && rootPane.getJMenuBar().isVisible() && isMenuBarEmbedded(); + boolean hasEmbeddedMenuBar = hasVisibleEmbeddedMenuBar( rootPane.getJMenuBar() ); Color background = FlatUIUtils.nonUIResource( active ? activeBackground : inactiveBackground ); Color foreground = FlatUIUtils.nonUIResource( active ? activeForeground : inactiveForeground ); Color titleForeground = (hasEmbeddedMenuBar && active) ? FlatUIUtils.nonUIResource( embeddedForeground ) : foreground; @@ -252,8 +275,6 @@ protected void activeChanged( boolean active ) { restoreButton.setForeground( foreground ); closeButton.setForeground( foreground ); - titleLabel.setHorizontalAlignment( hasEmbeddedMenuBar ? SwingConstants.CENTER : SwingConstants.LEADING ); - // this is necessary because hover/pressed colors are derived from background color iconifyButton.setBackground( background ); maximizeButton.setBackground( background ); @@ -394,6 +415,16 @@ protected void uninstallWindowListeners() { window.removeComponentListener( handler ); } + /** + * Returns whether this title pane currently has an visible and embedded menubar. + */ + protected boolean hasVisibleEmbeddedMenuBar( JMenuBar menuBar ) { + return menuBar != null && menuBar.isVisible() && isMenuBarEmbedded(); + } + + /** + * Returns whether the menubar should be embedded into the title pane. + */ protected boolean isMenuBarEmbedded() { // not storing value of "TitlePane.menuBarEmbedded" in class to allow changing at runtime return UIManager.getBoolean( "TitlePane.menuBarEmbedded" ) && @@ -412,13 +443,30 @@ protected Rectangle getMenuBarBounds() { Insets borderInsets = getBorder().getBorderInsets( this ); bounds.height += borderInsets.bottom; - return FlatUIUtils.subtractInsets( bounds, UIScale.scale( getMenuBarMargins() ) ); + // If menu bar is embedded and contains a horizontal glue component, + // then make the menu bar wider so that it completely overlaps the title label. + // Since the menu bar is not opaque, the title label is still visible. + // The title label is moved to the location of the glue component by the layout manager. + // This allows placing any component on the trailing side of the title pane. + Component horizontalGlue = findHorizontalGlue( rootPane.getJMenuBar() ); + if( horizontalGlue != null ) { + int titleWidth = Math.max( titleLabel.getWidth(), 0 ); // title width may be negative + bounds.width += titleWidth; + if( !getComponentOrientation().isLeftToRight() ) + bounds.x -= titleWidth; + } + + return bounds; } - protected Insets getMenuBarMargins() { - return getComponentOrientation().isLeftToRight() - ? menuBarMargins - : new Insets( menuBarMargins.top, menuBarMargins.right, menuBarMargins.bottom, menuBarMargins.left ); + protected Component findHorizontalGlue( JMenuBar menuBar ) { + int count = menuBar.getComponentCount(); + for( int i = count - 1; i >= 0; i-- ) { + Component c = menuBar.getComponent( i ); + if( c instanceof Box.Filler && c.getMaximumSize().width >= Short.MAX_VALUE ) + return c; + } + return null; } protected void menuBarChanged() { @@ -436,6 +484,7 @@ protected void menuBarChanged() { protected void menuBarLayouted() { updateNativeTitleBarHeightAndHitTestSpotsLater(); + revalidate(); } /*debug @@ -464,8 +513,10 @@ public void paint( Graphics g ) { @Override protected void paintComponent( Graphics g ) { - g.setColor( getBackground() ); - g.fillRect( 0, 0, getWidth(), getHeight() ); + if( !unifiedBackground ) { + g.setColor( getBackground() ); + g.fillRect( 0, 0, getWidth(), getHeight() ); + } } protected void repaintWindowBorder() { @@ -654,8 +705,37 @@ protected void updateNativeTitleBarHeightAndHitTestSpots() { else appIconBounds = iconBounds; } - addNativeHitTestSpot( buttonPanel, false, hitTestSpots ); - addNativeHitTestSpot( menuBarPlaceholder, true, hitTestSpots ); + + Rectangle r = getNativeHitTestSpot( buttonPanel ); + if( r != null ) + hitTestSpots.add( r ); + + r = getNativeHitTestSpot( menuBarPlaceholder ); + if( r != null ) { + Component horizontalGlue = findHorizontalGlue( rootPane.getJMenuBar() ); + if( horizontalGlue != null ) { + // If menu bar is embedded and contains a horizontal glue component, + // then split the hit test spot into two spots so that + // the glue component area can used to move the window. + + Point glueLocation = SwingUtilities.convertPoint( horizontalGlue, 0, 0, window ); + 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 ); + } 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.grow( HIT_TEST_SPOT_GROW, HIT_TEST_SPOT_GROW ); + hitTestSpots.add( r2 ); + } + + hitTestSpots.add( r ); + } FlatNativeWindowBorder.setTitleBarHeightAndHitTestSpots( window, titleBarHeight, hitTestSpots, appIconBounds ); @@ -667,27 +747,27 @@ protected void updateNativeTitleBarHeightAndHitTestSpots() { debug*/ } - protected void addNativeHitTestSpot( JComponent c, boolean subtractMenuBarMargins, List hitTestSpots ) { + protected Rectangle getNativeHitTestSpot( JComponent c ) { Dimension size = c.getSize(); if( size.width <= 0 || size.height <= 0 ) - return; + return null; Point location = SwingUtilities.convertPoint( c, 0, 0, window ); Rectangle r = new Rectangle( location, size ); - if( subtractMenuBarMargins ) - r = FlatUIUtils.subtractInsets( r, UIScale.scale( getMenuBarMargins() ) ); // slightly increase rectangle so that component receives mouseExit events - r.grow( 2, 2 ); - hitTestSpots.add( r ); + 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; private Rectangle debugAppIconBounds; debug*/ - //---- class TitlePaneBorder ---------------------------------------------- + //---- class FlatTitlePaneBorder ------------------------------------------ protected class FlatTitlePaneBorder extends AbstractBorder @@ -729,7 +809,42 @@ public void paintBorder( Component c, Graphics g, int x, int y, int width, int h protected Border getMenuBarBorder() { JMenuBar menuBar = rootPane.getJMenuBar(); - return (menuBar != null && menuBar.isVisible() && isMenuBarEmbedded()) ? menuBar.getBorder() : null; + return hasVisibleEmbeddedMenuBar( menuBar ) ? menuBar.getBorder() : null; + } + } + + //---- class FlatTitleLabelUI --------------------------------------------- + + protected class FlatTitleLabelUI + extends FlatLabelUI + { + @Override + protected void paintEnabledText( JLabel l, Graphics g, String s, int textX, int textY ) { + boolean hasEmbeddedMenuBar = hasVisibleEmbeddedMenuBar( rootPane.getJMenuBar() ); + int labelWidth = l.getWidth(); + int textWidth = labelWidth - (textX * 2); + int gap = UIScale.scale( menuBarTitleGap ); + + // The passed in textX coordinate is always to horizontally center the text within the label bounds. + // Modify textX so that the text is painted either centered within the window bounds or leading aligned. + boolean center = hasEmbeddedMenuBar ? centerTitleIfMenuBarEmbedded : centerTitle; + if( center ) { + // If window is wide enough, center title within window bounds. + // Otherwise leave it centered within free space (label bounds). + int centeredTextX = ((l.getParent().getWidth() - textWidth) / 2) - l.getX(); + if( centeredTextX >= gap && centeredTextX + textWidth <= labelWidth - gap ) + textX = centeredTextX; + } else { + // leading aligned + boolean leftToRight = getComponentOrientation().isLeftToRight(); + Insets insets = l.getInsets(); + int leadingInset = hasEmbeddedMenuBar ? gap : (leftToRight ? insets.left : insets.right); + int leadingTextX = leftToRight ? leadingInset : labelWidth - leadingInset - textWidth; + if( leftToRight ? leadingTextX < textX : leadingTextX > textX ) + textX = leadingTextX; + } + + super.paintEnabledText( l, g, s, textX, textY ); } } diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatUIUtils.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatUIUtils.java index 4030d43ad..5e0eb5f8d 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatUIUtils.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatUIUtils.java @@ -119,6 +119,11 @@ public static Color getUIColor( String key, String defaultKey ) { return (color != null) ? color : UIManager.getColor( defaultKey ); } + public static boolean getUIBoolean( String key, boolean defaultValue ) { + Object value = UIManager.get( key ); + return (value instanceof Boolean) ? (Boolean) value : defaultValue; + } + public static int getUIInt( String key, int defaultValue ) { Object value = UIManager.get( key ); return (value instanceof Integer) ? (Integer) value : defaultValue; 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 580ff417f..87949600c 100644 --- a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties +++ b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties @@ -687,12 +687,15 @@ TitledBorder.border = 1,1,1,1,$Separator.foreground TitlePane.useWindowDecorations = true TitlePane.menuBarEmbedded = true +TitlePane.unifiedBackground = false TitlePane.iconSize = 16,16 -TitlePane.iconMargins = 3,8,3,0 -TitlePane.menuBarMargins = 0,8,0,22 -TitlePane.titleMargins = 3,8,3,8 +TitlePane.iconMargins = 3,8,3,8 +TitlePane.titleMargins = 3,0,3,0 TitlePane.buttonSize = 44,30 TitlePane.buttonMaximizedHeight = 22 +TitlePane.centerTitle = false +TitlePane.centerTitleIfMenuBarEmbedded = true +TitlePane.menuBarTitleGap = 20 TitlePane.closeIcon = com.formdev.flatlaf.icons.FlatWindowCloseIcon TitlePane.iconifyIcon = com.formdev.flatlaf.icons.FlatWindowIconifyIcon TitlePane.maximizeIcon = com.formdev.flatlaf.icons.FlatWindowMaximizeIcon 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 876e3c8e9..3d61f6a72 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 @@ -32,6 +32,8 @@ import com.formdev.flatlaf.extras.FlatAnimatedLafChange; import com.formdev.flatlaf.extras.FlatSVGIcon; import com.formdev.flatlaf.extras.FlatUIDefaultsInspector; +import com.formdev.flatlaf.extras.components.FlatButton; +import com.formdev.flatlaf.extras.components.FlatButton.ButtonType; import com.formdev.flatlaf.extras.FlatSVGUtils; import com.formdev.flatlaf.ui.FlatNativeWindowBorder; import com.formdev.flatlaf.ui.JBRCustomDecorations; @@ -168,6 +170,11 @@ private void menuBarEmbeddedChanged() { // repaint(); } + private void unifiedTitleBar() { + UIManager.put( "TitlePane.unifiedBackground", unifiedTitleBarMenuItem.isSelected() ); + FlatLaf.updateUI(); + } + private void underlineMenuSelection() { UIManager.put( "MenuItem.selectionType", underlineMenuSelectionMenuItem.isSelected() ? "underline" : null ); } @@ -332,6 +339,7 @@ private void initComponents() { optionsMenu = new JMenu(); windowDecorationsCheckBoxMenuItem = new JCheckBoxMenuItem(); menuBarEmbeddedCheckBoxMenuItem = new JCheckBoxMenuItem(); + unifiedTitleBarMenuItem = new JCheckBoxMenuItem(); underlineMenuSelectionMenuItem = new JCheckBoxMenuItem(); alwaysShowMnemonicsMenuItem = new JCheckBoxMenuItem(); animatedLafChangeMenuItem = new JCheckBoxMenuItem(); @@ -593,6 +601,11 @@ private void initComponents() { menuBarEmbeddedCheckBoxMenuItem.addActionListener(e -> menuBarEmbeddedChanged()); optionsMenu.add(menuBarEmbeddedCheckBoxMenuItem); + //---- unifiedTitleBarMenuItem ---- + unifiedTitleBarMenuItem.setText("Unified Title Bar"); + unifiedTitleBarMenuItem.addActionListener(e -> unifiedTitleBar()); + optionsMenu.add(unifiedTitleBarMenuItem); + //---- underlineMenuSelectionMenuItem ---- underlineMenuSelectionMenuItem.setText("Use underline menu selection"); underlineMenuSelectionMenuItem.addActionListener(e -> underlineMenuSelection()); @@ -707,6 +720,15 @@ private void initComponents() { buttonGroup1.add(radioButtonMenuItem3); // JFormDesigner - End of component initialization //GEN-END:initComponents + // add "Users" button to menubar + FlatButton usersButton = new FlatButton(); + usersButton.setIcon( new FlatSVGIcon( "com/formdev/flatlaf/demo/icons/users.svg" ) ); + usersButton.setButtonType( ButtonType.toolBarButton ); + usersButton.setFocusable( false ); + usersButton.addActionListener( e -> JOptionPane.showMessageDialog( null, "Hello User! How are you?", "User", JOptionPane.INFORMATION_MESSAGE ) ); + menuBar1.add( Box.createGlue() ); + menuBar1.add( usersButton ); + undoMenuItem.setIcon( new FlatSVGIcon( "com/formdev/flatlaf/demo/icons/undo.svg" ) ); redoMenuItem.setIcon( new FlatSVGIcon( "com/formdev/flatlaf/demo/icons/redo.svg" ) ); @@ -749,6 +771,7 @@ private void initComponents() { private JMenu optionsMenu; private JCheckBoxMenuItem windowDecorationsCheckBoxMenuItem; private JCheckBoxMenuItem menuBarEmbeddedCheckBoxMenuItem; + private JCheckBoxMenuItem unifiedTitleBarMenuItem; 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 ba2075b66..d04959a08 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 @@ -1,4 +1,4 @@ -JFDML JFormDesigner: "7.0.2.0.298" Java: "15" encoding: "UTF-8" +JFDML JFormDesigner: "7.0.3.1.342" Java: "15" encoding: "UTF-8" new FormModel { contentType: "form/swing" @@ -360,6 +360,14 @@ new FormModel { } addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "menuBarEmbeddedChanged", false ) ) } ) + add( new FormComponent( "javax.swing.JCheckBoxMenuItem" ) { + name: "unifiedTitleBarMenuItem" + "text": "Unified Title Bar" + auxiliary() { + "JavaCodeGenerator.variableLocal": false + } + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "unifiedTitleBar", false ) ) + } ) add( new FormComponent( "javax.swing.JCheckBoxMenuItem" ) { name: "underlineMenuSelectionMenuItem" "text": "Use underline menu selection" diff --git a/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/icons/users.svg b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/icons/users.svg new file mode 100644 index 000000000..135e8e60c --- /dev/null +++ b/flatlaf-demo/src/main/resources/com/formdev/flatlaf/demo/icons/users.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/flatlaf-testing/dumps/uidefaults/FlatDarkLaf_1.8.0_202.txt b/flatlaf-testing/dumps/uidefaults/FlatDarkLaf_1.8.0_202.txt index 787ed4dfb..6394cd5da 100644 --- a/flatlaf-testing/dumps/uidefaults/FlatDarkLaf_1.8.0_202.txt +++ b/flatlaf-testing/dumps/uidefaults/FlatDarkLaf_1.8.0_202.txt @@ -1126,6 +1126,8 @@ TitlePane.buttonHoverBackground #484c4f com.formdev.flatlaf.util.DerivedColor TitlePane.buttonMaximizedHeight 22 TitlePane.buttonPressedBackground #616569 com.formdev.flatlaf.util.DerivedColor [UI] lighten(20% autoInverse) TitlePane.buttonSize 44,30 javax.swing.plaf.DimensionUIResource [UI] +TitlePane.centerTitle false +TitlePane.centerTitleIfMenuBarEmbedded true TitlePane.closeHoverBackground #e81123 javax.swing.plaf.ColorUIResource [UI] TitlePane.closeHoverForeground #ffffff javax.swing.plaf.ColorUIResource [UI] TitlePane.closeIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowCloseIcon [UI] @@ -1133,16 +1135,17 @@ TitlePane.closePressedBackground #e8112399 60% javax.swing.plaf.ColorUIResou TitlePane.closePressedForeground #ffffff javax.swing.plaf.ColorUIResource [UI] TitlePane.embeddedForeground #959595 javax.swing.plaf.ColorUIResource [UI] TitlePane.foreground #bbbbbb javax.swing.plaf.ColorUIResource [UI] -TitlePane.iconMargins 3,8,3,0 javax.swing.plaf.InsetsUIResource [UI] +TitlePane.iconMargins 3,8,3,8 javax.swing.plaf.InsetsUIResource [UI] TitlePane.iconSize 16,16 javax.swing.plaf.DimensionUIResource [UI] TitlePane.iconifyIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowIconifyIcon [UI] TitlePane.inactiveBackground #303234 javax.swing.plaf.ColorUIResource [UI] TitlePane.inactiveForeground #888888 javax.swing.plaf.ColorUIResource [UI] TitlePane.maximizeIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowMaximizeIcon [UI] TitlePane.menuBarEmbedded true -TitlePane.menuBarMargins 0,8,0,22 javax.swing.plaf.InsetsUIResource [UI] +TitlePane.menuBarTitleGap 20 TitlePane.restoreIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowRestoreIcon [UI] -TitlePane.titleMargins 3,8,3,8 javax.swing.plaf.InsetsUIResource [UI] +TitlePane.titleMargins 3,0,3,0 javax.swing.plaf.InsetsUIResource [UI] +TitlePane.unifiedBackground false TitlePane.useWindowDecorations true diff --git a/flatlaf-testing/dumps/uidefaults/FlatLightLaf_1.8.0_202.txt b/flatlaf-testing/dumps/uidefaults/FlatLightLaf_1.8.0_202.txt index 578a317e8..91ec37bbe 100644 --- a/flatlaf-testing/dumps/uidefaults/FlatLightLaf_1.8.0_202.txt +++ b/flatlaf-testing/dumps/uidefaults/FlatLightLaf_1.8.0_202.txt @@ -1131,6 +1131,8 @@ TitlePane.buttonHoverBackground #e6e6e6 com.formdev.flatlaf.util.DerivedColor TitlePane.buttonMaximizedHeight 22 TitlePane.buttonPressedBackground #cccccc com.formdev.flatlaf.util.DerivedColor [UI] darken(20% autoInverse) TitlePane.buttonSize 44,30 javax.swing.plaf.DimensionUIResource [UI] +TitlePane.centerTitle false +TitlePane.centerTitleIfMenuBarEmbedded true TitlePane.closeHoverBackground #e81123 javax.swing.plaf.ColorUIResource [UI] TitlePane.closeHoverForeground #ffffff javax.swing.plaf.ColorUIResource [UI] TitlePane.closeIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowCloseIcon [UI] @@ -1138,16 +1140,17 @@ TitlePane.closePressedBackground #e8112399 60% javax.swing.plaf.ColorUIResou TitlePane.closePressedForeground #ffffff javax.swing.plaf.ColorUIResource [UI] TitlePane.embeddedForeground #595959 javax.swing.plaf.ColorUIResource [UI] TitlePane.foreground #000000 javax.swing.plaf.ColorUIResource [UI] -TitlePane.iconMargins 3,8,3,0 javax.swing.plaf.InsetsUIResource [UI] +TitlePane.iconMargins 3,8,3,8 javax.swing.plaf.InsetsUIResource [UI] TitlePane.iconSize 16,16 javax.swing.plaf.DimensionUIResource [UI] TitlePane.iconifyIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowIconifyIcon [UI] TitlePane.inactiveBackground #ffffff javax.swing.plaf.ColorUIResource [UI] TitlePane.inactiveForeground #8c8c8c javax.swing.plaf.ColorUIResource [UI] TitlePane.maximizeIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowMaximizeIcon [UI] TitlePane.menuBarEmbedded true -TitlePane.menuBarMargins 0,8,0,22 javax.swing.plaf.InsetsUIResource [UI] +TitlePane.menuBarTitleGap 20 TitlePane.restoreIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowRestoreIcon [UI] -TitlePane.titleMargins 3,8,3,8 javax.swing.plaf.InsetsUIResource [UI] +TitlePane.titleMargins 3,0,3,0 javax.swing.plaf.InsetsUIResource [UI] +TitlePane.unifiedBackground false TitlePane.useWindowDecorations true diff --git a/flatlaf-testing/dumps/uidefaults/FlatTestLaf_1.8.0_202.txt b/flatlaf-testing/dumps/uidefaults/FlatTestLaf_1.8.0_202.txt index c89dd1a6a..707004a2e 100644 --- a/flatlaf-testing/dumps/uidefaults/FlatTestLaf_1.8.0_202.txt +++ b/flatlaf-testing/dumps/uidefaults/FlatTestLaf_1.8.0_202.txt @@ -1124,22 +1124,25 @@ TextPaneUI com.formdev.flatlaf.ui.FlatTextPaneUI TitlePane.background #00ff00 javax.swing.plaf.ColorUIResource [UI] TitlePane.buttonMaximizedHeight 22 TitlePane.buttonSize 44,30 javax.swing.plaf.DimensionUIResource [UI] +TitlePane.centerTitle false +TitlePane.centerTitleIfMenuBarEmbedded true TitlePane.closeHoverBackground #e81123 javax.swing.plaf.ColorUIResource [UI] TitlePane.closeHoverForeground #ffffff javax.swing.plaf.ColorUIResource [UI] TitlePane.closeIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowCloseIcon [UI] TitlePane.closePressedBackground #e8112399 60% javax.swing.plaf.ColorUIResource [UI] TitlePane.closePressedForeground #ffffff javax.swing.plaf.ColorUIResource [UI] TitlePane.foreground #0000ff javax.swing.plaf.ColorUIResource [UI] -TitlePane.iconMargins 3,8,3,0 javax.swing.plaf.InsetsUIResource [UI] +TitlePane.iconMargins 3,8,3,8 javax.swing.plaf.InsetsUIResource [UI] TitlePane.iconSize 16,16 javax.swing.plaf.DimensionUIResource [UI] TitlePane.iconifyIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowIconifyIcon [UI] TitlePane.inactiveBackground #008800 javax.swing.plaf.ColorUIResource [UI] TitlePane.inactiveForeground #ffffff javax.swing.plaf.ColorUIResource [UI] TitlePane.maximizeIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowMaximizeIcon [UI] TitlePane.menuBarEmbedded true -TitlePane.menuBarMargins 0,8,0,22 javax.swing.plaf.InsetsUIResource [UI] +TitlePane.menuBarTitleGap 20 TitlePane.restoreIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowRestoreIcon [UI] -TitlePane.titleMargins 3,8,3,8 javax.swing.plaf.InsetsUIResource [UI] +TitlePane.titleMargins 3,0,3,0 javax.swing.plaf.InsetsUIResource [UI] +TitlePane.unifiedBackground false TitlePane.useWindowDecorations true 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 d3ed01a07..7bdc8093b 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 @@ -25,6 +25,7 @@ import java.util.Random; import javax.swing.*; import com.formdev.flatlaf.FlatClientProperties; +import com.formdev.flatlaf.FlatLaf; import net.miginfocom.swing.*; /** @@ -109,6 +110,11 @@ else if( style == JRootPane.INFORMATION_DIALOG ) } } + private void unifiedBackgroundChanged() { + UIManager.put( "TitlePane.unifiedBackground", unifiedBackgroundCheckBox.isSelected() ); + FlatLaf.updateUI(); + } + private void menuBarChanged() { Window window = SwingUtilities.windowForComponent( this ); if( window instanceof JFrame ) { @@ -128,13 +134,48 @@ private void menuBarVisibleChanged() { menuBar.setVisible( menuBarVisibleCheckBox.isSelected() ); } + private void colorizeMenuBar() { + boolean colorize = colorizeMenuBarCheckBox.isSelected(); + Color menuBarBackground = colorize ? new Color( 0xffccff ) : UIManager.getColor( "MenuBar.background" ); + + menuBar.setOpaque( colorize ); + menuBar.setBackground( menuBarBackground ); + } + + private void colorizeMenus() { + boolean colorize = colorizeMenusCheckBox.isSelected(); + Color menuBackground = colorize ? new Color( 0xaaffff ) : UIManager.getColor( "Menu.background" ); + + for( Component c : menuBar.getComponents() ) { + if( c instanceof JMenu ) { + ((JMenu)c).setOpaque( colorize ); + c.setBackground( menuBackground ); + } + } + } + private void addMenu() { JMenu menu = new JMenu( "Hello" ); menu.add( new JMenuItem( "world" ) ); + + if( colorizeMenusCheckBox.isSelected() ) { + menu.setOpaque( true ); + menu.setBackground( new Color( 0xaaffff ) ); + } + menuBar.add( menu ); menuBar.revalidate(); } + private void addGlue() { + for( Component c : menuBar.getComponents() ) { + if( c instanceof Box.Filler ) + return; + } + menuBar.add( Box.createGlue() ); + menuBar.revalidate(); + } + private void removeMenu() { int menuCount = menuBar.getMenuCount(); if( menuCount <= 0 ) @@ -154,6 +195,14 @@ private void changeMenu() { menuBar.getMenu( menuCount - 1 ).setText( text ); } + private void changeTitle() { + Window window = SwingUtilities.windowForComponent( this ); + if( window instanceof Frame ) + ((Frame)window).setTitle( ((Frame)window).getTitle() + " bla" ); + else if( window instanceof Dialog ) + ((Dialog)window).setTitle( ((Dialog)window).getTitle() + " bla" ); + } + private void resizableChanged() { Window window = SwingUtilities.windowForComponent( this ); if( window instanceof Frame ) @@ -263,11 +312,17 @@ else if( window instanceof JDialog ) private void initComponents() { // JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents menuBarCheckBox = new JCheckBox(); + unifiedBackgroundCheckBox = new JCheckBox(); + JPanel panel3 = new JPanel(); addMenuButton = new JButton(); + JButton addGlueButton = new JButton(); removeMenuButton = new JButton(); changeMenuButton = new JButton(); + JButton changeTitleButton = new JButton(); menuBarEmbeddedCheckBox = new JCheckBox(); + colorizeMenuBarCheckBox = new JCheckBox(); menuBarVisibleCheckBox = new JCheckBox(); + colorizeMenusCheckBox = new JCheckBox(); resizableCheckBox = new JCheckBox(); maximizedBoundsCheckBox = new JCheckBox(); undecoratedCheckBox = new JCheckBox(); @@ -321,13 +376,14 @@ private void initComponents() { "ltr,insets dialog,hidemode 3", // columns "[left]para" + - "[left]", + "[left]" + + "[fill]", // rows "para[]0" + "[]0" + + "[]unrel" + "[]0" + - "[]0" + - "[]" + + "[]unrel" + "[]" + "[top]" + "[]")); @@ -338,20 +394,50 @@ private void initComponents() { menuBarCheckBox.addActionListener(e -> menuBarChanged()); add(menuBarCheckBox, "cell 0 0"); - //---- addMenuButton ---- - addMenuButton.setText("Add menu"); - addMenuButton.addActionListener(e -> addMenu()); - add(addMenuButton, "cell 1 0 1 2,align left top,grow 0 0"); + //---- unifiedBackgroundCheckBox ---- + unifiedBackgroundCheckBox.setText("unified background"); + unifiedBackgroundCheckBox.addActionListener(e -> unifiedBackgroundChanged()); + add(unifiedBackgroundCheckBox, "cell 1 0"); - //---- removeMenuButton ---- - removeMenuButton.setText("Remove menu"); - removeMenuButton.addActionListener(e -> removeMenu()); - add(removeMenuButton, "cell 1 0 1 2,align left top,grow 0 0"); + //======== panel3 ======== + { + panel3.setLayout(new MigLayout( + "hidemode 3", + // columns + "[fill]", + // rows + "[]" + + "[]" + + "[]" + + "[]unrel" + + "[]")); - //---- changeMenuButton ---- - changeMenuButton.setText("Change menu"); - changeMenuButton.addActionListener(e -> changeMenu()); - add(changeMenuButton, "cell 1 0 1 2,align left top,grow 0 0"); + //---- addMenuButton ---- + addMenuButton.setText("Add menu"); + addMenuButton.addActionListener(e -> addMenu()); + panel3.add(addMenuButton, "cell 0 0"); + + //---- addGlueButton ---- + addGlueButton.setText("Add glue"); + addGlueButton.addActionListener(e -> addGlue()); + panel3.add(addGlueButton, "cell 0 1"); + + //---- removeMenuButton ---- + removeMenuButton.setText("Remove menu"); + removeMenuButton.addActionListener(e -> removeMenu()); + panel3.add(removeMenuButton, "cell 0 2"); + + //---- changeMenuButton ---- + changeMenuButton.setText("Change menu"); + changeMenuButton.addActionListener(e -> changeMenu()); + panel3.add(changeMenuButton, "cell 0 3"); + + //---- changeTitleButton ---- + changeTitleButton.setText("Change title"); + changeTitleButton.addActionListener(e -> changeTitle()); + panel3.add(changeTitleButton, "cell 0 4"); + } + add(panel3, "cell 2 0 1 6,aligny top,growy 0"); //---- menuBarEmbeddedCheckBox ---- menuBarEmbeddedCheckBox.setText("embedded menu bar"); @@ -359,12 +445,22 @@ private void initComponents() { menuBarEmbeddedCheckBox.addActionListener(e -> menuBarEmbeddedChanged()); add(menuBarEmbeddedCheckBox, "cell 0 1"); + //---- colorizeMenuBarCheckBox ---- + colorizeMenuBarCheckBox.setText("colorize menu bar"); + colorizeMenuBarCheckBox.addActionListener(e -> colorizeMenuBar()); + add(colorizeMenuBarCheckBox, "cell 1 1"); + //---- menuBarVisibleCheckBox ---- menuBarVisibleCheckBox.setText("menu bar visible"); menuBarVisibleCheckBox.setSelected(true); menuBarVisibleCheckBox.addActionListener(e -> menuBarVisibleChanged()); add(menuBarVisibleCheckBox, "cell 0 2"); + //---- colorizeMenusCheckBox ---- + colorizeMenusCheckBox.setText("colorize menus"); + colorizeMenusCheckBox.addActionListener(e -> colorizeMenus()); + add(colorizeMenusCheckBox, "cell 1 2"); + //---- resizableCheckBox ---- resizableCheckBox.setText("resizable"); resizableCheckBox.setSelected(true); @@ -683,11 +779,14 @@ private void initComponents() { // JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables private JCheckBox menuBarCheckBox; + private JCheckBox unifiedBackgroundCheckBox; private JButton addMenuButton; private JButton removeMenuButton; private JButton changeMenuButton; private JCheckBox menuBarEmbeddedCheckBox; + private JCheckBox colorizeMenuBarCheckBox; private JCheckBox menuBarVisibleCheckBox; + private JCheckBox colorizeMenusCheckBox; private JCheckBox resizableCheckBox; private JCheckBox maximizedBoundsCheckBox; private JCheckBox undecoratedCheckBox; 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 d536cc396..64f877b72 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.2.0.298" Java: "15" encoding: "UTF-8" +JFDML JFormDesigner: "7.0.3.1.342" Java: "15" encoding: "UTF-8" new FormModel { contentType: "form/swing" @@ -8,8 +8,8 @@ new FormModel { } add( new FormContainer( "com.formdev.flatlaf.testing.FlatTestPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) { "$layoutConstraints": "ltr,insets dialog,hidemode 3" - "$columnConstraints": "[left]para[left]" - "$rowConstraints": "para[]0[]0[]0[]0[][][top][]" + "$columnConstraints": "[left]para[left][fill]" + "$rowConstraints": "para[]0[]0[]unrel[]0[]unrel[][top][]" } ) { name: "this" add( new FormComponent( "javax.swing.JCheckBox" ) { @@ -23,35 +23,68 @@ new FormModel { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { "value": "cell 0 0" } ) - add( new FormComponent( "javax.swing.JButton" ) { - name: "addMenuButton" - "text": "Add menu" - auxiliary() { - "JavaCodeGenerator.variableLocal": false - } - addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "addMenu", false ) ) - }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 1 0 1 2,align left top,grow 0 0" - } ) - add( new FormComponent( "javax.swing.JButton" ) { - name: "removeMenuButton" - "text": "Remove menu" + add( new FormComponent( "javax.swing.JCheckBox" ) { + name: "unifiedBackgroundCheckBox" + "text": "unified background" auxiliary() { "JavaCodeGenerator.variableLocal": false } - addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "removeMenu", false ) ) + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "unifiedBackgroundChanged", false ) ) }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 1 0 1 2,align left top,grow 0 0" + "value": "cell 1 0" } ) - add( new FormComponent( "javax.swing.JButton" ) { - name: "changeMenuButton" - "text": "Change menu" - auxiliary() { - "JavaCodeGenerator.variableLocal": false - } - addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "changeMenu", false ) ) + add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) { + "$layoutConstraints": "hidemode 3" + "$columnConstraints": "[fill]" + "$rowConstraints": "[][][][]unrel[]" + } ) { + name: "panel3" + add( new FormComponent( "javax.swing.JButton" ) { + name: "addMenuButton" + "text": "Add menu" + auxiliary() { + "JavaCodeGenerator.variableLocal": false + } + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "addMenu", false ) ) + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 0" + } ) + add( new FormComponent( "javax.swing.JButton" ) { + name: "addGlueButton" + "text": "Add glue" + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "addGlue", false ) ) + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 1" + } ) + add( new FormComponent( "javax.swing.JButton" ) { + name: "removeMenuButton" + "text": "Remove menu" + auxiliary() { + "JavaCodeGenerator.variableLocal": false + } + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "removeMenu", false ) ) + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 2" + } ) + add( new FormComponent( "javax.swing.JButton" ) { + name: "changeMenuButton" + "text": "Change menu" + auxiliary() { + "JavaCodeGenerator.variableLocal": false + } + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "changeMenu", false ) ) + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 3" + } ) + add( new FormComponent( "javax.swing.JButton" ) { + name: "changeTitleButton" + "text": "Change title" + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "changeTitle", false ) ) + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 4" + } ) }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 1 0 1 2,align left top,grow 0 0" + "value": "cell 2 0 1 6,aligny top,growy 0" } ) add( new FormComponent( "javax.swing.JCheckBox" ) { name: "menuBarEmbeddedCheckBox" @@ -64,6 +97,16 @@ new FormModel { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { "value": "cell 0 1" } ) + add( new FormComponent( "javax.swing.JCheckBox" ) { + name: "colorizeMenuBarCheckBox" + "text": "colorize menu bar" + auxiliary() { + "JavaCodeGenerator.variableLocal": false + } + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "colorizeMenuBar", false ) ) + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 1 1" + } ) add( new FormComponent( "javax.swing.JCheckBox" ) { name: "menuBarVisibleCheckBox" "text": "menu bar visible" @@ -75,6 +118,16 @@ new FormModel { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { "value": "cell 0 2" } ) + add( new FormComponent( "javax.swing.JCheckBox" ) { + name: "colorizeMenusCheckBox" + "text": "colorize menus" + auxiliary() { + "JavaCodeGenerator.variableLocal": false + } + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "colorizeMenus", false ) ) + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 1 2" + } ) add( new FormComponent( "javax.swing.JCheckBox" ) { name: "resizableCheckBox" "text": "resizable" @@ -289,7 +342,7 @@ new FormModel { } ) }, new FormLayoutConstraints( null ) { "location": new java.awt.Point( 0, 0 ) - "size": new java.awt.Dimension( 550, 440 ) + "size": new java.awt.Dimension( 690, 440 ) } ) add( new FormContainer( "javax.swing.JMenuBar", new FormLayoutManager( class javax.swing.JMenuBar ) ) { name: "menuBar" 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 dd90b82a6..a35f8b7db 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 @@ -836,6 +836,8 @@ TitlePane.buttonHoverBackground TitlePane.buttonMaximizedHeight TitlePane.buttonPressedBackground TitlePane.buttonSize +TitlePane.centerTitle +TitlePane.centerTitleIfMenuBarEmbedded TitlePane.closeHoverBackground TitlePane.closeHoverForeground TitlePane.closeIcon @@ -850,9 +852,10 @@ TitlePane.inactiveBackground TitlePane.inactiveForeground TitlePane.maximizeIcon TitlePane.menuBarEmbedded -TitlePane.menuBarMargins +TitlePane.menuBarTitleGap TitlePane.restoreIcon TitlePane.titleMargins +TitlePane.unifiedBackground TitlePane.useWindowDecorations TitledBorder.border TitledBorder.font