From 1f6a23f909cfd19e5bf815a8762d4835d7556c3c Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Fri, 5 Nov 2021 15:27:31 +0100 Subject: [PATCH] Styling: support defining component type specific styles, which are applied to all components of that type (e.g. `[style]ScrollPane = focusedBorderColor: #f00`) --- .../flatlaf/ui/FlatStylingSupport.java | 25 +- .../formdev/flatlaf/ui/TestFlatStyleType.java | 293 ++++++++++++++++++ .../com/formdev/flatlaf/ui/TestUtils.java | 8 +- 3 files changed, 324 insertions(+), 2 deletions(-) create mode 100644 flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyleType.java diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatStylingSupport.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatStylingSupport.java index cbbbeec1..dfb51780 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatStylingSupport.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatStylingSupport.java @@ -97,7 +97,8 @@ public class FlatStylingSupport Object style = getStyle( c ); Object styleClass = getStyleClass( c ); Object styleForClasses = getStyleForClasses( styleClass, type ); - return joinStyles( styleForClasses, style ); + Object styleForType = getStyleForType( type ); + return joinStyles( joinStyles( styleForType, styleForClasses ), style ); } /** @@ -162,6 +163,28 @@ public class FlatStylingSupport UIManager.get( "[style]" + type + '.' + styleClass ) ); } + /** + * Returns the styles for the given type. + *

+ * The style rules must be defined in UI defaults either as strings (in CSS syntax) + * or as {@link java.util.Map}<String, Object> (with binary values). + * The key must be in syntax: {@code [style]type}. + * E.g. in FlatLaf properties file: + *

{@code
+	 * [style]Button = borderColor: #08f; background: #08f; foreground: #fff
+	 * }
+ * or in Java code: + *
{@code
+	 * UIManager.put( "[style]Button", "borderColor: #08f; background: #08f; foreground: #fff" );
+	 * }
+ * + * @param type the type of the component + * @return the styles + */ + public static Object getStyleForType( String type ) { + return UIManager.get( "[style]" + type ); + } + /** * Joins two styles. They can be either strings (in CSS syntax) * or {@link java.util.Map}<String, Object> (with binary values). diff --git a/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyleType.java b/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyleType.java new file mode 100644 index 00000000..6954efd5 --- /dev/null +++ b/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyleType.java @@ -0,0 +1,293 @@ +/* + * Copyright 2021 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 org.junit.jupiter.api.Assertions.assertEquals; +import java.awt.Color; +import java.awt.Dimension; +import javax.swing.*; +import javax.swing.table.JTableHeader; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import com.formdev.flatlaf.FlatSystemProperties; + +/** + * @author Karl Tauber + */ +public class TestFlatStyleType +{ + @BeforeAll + static void setup() { + System.setProperty( FlatSystemProperties.UI_SCALE_ENABLED, "false" ); + TestUtils.setup( false ); + + UIManager.put( "[style]Button", "foreground: #000001" ); + UIManager.put( "[style]CheckBox", "foreground: #000002" ); + UIManager.put( "[style]ComboBox", "foreground: #000003" ); + UIManager.put( "[style]EditorPane", "foreground: #000004" ); + UIManager.put( "[style]FormattedTextField", "foreground: #000005" ); + UIManager.put( "[style]InternalFrame", "foreground: #000006" ); + UIManager.put( "[style]Label", "foreground: #000007" ); + UIManager.put( "[style]List", "foreground: #000008" ); + UIManager.put( "[style]MenuBar", "foreground: #000009" ); + UIManager.put( "[style]Menu", "foreground: #000010" ); + UIManager.put( "[style]MenuItem", "foreground: #000011" ); + UIManager.put( "[style]CheckBoxMenuItem", "foreground: #000012" ); + UIManager.put( "[style]RadioButtonMenuItem", "foreground: #000013" ); + UIManager.put( "[style]PasswordField", "foreground: #000014" ); + UIManager.put( "[style]PopupMenu", "foreground: #000015" ); + UIManager.put( "[style]PopupMenuSeparator", "foreground: #000016" ); + UIManager.put( "[style]ProgressBar", "foreground: #000017" ); + UIManager.put( "[style]RadioButton", "foreground: #000018" ); + UIManager.put( "[style]ScrollBar", "foreground: #000019" ); + UIManager.put( "[style]ScrollPane", "foreground: #000020" ); + UIManager.put( "[style]Separator", "foreground: #000021" ); + UIManager.put( "[style]Slider", "foreground: #000022" ); + UIManager.put( "[style]Spinner", "foreground: #000023" ); + UIManager.put( "[style]SplitPane", "foreground: #000024" ); + UIManager.put( "[style]TabbedPane", "foreground: #000025" ); + UIManager.put( "[style]Table", "foreground: #000026" ); + UIManager.put( "[style]TableHeader", "foreground: #000027" ); + UIManager.put( "[style]TextArea", "foreground: #000028" ); + UIManager.put( "[style]TextField", "foreground: #000029" ); + UIManager.put( "[style]TextPane", "foreground: #000030" ); + UIManager.put( "[style]ToggleButton", "foreground: #000031" ); + UIManager.put( "[style]ToolBar", "foreground: #000032" ); + UIManager.put( "[style]Tree", "foreground: #000033" ); + + // JToolBar.Separator + UIManager.put( "[style]ToolBarSeparator", "separatorWidth: 21" ); + } + + @AfterAll + static void cleanup() { + TestUtils.cleanup(); + System.clearProperty( FlatSystemProperties.UI_SCALE_ENABLED ); + } + + @Test + void styleForType() { + assertEquals( "foreground: #000001", FlatStylingSupport.getStyleForType( "Button" ) ); + } + + //---- components --------------------------------------------------------- + + @Test + void button() { + JButton c = new JButton(); + assertEquals( new Color( 0x000001 ), c.getForeground() ); + } + + @Test + void checkBox() { + JCheckBox c = new JCheckBox(); + assertEquals( new Color( 0x000002 ), c.getForeground() ); + } + + @Test + void comboBox() { + JComboBox c = new JComboBox<>(); + assertEquals( new Color( 0x000003 ), c.getForeground() ); + } + + @Test + void editorPane() { + JEditorPane c = new JEditorPane(); + assertEquals( new Color( 0x000004 ), c.getForeground() ); + } + + @Test + void formattedTextField() { + JFormattedTextField c = new JFormattedTextField(); + assertEquals( new Color( 0x000005 ), c.getForeground() ); + } + + @Test + void internalFrame() { + JInternalFrame c = new JInternalFrame(); + assertEquals( new Color( 0x000006 ), c.getForeground() ); + } + + @Test + void label() { + JLabel c = new JLabel(); + assertEquals( new Color( 0x000007 ), c.getForeground() ); + } + + @Test + void list() { + JList c = new JList<>(); + assertEquals( new Color( 0x000008 ), c.getForeground() ); + } + + @Test + void menuBar() { + JMenuBar c = new JMenuBar(); + assertEquals( new Color( 0x000009 ), c.getForeground() ); + } + + @Test + void menu() { + JMenu c = new JMenu(); + assertEquals( new Color( 0x000010 ), c.getForeground() ); + } + + @Test + void menuItem() { + JMenuItem c = new JMenuItem(); + assertEquals( new Color( 0x000011 ), c.getForeground() ); + } + + @Test + void checkBoxMenuItem() { + JCheckBoxMenuItem c = new JCheckBoxMenuItem(); + assertEquals( new Color( 0x000012 ), c.getForeground() ); + } + + @Test + void radioButtonMenuItem() { + JRadioButtonMenuItem c = new JRadioButtonMenuItem(); + assertEquals( new Color( 0x000013 ), c.getForeground() ); + } + + @Test + void passwordField() { + JPasswordField c = new JPasswordField(); + assertEquals( new Color( 0x000014 ), c.getForeground() ); + } + + @Test + void popupMenu() { + JPopupMenu c = new JPopupMenu(); + assertEquals( new Color( 0x000015 ), c.getForeground() ); + } + + @Test + void popupMenuSeparator() { + JPopupMenu.Separator c = new JPopupMenu.Separator(); + assertEquals( new Color( 0x000016 ), c.getForeground() ); + } + + @Test + void progressBar() { + JProgressBar c = new JProgressBar(); + assertEquals( new Color( 0x000017 ), c.getForeground() ); + } + + @Test + void radioButton() { + JRadioButton c = new JRadioButton(); + assertEquals( new Color( 0x000018 ), c.getForeground() ); + } + + @Test + void scrollBar() { + JScrollBar c = new JScrollBar(); + assertEquals( new Color( 0x000019 ), c.getForeground() ); + } + + @Test + void scrollPane() { + JScrollPane c = new JScrollPane(); + assertEquals( new Color( 0x000020 ), c.getForeground() ); + } + + @Test + void separator() { + JSeparator c = new JSeparator(); + assertEquals( new Color( 0x000021 ), c.getForeground() ); + } + + @Test + void slider() { + JSlider c = new JSlider(); + assertEquals( new Color( 0x000022 ), c.getForeground() ); + } + + @Test + void spinner() { + JSpinner c = new JSpinner(); + assertEquals( new Color( 0x000023 ), c.getForeground() ); + } + + @Test + void splitPane() { + JSplitPane c = new JSplitPane(); + assertEquals( new Color( 0x000024 ), c.getForeground() ); + } + + @Test + void tabbedPane() { + JTabbedPane c = new JTabbedPane(); + assertEquals( new Color( 0x000025 ), c.getForeground() ); + } + + @Test + void table() { + JTable c = new JTable(); + assertEquals( new Color( 0x000026 ), c.getForeground() ); + } + + @Test + void tableHeader() { + JTableHeader c = new JTableHeader(); + assertEquals( new Color( 0x000027 ), c.getForeground() ); + } + + @Test + void textArea() { + JTextArea c = new JTextArea(); + assertEquals( new Color( 0x000028 ), c.getForeground() ); + } + + @Test + void textField() { + JTextField c = new JTextField(); + assertEquals( new Color( 0x000029 ), c.getForeground() ); + } + + @Test + void textPane() { + JTextPane c = new JTextPane(); + assertEquals( new Color( 0x000030 ), c.getForeground() ); + } + + @Test + void toggleButton() { + JToggleButton c = new JToggleButton(); + assertEquals( new Color( 0x000031 ), c.getForeground() ); + } + + @Test + void toolBar() { + JToolBar c = new JToolBar(); + assertEquals( new Color( 0x000032 ), c.getForeground() ); + } + + @Test + void toolBarSeparator() { + JToolBar.Separator c = new JToolBar.Separator(); + assertEquals( new Dimension( 0, 21 ), c.getPreferredSize() ); + } + + @Test + void tree() { + JTree c = new JTree(); + assertEquals( new Color( 0x000033 ), c.getForeground() ); + } +} diff --git a/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestUtils.java b/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestUtils.java index d9399383..ccbe0df4 100644 --- a/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestUtils.java +++ b/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestUtils.java @@ -17,6 +17,7 @@ package com.formdev.flatlaf.ui; import java.awt.Font; +import java.util.Iterator; import java.util.Map; import java.util.Objects; import javax.swing.UIManager; @@ -42,7 +43,12 @@ public class TestUtils } public static void cleanup() { - UIManager.put( "defaultFont", null ); + // remove all properties added by UIManager.put() + Iterator it = UIManager.getDefaults().keySet().iterator(); + while( it.hasNext() ) { + it.next(); + it.remove(); + } } public static void scaleFont( float factor ) {