From df4f51eff329c4865a51a3365e90a939eba62d0b Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Mon, 27 Jan 2020 15:23:03 +0100 Subject: [PATCH] InternalFrame: basic implementation (issues #39 and #11) --- CHANGELOG.md | 1 + .../java/com/formdev/flatlaf/FlatLaf.java | 3 +- .../icons/FlatInternalFrameAbstractIcon.java | 60 ++++++ .../icons/FlatInternalFrameCloseIcon.java | 17 +- .../icons/FlatInternalFrameIconifyIcon.java | 11 +- .../icons/FlatInternalFrameMaximizeIcon.java | 11 +- .../icons/FlatInternalFrameMinimizeIcon.java | 10 +- .../formdev/flatlaf/ui/FlatDesktopPaneUI.java | 39 ++++ .../ui/FlatInternalFrameTitlePane.java | 190 ++++++++++++++++++ .../flatlaf/ui/FlatInternalFrameUI.java | 155 ++++++++++++++ .../com/formdev/flatlaf/ui/FlatUIUtils.java | 9 +- .../formdev/flatlaf/FlatDarkLaf.properties | 23 +++ .../com/formdev/flatlaf/FlatLaf.properties | 18 ++ .../formdev/flatlaf/FlatLightLaf.properties | 23 +++ .../testing/FlatInternalFrameTest.java | 35 +++- .../flatlaf/testing/FlatInternalFrameTest.jfd | 18 +- .../flatlaf/testing/FlatTestFrame.java | 4 +- .../flatlaf/testing/FlatTestLaf.properties | 23 +++ 18 files changed, 612 insertions(+), 38 deletions(-) create mode 100644 flatlaf-core/src/main/java/com/formdev/flatlaf/icons/FlatInternalFrameAbstractIcon.java create mode 100644 flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatDesktopPaneUI.java create mode 100644 flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatInternalFrameTitlePane.java create mode 100644 flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatInternalFrameUI.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 6f589655..3e137af1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ FlatLaf Change Log ## Unreleased +- Support `JInternalFrame`. (issues #39 and #11) - ProgressBar: Fixed visual artifacts in indeterminate mode, on HiDPI screens at 125%, 150% and 175% scaling, when the progress moves around. 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 09e6d512..eb13d56b 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatLaf.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatLaf.java @@ -294,10 +294,9 @@ public abstract class FlatLaf // override fonts for( Object key : defaults.keySet() ) { - if( key instanceof String && ((String)key).endsWith( ".font" ) ) + if( key instanceof String && (((String)key).endsWith( ".font" ) || ((String)key).endsWith( "Font" )) ) defaults.put( key, uiFont ); } - defaults.put( "MenuItem.acceleratorFont", uiFont ); // use smaller font for progress bar defaults.put( "ProgressBar.font", UIScale.scaleFont( uiFont, 0.85f ) ); diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/icons/FlatInternalFrameAbstractIcon.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/icons/FlatInternalFrameAbstractIcon.java new file mode 100644 index 00000000..c1d4b982 --- /dev/null +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/icons/FlatInternalFrameAbstractIcon.java @@ -0,0 +1,60 @@ +/* + * Copyright 2019 FormDev Software GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.formdev.flatlaf.icons; + +import java.awt.Color; +import java.awt.Component; +import java.awt.Graphics2D; +import javax.swing.UIManager; +import com.formdev.flatlaf.ui.FlatButtonUI; +import com.formdev.flatlaf.ui.FlatUIUtils; + +/** + * Base class for internal frame icons. + * + * @uiDefault InternalFrame.buttonHoverBackground Color + * @uiDefault InternalFrame.buttonPressedBackground Color + * @uiDefault Button.arc int + * + * @author Karl Tauber + */ +public abstract class FlatInternalFrameAbstractIcon + extends FlatAbstractIcon +{ + private final Color hoverBackground; + private final Color pressedBackground; + private final int arc = UIManager.getInt( "Button.arc" ); + + public FlatInternalFrameAbstractIcon() { + this( UIManager.getColor( "InternalFrame.buttonHoverBackground" ), + UIManager.getColor( "InternalFrame.buttonPressedBackground" ) ); + } + + public FlatInternalFrameAbstractIcon( Color hoverBackground, Color pressedBackground ) { + super( 16, 16, null ); + this.hoverBackground = hoverBackground; + this.pressedBackground = pressedBackground; + } + + protected void paintBackground( Component c, Graphics2D g ) { + Color background = FlatButtonUI.buttonStateColor( c, null, null, null, hoverBackground, pressedBackground ); + if( background != null ) { + FlatUIUtils.setColor( g, background, c.getBackground() ); + g.fillRoundRect( 0, 0, width, height, arc, arc ); + } + } +} diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/icons/FlatInternalFrameCloseIcon.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/icons/FlatInternalFrameCloseIcon.java index 3471eece..3d3b56d2 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/icons/FlatInternalFrameCloseIcon.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/icons/FlatInternalFrameCloseIcon.java @@ -17,28 +17,39 @@ package com.formdev.flatlaf.icons; import java.awt.BasicStroke; +import java.awt.Color; import java.awt.Component; import java.awt.Graphics2D; import java.awt.geom.Line2D; import java.awt.geom.Path2D; import javax.swing.UIManager; +import com.formdev.flatlaf.ui.FlatButtonUI; /** * "close" icon for {@link javax.swing.JInternalFrame}. * - * @uiDefault InternalFrame.iconColor Color + * @uiDefault InternalFrame.buttonHoverBackground Color + * @uiDefault InternalFrame.buttonPressedBackground Color * * @author Karl Tauber */ public class FlatInternalFrameCloseIcon - extends FlatAbstractIcon + extends FlatInternalFrameAbstractIcon { + private final Color hoverForeground = UIManager.getColor( "InternalFrame.closeHoverForeground" ); + private final Color pressedForeground = UIManager.getColor( "InternalFrame.closePressedForeground" ); + public FlatInternalFrameCloseIcon() { - super( 16, 16, UIManager.getColor( "InternalFrame.iconColor" ) ); + super( UIManager.getColor( "InternalFrame.closeHoverBackground" ), + UIManager.getColor( "InternalFrame.closePressedBackground" ) ); } @Override protected void paintIcon( Component c, Graphics2D g ) { + paintBackground( c, g ); + + g.setColor( FlatButtonUI.buttonStateColor( c, null, null, null, hoverForeground, pressedForeground ) ); + float mx = 8; float my = 8; float r = 3.25f; diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/icons/FlatInternalFrameIconifyIcon.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/icons/FlatInternalFrameIconifyIcon.java index 2f59b283..b82b7225 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/icons/FlatInternalFrameIconifyIcon.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/icons/FlatInternalFrameIconifyIcon.java @@ -18,24 +18,23 @@ package com.formdev.flatlaf.icons; import java.awt.Component; import java.awt.Graphics2D; -import javax.swing.UIManager; /** * "iconify" icon for {@link javax.swing.JInternalFrame}. * - * @uiDefault InternalFrame.iconColor Color - * * @author Karl Tauber */ public class FlatInternalFrameIconifyIcon - extends FlatAbstractIcon + extends FlatInternalFrameAbstractIcon { public FlatInternalFrameIconifyIcon() { - super( 16, 16, UIManager.getColor( "InternalFrame.iconColor" ) ); } @Override protected void paintIcon( Component c, Graphics2D g ) { - g.fillRect( 3, 8, 10, 1 ); + paintBackground( c, g ); + + g.setColor( c.getForeground() ); + g.fillRect( 4, 8, 8, 1 ); } } diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/icons/FlatInternalFrameMaximizeIcon.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/icons/FlatInternalFrameMaximizeIcon.java index 3439e3de..99239ce4 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/icons/FlatInternalFrameMaximizeIcon.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/icons/FlatInternalFrameMaximizeIcon.java @@ -18,25 +18,24 @@ package com.formdev.flatlaf.icons; import java.awt.Component; import java.awt.Graphics2D; -import javax.swing.UIManager; import com.formdev.flatlaf.ui.FlatUIUtils; /** * "maximize" icon for {@link javax.swing.JInternalFrame}. * - * @uiDefault InternalFrame.iconColor Color - * * @author Karl Tauber */ public class FlatInternalFrameMaximizeIcon - extends FlatAbstractIcon + extends FlatInternalFrameAbstractIcon { public FlatInternalFrameMaximizeIcon() { - super( 16, 16, UIManager.getColor( "InternalFrame.iconColor" ) ); } @Override protected void paintIcon( Component c, Graphics2D g ) { - g.fill( FlatUIUtils.createRectangle( 3, 3, 10, 10, 1 ) ); + paintBackground( c, g ); + + g.setColor( c.getForeground() ); + g.fill( FlatUIUtils.createRectangle( 4, 4, 8, 8, 1 ) ); } } diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/icons/FlatInternalFrameMinimizeIcon.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/icons/FlatInternalFrameMinimizeIcon.java index d829cfcc..0745cec0 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/icons/FlatInternalFrameMinimizeIcon.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/icons/FlatInternalFrameMinimizeIcon.java @@ -21,25 +21,25 @@ import java.awt.Graphics2D; import java.awt.geom.Area; import java.awt.geom.Path2D; import java.awt.geom.Rectangle2D; -import javax.swing.UIManager; import com.formdev.flatlaf.ui.FlatUIUtils; /** * "minimize" (actually "restore") icon for {@link javax.swing.JInternalFrame}. * - * @uiDefault InternalFrame.iconColor Color - * * @author Karl Tauber */ public class FlatInternalFrameMinimizeIcon - extends FlatAbstractIcon + extends FlatInternalFrameAbstractIcon { public FlatInternalFrameMinimizeIcon() { - super( 16, 16, UIManager.getColor( "InternalFrame.iconColor" ) ); } @Override protected void paintIcon( Component c, Graphics2D g ) { + paintBackground( c, g ); + + g.setColor( c.getForeground() ); + Path2D r1 = FlatUIUtils.createRectangle( 5, 3, 8, 8, 1 ); Path2D r2 = FlatUIUtils.createRectangle( 3, 5, 8, 8, 1 ); diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatDesktopPaneUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatDesktopPaneUI.java new file mode 100644 index 00000000..bcaa0896 --- /dev/null +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatDesktopPaneUI.java @@ -0,0 +1,39 @@ +/* + * Copyright 2020 FormDev Software GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.formdev.flatlaf.ui; + +import javax.swing.JComponent; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.basic.BasicDesktopPaneUI; + +/** + * Provides the Flat LaF UI delegate for {@link javax.swing.JDesktopPane}. + * + * + * + * @uiDefault Desktop.background Color + * @uiDefault Desktop.minOnScreenInsets Insets + * + * @author Karl Tauber + */ +public class FlatDesktopPaneUI + extends BasicDesktopPaneUI +{ + public static ComponentUI createUI( JComponent c ) { + return new FlatDesktopPaneUI(); + } +} diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatInternalFrameTitlePane.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatInternalFrameTitlePane.java new file mode 100644 index 00000000..30596cf6 --- /dev/null +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatInternalFrameTitlePane.java @@ -0,0 +1,190 @@ +/* + * Copyright 2020 FormDev Software GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.formdev.flatlaf.ui; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.LayoutManager; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import javax.swing.BorderFactory; +import javax.swing.BoxLayout; +import javax.swing.Icon; +import javax.swing.JInternalFrame; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.LookAndFeel; +import javax.swing.UIManager; +import javax.swing.border.Border; +import javax.swing.plaf.basic.BasicInternalFrameTitlePane; +import com.formdev.flatlaf.util.UIScale; + +/** + * Provides the Flat LaF internal frame title bar. + * + * @author Karl Tauber + */ +public class FlatInternalFrameTitlePane + extends BasicInternalFrameTitlePane +{ + private JLabel titleLabel; + private JPanel buttonPanel; + + public FlatInternalFrameTitlePane( JInternalFrame f ) { + super( f ); + } + + @Override + protected void installDefaults() { + super.installDefaults(); + + LookAndFeel.installBorder( this, "InternalFrameTitlePane.border" ); + } + + @Override + protected PropertyChangeListener createPropertyChangeListener() { + return new FlatPropertyChangeHandler(); + } + + @Override + protected LayoutManager createLayout() { + return new BorderLayout( UIScale.scale( 4 ), 0 ); + } + + @Override + protected void createButtons() { + super.createButtons(); + + iconButton.setContentAreaFilled( false ); + maxButton.setContentAreaFilled( false ); + closeButton.setContentAreaFilled( false ); + + Border emptyBorder = BorderFactory.createEmptyBorder(); + iconButton.setBorder( emptyBorder ); + maxButton.setBorder( emptyBorder ); + closeButton.setBorder( emptyBorder ); + + updateButtonsVisibility(); + } + + @Override + protected void addSubComponents() { + titleLabel = new JLabel( frame.getTitle() ); + titleLabel.setFont( FlatUIUtils.nonUIResource( getFont() ) ); + titleLabel.setMinimumSize( new Dimension( UIScale.scale( 32 ), 1 ) ); + updateFrameIcon(); + updateColors(); + + buttonPanel = new JPanel(); + buttonPanel.setLayout( new BoxLayout( buttonPanel, BoxLayout.LINE_AXIS ) ); + buttonPanel.setOpaque( false ); + + buttonPanel.add( iconButton ); + buttonPanel.add( maxButton ); + buttonPanel.add( closeButton ); + + add( titleLabel, BorderLayout.CENTER ); + add( buttonPanel, BorderLayout.LINE_END ); + } + + private void updateFrameIcon() { + Icon frameIcon = frame.getFrameIcon(); + if( frameIcon == UIManager.getIcon( "InternalFrame.icon" ) ) + frameIcon = null; + titleLabel.setIcon( frameIcon ); + } + + private void updateColors() { + Color background = FlatUIUtils.nonUIResource( frame.isSelected() ? selectedTitleColor : notSelectedTitleColor ); + Color foreground = FlatUIUtils.nonUIResource( frame.isSelected() ? selectedTextColor : notSelectedTextColor ); + + titleLabel.setForeground( foreground ); + iconButton.setBackground( background ); + iconButton.setForeground( foreground ); + maxButton.setBackground( background ); + maxButton.setForeground( foreground ); + closeButton.setBackground( background ); + closeButton.setForeground( foreground ); + } + + private void updateButtonsVisibility() { + iconButton.setVisible( frame.isIconifiable() ); + maxButton.setVisible( frame.isMaximizable() ); + closeButton.setVisible( frame.isClosable() ); + } + + /** + * Does nothing because FlatLaf internal frames do not have system menus. + */ + @Override + protected void assembleSystemMenu() { + } + + /** + * Does nothing because FlatLaf internal frames do not have system menus. + */ + @Override + protected void showSystemMenu() { + } + + @Override + public void paintComponent( Graphics g ) { + paintTitleBackground( g ); + } + + //---- class FlatPropertyChangeHandler ------------------------------------ + + private class FlatPropertyChangeHandler + extends PropertyChangeHandler + { + @Override + public void propertyChange( PropertyChangeEvent e ) { + switch( e.getPropertyName() ) { + case JInternalFrame.TITLE_PROPERTY: + titleLabel.setText( frame.getTitle() ); + break; + + case JInternalFrame.FRAME_ICON_PROPERTY: + updateFrameIcon(); + break; + + case JInternalFrame.IS_SELECTED_PROPERTY: + updateColors(); + break; + + case "iconable": + case "maximizable": + case "closable": + updateButtonsVisibility(); + enableActions(); + revalidate(); + repaint(); + + // do not invoke super.propertyChange() because this adds/removes the buttons + return; + + case "componentOrientation": + applyComponentOrientation( frame.getComponentOrientation() ); + break; + } + + super.propertyChange( e ); + } + } +} diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatInternalFrameUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatInternalFrameUI.java new file mode 100644 index 00000000..5d60fd17 --- /dev/null +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatInternalFrameUI.java @@ -0,0 +1,155 @@ +/* + * Copyright 2020 FormDev Software GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.formdev.flatlaf.ui; + +import static com.formdev.flatlaf.util.UIScale.scale; +import java.awt.Color; +import java.awt.Component; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Insets; +import javax.swing.JComponent; +import javax.swing.JInternalFrame; +import javax.swing.LookAndFeel; +import javax.swing.UIManager; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.basic.BasicInternalFrameUI; + +/** + * Provides the Flat LaF UI delegate for {@link javax.swing.JInternalFrame}. + * + * + * + * @uiDefault control Color + * @uiDefault InternalFrame.icon Icon + * @uiDefault InternalFrame.border Border + * @uiDefault InternalFrame.layoutTitlePaneAtOrigin boolean + * + * + * + * @uiDefault InternalFrame.titleFont Font + * @uiDefault InternalFrame.icon Icon + * @uiDefault InternalFrame.maximizeIcon Icon + * @uiDefault InternalFrame.minimizeIcon Icon + * @uiDefault InternalFrame.iconifyIcon Icon + * @uiDefault InternalFrame.closeIcon Icon + * @uiDefault InternalFrame.activeTitleBackground Color + * @uiDefault InternalFrame.activeTitleForeground Color + * @uiDefault InternalFrame.inactiveTitleBackground Color + * @uiDefault InternalFrame.inactiveTitleForeground Color + * @uiDefault InternalFrame.closeButtonToolTip String + * @uiDefault InternalFrame.iconButtonToolTip String + * @uiDefault InternalFrame.restoreButtonToolTip String + * @uiDefault InternalFrame.maxButtonToolTip String + * @uiDefault InternalFrameTitlePane.closeButtonText String + * @uiDefault InternalFrameTitlePane.minimizeButtonText String + * @uiDefault InternalFrameTitlePane.restoreButtonText String + * @uiDefault InternalFrameTitlePane.maximizeButtonText String + * @uiDefault InternalFrameTitlePane.moveButtonText String + * @uiDefault InternalFrameTitlePane.sizeButtonText String + * @uiDefault InternalFrameTitlePane.closeButton.mnemonic Integer + * @uiDefault InternalFrameTitlePane.minimizeButton.mnemonic Integer + * @uiDefault InternalFrameTitlePane.restoreButton.mnemonic Integer + * @uiDefault InternalFrameTitlePane.maximizeButton.mnemonic Integer + * @uiDefault InternalFrameTitlePane.moveButton.mnemonic Integer + * @uiDefault InternalFrameTitlePane.sizeButton.mnemonic Integer + * + * + * + * @uiDefault InternalFrame.activeBorderColor Color + * @uiDefault InternalFrame.inactiveBorderColor Color + * @uiDefault InternalFrame.borderLineWidth int + * @uiDefault InternalFrame.borderMargins Insets + * + * + * + * @uiDefault InternalFrameTitlePane.border Border + * + * @author Karl Tauber + */ +public class FlatInternalFrameUI + extends BasicInternalFrameUI +{ + public static ComponentUI createUI( JComponent c ) { + return new FlatInternalFrameUI( (JInternalFrame) c ); + } + + public FlatInternalFrameUI( JInternalFrame b ) { + super( b ); + } + + @Override + public void installUI( JComponent c ) { + super.installUI( c ); + + LookAndFeel.installProperty( frame, "opaque", false ); + } + + @Override + protected JComponent createNorthPane( JInternalFrame w ) { + return new FlatInternalFrameTitlePane( w ); + } + + //---- class FlatInternalFrameBorder -------------------------------------- + + public static class FlatInternalFrameBorder + extends FlatEmptyBorder + { + private final Color activeBorderColor = UIManager.getColor( "InternalFrame.activeBorderColor" ); + private final Color inactiveBorderColor = UIManager.getColor( "InternalFrame.inactiveBorderColor" ); + private final int borderLineWidth = FlatUIUtils.getUIInt( "InternalFrame.borderLineWidth", 1 ); + + public FlatInternalFrameBorder() { + super( UIManager.getInsets( "InternalFrame.borderMargins" ) ); + } + + @Override + public Insets getBorderInsets( Component c, Insets insets ) { + if( c instanceof JInternalFrame && ((JInternalFrame)c).isMaximum() ) { + insets.left = scale( Math.min( borderLineWidth, left ) ); + insets.top = scale( Math.min( borderLineWidth, top ) ); + insets.right = scale( Math.min( borderLineWidth, right ) ); + insets.bottom = scale( Math.min( borderLineWidth, bottom ) ); + return insets; + } + + return super.getBorderInsets( c, insets ); + } + + @Override + public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) { + JInternalFrame f = (JInternalFrame) c; + + Insets insets = getBorderInsets( c ); + float lineWidth = scale( (float) borderLineWidth ); + + Graphics2D g2 = (Graphics2D) g.create(); + try { + FlatUIUtils.setRenderingHints( g2 ); + g2.setColor( f.isSelected() ? activeBorderColor : inactiveBorderColor ); + g2.fill( FlatUIUtils.createRectangle( + x + insets.left - lineWidth, + y + insets.top - lineWidth, + width - insets.left - insets.right + (lineWidth * 2), + height - insets.top - insets.bottom + (lineWidth * 2), + lineWidth ) ); + } finally { + g2.dispose(); + } + } + } +} 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 e8e1dec1..68e005e6 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 @@ -20,6 +20,7 @@ import java.awt.Color; import java.awt.Component; import java.awt.Container; import java.awt.Dimension; +import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Insets; @@ -37,7 +38,7 @@ import java.util.function.Consumer; import javax.swing.JComponent; import javax.swing.LookAndFeel; import javax.swing.UIManager; -import javax.swing.plaf.ColorUIResource; +import javax.swing.plaf.UIResource; import com.formdev.flatlaf.FlatClientProperties; import com.formdev.flatlaf.util.DerivedColor; import com.formdev.flatlaf.util.HiDPIUtils; @@ -109,7 +110,11 @@ public class FlatUIUtils } public static Color nonUIResource( Color c ) { - return (c instanceof ColorUIResource) ? new Color( c.getRGB(), true ) : c; + return (c instanceof UIResource) ? new Color( c.getRGB(), true ) : c; + } + + public static Font nonUIResource( Font font ) { + return (font instanceof UIResource) ? new Font( font.getName(), font.getStyle(), font.getSize() ) : font; } public static int minimumWidth( JComponent c, int minimumWidth ) { diff --git a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatDarkLaf.properties b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatDarkLaf.properties index e529f9ff..41153a26 100644 --- a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatDarkLaf.properties +++ b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatDarkLaf.properties @@ -131,6 +131,29 @@ Component.focusColor=#3d6185 Component.linkColor=#589df6 +#---- Desktop ---- + +Desktop.background=#3E434C + + +#---- InternalFrame ---- + +InternalFrame.activeTitleBackground=darken(@background,10%) +InternalFrame.activeTitleForeground=@foreground +InternalFrame.inactiveTitleBackground=darken(@background,5%) +InternalFrame.inactiveTitleForeground=@disabledText + +InternalFrame.activeBorderColor=lighten($Component.borderColor,10%) +InternalFrame.inactiveBorderColor=$Component.borderColor + +InternalFrame.buttonHoverBackground=lighten(10%,autoInverse) +InternalFrame.buttonPressedBackground=lighten(20%,autoInverse) +InternalFrame.closeHoverBackground=lazy(Actions.Red) +InternalFrame.closePressedBackground=darken(Actions.Red,10%,lazy) +InternalFrame.closeHoverForeground=#fff +InternalFrame.closePressedForeground=#fff + + #---- List ---- List.background=@textComponentBackground 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 af9c9d31..adb54bea 100644 --- a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties +++ b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties @@ -21,9 +21,11 @@ CheckBoxUI=com.formdev.flatlaf.ui.FlatCheckBoxUI CheckBoxMenuItemUI=com.formdev.flatlaf.ui.FlatCheckBoxMenuItemUI ColorChooserUI=com.formdev.flatlaf.ui.FlatColorChooserUI ComboBoxUI=com.formdev.flatlaf.ui.FlatComboBoxUI +DesktopPaneUI=com.formdev.flatlaf.ui.FlatDesktopPaneUI EditorPaneUI=com.formdev.flatlaf.ui.FlatEditorPaneUI FileChooserUI=com.formdev.flatlaf.ui.FlatFileChooserUI FormattedTextFieldUI=com.formdev.flatlaf.ui.FlatFormattedTextFieldUI +InternalFrameUI=com.formdev.flatlaf.ui.FlatInternalFrameUI LabelUI=com.formdev.flatlaf.ui.FlatLabelUI ListUI=com.formdev.flatlaf.ui.FlatListUI MenuUI=com.formdev.flatlaf.ui.FlatMenuUI @@ -197,6 +199,22 @@ HelpButton.questionMarkColor=$CheckBox.icon.checkmarkColor HelpButton.disabledQuestionMarkColor=$CheckBox.icon.disabledCheckmarkColor +#---- InternalFrame ---- + +InternalFrame.border=com.formdev.flatlaf.ui.FlatInternalFrameUI$FlatInternalFrameBorder +InternalFrame.borderLineWidth=1 +InternalFrame.borderMargins=6,6,6,6 +InternalFrame.closeIcon=com.formdev.flatlaf.icons.FlatInternalFrameCloseIcon +InternalFrame.iconifyIcon=com.formdev.flatlaf.icons.FlatInternalFrameIconifyIcon +InternalFrame.maximizeIcon=com.formdev.flatlaf.icons.FlatInternalFrameMaximizeIcon +InternalFrame.minimizeIcon=com.formdev.flatlaf.icons.FlatInternalFrameMinimizeIcon + + +#---- InternalFrameTitlePane ---- + +InternalFrameTitlePane.border=4,8,4,4 + + #---- List ---- List.border=1,0,1,0 diff --git a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLightLaf.properties b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLightLaf.properties index 6039030a..c8c66dc0 100644 --- a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLightLaf.properties +++ b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLightLaf.properties @@ -133,11 +133,34 @@ Component.focusColor=#97c3f3 Component.linkColor=#2470B3 +#---- Desktop ---- + +Desktop.background=#E6EBF0 + + #---- HelpButton ---- HelpButton.questionMarkColor=#4F9EE3 +#---- InternalFrame ---- + +InternalFrame.activeTitleBackground=#fff +InternalFrame.activeTitleForeground=@foreground +InternalFrame.inactiveTitleBackground=#fafafa +InternalFrame.inactiveTitleForeground=@disabledText + +InternalFrame.activeBorderColor=darken($Component.borderColor,20%) +InternalFrame.inactiveBorderColor=$Component.borderColor + +InternalFrame.buttonHoverBackground=darken(10%,autoInverse) +InternalFrame.buttonPressedBackground=darken(20%,autoInverse) +InternalFrame.closeHoverBackground=lazy(Actions.Red) +InternalFrame.closePressedBackground=darken(Actions.Red,10%,lazy) +InternalFrame.closeHoverForeground=#fff +InternalFrame.closePressedForeground=#fff + + #---- List ---- List.background=@textComponentBackground diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatInternalFrameTest.java b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatInternalFrameTest.java index 634fe7b6..4c2a7567 100644 --- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatInternalFrameTest.java +++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatInternalFrameTest.java @@ -7,6 +7,7 @@ package com.formdev.flatlaf.testing; import java.awt.*; import java.beans.PropertyVetoException; import javax.swing.*; +import com.formdev.flatlaf.icons.FlatFileViewFloppyDriveIcon; import com.formdev.flatlaf.util.UIScale; import net.miginfocom.swing.*; @@ -49,10 +50,25 @@ public class FlatInternalFrameTest maximizableCheckBox.isSelected(), iconifiableCheckBox.isSelected() ); - JPanel panel = new JPanel(); - panel.setBackground( new Color( (int) (Math.random() * 0xffffff) ) ); + if( iconCheckBox.isSelected() ) + internalFrame.setFrameIcon( new FlatFileViewFloppyDriveIcon() ); + + JPanel panel = new JPanel() { + private final Color color = new Color( (int) (Math.random() * 0xffffff) | 0x20000000, true ); + + @Override + protected void paintComponent( Graphics g ) { + super.paintComponent( g ); + + g.setColor( color ); + g.fillRect( 20, 20, getWidth() - 40, getHeight() - 40 ); + } + }; internalFrame.setContentPane( panel ); + if( !palette.getComponentOrientation().isLeftToRight() ) + internalFrame.setComponentOrientation( ComponentOrientation.RIGHT_TO_LEFT ); + internalFrame.setBounds( frameX + UIScale.scale( GAP ) * (frameCount % 10), frameY + UIScale.scale( GAP ) * (frameCount % 10), UIScale.scale( 200 ), UIScale.scale( 200 ) ); desktopPane.add( internalFrame, JLayeredPane.DEFAULT_LAYER ); @@ -76,6 +92,7 @@ public class FlatInternalFrameTest closableCheckBox = new JCheckBox(); iconifiableCheckBox = new JCheckBox(); maximizableCheckBox = new JCheckBox(); + iconCheckBox = new JCheckBox(); titleLabel = new JLabel(); titleField = new JTextField(); createFrameButton = new JButton(); @@ -107,6 +124,7 @@ public class FlatInternalFrameTest // rows "[fill]0" + "[]0" + + "[]0" + "[]unrel" + "[]unrel")); @@ -130,18 +148,22 @@ public class FlatInternalFrameTest maximizableCheckBox.setSelected(true); paletteContentPane.add(maximizableCheckBox, "cell 1 1,alignx left,growx 0"); + //---- iconCheckBox ---- + iconCheckBox.setText("Frame icon"); + paletteContentPane.add(iconCheckBox, "cell 0 2"); + //---- titleLabel ---- titleLabel.setText("Frame title:"); - paletteContentPane.add(titleLabel, "cell 0 2"); - paletteContentPane.add(titleField, "cell 1 2"); + paletteContentPane.add(titleLabel, "cell 0 3"); + paletteContentPane.add(titleField, "cell 1 3"); //---- createFrameButton ---- createFrameButton.setText("Create Frame"); createFrameButton.addActionListener(e -> createInternalFrame()); - paletteContentPane.add(createFrameButton, "cell 1 3,alignx right,growx 0"); + paletteContentPane.add(createFrameButton, "cell 1 4,alignx right,growx 0"); } desktopPane.add(palette, JLayeredPane.PALETTE_LAYER); - palette.setBounds(15, 25, 220, 160); + palette.setBounds(15, 25, 220, 185); } add(desktopPane, "cell 0 0,width 600,height 600"); // JFormDesigner - End of component initialization //GEN-END:initComponents @@ -157,6 +179,7 @@ public class FlatInternalFrameTest private JCheckBox closableCheckBox; private JCheckBox iconifiableCheckBox; private JCheckBox maximizableCheckBox; + private JCheckBox iconCheckBox; private JLabel titleLabel; private JTextField titleField; private JButton createFrameButton; diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatInternalFrameTest.jfd b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatInternalFrameTest.jfd index fef36b35..e74e2a14 100644 --- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatInternalFrameTest.jfd +++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatInternalFrameTest.jfd @@ -1,4 +1,4 @@ -JFDML JFormDesigner: "7.0.0.0.194" Java: "11.0.2" encoding: "UTF-8" +JFDML JFormDesigner: "7.0.0.0.194" Java: "13.0.1" encoding: "UTF-8" new FormModel { contentType: "form/swing" @@ -14,7 +14,7 @@ new FormModel { add( new FormContainer( "javax.swing.JInternalFrame", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) { "$layoutConstraints": "hidemode 3" "$columnConstraints": "[fill][fill]" - "$rowConstraints": "[fill]0[]0[]unrel[]unrel" + "$rowConstraints": "[fill]0[]0[]0[]unrel[]unrel" } ) { name: "palette" "visible": true @@ -50,29 +50,35 @@ new FormModel { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { "value": "cell 1 1,alignx left,growx 0" } ) + add( new FormComponent( "javax.swing.JCheckBox" ) { + name: "iconCheckBox" + "text": "Frame icon" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 2" + } ) add( new FormComponent( "javax.swing.JLabel" ) { name: "titleLabel" "text": "Frame title:" }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 0 2" + "value": "cell 0 3" } ) add( new FormComponent( "javax.swing.JTextField" ) { name: "titleField" }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 1 2" + "value": "cell 1 3" } ) add( new FormComponent( "javax.swing.JButton" ) { name: "createFrameButton" "text": "Create Frame" addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "createInternalFrame", false ) ) }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 1 3,alignx right,growx 0" + "value": "cell 1 4,alignx right,growx 0" } ) }, new FormLayoutConstraints( null ) { "x": 15 "y": 25 "width": 220 - "height": 160 + "height": 185 "layer": 100 } ) }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatTestFrame.java b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatTestFrame.java index 97f8c5da..87ef3afc 100644 --- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatTestFrame.java +++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatTestFrame.java @@ -403,8 +403,8 @@ public class FlatTestFrame private void updateComponentsRecur( Container container, BiConsumer action ) { for( Component c : container.getComponents() ) { - if( c instanceof JPanel ) { - updateComponentsRecur( (JPanel) c, action ); + if( c instanceof JPanel || c instanceof JDesktopPane ) { + updateComponentsRecur( (Container) c, action ); continue; } diff --git a/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/FlatTestLaf.properties b/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/FlatTestLaf.properties index 15353a21..439f3322 100644 --- a/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/FlatTestLaf.properties +++ b/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/FlatTestLaf.properties @@ -130,11 +130,34 @@ Component.focusColor=#97c3f3 #Component.arc=8 +#---- Desktop ---- + +Desktop.background=#afe + + #---- HelpButton ---- HelpButton.questionMarkColor=#0000ff +#---- InternalFrame ---- + +InternalFrame.activeTitleBackground=#800 +InternalFrame.activeTitleForeground=#faa +InternalFrame.inactiveTitleBackground=#080 +InternalFrame.inactiveTitleForeground=#afa + +InternalFrame.activeBorderColor=#f00 +InternalFrame.inactiveBorderColor=#0f0 + +InternalFrame.buttonHoverBackground=#080 +InternalFrame.buttonPressedBackground=#0a0 +InternalFrame.closeHoverBackground=#008 +InternalFrame.closePressedBackground=#00f +InternalFrame.closeHoverForeground=#fff +InternalFrame.closePressedForeground=#fff + + #---- Label ---- Label.foreground=#008800