From d0b0f098d9e49806e8bcd0247bd267d66dfec5f0 Mon Sep 17 00:00:00 2001 From: mmatessi <17149962+basix86@users.noreply.github.com> Date: Thu, 27 Feb 2020 15:46:28 +0100 Subject: [PATCH 1/8] disabledIcon --- .../java/com/formdev/flatlaf/FlatLaf.java | 18 ++++---- .../com/formdev/flatlaf/ui/FlatButtonUI.java | 2 + .../ui/FlatDisabledButtonImageFilter.java | 28 ++++++++++++ .../com/formdev/flatlaf/ui/FlatUIUtils.java | 45 +++++++++++++------ 4 files changed, 69 insertions(+), 24 deletions(-) create mode 100644 flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatDisabledButtonImageFilter.java 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 c02ec1e1..eb72c17b 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatLaf.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatLaf.java @@ -36,20 +36,13 @@ import java.util.Map; import java.util.function.Consumer; import java.util.logging.Level; import java.util.logging.Logger; -import javax.swing.AbstractButton; -import javax.swing.JLabel; -import javax.swing.JRootPane; -import javax.swing.JTabbedPane; -import javax.swing.LookAndFeel; -import javax.swing.PopupFactory; -import javax.swing.SwingUtilities; -import javax.swing.UIDefaults; -import javax.swing.UIManager; -import javax.swing.UnsupportedLookAndFeelException; +import javax.swing.*; import javax.swing.plaf.ColorUIResource; import javax.swing.plaf.FontUIResource; +import javax.swing.plaf.IconUIResource; import javax.swing.plaf.basic.BasicLookAndFeel; import javax.swing.text.html.HTMLEditorKit; +import com.formdev.flatlaf.ui.FlatUIUtils; import com.formdev.flatlaf.util.SystemInfo; import com.formdev.flatlaf.util.UIScale; @@ -111,6 +104,11 @@ public abstract class FlatLaf return true; } + @Override + public Icon getDisabledIcon(JComponent component, Icon icon) { + return new IconUIResource(FlatUIUtils.getDisabledIcon(icon)); + } + @Override public void initialize() { if( SystemInfo.IS_MAC ) diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatButtonUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatButtonUI.java index 6055b3bd..2c8ec701 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatButtonUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatButtonUI.java @@ -86,6 +86,8 @@ import com.formdev.flatlaf.util.UIScale; * @uiDefault Button.toolbar.spacingInsets Insets * @uiDefault Button.toolbar.hoverBackground Color * @uiDefault Button.toolbar.pressedBackground Color + * @uiDefault Button.disabledGrayMinValue int optional + * @uiDefault Button.disabledGrayMinValue int optional * * @author Karl Tauber */ diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatDisabledButtonImageFilter.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatDisabledButtonImageFilter.java new file mode 100644 index 00000000..7e1c4a5f --- /dev/null +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatDisabledButtonImageFilter.java @@ -0,0 +1,28 @@ +package com.formdev.flatlaf.ui; + +import java.awt.image.RGBImageFilter; + +/** + * Used to create a disabled Icon with the ocean look. + *

+ * Imported from MetalUtils.getOceanDisabledButtonIcon + */ +class FlatDisabledButtonImageFilter extends RGBImageFilter { + private float min; + private float factor; + + FlatDisabledButtonImageFilter( int min, int max ) { + canFilterIndexColorModel = true; + this.min = ( float ) min; + this.factor = ( max - min ) / 255f; + } + + public int filterRGB( int x, int y, int rgb ) { + // Coefficients are from the sRGB color space: + int gray = Math.min( 255, ( int ) ( ( ( 0.2125f * ( ( rgb >> 16 ) & 0xFF ) ) + + ( 0.7154f * ( ( rgb >> 8 ) & 0xFF ) ) + + ( 0.0721f * ( rgb & 0xFF )) + .5f ) * factor + min) ); + + return ( rgb & 0xff000000 ) | ( gray << 16 ) | ( gray << 8 ) | ( gray ); + } +} 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 8a15c8d1..590baf62 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 @@ -16,17 +16,7 @@ package com.formdev.flatlaf.ui; -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; -import java.awt.Rectangle; -import java.awt.RenderingHints; -import java.awt.Shape; +import java.awt.*; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; import java.awt.event.MouseAdapter; @@ -34,10 +24,11 @@ import java.awt.event.MouseEvent; import java.awt.geom.Path2D; import java.awt.geom.Rectangle2D; import java.awt.geom.RoundRectangle2D; +import java.awt.image.BufferedImage; +import java.awt.image.FilteredImageSource; +import java.awt.image.ImageProducer; import java.util.function.Consumer; -import javax.swing.JComponent; -import javax.swing.LookAndFeel; -import javax.swing.UIManager; +import javax.swing.*; import javax.swing.plaf.UIResource; import com.formdev.flatlaf.FlatClientProperties; import com.formdev.flatlaf.util.DerivedColor; @@ -433,6 +424,32 @@ public class FlatUIUtils return explicitlySet; } + public static Icon getDisabledIcon( Icon icon ) { + Image image = safeGetImage(icon); + int grayMinValue = FlatUIUtils.getUIInt( "Button.disabledGrayMinValue", 180 ); + int grayMaxValue = FlatUIUtils.getUIInt( "Button.disabledGrayMaxValue", 215 ); + FlatDisabledButtonImageFilter imageFilter = new FlatDisabledButtonImageFilter(grayMinValue, grayMaxValue); + ImageProducer producer = new FilteredImageSource(image.getSource(), imageFilter); + return new ImageIcon(Toolkit.getDefaultToolkit().createImage(producer)); + } + + private static Image safeGetImage(Icon icon) { + if ( icon instanceof ImageIcon ) { + return ( ( ImageIcon ) icon ).getImage(); + } else { + int width = icon.getIconWidth(); + int height = icon.getIconHeight(); + GraphicsEnvironment environment = GraphicsEnvironment.getLocalGraphicsEnvironment(); + GraphicsDevice device = environment.getDefaultScreenDevice(); + GraphicsConfiguration configuration = device.getDefaultConfiguration(); + BufferedImage image = configuration.createCompatibleImage( width, height ); + Graphics2D g = image.createGraphics(); + icon.paintIcon( null, g, 0, 0 ); + g.dispose(); + return image; + } + } + //---- class HoverListener ------------------------------------------------ public static class HoverListener From 7c25f087fb36d2b1b7062091f8678ecad16f7f49 Mon Sep 17 00:00:00 2001 From: mmatessi <17149962+basix86@users.noreply.github.com> Date: Thu, 27 Feb 2020 16:14:51 +0100 Subject: [PATCH 2/8] NPE getDisabledIcon Fix --- flatlaf-core/src/main/java/com/formdev/flatlaf/FlatLaf.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 eb72c17b..501d04f1 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatLaf.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatLaf.java @@ -106,7 +106,7 @@ public abstract class FlatLaf @Override public Icon getDisabledIcon(JComponent component, Icon icon) { - return new IconUIResource(FlatUIUtils.getDisabledIcon(icon)); + return ( icon == null ) ? null : new IconUIResource( FlatUIUtils.getDisabledIcon( icon ) ); } @Override From 8ee6588d468f3ff1b4731dbb47d6ca13b8ee833a Mon Sep 17 00:00:00 2001 From: mmatessi <17149962+basix86@users.noreply.github.com> Date: Thu, 5 Mar 2020 13:08:49 +0100 Subject: [PATCH 3/8] fix review #70 --- .../java/com/formdev/flatlaf/FlatLaf.java | 13 ++++++++++- .../com/formdev/flatlaf/ui/FlatUIUtils.java | 23 +++++++++++++++++-- 2 files changed, 33 insertions(+), 3 deletions(-) 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 501d04f1..429d8602 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatLaf.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatLaf.java @@ -36,7 +36,18 @@ import java.util.Map; import java.util.function.Consumer; import java.util.logging.Level; import java.util.logging.Logger; -import javax.swing.*; +import javax.swing.AbstractButton; +import javax.swing.Icon; +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.JRootPane; +import javax.swing.JTabbedPane; +import javax.swing.LookAndFeel; +import javax.swing.PopupFactory; +import javax.swing.SwingUtilities; +import javax.swing.UIDefaults; +import javax.swing.UIManager; +import javax.swing.UnsupportedLookAndFeelException; import javax.swing.plaf.ColorUIResource; import javax.swing.plaf.FontUIResource; import javax.swing.plaf.IconUIResource; 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 590baf62..844262af 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 @@ -16,7 +16,22 @@ package com.formdev.flatlaf.ui; -import java.awt.*; +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.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; +import java.awt.Image; +import java.awt.Insets; +import java.awt.Rectangle; +import java.awt.RenderingHints; +import java.awt.Shape; +import java.awt.Toolkit; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; import java.awt.event.MouseAdapter; @@ -28,7 +43,11 @@ import java.awt.image.BufferedImage; import java.awt.image.FilteredImageSource; import java.awt.image.ImageProducer; import java.util.function.Consumer; -import javax.swing.*; +import javax.swing.Icon; +import javax.swing.ImageIcon; +import javax.swing.JComponent; +import javax.swing.LookAndFeel; +import javax.swing.UIManager; import javax.swing.plaf.UIResource; import com.formdev.flatlaf.FlatClientProperties; import com.formdev.flatlaf.util.DerivedColor; From 73cb63c9f93baaa5277660f1af854bc735cfe2b0 Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Mon, 13 Apr 2020 15:48:07 +0200 Subject: [PATCH 4/8] Testing: added FlatDisabledIconsTest to compare different methods to create disabled icons --- .../testing/FlatDisabledIconsTest.java | 781 ++++++++++++++++++ .../flatlaf/testing/FlatDisabledIconsTest.jfd | 458 ++++++++++ .../testing/disabled_icons_test/LICENSE.txt | 12 + .../disabled_icons_test/intellij-menu-cut.png | Bin 0 -> 262 bytes .../intellij-menu-cut@2x.png | Bin 0 -> 504 bytes .../intellij-menu-paste.png | Bin 0 -> 98 bytes .../intellij-menu-paste@2x.png | Bin 0 -> 122 bytes .../disabled_icons_test/intellij-search.png | Bin 0 -> 309 bytes .../intellij-search@2x.png | Bin 0 -> 687 bytes .../disabled_icons_test/intellij-show.png | Bin 0 -> 246 bytes .../disabled_icons_test/intellij-show@2x.png | Bin 0 -> 422 bytes .../intellij-showReadAccess.png | Bin 0 -> 305 bytes .../intellij-showReadAccess@2x.png | Bin 0 -> 498 bytes .../intellij-showWriteAccess.png | Bin 0 -> 325 bytes .../intellij-showWriteAccess@2x.png | Bin 0 -> 495 bytes .../disabled_icons_test/netbeans-copy24.gif | Bin 0 -> 733 bytes .../disabled_icons_test/netbeans-cut24.gif | Bin 0 -> 1517 bytes .../disabled_icons_test/netbeans-find24.gif | Bin 0 -> 1154 bytes .../disabled_icons_test/netbeans-paste24.gif | Bin 0 -> 880 bytes .../disabled_icons_test/netbeans-redo24.gif | Bin 0 -> 1254 bytes .../disabled_icons_test/netbeans-undo24.gif | Bin 0 -> 1282 bytes .../testing/disabled_icons_test/zip128.png | Bin 0 -> 17570 bytes 22 files changed, 1251 insertions(+) create mode 100644 flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatDisabledIconsTest.java create mode 100644 flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatDisabledIconsTest.jfd create mode 100644 flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/LICENSE.txt create mode 100644 flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-menu-cut.png create mode 100644 flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-menu-cut@2x.png create mode 100644 flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-menu-paste.png create mode 100644 flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-menu-paste@2x.png create mode 100644 flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-search.png create mode 100644 flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-search@2x.png create mode 100644 flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-show.png create mode 100644 flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-show@2x.png create mode 100644 flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-showReadAccess.png create mode 100644 flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-showReadAccess@2x.png create mode 100644 flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-showWriteAccess.png create mode 100644 flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-showWriteAccess@2x.png create mode 100644 flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/netbeans-copy24.gif create mode 100644 flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/netbeans-cut24.gif create mode 100644 flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/netbeans-find24.gif create mode 100644 flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/netbeans-paste24.gif create mode 100644 flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/netbeans-redo24.gif create mode 100644 flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/netbeans-undo24.gif create mode 100644 flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/zip128.png diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatDisabledIconsTest.java b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatDisabledIconsTest.java new file mode 100644 index 00000000..cb6ed331 --- /dev/null +++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatDisabledIconsTest.java @@ -0,0 +1,781 @@ +/* + * 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.testing; + +import java.awt.Component; +import java.awt.Image; +import java.awt.Toolkit; +import java.awt.image.FilteredImageSource; +import java.awt.image.ImageProducer; +import java.awt.image.RGBImageFilter; +import java.beans.*; +import javax.swing.*; +import net.miginfocom.swing.*; + +/** + * @author Karl Tauber + */ +public class FlatDisabledIconsTest + extends FlatTestPanel +{ + public static void main( String[] args ) { + SwingUtilities.invokeLater( () -> { + FlatTestFrame frame = FlatTestFrame.create( args, "FlatDisabledIconsTest" ); + frame.showFrame( FlatDisabledIconsTest::new ); + } ); + } + + FlatDisabledIconsTest() { + initComponents(); + + RGBImageFilter plasticLafFilter = new PlasticRGBGrayFilter(); + RGBImageFilter intellijTextFilter = new IntelliJGrayFilter( 20, 0, 100 ); + RGBImageFilter netbeansFilter = new NetBeansDisabledButtonFilter(); + + for( Component c : enabledToolBar.getComponents() ) { + AbstractButton b = (AbstractButton) c; + Icon icon = b.getIcon(); + + JToggleButton cb = new JToggleButton( icon ); + cb.setEnabled( false ); + currentLafToolBar.add( cb ); + basicLafToolBar.add( new FilterButton( null, icon ) ); + metalLafToolBar.add( new FilterButton( null, icon ) ); + plasticToolBar.add( new FilterButton( plasticLafFilter, icon ) ); + intellijTextToolBar.add( new FilterButton( intellijTextFilter, icon ) ); + intellijLightToolBar.add( new FilterButton( null, icon ) ); + intellijDarkToolBar.add( new FilterButton( null, icon ) ); + netbeansToolBar.add( new FilterButton( netbeansFilter, icon ) ); + } + + Icon zipIcon = zipButton.getIcon(); + JToggleButton cb = new JToggleButton( zipIcon ); + cb.setEnabled( false ); + zipToolBar.add( cb ); + zipToolBar.add( new FilterButton( null, zipIcon ) ); + zipToolBar.add( new FilterButton( null, zipIcon ) ); + zipToolBar.add( new FilterButton( plasticLafFilter, zipIcon ) ); + zipToolBar.add( new FilterButton( intellijTextFilter, zipIcon ) ); + zipToolBar.add( new FilterButton( null, zipIcon ) ); + zipToolBar.add( new FilterButton( null, zipIcon ) ); + zipToolBar.add( new FilterButton( netbeansFilter, zipIcon ) ); + + basicLafReset(); + metalLafReset(); + + intelliJTextFilterController.defaultBrightness = 20; + intelliJTextFilterController.defaultContrast = 0; + intelliJTextFilterController.reset(); + + // values from intellijlaf.properties + intelliJLightFilterController.defaultBrightness = 33; + intelliJLightFilterController.defaultContrast = -35; + intelliJLightFilterController.reset(); + + // values from darcula.properties + intelliJDarkFilterController.defaultBrightness = -70; + intelliJDarkFilterController.defaultContrast = -70; + intelliJDarkFilterController.reset(); + } + + private void selectedChanged() { + boolean armed = selectedCheckBox.isSelected(); + for( Component c : getComponents() ) { + if( c instanceof JToolBar ) { + for( Component c2 : ((JToolBar)c).getComponents() ) { + if( c2 instanceof JToggleButton ) + ((JToggleButton)c2).getModel().setSelected( armed ); + } + } + } + } + + private void basicLafChanged() { + boolean brighter = basicLafBrighterCheckBox.isSelected(); + int percent = basicLafPercentSlider.getValue(); + + basicLafPercentValue.setText( String.valueOf( percent ) ); + + RGBImageFilter filter = new GrayFilter( brighter, percent ); + updateFilter( basicLafToolBar, 2, filter ); + } + + private void basicLafReset() { + basicLafBrighterCheckBox.setSelected( true ); + basicLafPercentSlider.setValue( 50 ); + basicLafChanged(); + } + + private void metalLafChanged() { + int min = metalLafMinSlider.getValue(); + int max = metalLafMaxSlider.getValue(); + + metalLafMinValue.setText( String.valueOf( min ) ); + metalLafMaxValue.setText( String.valueOf( max ) ); + + RGBImageFilter filter = new MetalDisabledButtonImageFilter( min, max ); + updateFilter( metalLafToolBar, 3, filter ); + } + + private void metalLafReset() { + metalLafMinSlider.setValue( 180 ); + metalLafMaxSlider.setValue( 215 ); + metalLafChanged(); + } + + private void intelliJTextFilterChanged(PropertyChangeEvent e) { + updateFilter( intellijTextToolBar, 5, (RGBImageFilter) e.getNewValue() ); + } + + private void intelliJLightFilterChanged(PropertyChangeEvent e) { + updateFilter( intellijLightToolBar, 6, (RGBImageFilter) e.getNewValue() ); + } + + private void intelliJDarkFilterChanged(PropertyChangeEvent e) { + updateFilter( intellijDarkToolBar, 7, (RGBImageFilter) e.getNewValue() ); + } + + private void updateFilter( JToolBar toolBar, int zipIndex, RGBImageFilter filter ) { + for( Component c : toolBar.getComponents() ) + ((FilterButton)c).setFilter( filter ); + + ((FilterButton)zipToolBar.getComponent( zipIndex )).setFilter( filter ); + } + + private void initComponents() { + // JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents + JLabel enabledLabel = new JLabel(); + enabledToolBar = new JToolBar(); + JToggleButton button1 = new JToggleButton(); + JToggleButton button2 = new JToggleButton(); + JToggleButton button3 = new JToggleButton(); + JToggleButton button4 = new JToggleButton(); + JToggleButton button5 = new JToggleButton(); + JToggleButton button6 = new JToggleButton(); + JToggleButton button7 = new JToggleButton(); + JToggleButton button8 = new JToggleButton(); + JToggleButton button9 = new JToggleButton(); + JToggleButton button10 = new JToggleButton(); + JToggleButton button11 = new JToggleButton(); + JToggleButton button12 = new JToggleButton(); + JToggleButton button13 = new JToggleButton(); + JToggleButton button14 = new JToggleButton(); + JToggleButton button15 = new JToggleButton(); + JToggleButton button16 = new JToggleButton(); + JToggleButton button17 = new JToggleButton(); + JToggleButton button18 = new JToggleButton(); + JLabel currentLabel = new JLabel(); + currentLafToolBar = new JToolBar(); + JLabel basicLafLabel = new JLabel(); + basicLafToolBar = new JToolBar(); + JPanel panel2 = new JPanel(); + basicLafBrighterCheckBox = new JCheckBox(); + JLabel basicLafPercentLabel = new JLabel(); + basicLafPercentSlider = new JSlider(); + basicLafPercentValue = new JLabel(); + JButton basicLafResetButton = new JButton(); + JLabel metalLafLabel = new JLabel(); + metalLafToolBar = new JToolBar(); + JPanel panel4 = new JPanel(); + JLabel metalLafMinLabel = new JLabel(); + metalLafMinSlider = new JSlider(); + metalLafMinValue = new JLabel(); + JButton metalLafResetButton = new JButton(); + JLabel metalLafMaxLabel = new JLabel(); + metalLafMaxSlider = new JSlider(); + metalLafMaxValue = new JLabel(); + JLabel plasticLabel = new JLabel(); + plasticToolBar = new JToolBar(); + JLabel intellijTextLabel = new JLabel(); + intellijTextToolBar = new JToolBar(); + intelliJTextFilterController = new FlatDisabledIconsTest.IntelliJFilterController(); + JLabel intellijLightLabel = new JLabel(); + intellijLightToolBar = new JToolBar(); + intelliJLightFilterController = new FlatDisabledIconsTest.IntelliJFilterController(); + JLabel intellijDarkLabel = new JLabel(); + intellijDarkToolBar = new JToolBar(); + intelliJDarkFilterController = new FlatDisabledIconsTest.IntelliJFilterController(); + JLabel netbeansLabel = new JLabel(); + netbeansToolBar = new JToolBar(); + zipToolBar = new JToolBar(); + zipButton = new JToggleButton(); + selectedCheckBox = new JCheckBox(); + + //======== this ======== + setLayout(new MigLayout( + "ltr,insets dialog,hidemode 3", + // columns + "[fill]" + + "[fill]" + + "[left]" + + "[fill]", + // rows + "[]" + + "[]" + + "[center]" + + "[center]" + + "[center]" + + "[center]" + + "[center]" + + "[center]" + + "[center]para" + + "[center]" + + "[]")); + + //---- enabledLabel ---- + enabledLabel.setText("enabled"); + add(enabledLabel, "cell 0 0"); + + //======== enabledToolBar ======== + { + + //---- button1 ---- + button1.setIcon(new ImageIcon(getClass().getResource("/com/formdev/flatlaf/testing/disabled_icons_test/netbeans-cut24.gif"))); + enabledToolBar.add(button1); + + //---- button2 ---- + button2.setIcon(new ImageIcon(getClass().getResource("/com/formdev/flatlaf/testing/disabled_icons_test/netbeans-copy24.gif"))); + enabledToolBar.add(button2); + + //---- button3 ---- + button3.setIcon(new ImageIcon(getClass().getResource("/com/formdev/flatlaf/testing/disabled_icons_test/netbeans-paste24.gif"))); + enabledToolBar.add(button3); + + //---- button4 ---- + button4.setIcon(new ImageIcon(getClass().getResource("/com/formdev/flatlaf/testing/disabled_icons_test/netbeans-undo24.gif"))); + enabledToolBar.add(button4); + + //---- button5 ---- + button5.setIcon(new ImageIcon(getClass().getResource("/com/formdev/flatlaf/testing/disabled_icons_test/netbeans-redo24.gif"))); + enabledToolBar.add(button5); + + //---- button6 ---- + button6.setIcon(new ImageIcon(getClass().getResource("/com/formdev/flatlaf/testing/disabled_icons_test/netbeans-find24.gif"))); + enabledToolBar.add(button6); + + //---- button7 ---- + button7.setIcon(new ImageIcon(getClass().getResource("/com/formdev/flatlaf/testing/disabled_icons_test/intellij-menu-cut.png"))); + enabledToolBar.add(button7); + + //---- button8 ---- + button8.setIcon(new ImageIcon(getClass().getResource("/com/formdev/flatlaf/testing/disabled_icons_test/intellij-menu-paste.png"))); + enabledToolBar.add(button8); + + //---- button9 ---- + button9.setIcon(new ImageIcon(getClass().getResource("/com/formdev/flatlaf/testing/disabled_icons_test/intellij-show.png"))); + enabledToolBar.add(button9); + + //---- button10 ---- + button10.setIcon(new ImageIcon(getClass().getResource("/com/formdev/flatlaf/testing/disabled_icons_test/intellij-showReadAccess.png"))); + enabledToolBar.add(button10); + + //---- button11 ---- + button11.setIcon(new ImageIcon(getClass().getResource("/com/formdev/flatlaf/testing/disabled_icons_test/intellij-showWriteAccess.png"))); + enabledToolBar.add(button11); + + //---- button12 ---- + button12.setIcon(new ImageIcon(getClass().getResource("/com/formdev/flatlaf/testing/disabled_icons_test/intellij-search.png"))); + enabledToolBar.add(button12); + + //---- button13 ---- + button13.setIcon(new ImageIcon(getClass().getResource("/com/formdev/flatlaf/testing/disabled_icons_test/intellij-menu-cut@2x.png"))); + enabledToolBar.add(button13); + + //---- button14 ---- + button14.setIcon(new ImageIcon(getClass().getResource("/com/formdev/flatlaf/testing/disabled_icons_test/intellij-menu-paste@2x.png"))); + enabledToolBar.add(button14); + + //---- button15 ---- + button15.setIcon(new ImageIcon(getClass().getResource("/com/formdev/flatlaf/testing/disabled_icons_test/intellij-show@2x.png"))); + enabledToolBar.add(button15); + + //---- button16 ---- + button16.setIcon(new ImageIcon(getClass().getResource("/com/formdev/flatlaf/testing/disabled_icons_test/intellij-showReadAccess@2x.png"))); + enabledToolBar.add(button16); + + //---- button17 ---- + button17.setIcon(new ImageIcon(getClass().getResource("/com/formdev/flatlaf/testing/disabled_icons_test/intellij-showWriteAccess@2x.png"))); + enabledToolBar.add(button17); + + //---- button18 ---- + button18.setIcon(new ImageIcon(getClass().getResource("/com/formdev/flatlaf/testing/disabled_icons_test/intellij-search@2x.png"))); + enabledToolBar.add(button18); + } + add(enabledToolBar, "cell 1 0"); + + //---- currentLabel ---- + currentLabel.setText("current LaF"); + add(currentLabel, "cell 0 1"); + add(currentLafToolBar, "cell 1 1"); + + //---- basicLafLabel ---- + basicLafLabel.setText("Basic LaF"); + add(basicLafLabel, "cell 0 2"); + add(basicLafToolBar, "cell 1 2"); + + //======== panel2 ======== + { + panel2.setLayout(new MigLayout( + "insets 0,hidemode 3,gap 0 0", + // columns + "[60,fill]" + + "[fill]" + + "[25,right]rel" + + "[fill]", + // rows + "[center]" + + "[center]")); + + //---- basicLafBrighterCheckBox ---- + basicLafBrighterCheckBox.setText("brighter"); + basicLafBrighterCheckBox.addActionListener(e -> basicLafChanged()); + panel2.add(basicLafBrighterCheckBox, "cell 0 0 2 1,alignx left,growx 0"); + + //---- basicLafPercentLabel ---- + basicLafPercentLabel.setText("Percent"); + panel2.add(basicLafPercentLabel, "cell 0 1"); + + //---- basicLafPercentSlider ---- + basicLafPercentSlider.setToolTipText("Percent"); + basicLafPercentSlider.setValue(0); + basicLafPercentSlider.addChangeListener(e -> basicLafChanged()); + panel2.add(basicLafPercentSlider, "cell 1 1"); + + //---- basicLafPercentValue ---- + basicLafPercentValue.setText("000"); + panel2.add(basicLafPercentValue, "cell 2 1"); + + //---- basicLafResetButton ---- + basicLafResetButton.setText("Reset"); + basicLafResetButton.addActionListener(e -> basicLafReset()); + panel2.add(basicLafResetButton, "cell 3 0 1 2"); + } + add(panel2, "cell 2 2"); + + //---- metalLafLabel ---- + metalLafLabel.setText("Metal LaF"); + add(metalLafLabel, "cell 0 3"); + add(metalLafToolBar, "cell 1 3"); + + //======== panel4 ======== + { + panel4.setLayout(new MigLayout( + "insets 0,hidemode 3,gap 0 0", + // columns + "[60,fill]" + + "[fill]" + + "[25,right]rel" + + "[fill]", + // rows + "[center]" + + "[center]")); + + //---- metalLafMinLabel ---- + metalLafMinLabel.setText("Min"); + panel4.add(metalLafMinLabel, "cell 0 0"); + + //---- metalLafMinSlider ---- + metalLafMinSlider.setMaximum(255); + metalLafMinSlider.addChangeListener(e -> metalLafChanged()); + panel4.add(metalLafMinSlider, "cell 1 0"); + + //---- metalLafMinValue ---- + metalLafMinValue.setText("000"); + panel4.add(metalLafMinValue, "cell 2 0"); + + //---- metalLafResetButton ---- + metalLafResetButton.setText("Reset"); + metalLafResetButton.addActionListener(e -> metalLafReset()); + panel4.add(metalLafResetButton, "cell 3 0 1 2"); + + //---- metalLafMaxLabel ---- + metalLafMaxLabel.setText("Max"); + panel4.add(metalLafMaxLabel, "cell 0 1"); + + //---- metalLafMaxSlider ---- + metalLafMaxSlider.setMaximum(255); + metalLafMaxSlider.addChangeListener(e -> metalLafChanged()); + panel4.add(metalLafMaxSlider, "cell 1 1"); + + //---- metalLafMaxValue ---- + metalLafMaxValue.setText("000"); + panel4.add(metalLafMaxValue, "cell 2 1"); + } + add(panel4, "cell 2 3"); + + //---- plasticLabel ---- + plasticLabel.setText("Plastic LaF"); + add(plasticLabel, "cell 0 4"); + add(plasticToolBar, "cell 1 4"); + + //---- intellijTextLabel ---- + intellijTextLabel.setText("IntelliJ text"); + add(intellijTextLabel, "cell 0 5"); + add(intellijTextToolBar, "cell 1 5"); + + //---- intelliJTextFilterController ---- + intelliJTextFilterController.addPropertyChangeListener("filter", e -> intelliJTextFilterChanged(e)); + add(intelliJTextFilterController, "cell 2 5"); + + //---- intellijLightLabel ---- + intellijLightLabel.setText("IntelliJ light"); + add(intellijLightLabel, "cell 0 6"); + add(intellijLightToolBar, "cell 1 6"); + + //---- intelliJLightFilterController ---- + intelliJLightFilterController.addPropertyChangeListener("filter", e -> intelliJLightFilterChanged(e)); + add(intelliJLightFilterController, "cell 2 6"); + + //---- intellijDarkLabel ---- + intellijDarkLabel.setText("IntelliJ dark"); + add(intellijDarkLabel, "cell 0 7"); + add(intellijDarkToolBar, "cell 1 7"); + + //---- intelliJDarkFilterController ---- + intelliJDarkFilterController.addPropertyChangeListener("filter", e -> intelliJDarkFilterChanged(e)); + add(intelliJDarkFilterController, "cell 2 7"); + + //---- netbeansLabel ---- + netbeansLabel.setText("NetBeans"); + add(netbeansLabel, "cell 0 8"); + add(netbeansToolBar, "cell 1 8"); + + //======== zipToolBar ======== + { + + //---- zipButton ---- + zipButton.setIcon(new ImageIcon(getClass().getResource("/com/formdev/flatlaf/testing/disabled_icons_test/zip128.png"))); + zipToolBar.add(zipButton); + } + add(zipToolBar, "cell 1 9 3 1"); + + //---- selectedCheckBox ---- + selectedCheckBox.setText("selected"); + selectedCheckBox.addActionListener(e -> selectedChanged()); + add(selectedCheckBox, "cell 0 10"); + // JFormDesigner - End of component initialization //GEN-END:initComponents + } + + // JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables + private JToolBar enabledToolBar; + private JToolBar currentLafToolBar; + private JToolBar basicLafToolBar; + private JCheckBox basicLafBrighterCheckBox; + private JSlider basicLafPercentSlider; + private JLabel basicLafPercentValue; + private JToolBar metalLafToolBar; + private JSlider metalLafMinSlider; + private JLabel metalLafMinValue; + private JSlider metalLafMaxSlider; + private JLabel metalLafMaxValue; + private JToolBar plasticToolBar; + private JToolBar intellijTextToolBar; + private FlatDisabledIconsTest.IntelliJFilterController intelliJTextFilterController; + private JToolBar intellijLightToolBar; + private FlatDisabledIconsTest.IntelliJFilterController intelliJLightFilterController; + private JToolBar intellijDarkToolBar; + private FlatDisabledIconsTest.IntelliJFilterController intelliJDarkFilterController; + private JToolBar netbeansToolBar; + private JToolBar zipToolBar; + private JToggleButton zipButton; + private JCheckBox selectedCheckBox; + // JFormDesigner - End of variables declaration //GEN-END:variables + + //---- class IntelliJFilterController ------------------------------------ + + private static class IntelliJFilterController + extends JPanel + { + int defaultBrightness; + int defaultContrast; + + private IntelliJFilterController() { + initComponents(); + } + + private void changed() { + int brightness = intellijBrightnessSlider.getValue(); + int contrast = intellijContrastSlider.getValue(); + + intellijBrightnessValue.setText( String.valueOf( brightness ) ); + intellijContrastValue.setText( String.valueOf( contrast ) ); + + RGBImageFilter filter = new IntelliJGrayFilter( brightness, contrast, 100 ); + firePropertyChange( "filter", null, filter ); + } + + private void reset() { + intellijBrightnessSlider.setValue( defaultBrightness ); + intellijContrastSlider.setValue( defaultContrast ); + changed(); + } + + private void initComponents() { + // JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents + JLabel intellijBrightnessLabel = new JLabel(); + intellijBrightnessSlider = new JSlider(); + intellijBrightnessValue = new JLabel(); + JLabel intellijContrastLabel = new JLabel(); + intellijContrastSlider = new JSlider(); + intellijContrastValue = new JLabel(); + JButton intellijLightResetButton = new JButton(); + + //======== this ======== + setLayout(new MigLayout( + "insets 0,hidemode 3,gap 0 0", + // columns + "[60,fill]" + + "[fill]" + + "[25,right]rel" + + "[fill]", + // rows + "[center]" + + "[center]")); + + //---- intellijBrightnessLabel ---- + intellijBrightnessLabel.setText("Brightness"); + add(intellijBrightnessLabel, "cell 0 0"); + + //---- intellijBrightnessSlider ---- + intellijBrightnessSlider.setMinimum(-100); + intellijBrightnessSlider.addChangeListener(e -> changed()); + add(intellijBrightnessSlider, "cell 1 0"); + + //---- intellijBrightnessValue ---- + intellijBrightnessValue.setText("000"); + add(intellijBrightnessValue, "cell 2 0"); + + //---- intellijContrastLabel ---- + intellijContrastLabel.setText("Contrast"); + add(intellijContrastLabel, "cell 0 1"); + + //---- intellijContrastSlider ---- + intellijContrastSlider.setMinimum(-100); + intellijContrastSlider.addChangeListener(e -> changed()); + add(intellijContrastSlider, "cell 1 1"); + + //---- intellijContrastValue ---- + intellijContrastValue.setText("-000"); + add(intellijContrastValue, "cell 2 1"); + + //---- intellijLightResetButton ---- + intellijLightResetButton.setText("Reset"); + intellijLightResetButton.addActionListener(e -> reset()); + add(intellijLightResetButton, "cell 3 0 1 2"); + // JFormDesigner - End of component initialization //GEN-END:initComponents + } + + // JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables + private JSlider intellijBrightnessSlider; + private JLabel intellijBrightnessValue; + private JSlider intellijContrastSlider; + private JLabel intellijContrastValue; + // JFormDesigner - End of variables declaration //GEN-END:variables + } + + //---- class FilterButton ------------------------------------------------- + + private static class FilterButton + extends JToggleButton + { + private RGBImageFilter filter; + + FilterButton( RGBImageFilter filter, Icon icon ) { + this.filter = filter; + + setEnabled( false ); + setIcon( icon ); + + if( filter != null ) + updateDisabledIcon(); + } + + void setFilter( RGBImageFilter filter ) { + this.filter = filter; + updateDisabledIcon(); + } + + @Override + public void updateUI() { + super.updateUI(); + updateDisabledIcon(); + } + + private void updateDisabledIcon() { + setDisabledIcon( createDisabledIcon( getIcon() ) ); + } + + protected Icon createDisabledIcon( Icon icon ) { + if( !(icon instanceof ImageIcon) ) + return null; + + Image image = ((ImageIcon) icon).getImage(); + ImageProducer producer = new FilteredImageSource( image.getSource(), filter ); + Image disabledImage = Toolkit.getDefaultToolkit().createImage( producer ); + return new ImageIcon( disabledImage ); + } + } + + //---- class PlasticRGBGrayFilter ----------------------------------------- + + // from https://github.com/openjdk/jdk/blob/6bab0f539fba8fb441697846347597b4a0ade428/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalUtils.java#L415-L434 + // license https://github.com/openjdk/jdk/blob/master/LICENSE + private static class MetalDisabledButtonImageFilter + extends RGBImageFilter + { + private final float min; + private final float factor; + + MetalDisabledButtonImageFilter(int min, int max) { + canFilterIndexColorModel = true; + this.min = min; + this.factor = (max - min) / 255f; + } + + @Override + public int filterRGB(int x, int y, int rgb) { + // Coefficients are from the sRGB color space: + int gray = Math.min(255, (int)(((0.2125f * ((rgb >> 16) & 0xFF)) + + (0.7154f * ((rgb >> 8) & 0xFF)) + + (0.0721f * (rgb & 0xFF)) + .5f) * factor + min)); + + return (rgb & 0xff000000) | (gray << 16) | (gray << 8) | + (gray << 0); + } + } + + //---- class PlasticRGBGrayFilter ----------------------------------------- + + // from https://github.com/JFormDesigner/swing-jgoodies-looks/blob/master/src/main/java/com/jgoodies/looks/common/RGBGrayFilter.java + // license https://github.com/JFormDesigner/swing-jgoodies-looks/blob/master/LICENSE.txt + private static final class PlasticRGBGrayFilter + extends RGBImageFilter + { + private PlasticRGBGrayFilter() { + canFilterIndexColorModel = true; + } + + @Override + public int filterRGB(int x, int y, int rgb) { + // Find the average of red, green, and blue. + float avg = (((rgb >> 16) & 0xff) / 255f + + ((rgb >> 8) & 0xff) / 255f + + (rgb & 0xff) / 255f) / 3; + // Pull out the alpha channel. + float alpha = (((rgb >> 24) & 0xff) / 255f); + + // Calculate the average. + // Sun's formula: Math.min(1.0f, (1f - avg) / (100.0f / 35.0f) + avg); + // The following formula uses less operations and hence is faster. + avg = Math.min(1.0f, 0.35f + 0.65f * avg); + // Convert back into RGB. + return (int) (alpha * 255f) << 24 | + (int) (avg * 255f) << 16 | + (int) (avg * 255f) << 8 | + (int) (avg * 255f); + } + } + + //---- class IntelliJGrayFilter ------------------------------------------- + + // from https://github.com/JetBrains/intellij-community/blob/3840eab54746f5c4f301bb3ac78f00a980b5fd6e/platform/util/ui/src/com/intellij/util/ui/UIUtil.java#L253-L347 + // license https://github.com/JetBrains/intellij-community/blob/master/LICENSE.txt + private static class IntelliJGrayFilter + extends RGBImageFilter + { + private float brightness; + private float contrast; + private int alpha; + + private int origContrast; + private int origBrightness; + + /** + * @param brightness in range [-100..100] where 0 has no effect + * @param contrast in range [-100..100] where 0 has no effect + * @param alpha in range [0..100] where 0 is transparent, 100 has no effect + */ + public IntelliJGrayFilter(int brightness, int contrast, int alpha) { + setBrightness(brightness); + setContrast(contrast); + setAlpha(alpha); + } + + private void setBrightness(int brightness) { + origBrightness = Math.max(-100, Math.min(100, brightness)); + this.brightness = (float)(Math.pow(origBrightness, 3) / (100f * 100f)); // cubic in [0..100] + } + + private void setContrast(int contrast) { + origContrast = Math.max(-100, Math.min(100, contrast)); + this.contrast = origContrast / 100f; + } + + private void setAlpha(int alpha) { + this.alpha = Math.max(0, Math.min(100, alpha)); + } + + @Override + public int filterRGB(int x, int y, int rgb) { + // Use NTSC conversion formula. + int gray = (int)(0.30 * (rgb >> 16 & 0xff) + + 0.59 * (rgb >> 8 & 0xff) + + 0.11 * (rgb & 0xff)); + + if (brightness >= 0) { + gray = (int)((gray + brightness * 255) / (1 + brightness)); + } + else { + gray = (int)(gray / (1 - brightness)); + } + + if (contrast >= 0) { + if (gray >= 127) { + gray = (int)(gray + (255 - gray) * contrast); + } + else { + gray = (int)(gray - gray * contrast); + } + } + else { + gray = (int)(127 + (gray - 127) * (contrast + 1)); + } + + int a = ((rgb >> 24) & 0xff) * alpha / 100; + + return (a << 24) | (gray << 16) | (gray << 8) | gray; + } + } + + //---- NetBeansDisabledButtonFilter --------------------------------------- + + // from https://github.com/apache/netbeans/blob/166e2bb491c29f6778223c6e9e16f70664252bce/platform/openide.util.ui/src/org/openide/util/ImageUtilities.java#L1202-L1221 + // license https://github.com/apache/netbeans/blob/master/LICENSE + private static class NetBeansDisabledButtonFilter + extends RGBImageFilter + { + NetBeansDisabledButtonFilter() { + canFilterIndexColorModel = true; + } + + @Override + public int filterRGB(int x, int y, int rgb) { + // Reduce the color bandwidth in quarter (>> 2) and Shift 0x88. + return (rgb & 0xff000000) + 0x888888 + ((((rgb >> 16) & 0xff) >> 2) << 16) + ((((rgb >> 8) & 0xff) >> 2) << 8) + (((rgb) & 0xff) >> 2); + } + } +} diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatDisabledIconsTest.jfd b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatDisabledIconsTest.jfd new file mode 100644 index 00000000..b0773567 --- /dev/null +++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatDisabledIconsTest.jfd @@ -0,0 +1,458 @@ +JFDML JFormDesigner: "7.0.1.0.272" Java: "13.0.2" encoding: "UTF-8" + +new FormModel { + contentType: "form/swing" + root: new FormRoot { + auxiliary() { + "JavaCodeGenerator.defaultVariableLocal": true + } + add( new FormContainer( "com.formdev.flatlaf.testing.FlatTestPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) { + "$layoutConstraints": "ltr,insets dialog,hidemode 3" + "$columnConstraints": "[fill][fill][left][fill]" + "$rowConstraints": "[][][center][center][center][center][center][center][center]para[center][]" + } ) { + name: "this" + add( new FormComponent( "javax.swing.JLabel" ) { + name: "enabledLabel" + "text": "enabled" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 0" + } ) + add( new FormContainer( "javax.swing.JToolBar", new FormLayoutManager( class javax.swing.JToolBar ) ) { + name: "enabledToolBar" + auxiliary() { + "JavaCodeGenerator.variableLocal": false + } + add( new FormComponent( "javax.swing.JToggleButton" ) { + name: "button1" + "icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/testing/disabled_icons_test/netbeans-cut24.gif" ) + } ) + add( new FormComponent( "javax.swing.JToggleButton" ) { + name: "button2" + "icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/testing/disabled_icons_test/netbeans-copy24.gif" ) + } ) + add( new FormComponent( "javax.swing.JToggleButton" ) { + name: "button3" + "icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/testing/disabled_icons_test/netbeans-paste24.gif" ) + } ) + add( new FormComponent( "javax.swing.JToggleButton" ) { + name: "button4" + "icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/testing/disabled_icons_test/netbeans-undo24.gif" ) + } ) + add( new FormComponent( "javax.swing.JToggleButton" ) { + name: "button5" + "icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/testing/disabled_icons_test/netbeans-redo24.gif" ) + } ) + add( new FormComponent( "javax.swing.JToggleButton" ) { + name: "button6" + "icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/testing/disabled_icons_test/netbeans-find24.gif" ) + } ) + add( new FormComponent( "javax.swing.JToggleButton" ) { + name: "button7" + "icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-menu-cut.png" ) + } ) + add( new FormComponent( "javax.swing.JToggleButton" ) { + name: "button8" + "icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-menu-paste.png" ) + } ) + add( new FormComponent( "javax.swing.JToggleButton" ) { + name: "button9" + "icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-show.png" ) + } ) + add( new FormComponent( "javax.swing.JToggleButton" ) { + name: "button10" + "icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-showReadAccess.png" ) + } ) + add( new FormComponent( "javax.swing.JToggleButton" ) { + name: "button11" + "icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-showWriteAccess.png" ) + } ) + add( new FormComponent( "javax.swing.JToggleButton" ) { + name: "button12" + "icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-search.png" ) + } ) + add( new FormComponent( "javax.swing.JToggleButton" ) { + name: "button13" + "icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-menu-cut@2x.png" ) + } ) + add( new FormComponent( "javax.swing.JToggleButton" ) { + name: "button14" + "icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-menu-paste@2x.png" ) + } ) + add( new FormComponent( "javax.swing.JToggleButton" ) { + name: "button15" + "icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-show@2x.png" ) + } ) + add( new FormComponent( "javax.swing.JToggleButton" ) { + name: "button16" + "icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-showReadAccess@2x.png" ) + } ) + add( new FormComponent( "javax.swing.JToggleButton" ) { + name: "button17" + "icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-showWriteAccess@2x.png" ) + } ) + add( new FormComponent( "javax.swing.JToggleButton" ) { + name: "button18" + "icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-search@2x.png" ) + } ) + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 1 0" + } ) + add( new FormComponent( "javax.swing.JLabel" ) { + name: "currentLabel" + "text": "current LaF" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 1" + } ) + add( new FormContainer( "javax.swing.JToolBar", new FormLayoutManager( class javax.swing.JToolBar ) ) { + name: "currentLafToolBar" + auxiliary() { + "JavaCodeGenerator.variableLocal": false + } + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 1 1" + } ) + add( new FormComponent( "javax.swing.JLabel" ) { + name: "basicLafLabel" + "text": "Basic LaF" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 2" + } ) + add( new FormContainer( "javax.swing.JToolBar", new FormLayoutManager( class javax.swing.JToolBar ) ) { + name: "basicLafToolBar" + auxiliary() { + "JavaCodeGenerator.variableLocal": false + } + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 1 2" + } ) + add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) { + "$layoutConstraints": "insets 0,hidemode 3,gap 0 0" + "$columnConstraints": "[60,fill][fill][25,right]rel[fill]" + "$rowConstraints": "[center][center]" + } ) { + name: "panel2" + add( new FormComponent( "javax.swing.JCheckBox" ) { + name: "basicLafBrighterCheckBox" + "text": "brighter" + auxiliary() { + "JavaCodeGenerator.variableLocal": false + } + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "basicLafChanged", false ) ) + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 0 2 1,alignx left,growx 0" + } ) + add( new FormComponent( "javax.swing.JLabel" ) { + name: "basicLafPercentLabel" + "text": "Percent" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 1" + } ) + add( new FormComponent( "javax.swing.JSlider" ) { + name: "basicLafPercentSlider" + "toolTipText": "Percent" + "value": 0 + auxiliary() { + "JavaCodeGenerator.variableLocal": false + } + addEvent( new FormEvent( "javax.swing.event.ChangeListener", "stateChanged", "basicLafChanged", false ) ) + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 1 1" + } ) + add( new FormComponent( "javax.swing.JLabel" ) { + name: "basicLafPercentValue" + "text": "000" + auxiliary() { + "JavaCodeGenerator.variableLocal": false + } + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 2 1" + } ) + add( new FormComponent( "javax.swing.JButton" ) { + name: "basicLafResetButton" + "text": "Reset" + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "basicLafReset", false ) ) + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 3 0 1 2" + } ) + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 2 2" + } ) + add( new FormComponent( "javax.swing.JLabel" ) { + name: "metalLafLabel" + "text": "Metal LaF" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 3" + } ) + add( new FormContainer( "javax.swing.JToolBar", new FormLayoutManager( class javax.swing.JToolBar ) ) { + name: "metalLafToolBar" + auxiliary() { + "JavaCodeGenerator.variableLocal": false + } + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 1 3" + } ) + add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) { + "$layoutConstraints": "insets 0,hidemode 3,gap 0 0" + "$columnConstraints": "[60,fill][fill][25,right]rel[fill]" + "$rowConstraints": "[center][center]" + } ) { + name: "panel4" + add( new FormComponent( "javax.swing.JLabel" ) { + name: "metalLafMinLabel" + "text": "Min" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 0" + } ) + add( new FormComponent( "javax.swing.JSlider" ) { + name: "metalLafMinSlider" + "maximum": 255 + auxiliary() { + "JavaCodeGenerator.variableLocal": false + } + addEvent( new FormEvent( "javax.swing.event.ChangeListener", "stateChanged", "metalLafChanged", false ) ) + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 1 0" + } ) + add( new FormComponent( "javax.swing.JLabel" ) { + name: "metalLafMinValue" + "text": "000" + auxiliary() { + "JavaCodeGenerator.variableLocal": false + } + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 2 0" + } ) + add( new FormComponent( "javax.swing.JButton" ) { + name: "metalLafResetButton" + "text": "Reset" + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "metalLafReset", false ) ) + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 3 0 1 2" + } ) + add( new FormComponent( "javax.swing.JLabel" ) { + name: "metalLafMaxLabel" + "text": "Max" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 1" + } ) + add( new FormComponent( "javax.swing.JSlider" ) { + name: "metalLafMaxSlider" + "maximum": 255 + auxiliary() { + "JavaCodeGenerator.variableLocal": false + } + addEvent( new FormEvent( "javax.swing.event.ChangeListener", "stateChanged", "metalLafChanged", false ) ) + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 1 1" + } ) + add( new FormComponent( "javax.swing.JLabel" ) { + name: "metalLafMaxValue" + "text": "000" + auxiliary() { + "JavaCodeGenerator.variableLocal": false + } + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 2 1" + } ) + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 2 3" + } ) + add( new FormComponent( "javax.swing.JLabel" ) { + name: "plasticLabel" + "text": "Plastic LaF" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 4" + } ) + add( new FormContainer( "javax.swing.JToolBar", new FormLayoutManager( class javax.swing.JToolBar ) ) { + name: "plasticToolBar" + auxiliary() { + "JavaCodeGenerator.variableLocal": false + } + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 1 4" + } ) + add( new FormComponent( "javax.swing.JLabel" ) { + name: "intellijTextLabel" + "text": "IntelliJ text" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 5" + } ) + add( new FormContainer( "javax.swing.JToolBar", new FormLayoutManager( class javax.swing.JToolBar ) ) { + name: "intellijTextToolBar" + auxiliary() { + "JavaCodeGenerator.variableLocal": false + } + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 1 5" + } ) + add( new FormComponent( "com.formdev.flatlaf.testing.FlatDisabledIconsTest$IntelliJFilterController" ) { + name: "intelliJTextFilterController" + auxiliary() { + "JavaCodeGenerator.variableLocal": false + } + addEvent( new FormEvent( "java.beans.PropertyChangeListener", "propertyChange", "intelliJTextFilterChanged", true, "filter" ) ) + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 2 5" + } ) + add( new FormComponent( "javax.swing.JLabel" ) { + name: "intellijLightLabel" + "text": "IntelliJ light" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 6" + } ) + add( new FormContainer( "javax.swing.JToolBar", new FormLayoutManager( class javax.swing.JToolBar ) ) { + name: "intellijLightToolBar" + auxiliary() { + "JavaCodeGenerator.variableLocal": false + } + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 1 6" + } ) + add( new FormComponent( "com.formdev.flatlaf.testing.FlatDisabledIconsTest$IntelliJFilterController" ) { + name: "intelliJLightFilterController" + auxiliary() { + "JavaCodeGenerator.variableLocal": false + } + addEvent( new FormEvent( "java.beans.PropertyChangeListener", "propertyChange", "intelliJLightFilterChanged", true, "filter" ) ) + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 2 6" + } ) + add( new FormComponent( "javax.swing.JLabel" ) { + name: "intellijDarkLabel" + "text": "IntelliJ dark" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 7" + } ) + add( new FormContainer( "javax.swing.JToolBar", new FormLayoutManager( class javax.swing.JToolBar ) ) { + name: "intellijDarkToolBar" + auxiliary() { + "JavaCodeGenerator.variableLocal": false + } + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 1 7" + } ) + add( new FormComponent( "com.formdev.flatlaf.testing.FlatDisabledIconsTest$IntelliJFilterController" ) { + name: "intelliJDarkFilterController" + auxiliary() { + "JavaCodeGenerator.variableLocal": false + } + addEvent( new FormEvent( "java.beans.PropertyChangeListener", "propertyChange", "intelliJDarkFilterChanged", true, "filter" ) ) + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 2 7" + } ) + add( new FormComponent( "javax.swing.JLabel" ) { + name: "netbeansLabel" + "text": "NetBeans" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 8" + } ) + add( new FormContainer( "javax.swing.JToolBar", new FormLayoutManager( class javax.swing.JToolBar ) ) { + name: "netbeansToolBar" + auxiliary() { + "JavaCodeGenerator.variableLocal": false + } + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 1 8" + } ) + add( new FormContainer( "javax.swing.JToolBar", new FormLayoutManager( class javax.swing.JToolBar ) ) { + name: "zipToolBar" + auxiliary() { + "JavaCodeGenerator.variableLocal": false + } + add( new FormComponent( "javax.swing.JToggleButton" ) { + name: "zipButton" + "icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/testing/disabled_icons_test/zip128.png" ) + auxiliary() { + "JavaCodeGenerator.variableLocal": false + } + } ) + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 1 9 3 1" + } ) + add( new FormComponent( "javax.swing.JCheckBox" ) { + name: "selectedCheckBox" + "text": "selected" + auxiliary() { + "JavaCodeGenerator.variableLocal": false + } + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "selectedChanged", false ) ) + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 10" + } ) + }, new FormLayoutConstraints( null ) { + "location": new java.awt.Point( 0, 0 ) + "size": new java.awt.Dimension( 1095, 625 ) + } ) + add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) { + "$layoutConstraints": "insets 0,hidemode 3,gap 0 0" + "$columnConstraints": "[60,fill][fill][25,right]rel[fill]" + "$rowConstraints": "[center][center]" + } ) { + name: "panel1" + auxiliary() { + "JavaCodeGenerator.className": "IntelliJFilterController" + } + add( new FormComponent( "javax.swing.JLabel" ) { + name: "intellijBrightnessLabel" + "text": "Brightness" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 0" + } ) + add( new FormComponent( "javax.swing.JSlider" ) { + name: "intellijBrightnessSlider" + "minimum": -100 + auxiliary() { + "JavaCodeGenerator.variableLocal": false + } + addEvent( new FormEvent( "javax.swing.event.ChangeListener", "stateChanged", "changed", false ) ) + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 1 0" + } ) + add( new FormComponent( "javax.swing.JLabel" ) { + name: "intellijBrightnessValue" + "text": "000" + auxiliary() { + "JavaCodeGenerator.variableLocal": false + } + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 2 0" + } ) + add( new FormComponent( "javax.swing.JLabel" ) { + name: "intellijContrastLabel" + "text": "Contrast" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 1" + } ) + add( new FormComponent( "javax.swing.JSlider" ) { + name: "intellijContrastSlider" + "minimum": -100 + auxiliary() { + "JavaCodeGenerator.variableLocal": false + } + addEvent( new FormEvent( "javax.swing.event.ChangeListener", "stateChanged", "changed", false ) ) + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 1 1" + } ) + add( new FormComponent( "javax.swing.JLabel" ) { + name: "intellijContrastValue" + "text": "-000" + auxiliary() { + "JavaCodeGenerator.variableLocal": false + } + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 2 1" + } ) + add( new FormComponent( "javax.swing.JButton" ) { + name: "intellijLightResetButton" + "text": "Reset" + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "reset", false ) ) + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 3 0 1 2" + } ) + }, new FormLayoutConstraints( null ) { + "location": new java.awt.Point( 0, 660 ) + "size": new java.awt.Dimension( 286, 39 ) + } ) + } +} diff --git a/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/LICENSE.txt b/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/LICENSE.txt new file mode 100644 index 00000000..bc63f393 --- /dev/null +++ b/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/LICENSE.txt @@ -0,0 +1,12 @@ +The icons in this folder starting with 'intellij-' are from IntelliJ IDEA Community Edition, +which is licensed under the Apache 2.0 license. Copyright 2000-2020 JetBrains s.r.o. +See: https://github.com/JetBrains/intellij-community/ + +The icons in this folder starting with 'netbeans-' are from Apache NetBeans, +which is licensed under the Apache 2.0 license to the Apache Software Foundation (ASF). +See: https://github.com/apache/netbeans/ + +zip128.png is from +http://www.iconarchive.com/show/plump-icons-by-zerode/Folder-Archive-zip-icon.html +License: Free for non-commercial use. +Commercial usage: Not allowed diff --git a/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-menu-cut.png b/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-menu-cut.png new file mode 100644 index 0000000000000000000000000000000000000000..c49ce7224e7e6af55cc5a7b3001688a61615ecb3 GIT binary patch literal 262 zcmV+h0r~!kP)8yttM*si- M07*qoM6N<$g2vQk1ONa4 literal 0 HcmV?d00001 diff --git a/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-menu-cut@2x.png b/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-menu-cut@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..72ba5d3135eb30fa88f83e9a90d17f36e6da258e GIT binary patch literal 504 zcmV$Lqh{gUS6I~K|z5-adEK-T`kYg&u<1={vL?`!*FhH?*78ULKS-WdNs1eX!vtZ zPL2sFW&%S{0jTdjnmG-)d|rX1=s7ebQh<0nlK6FyLn*NQKTtdXs|F;+@6m%BD7F~M z00(j{2YCpqhODeC378_F&-<|$Xn-VNL8j#;I5m;t0Gx4%-|`HCaRyZMn3yO4=7C+5_SXcB}~)2MO)0000Ar-fh6BdYS=;{6I@6o*E vvL*2aS7G8UX@_-xRxmc7YH0NKU}j=aird{-kn6(%)WqQF>gTe~DWM4f#JC)l literal 0 HcmV?d00001 diff --git a/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-menu-paste@2x.png b/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-menu-paste@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..9df8e303d93f8388c6fd92e9c29d98c9263304bf GIT binary patch literal 122 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdzM^6{WkcwMxuN~xMFyLTutlsy} z(@KD^N#ZW+{6{vu3dWx5vn?6EUnq{KZm?$f#~$*Y8K?^g{xbYw{>`vu8F$m&ck=y} QK6gNZp00i_>zopr0LsxNcmMzZ literal 0 HcmV?d00001 diff --git a/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-search.png b/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-search.png new file mode 100644 index 0000000000000000000000000000000000000000..2b2b1b9c48e380d263f0f9ee35414caf2ff5e91b GIT binary patch literal 309 zcmV-50m}Y~P)ko}|0~)tB4r|!KgSGLufHoWVP;X5)M#w#DmeYL< zkWp_?!@?e%s3$eJvgc#K86y6&Tn`j+k~MpN3J73GfeN^M+k%W)#R3nS?gFmH#b8q2WcHFYkzZ{t6n8D=o|DYXr300000NkvXX Hu0mjf1PXwv literal 0 HcmV?d00001 diff --git a/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-search@2x.png b/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-search@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..fa13a324698dd6da3cfa5e559e73977cf0fdd4e2 GIT binary patch literal 687 zcmV;g0#N;lP)39ECKT zh1Z794HO$-lQ#1o(4l6w{nEog!v7L{^pjeML&XGmAqL9BHa0vAFJYQSp`Af$;H#+n z0xNt1Y}RJd#pYMxo5dA|*r(N|eF9t%15Chj44#IG2(1k9T-4w83GhS=Fv!_IfNX^O z4A3L$Kl=oDD+V~j0FU8WghvdpM_YzOp#k0*0$hh%5e6Axx2T`>2{0rExW)h{;e3P> z4A3R&Klv;{zjl<$FmN>+xKuH~u&BS|6QD_3!&7_;8=%Ev9h>jaYLD1%L{|W{X0OB` z-(e#|tmaG`pq_tMuz4kni@GUT=@UTN0*hiW_4;jB;q&Ke+}1CrH#SSg^oB!Q6bi zn!f&f3xRs}NB13SBs-)XiYiQ>0|A5RKK4id9ctt|(wTW@^DJ5KeDq%Pm4vH2Q_eJK z{o)TXvDen_W>>p@;lcqXk@<>l=L;>SSzABx`t@nImI4wQERsin5XIcOFV!q0)Y zBr7Y6ha$^CJ_Z_ep9G81@ncYkkYzbga|RIq#$xDeprJK6IXNbB7(8KBopvPheX#@r3cO1bkgXB{K zpxAb3VtWsi+YgEow2*j?#hmZR>aaQBIF2~1L9_fb7InXY>MUUDK=FX*~K`57G5Bsg(yLX4ju;#coYnHA|#Xz zkqaQGBS0bX8deb@TMo^J_esu%16~jjQxq2$7mMI4ih+9PQ&bcaQyGCA2#N++Tmpkt z0~+V|sZtpYit2b!G)T}L0t|KsP?HQ=Xgx=3l7X`DY>}1CoEv^h?tk>wC&l6 z)JVCB+D7&6>(2BjMi&3*;*nkO?7G7r`4o>YT|V4<*uHe0cXEEho^cbY-LU1P-0x#sc?zGM#`S~sHun7 zp#kI$E- ziA1c(yp3cz1h33^9J(q?g7ywrk+~bgayZU9oiIOvgJzaTEzg{e#p2&+A+eewO9~1K z1aPGI8g$E}mS;6YuE?ms6whoX+w%PU{L`3;E-M7nruVYqasSxxzvgPDD09rmc04@EFmNTv=tjC_NP=cKlj5nJC;~q;+*$qoC6kASA z2!V0|mYgwtKpgfztJq;kF$it<_PL0!p!>w>j-p5kYhP0rGqLYG|N8&D=!U- z3LmUPe zMJ6mKX!Mv5atMz9d@Cx!fG(C_ z4b9>KT6!H}IouJC?}sKx(A4t%4h<|oi#B6g4tK=q`w0mgG>rH7$yhA?jmBS1H4BT2 zi$%~99jfKw3H?A^fi8Y0BEFd_4#>;PJCE#$TM>yha7!ZNcY~q?oE;+)=3_W6GBJi4 z4)~A55!ZonEr6Of682+6O?ZL@H5`E92xQCQV!#}Lnl-_Wczq`{S%n%7z;Fbi!U+jq z$L3&c77&98I|3N@7>N=oy-?}^q8tIr1(-P_VfuhN;8tY9aymu=bMoU8dNTb5;A}WUnZs?x)q-2L)D`A zPIzJtB7Wmn!?M=x@c7vnsUE17s+G~*$Rr!|#C0noz8hO*1QMrJb-b8Rbqp$WXx1ix z#`SSL4U)?^i(P7gn~`ZEK#Oi;Ym$N5igalgg0dDc?%yLh;5#Ud(6wcJD=f(c5&wxH l1JXBulnDt9qg}Ki2LSf*ka5I|9rFMH002ovPDHLkV1np6(V+kU literal 0 HcmV?d00001 diff --git a/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/netbeans-copy24.gif b/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/netbeans-copy24.gif new file mode 100644 index 0000000000000000000000000000000000000000..5a50e326efc517cc1ab5e15c7f3c94751d674b92 GIT binary patch literal 733 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjEa{HEjtmUzPnffIy#(?lOI#yL zg7ec#$`gxH85~pclTsBta}(23gHjVyDhp4h+AuIM<$Jm~hE&{2`t$$4J+m&O1B0RA z1qlWg0dAw^$+v{|+*^5~D^cYtQv*X11FImH!dCqKOYem_tAzW-?+{k(}8Gq*G>@nGgq2;u(s zFZBnniHIa~?70uGujjXYpTFO@=FhLmib^M@FI-u#cX1lf0bQ*1|CxAye-;;I*8ThI zuk_*P@An`0@%p?y&px|2p0BpXotsz`8UmDlo}X|3;DH0%{<{Ck6(1j|9$s}d+u%{3 z1cQKshS(q0s1LvSSFzSNeth))DHqSOcmaK5L&FWl1qN$k_BLv8Gca)+X0LB}*vBL> zQ_^Bbg~SaDfkz774r1z0!~TR{zH)GO4vwoc{kbNsXa z|34#^-_^z~zp4#2PI?-OEO#~9;v3l_mzHG|&DY=wI(_5>M_2BilM)II7bd-oPe}XiFT%ExHS)lbBOT_F%)lt9a{KL`@`-sR ztK>PJBR?h?IxsAZV(8g1^Rk+7EKdVZdTMIohk{Zjw#)t=i;`249x$jq=9S*w@Dpf# z(!oEPbJc$E^muAp2tRnv{G6ME%cx)jbFi4P{SFyt|6>Zk@X^V*XVrbasp*y{9q5gQ{gwiTDAu&DZmiKQ*N+Qi_%FfoNuBXiS6BjL4TEDTH?Ch`oye9{~3 zesF&TCK-sNk+C3DlDk1LJRs0NXey6@L(dYEXbDNlUe7h}&oi+|FsRBraM|XpuL(?_ N44$rjF6*2UngD~cBo_bx literal 0 HcmV?d00001 diff --git a/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/netbeans-cut24.gif b/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/netbeans-cut24.gif new file mode 100644 index 0000000000000000000000000000000000000000..2520d4ec01b80a87b9acc2c17bc47d72001b74ae GIT binary patch literal 1517 zcmV1PMC!D9mz>M4iLm^?2b3o?w zwuYK4fB<3w3I6-{FSEQTpFu!S=p0A^C5D5{0GS0c6C?%@Kwu00{{72v{pKBp%926` zUOs-ZECJ~O=>?eqG7DrT2mk~S*n%%#KApJ#-~q$!JNFoB%1anHxwuHO1f&+E2c#Ed z2FNUsnIJiU00LX^^7)HJ=PzDjc=hHj(DvI54b_zlEG(=FMP*YLH089XQEdj}a)PU52^nmn&%mA4M zG83c*Ab{Y>l#!89F*Ygnu%n}+G#4iqgSeO|gNB+aLuG9p13NoAM(P3?{`2S0bM4Jd z3^#7wW_bDPHN&^>-x&7q-~V*+yxF!ubMJ%H0R#|AJ^)&x6CIy)Ilw;Ws zea0XpAi%I{^-6}-%a@n{%{z;19zX!Gpoc3+0nieYU%!5xiHVM7xO@LT!=FFD8Hz2r z8D1Zm1Ij=QqBb!Mr_P>Zc=-4UgQS=^!;+bw z3?Fv%F#LaZoWUc}0W7~`{t||dx9>7YI_5LXUoe+p+olaz4F>^$0K!`qfr87`!~0Ac z$9@K%Bs+$`Pws-nnPrq2w#+-kaQCkmgY^Gb*Ev`iG@)8RmP`*>|8*|R41fSav0!xo zH@HkfR{ZMQe-9ych7fNz39#V5w|^LzgjpEAb4xIM`tXf`o0o$@K!gV@_u2^Q<-)FM}X2Gnl=0{|APb-~Mj|vBkL< z{ev9^7(VleFl^g+=Tg@G@A?1%0AT>0{{jF2008#+0BuD{BLKjz)Bx4p_yB&y`Ayf{ z_5j7Y-2nL5-2fm8007j3`z|1JOk00062VE~^00+2cg0sQ;_CIji{0Pyzz0LJD0eQhfRO!@l% z05~=h0Q>g(0HnL|0Q&p?v8vqrW1`ype&F){s009930Ro5-6b}uCY&U`oS=9ata4;M_`;Fnt*MAHtF(M2mUEu_g?v30SwMt(9|Vaq|G{Agq_hp&XSpdLz$0Z-L_8*g8a-3c6w|KFYbS1 zSbP58t)`2=Gynn!90$p&tj!ACj5YoyEDREg91M&sj0~@@ePvjC@gKw6pZ_;byz!?L zsO~me5?0GoXXz3KTH>q2$RMT8!SMh0KZfV`ele`R`2W_+AOBa)z4N;kAb`LYfLs(U z&s;1Gj3jm@24#@`KR~t5fBfIH;Qrq}n9H%`6SYWr<`fxDpgv{>HIUfPzYMot{`|jc z(fz;Efcl;T1Q2p*Dg~rKmJFqA^c&22iQ8hd`QR zNXQf>bMx}PrY5IpQ>Th9pEOCRdBqBih<9IKU+4M$?ryS0*_#{R+4<#se*gOVdP?f) zX|@U}K4b&L z&lNm9mD;8oy-nx$pP$8FPfgX9f3TTBp&=rHM^A5E&4h`KW;a0D-`93Bu(MR3P4Gc`~MJ_Ha(gqfnQd3eTx5?NY zPsmF<^B^_*&;lLpa|aF|Wj&@~=E0-F9>g5PeTn%}_jx9urf7zqfcV4E6o)_?zhgJB1+5cA2#D-BngzBGJ!1ajm7u?-tHMsD1^*?7;N zKeHX(Lnl7uXBIxZ-u}Nt-JgHmO^!(lmJ_5VL`{&J5LY7xihwKZtL*FkB>edFTK@26 z{sSJV&l3}p|DHc^=*W=+XIMNF>;L~v|MB^~{9*kCt_r3KTNP{-_Wsae;857Wy1)K^ zTFvioy3EGL+=rjP-!FNu_Al$Dj!@^mfpDt2|GYazudl5&b?=u;Gzbw%{PFRl>EXle z{F3`>f3uaCGD|eyP%xYzBAnyRYklecfrrY0mDP|(xk3*#tZINZuDF0n1|?yt8;I)!6y-n_|ke!hKr#P&Sd z=FU#e!?(6(OKzO%%D{M}>Bzs*-{0O&cBqk`;oNUu{p}2w#Kx)v9ic4GoA=kh{|`*= zLIy$ojLon9U0E5tz43@+;o`-Mne|>f@VRXVri_5DY?TA-M{OL=FpBDO}>(n#krP31I#Vh)8YH`I(=e|35x1?q7Xv?ce_o9z6K3 zV4NtS&>*oQKs`A^NJNBXI}4CEAy-+vS%>i`;~61kW#t{L42&*Qz2q|lG|Xr3ss7G4 xC%j>$pdPz`L(i3*Z4AQQhO?IPFfg()Ncu|uUvoeA9k38#@O1TaS?83{1ORO7=-dDR literal 0 HcmV?d00001 diff --git a/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/netbeans-paste24.gif b/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/netbeans-paste24.gif new file mode 100644 index 0000000000000000000000000000000000000000..65c0ec02c2b150ae29df85b38220d95d7196ff68 GIT binary patch literal 880 zcmV-$1CRWPP)@R3;D`1MyiPp1xz-mbrxV0R#{OD2Rx`PA+a2 zE?&O+|LgZ3|3Nf}PmDf*07CIWd92tbAmxkAA-{j?Fx;{jfUF-3uU@}l`1un-AGo8!;O1z;kQ(ca zqGw8L4BU|b0fc4&1H;ER_uxUdaP={Uy+^Jy95}EaEcX1>8-}RRAUF*I4i1hC-#))% zh!3@5U}R*3n*##?0fb_~zkmN3{{8vIaP8J(Fn`0mF^G z?O^@?kh}m8Ko~yw`{xJ4w=ZA7-i=DiWbg_IBWQtukT6(1NFPW)vJU_P2-AY!KN)`g z`T^!kNJ=w^OGpv402cNjeIWhF761egMiBi0D){^74+Aq3BTPHdxfY}kq#rqm00IbW z5dHi2i-DP$^il+*4?Tzg0tm%|zki_?08 zm4FZa{rk&cYG%Q}#l^+I&(F_r=F}mE7m$36;sbyH!tenMu(2}ZFXx$A7z70c83Y8l z7=$?(7{(s`Hr!ZS0v>P3<^Ti`YH9k90qjL)U=nT0vt#)3 z?H7JuurXs84l@S^00IbW5P`h<^*b*8z7a*$jA@{G;SG?Jsl`_1SAI#Kv*r1Nt^2mq|%)9Qz+c)@Z{ z-+X4c_T&x2xw|hI_Fa0o1}HS^|Gz&e4N(qZE(VGWdoJ8(Xjpb&)zdlY;UM(@0mOoC zxOB>_91~Tk$-ZW440_7a44;1fW%&B*AH$VbzrgYwEF26vDsl`~+KLQz+HxVAPu&VR zbNd;CoU|mv@rPf)Gy?-8$md`S00Icb0;!}KIZpaYll`o;8JO6)7|uQYhBwSbghd&m zowylzIoKHPzxxRm`}E^4!~cK(7#M*77&`v}0tjw_WWp3zBNge%j>Z}cuYR&JeEIy7 zV5ENd{+EG=jgfJ;1j_<-Tusl(g8U)x{*Ao&ZIE-=0Efm<8SrFzH zW^1SpS9AE@XNJ3PG2`mrAA}D80tjlse}(T%91K5@y!zt#Glst(p6>%04p#I3f7nlM z35FTRUlELa~)?!G(e5 z!7Ts?AV?hi{{Hy$rwWXf}#VIo;giI=3P3lk>N5sj|V{?eE+lt z#s&x=um%5qe!KYd<7*TPl#~=0PM*6E#O+qR|Ld;aS3l0K-3}B!1H?i^lzXrLL(3q5 z00Ngq9Hx=k8m4wr6wKV)m!%&{{8#U@Zrn zQtAkR0D>14f39v{e}|Dpi-m)$OvBunK|oXjlHops@K2zRelm#iNP>J}M2ZCf0mOn7 zZl8cb)qDN_Uxr`bzm};Q*)S;UnxH8D@()sw!AeSEEC2`~7PQED1+wJMw~r6+UpgJE zX6E1|tE$ByrJ%|n2=vj1H!m6f|NeQC6dwQt5DS(R0J3BWFfZ=B{`qz2^`m?y3@q&0 z42;aOz%2TN;m4QP$#$OX_0YHEO0DhAB)fj_z Q4FCWD07*qoM6N<$g4@qPaR2}S literal 0 HcmV?d00001 diff --git a/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/netbeans-undo24.gif b/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/netbeans-undo24.gif new file mode 100644 index 0000000000000000000000000000000000000000..e2c01c01caa53d9f900bb18b5c8b6af671c13e14 GIT binary patch literal 1282 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 literal 0 HcmV?d00001 From 225018548722be4ca14a12034bcb691f2b47faff Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Tue, 14 Apr 2020 12:41:14 +0200 Subject: [PATCH 5/8] Testing: FlatDisabledIconsTest: use intellij dark icons in dark themes --- .../testing/FlatDisabledIconsTest.java | 119 ++++++++++++------ .../flatlaf/testing/FlatDisabledIconsTest.jfd | 12 -- .../intellij-menu-cut@2x_dark.png | Bin 0 -> 536 bytes .../intellij-menu-cut_dark.png | Bin 0 -> 285 bytes .../intellij-menu-paste@2x_dark.png | Bin 0 -> 124 bytes .../intellij-menu-paste_dark.png | Bin 0 -> 99 bytes .../intellij-search@2x_dark.png | Bin 0 -> 687 bytes .../intellij-search_dark.png | Bin 0 -> 308 bytes .../intellij-show@2x_dark.png | Bin 0 -> 467 bytes .../intellij-showReadAccess@2x_dark.png | Bin 0 -> 511 bytes .../intellij-showReadAccess_dark.png | Bin 0 -> 324 bytes .../intellij-showWriteAccess@2x_dark.png | Bin 0 -> 492 bytes .../intellij-showWriteAccess_dark.png | Bin 0 -> 330 bytes .../intellij-show_dark.png | Bin 0 -> 273 bytes 14 files changed, 83 insertions(+), 48 deletions(-) create mode 100644 flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-menu-cut@2x_dark.png create mode 100644 flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-menu-cut_dark.png create mode 100644 flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-menu-paste@2x_dark.png create mode 100644 flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-menu-paste_dark.png create mode 100644 flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-search@2x_dark.png create mode 100644 flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-search_dark.png create mode 100644 flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-show@2x_dark.png create mode 100644 flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-showReadAccess@2x_dark.png create mode 100644 flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-showReadAccess_dark.png create mode 100644 flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-showWriteAccess@2x_dark.png create mode 100644 flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-showWriteAccess_dark.png create mode 100644 flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-show_dark.png diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatDisabledIconsTest.java b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatDisabledIconsTest.java index cb6ed331..fa4a2e96 100644 --- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatDisabledIconsTest.java +++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatDisabledIconsTest.java @@ -17,6 +17,7 @@ package com.formdev.flatlaf.testing; import java.awt.Component; +import java.awt.Graphics; import java.awt.Image; import java.awt.Toolkit; import java.awt.image.FilteredImageSource; @@ -24,6 +25,7 @@ import java.awt.image.ImageProducer; import java.awt.image.RGBImageFilter; import java.beans.*; import javax.swing.*; +import com.formdev.flatlaf.FlatLaf; import net.miginfocom.swing.*; /** @@ -266,53 +268,17 @@ public class FlatDisabledIconsTest //---- button6 ---- button6.setIcon(new ImageIcon(getClass().getResource("/com/formdev/flatlaf/testing/disabled_icons_test/netbeans-find24.gif"))); enabledToolBar.add(button6); - - //---- button7 ---- - button7.setIcon(new ImageIcon(getClass().getResource("/com/formdev/flatlaf/testing/disabled_icons_test/intellij-menu-cut.png"))); enabledToolBar.add(button7); - - //---- button8 ---- - button8.setIcon(new ImageIcon(getClass().getResource("/com/formdev/flatlaf/testing/disabled_icons_test/intellij-menu-paste.png"))); enabledToolBar.add(button8); - - //---- button9 ---- - button9.setIcon(new ImageIcon(getClass().getResource("/com/formdev/flatlaf/testing/disabled_icons_test/intellij-show.png"))); enabledToolBar.add(button9); - - //---- button10 ---- - button10.setIcon(new ImageIcon(getClass().getResource("/com/formdev/flatlaf/testing/disabled_icons_test/intellij-showReadAccess.png"))); enabledToolBar.add(button10); - - //---- button11 ---- - button11.setIcon(new ImageIcon(getClass().getResource("/com/formdev/flatlaf/testing/disabled_icons_test/intellij-showWriteAccess.png"))); enabledToolBar.add(button11); - - //---- button12 ---- - button12.setIcon(new ImageIcon(getClass().getResource("/com/formdev/flatlaf/testing/disabled_icons_test/intellij-search.png"))); enabledToolBar.add(button12); - - //---- button13 ---- - button13.setIcon(new ImageIcon(getClass().getResource("/com/formdev/flatlaf/testing/disabled_icons_test/intellij-menu-cut@2x.png"))); enabledToolBar.add(button13); - - //---- button14 ---- - button14.setIcon(new ImageIcon(getClass().getResource("/com/formdev/flatlaf/testing/disabled_icons_test/intellij-menu-paste@2x.png"))); enabledToolBar.add(button14); - - //---- button15 ---- - button15.setIcon(new ImageIcon(getClass().getResource("/com/formdev/flatlaf/testing/disabled_icons_test/intellij-show@2x.png"))); enabledToolBar.add(button15); - - //---- button16 ---- - button16.setIcon(new ImageIcon(getClass().getResource("/com/formdev/flatlaf/testing/disabled_icons_test/intellij-showReadAccess@2x.png"))); enabledToolBar.add(button16); - - //---- button17 ---- - button17.setIcon(new ImageIcon(getClass().getResource("/com/formdev/flatlaf/testing/disabled_icons_test/intellij-showWriteAccess@2x.png"))); enabledToolBar.add(button17); - - //---- button18 ---- - button18.setIcon(new ImageIcon(getClass().getResource("/com/formdev/flatlaf/testing/disabled_icons_test/intellij-search@2x.png"))); enabledToolBar.add(button18); } add(enabledToolBar, "cell 1 0"); @@ -468,6 +434,44 @@ public class FlatDisabledIconsTest selectedCheckBox.addActionListener(e -> selectedChanged()); add(selectedCheckBox, "cell 0 10"); // JFormDesigner - End of component initialization //GEN-END:initComponents + + button7.setIcon( new LightOrDarkIcon( + "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-menu-cut.png", + "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-menu-cut_dark.png" ) ); + button8.setIcon( new LightOrDarkIcon( + "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-menu-paste.png", + "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-menu-paste_dark.png" ) ); + button9.setIcon( new LightOrDarkIcon( + "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-show.png", + "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-show_dark.png" ) ); + button10.setIcon( new LightOrDarkIcon( + "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-showReadAccess.png", + "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-showReadAccess_dark.png" ) ); + button11.setIcon( new LightOrDarkIcon( + "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-showWriteAccess.png", + "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-showWriteAccess_dark.png" ) ); + button12.setIcon( new LightOrDarkIcon( + "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-search.png", + "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-search_dark.png" ) ); + + button13.setIcon( new LightOrDarkIcon( + "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-menu-cut@2x.png", + "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-menu-cut@2x_dark.png" ) ); + button14.setIcon( new LightOrDarkIcon( + "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-menu-paste@2x.png", + "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-menu-paste@2x_dark.png" ) ); + button15.setIcon( new LightOrDarkIcon( + "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-show@2x.png", + "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-show@2x_dark.png" ) ); + button16.setIcon( new LightOrDarkIcon( + "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-showReadAccess@2x.png", + "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-showReadAccess@2x_dark.png" ) ); + button17.setIcon( new LightOrDarkIcon( + "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-showWriteAccess@2x.png", + "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-showWriteAccess@2x_dark.png" ) ); + button18.setIcon( new LightOrDarkIcon( + "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-search@2x.png", + "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-search@2x_dark.png" ) ); } // JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables @@ -495,6 +499,49 @@ public class FlatDisabledIconsTest private JCheckBox selectedCheckBox; // JFormDesigner - End of variables declaration //GEN-END:variables + //---- class LightOrDarkIcon ---------------------------------------------- + + private static class LightOrDarkIcon + extends ImageIcon + { + private final ImageIcon lightIcon; + private final ImageIcon darkIcon; + + LightOrDarkIcon( String lightIconName, String darkIconName ) { + this.lightIcon = new ImageIcon( getClass().getResource( lightIconName ) ); + this.darkIcon = new ImageIcon( getClass().getResource( darkIconName ) ); + } + + private ImageIcon getCurrentIcon() { + return isDark() ? darkIcon : lightIcon; + } + + private boolean isDark() { + LookAndFeel lookAndFeel = UIManager.getLookAndFeel(); + return lookAndFeel instanceof FlatLaf && ((FlatLaf)lookAndFeel).isDark(); + } + + @Override + public int getIconWidth() { + return getCurrentIcon().getIconWidth(); + } + + @Override + public int getIconHeight() { + return getCurrentIcon().getIconHeight(); + } + + @Override + public synchronized void paintIcon( Component c, Graphics g, int x, int y ) { + getCurrentIcon().paintIcon( c, g, x, y ); + } + + @Override + public Image getImage() { + return getCurrentIcon().getImage(); + } + } + //---- class IntelliJFilterController ------------------------------------ private static class IntelliJFilterController diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatDisabledIconsTest.jfd b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatDisabledIconsTest.jfd index b0773567..ca8f1851 100644 --- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatDisabledIconsTest.jfd +++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatDisabledIconsTest.jfd @@ -49,51 +49,39 @@ new FormModel { } ) add( new FormComponent( "javax.swing.JToggleButton" ) { name: "button7" - "icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-menu-cut.png" ) } ) add( new FormComponent( "javax.swing.JToggleButton" ) { name: "button8" - "icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-menu-paste.png" ) } ) add( new FormComponent( "javax.swing.JToggleButton" ) { name: "button9" - "icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-show.png" ) } ) add( new FormComponent( "javax.swing.JToggleButton" ) { name: "button10" - "icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-showReadAccess.png" ) } ) add( new FormComponent( "javax.swing.JToggleButton" ) { name: "button11" - "icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-showWriteAccess.png" ) } ) add( new FormComponent( "javax.swing.JToggleButton" ) { name: "button12" - "icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-search.png" ) } ) add( new FormComponent( "javax.swing.JToggleButton" ) { name: "button13" - "icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-menu-cut@2x.png" ) } ) add( new FormComponent( "javax.swing.JToggleButton" ) { name: "button14" - "icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-menu-paste@2x.png" ) } ) add( new FormComponent( "javax.swing.JToggleButton" ) { name: "button15" - "icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-show@2x.png" ) } ) add( new FormComponent( "javax.swing.JToggleButton" ) { name: "button16" - "icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-showReadAccess@2x.png" ) } ) add( new FormComponent( "javax.swing.JToggleButton" ) { name: "button17" - "icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-showWriteAccess@2x.png" ) } ) add( new FormComponent( "javax.swing.JToggleButton" ) { name: "button18" - "icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-search@2x.png" ) } ) }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { "value": "cell 1 0" diff --git a/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-menu-cut@2x_dark.png b/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-menu-cut@2x_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..d2b603cbdfdfef9342ccbbe6aa883e586a09a437 GIT binary patch literal 536 zcmV+z0_XjSP)lYx{H428YHUs~=pyyh;+4b-$+2jHKP$oPN&phC7nfqVl=p4p} z4Dm>j`gC(tOg97mlqwLosB4@8lD^;s!TNL~zb`8cc9Q3msanQ4zf`_t;()S-GmHyt zo$H{#uT=uhPpzcA3_|~|3WV{xux^~>F$|Zf-)FR;RPkJCm(7AW-GhR{(tnrp!wh~t zv;n6hq?8O$yl%&)h^)R8q z2eJ-5B*(Jxv8x`%)qEg{yvPX@nHU%WQ=1Qfe_}8v^qjDD92eSj3e2i<7&_3gO2th1 zfKEzfnW&r-ntY(|IL?ax*v&V@0(8wAx7^>nd9w(91Awl^NY zy#RE#>3`Gk>?1m7E#{K*Ev*0y^*n|XjAvQxu jNy>0T&@7-VGf@Hn_U}5pvwN|o00000NkvXXu0mjfQQ3c> literal 0 HcmV?d00001 diff --git a/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-menu-paste@2x_dark.png b/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-menu-paste@2x_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..fc404c0ea4110e2b21202c6121eedf601b557371 GIT binary patch literal 124 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdzXHOT$kcwN$2@@WOWpW-u7 vZ4s|?cnA08dkjTS-FYQK*mz=`q<|WK&HB2~@%}V(pe_baS3j3^P64M<6kRkRO7d%2Ye3TxAYtXxEBjTN+zpr9~>+(`ukMz#n+abZvdf;P1j ziC#!8tVJ%G9@Hk%ut6{zU$_5>fADcQ=iEDIrjiyv5Sj0M|8vjd&IDl?2LDp9Bm<<= zX`5xRAG+ZUOv4n6!5ugXWsdry0@T7Ngb_Z%kx~b^0P``LOP!D`MSzQj!9T!tI0Y%V z46hBJ>n=9Hc5UWApjpjq&yAr#!v7L{^pjeMb2UGPk?J;fC*TR!Ba31p@AWui~4?_0FT4~eVqLR$VRx& z0Ij0_vrmAxVt_UVcnHrT3^TwXZ5a}U26$%(a0~86=wpC`qJGvVz!Nb*F9V!|jtFNN zpheVw@>zmT?I@LD;0;dZy%K}W zz&3_h!$U2&5`I#VQfPlL{_q%zVO;`yzL-TQ{ z&^Kp{072wMWZ3n)ATOFvLyhTl{HXv+BP_x^)Y*<_Nq(9+&VMU3yY7eo@5kxi^b?tF V*5;M(2J-*_002ovPDHLkV1hQQFeU&1 literal 0 HcmV?d00001 diff --git a/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-search_dark.png b/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-search_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..bdfa83e5e7de88221498690fc1bb2970fee5696b GIT binary patch literal 308 zcmV-40n7f0P)#K1#{2f!#XnmQURyo4@N5fjlT>F)n{eMi0~r&pDv!%yq< z+|RjJYOJ-Ui1&x@`>r1B;YxDf)jfFuGqCW0Egay<+U!?AmyJhgcIG=HAnWY zsCQ^!;Q-DwkQ&_B^EKcCA%9t}Cki>qmOXz33}He;6>$Bv1sSuB1s=4?L#?K_kc7Aa zJs#8{;}9c0TjmAmzfle|q&sVgQ7Rw^f)qS#K_8|hW3Sv09k2kKVWC3BSOvs7pag4Y z@tSoVkc7lgako&0h>IhBHyHuu;}BJ26*j!4&L#J4EaC;ehg=W|rHR7;0000fd%!t zEn9RzKE@eJo3<2?X8DHA6*z)+`Kqm3C2;9mzka>I`i+|w;|PrgB7MFk0-Mi4mJ{m% z+>Y21gWqycP;T7(9b2%kUAs*N;nS@K8#Zp*4oYm`9I$Egeo&MkhXhm(-4oxD)nNdj zg5x-XuLjw2ApbKKHNV$x+GGJ&2aI>@W^FpXfB$|KOy6(X%Y=~R{K^?IhS}KAoA{5KP z1rlZvPB0q|ctJ!=QM`HcW)Zwa@rEt)DJqJIsf@r51V#faF4t_{tO1F095pAYmC>N6 zjt5191j8ZgH#>lvWWYiTtw4GY%EIe5ZJrJCF;y)d1*2ft0|4X9Hb0F&dIJCe002ov JPDHLkV1nEf#906U literal 0 HcmV?d00001 diff --git a/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-showReadAccess@2x_dark.png b/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-showReadAccess@2x_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..48c41156a3f0de1ecc9f2c69fe1151fc53b66d24 GIT binary patch literal 511 zcmVnELmgVa=ZvKxF=fKnrH1Iu|1&5L28sre5*nW(tnH^+7l;!*P?`Hv8d>CXox&w$# zoWL9awDdWeBVN1D2~{D&=LpNmbpSY>%noq?TKXL&JCWJt_03*8sv+%$=U{1(#dPc!-G|TtnEFrNuf|`lYb58Jmf^`JCBgnBF zl+r;J5}MCHyUh&Npr{~%*8AVdDTusgh4@gVC32|Wp>Ll6*c6AyKd`|vFnt4H4glqZ(JtDM0|3d}p?d#VjR*h$002ovPDHLkV1ff+ B;>G{~ literal 0 HcmV?d00001 diff --git a/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-showReadAccess_dark.png b/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-showReadAccess_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..d24cc28bf74ba18a1e67a0fd78a27829cdf2bcc8 GIT binary patch literal 324 zcmV-K0lWT*P){A7qH<>>vxg8usts&jMoy%nuL% zYPt>8d>Tr>cApcfg42NY8#gTm(GK$yIJ{q-)nBjb&%m0 zn%8aIyn6k{&Hr&34l)F2z<#hHK*K?NxU<)9*fJla85>461jSpkL#BfT=kMRo0aUn| zSOY*_fQH9%xCF8x#CQQjgTe_#0mzUI8#ir-1)}Gi(BrT`grtYy`4G*)_r2zaN?^4G zWC)DyJ2O%QDGk7)@w3~^U=5OzFh~e?kHW?SeiyU@{hqf1^4ga5dE| z+`M_S2x_83wfsa#K>vx*zzQsmYNm<<)^FT=9?cOoa7#i1c7vh>8Zz@S92XoALk$P~ z$L-z%&1klpPe)On05fo%W4F_O20@-pH0ObI*tO>%ekA?cFP{RQjjv!PxAuwua z;j@4kOwbXaxW`D8Na=-A2M`+)&6qjEfBHZ>U^zXb;5V8B_LEgYB3r&;BNf-H#AIDh|sj{N}v z0>^^`?t?S~4LJ`rm6hKA#z0lW7nB!Jk9A%^&02N_Ptfd4Q< z_B%MRfW$yF(1875LqLW?#gR2&;0+r$Z3h_wQwR1|NWg8VOQsVvVEx8Tr&q07#e-^q z|8=MV%L#em@aD~%MX-7SNQ1%!j{%!buV23&7z=?JFq?oeG9RoN7&E6rLnZJABFNeM zLqmCh8Xki*9SaFK4Ym36vEX10q7%}|U_TR3DugAZV0Gn>j&}`OO#{d8T07*qoM6N<$f`r9|q5uE@ literal 0 HcmV?d00001 diff --git a/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-show_dark.png b/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-show_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..d758d2e85d0c76753e824ce277ba80e7e6c22bb2 GIT binary patch literal 273 zcmV+s0q*{ZP)=`t<_qH*T)kuyONoApQ Date: Sun, 19 Apr 2020 10:23:40 +0200 Subject: [PATCH 6/8] FlatDisabledIconsTest: renamed @2x_dark.png icons to _dark@2x.png so that they are automatically loaded on macOS Retina displays --- .../flatlaf/testing/FlatDisabledIconsTest.java | 12 ++++++------ ...ut@2x_dark.png => intellij-menu-cut_dark@2x.png} | Bin ...@2x_dark.png => intellij-menu-paste_dark@2x.png} | Bin ...arch@2x_dark.png => intellij-search_dark@2x.png} | Bin ...dark.png => intellij-showReadAccess_dark@2x.png} | Bin ...ark.png => intellij-showWriteAccess_dark@2x.png} | Bin ...j-show@2x_dark.png => intellij-show_dark@2x.png} | Bin 7 files changed, 6 insertions(+), 6 deletions(-) rename flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/{intellij-menu-cut@2x_dark.png => intellij-menu-cut_dark@2x.png} (100%) rename flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/{intellij-menu-paste@2x_dark.png => intellij-menu-paste_dark@2x.png} (100%) rename flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/{intellij-search@2x_dark.png => intellij-search_dark@2x.png} (100%) rename flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/{intellij-showReadAccess@2x_dark.png => intellij-showReadAccess_dark@2x.png} (100%) rename flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/{intellij-showWriteAccess@2x_dark.png => intellij-showWriteAccess_dark@2x.png} (100%) rename flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/{intellij-show@2x_dark.png => intellij-show_dark@2x.png} (100%) diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatDisabledIconsTest.java b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatDisabledIconsTest.java index fa4a2e96..68261354 100644 --- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatDisabledIconsTest.java +++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatDisabledIconsTest.java @@ -456,22 +456,22 @@ public class FlatDisabledIconsTest button13.setIcon( new LightOrDarkIcon( "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-menu-cut@2x.png", - "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-menu-cut@2x_dark.png" ) ); + "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-menu-cut_dark@2x.png" ) ); button14.setIcon( new LightOrDarkIcon( "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-menu-paste@2x.png", - "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-menu-paste@2x_dark.png" ) ); + "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-menu-paste_dark@2x.png" ) ); button15.setIcon( new LightOrDarkIcon( "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-show@2x.png", - "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-show@2x_dark.png" ) ); + "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-show_dark@2x.png" ) ); button16.setIcon( new LightOrDarkIcon( "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-showReadAccess@2x.png", - "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-showReadAccess@2x_dark.png" ) ); + "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-showReadAccess_dark@2x.png" ) ); button17.setIcon( new LightOrDarkIcon( "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-showWriteAccess@2x.png", - "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-showWriteAccess@2x_dark.png" ) ); + "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-showWriteAccess_dark@2x.png" ) ); button18.setIcon( new LightOrDarkIcon( "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-search@2x.png", - "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-search@2x_dark.png" ) ); + "/com/formdev/flatlaf/testing/disabled_icons_test/intellij-search_dark@2x.png" ) ); } // JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables diff --git a/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-menu-cut@2x_dark.png b/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-menu-cut_dark@2x.png similarity index 100% rename from flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-menu-cut@2x_dark.png rename to flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-menu-cut_dark@2x.png diff --git a/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-menu-paste@2x_dark.png b/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-menu-paste_dark@2x.png similarity index 100% rename from flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-menu-paste@2x_dark.png rename to flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-menu-paste_dark@2x.png diff --git a/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-search@2x_dark.png b/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-search_dark@2x.png similarity index 100% rename from flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-search@2x_dark.png rename to flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-search_dark@2x.png diff --git a/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-showReadAccess@2x_dark.png b/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-showReadAccess_dark@2x.png similarity index 100% rename from flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-showReadAccess@2x_dark.png rename to flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-showReadAccess_dark@2x.png diff --git a/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-showWriteAccess@2x_dark.png b/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-showWriteAccess_dark@2x.png similarity index 100% rename from flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-showWriteAccess@2x_dark.png rename to flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-showWriteAccess_dark@2x.png diff --git a/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-show@2x_dark.png b/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-show_dark@2x.png similarity index 100% rename from flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-show@2x_dark.png rename to flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/disabled_icons_test/intellij-show_dark@2x.png From a39ae5a8c57248362089673aa9b4f746c823cf16 Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Fri, 24 Apr 2020 00:16:44 +0200 Subject: [PATCH 7/8] FlatDisabledIconsTest: support palette icons --- .../testing/FlatDisabledIconsTest.java | 97 +++++++++++++++++++ .../flatlaf/testing/FlatDisabledIconsTest.jfd | 10 ++ 2 files changed, 107 insertions(+) diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatDisabledIconsTest.java b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatDisabledIconsTest.java index 68261354..c4f0dfd3 100644 --- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatDisabledIconsTest.java +++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatDisabledIconsTest.java @@ -16,16 +16,20 @@ package com.formdev.flatlaf.testing; +import java.awt.Color; import java.awt.Component; import java.awt.Graphics; +import java.awt.Graphics2D; import java.awt.Image; import java.awt.Toolkit; +import java.awt.image.BufferedImage; import java.awt.image.FilteredImageSource; import java.awt.image.ImageProducer; import java.awt.image.RGBImageFilter; import java.beans.*; import javax.swing.*; import com.formdev.flatlaf.FlatLaf; +import com.formdev.flatlaf.util.UIScale; import net.miginfocom.swing.*; /** @@ -92,6 +96,18 @@ public class FlatDisabledIconsTest intelliJDarkFilterController.defaultBrightness = -70; intelliJDarkFilterController.defaultContrast = -70; intelliJDarkFilterController.reset(); + + toolBars = new JToolBar[] { + enabledToolBar, + currentLafToolBar, + basicLafToolBar, + metalLafToolBar, + plasticToolBar, + intellijTextToolBar, + intellijLightToolBar, + intellijDarkToolBar, + netbeansToolBar + }; } private void selectedChanged() { @@ -106,6 +122,50 @@ public class FlatDisabledIconsTest } } + private final JToolBar[] toolBars; + private Icon[] oldIcons; + private static final String[] COLOR_NAMES = { + "Actions.Red", + "Actions.Yellow", + "Actions.Green", + "Actions.Blue", + "Actions.Grey", + "Actions.GreyInline", + + "Objects.Grey", + "Objects.Blue", + "Objects.Green", + "Objects.Yellow", + "Objects.YellowDark", + "Objects.Purple", + "Objects.Pink", + "Objects.Red", + "Objects.RedStatus", + "Objects.GreenAndroid", + "Objects.BlackText", + + "", // black + }; + + private void paletteIconsChanged() { + if( paletteIconsCheckBox.isSelected() ) { + oldIcons = new Icon[COLOR_NAMES.length]; + for( int i = 0; i < COLOR_NAMES.length; i++ ) + oldIcons[i] = ((JToggleButton)enabledToolBar.getComponent( i )).getIcon(); + + for( int i = 0; i < COLOR_NAMES.length; i++ ) { + ColorIcon icon = new ColorIcon( UIManager.getColor( COLOR_NAMES[i] ) ); + for( JToolBar toolBar : toolBars ) + ((JToggleButton)toolBar.getComponent( i )).setIcon( icon ); + } + } else if( oldIcons != null ){ + for( int i = 0; i < COLOR_NAMES.length; i++ ) { + for( JToolBar toolBar : toolBars ) + ((JToggleButton)toolBar.getComponent( i )).setIcon( oldIcons[i] ); + } + } + } + private void basicLafChanged() { boolean brighter = basicLafBrighterCheckBox.isSelected(); int percent = basicLafPercentSlider.getValue(); @@ -216,6 +276,7 @@ public class FlatDisabledIconsTest zipToolBar = new JToolBar(); zipButton = new JToggleButton(); selectedCheckBox = new JCheckBox(); + paletteIconsCheckBox = new JCheckBox(); //======== this ======== setLayout(new MigLayout( @@ -433,6 +494,11 @@ public class FlatDisabledIconsTest selectedCheckBox.setText("selected"); selectedCheckBox.addActionListener(e -> selectedChanged()); add(selectedCheckBox, "cell 0 10"); + + //---- paletteIconsCheckBox ---- + paletteIconsCheckBox.setText("palette icons"); + paletteIconsCheckBox.addActionListener(e -> paletteIconsChanged()); + add(paletteIconsCheckBox, "cell 1 10,alignx left,growx 0"); // JFormDesigner - End of component initialization //GEN-END:initComponents button7.setIcon( new LightOrDarkIcon( @@ -497,6 +563,7 @@ public class FlatDisabledIconsTest private JToolBar zipToolBar; private JToggleButton zipButton; private JCheckBox selectedCheckBox; + private JCheckBox paletteIconsCheckBox; // JFormDesigner - End of variables declaration //GEN-END:variables //---- class LightOrDarkIcon ---------------------------------------------- @@ -542,6 +609,31 @@ public class FlatDisabledIconsTest } } + //---- class ColorIcon ---------------------------------------------------- + + private static class ColorIcon + extends ImageIcon + { + ColorIcon( Color color ) { + super( createColorImage( color ) ); + } + + private static Image createColorImage( Color color ) { + if( color == null ) + color = Color.black; + + BufferedImage image = new BufferedImage( UIScale.scale( 16 ), UIScale.scale( 16 ), BufferedImage.TYPE_INT_ARGB ); + Graphics2D g = image.createGraphics(); + try { + g.setColor( color ); + g.fillRect( UIScale.scale( 1 ), UIScale.scale( 2 ), UIScale.scale( 14 ), UIScale.scale( 12 ) ); + } finally { + g.dispose(); + } + return image; + } + } + //---- class IntelliJFilterController ------------------------------------ private static class IntelliJFilterController @@ -646,6 +738,11 @@ public class FlatDisabledIconsTest setEnabled( false ); setIcon( icon ); + } + + @Override + public void setIcon( Icon defaultIcon ) { + super.setIcon( defaultIcon ); if( filter != null ) updateDisabledIcon(); diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatDisabledIconsTest.jfd b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatDisabledIconsTest.jfd index ca8f1851..1e4e2bab 100644 --- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatDisabledIconsTest.jfd +++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatDisabledIconsTest.jfd @@ -368,6 +368,16 @@ new FormModel { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { "value": "cell 0 10" } ) + add( new FormComponent( "javax.swing.JCheckBox" ) { + name: "paletteIconsCheckBox" + "text": "palette icons" + auxiliary() { + "JavaCodeGenerator.variableLocal": false + } + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "paletteIconsChanged", false ) ) + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 1 10,alignx left,growx 0" + } ) }, new FormLayoutConstraints( null ) { "location": new java.awt.Point( 0, 0 ) "size": new java.awt.Dimension( 1095, 625 ) From 0660f9a511ac54694ad7053a825259bd18295171 Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Fri, 24 Apr 2020 00:46:16 +0200 Subject: [PATCH 8/8] improved creation of disabled grayscale icons (issue #70) --- CHANGELOG.md | 7 ++ .../java/com/formdev/flatlaf/FlatLaf.java | 35 +++++++- .../com/formdev/flatlaf/UIDefaultsLoader.java | 21 ++++- .../com/formdev/flatlaf/ui/FlatUIUtils.java | 64 --------------- .../com/formdev/flatlaf/util/GrayFilter.java | 81 +++++++++++++++++++ .../formdev/flatlaf/FlatDarkLaf.properties | 1 + .../formdev/flatlaf/FlatLightLaf.properties | 1 + .../flatlaf/testing/FlatTestLaf.properties | 1 + 8 files changed, 143 insertions(+), 68 deletions(-) create mode 100644 flatlaf-core/src/main/java/com/formdev/flatlaf/util/GrayFilter.java diff --git a/CHANGELOG.md b/CHANGELOG.md index c3018a7b..cfaf36ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,13 @@ FlatLaf Change Log ================== +## Unreleased + +- Improved creation of disabled grayscale icons used in disabled buttons, labels + and tabs. They now have more contrast and are lighter in light themes and + darker in dark themes. (issue #70) + + ## 0.30 - Windows: Fixed rendering of Unicode characters. Previously not all Unicode 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 37ee9bec..b1b18053 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatLaf.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatLaf.java @@ -21,12 +21,16 @@ import java.awt.Component; import java.awt.Container; import java.awt.EventQueue; import java.awt.Font; +import java.awt.Image; import java.awt.KeyEventPostProcessor; import java.awt.KeyboardFocusManager; import java.awt.RenderingHints; import java.awt.Toolkit; import java.awt.Window; import java.awt.event.KeyEvent; +import java.awt.image.FilteredImageSource; +import java.awt.image.ImageFilter; +import java.awt.image.ImageProducer; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.lang.ref.WeakReference; @@ -41,6 +45,7 @@ import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.AbstractButton; import javax.swing.Icon; +import javax.swing.ImageIcon; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JRootPane; @@ -54,12 +59,11 @@ import javax.swing.UnsupportedLookAndFeelException; import javax.swing.UIDefaults.ActiveValue; import javax.swing.plaf.ColorUIResource; import javax.swing.plaf.FontUIResource; -import javax.swing.plaf.IconUIResource; import javax.swing.plaf.UIResource; import javax.swing.plaf.basic.BasicLookAndFeel; import javax.swing.text.StyleContext; import javax.swing.text.html.HTMLEditorKit; -import com.formdev.flatlaf.ui.FlatUIUtils; +import com.formdev.flatlaf.util.GrayFilter; import com.formdev.flatlaf.util.SystemInfo; import com.formdev.flatlaf.util.UIScale; @@ -123,7 +127,21 @@ public abstract class FlatLaf @Override public Icon getDisabledIcon( JComponent component, Icon icon ) { - return (icon == null) ? null : new IconUIResource( FlatUIUtils.getDisabledIcon( icon ) ); + if( icon instanceof ImageIcon ) { + Object grayFilter = UIManager.get( "Component.grayFilter" ); + if( !(grayFilter instanceof ImageFilter) ) { + // fallback + grayFilter = isDark() + ? new GrayFilter( -20, -70, 100 ) + : new GrayFilter( 25, -25, 100 ); + } + + Image image = ((ImageIcon)icon).getImage(); + ImageProducer producer = new FilteredImageSource( image.getSource(), (ImageFilter) grayFilter ); + return new ImageIconUIResource( Toolkit.getDefaultToolkit().createImage( producer ) ); + } + + return null; } @Override @@ -629,4 +647,15 @@ public abstract class FlatLaf return font; } } + + //---- class ImageIconUIResource ------------------------------------------ + + private static class ImageIconUIResource + extends ImageIcon + implements UIResource + { + ImageIconUIResource( Image image ) { + super( image ); + } + } } diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/UIDefaultsLoader.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/UIDefaultsLoader.java index da3557d5..56269090 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/UIDefaultsLoader.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/UIDefaultsLoader.java @@ -41,6 +41,7 @@ import com.formdev.flatlaf.ui.FlatEmptyBorder; import com.formdev.flatlaf.ui.FlatLineBorder; import com.formdev.flatlaf.util.ColorFunctions; import com.formdev.flatlaf.util.DerivedColor; +import com.formdev.flatlaf.util.GrayFilter; import com.formdev.flatlaf.util.HSLColor; import com.formdev.flatlaf.util.StringUtils; import com.formdev.flatlaf.util.SystemInfo; @@ -222,7 +223,7 @@ class UIDefaultsLoader } private enum ValueType { UNKNOWN, STRING, CHARACTER, INTEGER, FLOAT, BORDER, ICON, INSETS, DIMENSION, COLOR, - SCALEDINTEGER, SCALEDFLOAT, SCALEDINSETS, SCALEDDIMENSION, INSTANCE, CLASS } + SCALEDINTEGER, SCALEDFLOAT, SCALEDINSETS, SCALEDDIMENSION, INSTANCE, CLASS, GRAYFILTER } static Object parseValue( String key, String value ) { return parseValue( key, value, v -> v, Collections.emptyList() ); @@ -289,6 +290,8 @@ class UIDefaultsLoader valueType = ValueType.CHARACTER; else if( key.endsWith( "UI" ) ) valueType = ValueType.STRING; + else if( key.endsWith( "grayFilter" ) ) + valueType = ValueType.GRAYFILTER; } // parse value @@ -308,6 +311,7 @@ class UIDefaultsLoader case SCALEDDIMENSION:return parseScaledDimension( value ); case INSTANCE: return parseInstance( value, addonClassLoaders ); case CLASS: return parseClass( value, addonClassLoaders ); + case GRAYFILTER: return parseGrayFilter( value ); case UNKNOWN: default: // colors @@ -664,6 +668,21 @@ class UIDefaultsLoader }; } + private static Object parseGrayFilter( String value ) { + List numbers = split( value, ',' ); + try { + int brightness = Integer.parseInt( numbers.get( 0 ) ); + int contrast = Integer.parseInt( numbers.get( 1 ) ); + int alpha = Integer.parseInt( numbers.get( 2 ) ); + + return (LazyValue) t -> { + return new GrayFilter( brightness, contrast, alpha ); + }; + } catch( NumberFormatException ex ) { + throw new IllegalArgumentException( "invalid gray filter '" + value + "'" ); + } + } + /** * Split string and trim parts. */ 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 2ad5baf1..4264dfec 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 @@ -23,15 +23,10 @@ import java.awt.Dimension; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; -import java.awt.GraphicsConfiguration; -import java.awt.GraphicsDevice; -import java.awt.GraphicsEnvironment; -import java.awt.Image; import java.awt.Insets; import java.awt.Rectangle; import java.awt.RenderingHints; import java.awt.Shape; -import java.awt.Toolkit; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; import java.awt.event.MouseAdapter; @@ -39,13 +34,7 @@ import java.awt.event.MouseEvent; import java.awt.geom.Path2D; import java.awt.geom.Rectangle2D; import java.awt.geom.RoundRectangle2D; -import java.awt.image.BufferedImage; -import java.awt.image.FilteredImageSource; -import java.awt.image.ImageProducer; -import java.awt.image.RGBImageFilter; import java.util.function.Consumer; -import javax.swing.Icon; -import javax.swing.ImageIcon; import javax.swing.JComponent; import javax.swing.LookAndFeel; import javax.swing.UIManager; @@ -444,59 +433,6 @@ public class FlatUIUtils return explicitlySet; } - public static Icon getDisabledIcon( Icon icon ) { - Image image = safeGetImage( icon ); - int grayMinValue = FlatUIUtils.getUIInt( "Button.disabledGrayMinValue", 180 ); - int grayMaxValue = FlatUIUtils.getUIInt( "Button.disabledGrayMaxValue", 215 ); - DisabledImageFilter imageFilter = new DisabledImageFilter( grayMinValue, grayMaxValue ); - ImageProducer producer = new FilteredImageSource( image.getSource(), imageFilter ); - return new ImageIcon( Toolkit.getDefaultToolkit().createImage( producer ) ); - } - - private static Image safeGetImage( Icon icon ) { - if( icon instanceof ImageIcon ) { - return ((ImageIcon)icon).getImage(); - } else { - int width = icon.getIconWidth(); - int height = icon.getIconHeight(); - GraphicsEnvironment environment = GraphicsEnvironment.getLocalGraphicsEnvironment(); - GraphicsDevice device = environment.getDefaultScreenDevice(); - GraphicsConfiguration configuration = device.getDefaultConfiguration(); - BufferedImage image = configuration.createCompatibleImage( width, height ); - Graphics2D g = image.createGraphics(); - icon.paintIcon( null, g, 0, 0 ); - g.dispose(); - return image; - } - } - - //---- class DisabledImageFilter ------------------------------------------ - - private static class DisabledImageFilter - extends RGBImageFilter - { - private final float min; - private final float factor; - - DisabledImageFilter( int min, int max ) { - this.min = min; - this.factor = (max - min) / 255f; - - canFilterIndexColorModel = true; - } - - @Override - public int filterRGB( int x, int y, int rgb ) { - // https://en.wikipedia.org/wiki/Grayscale - float linearLuminance = - (0.2126f * ((rgb >> 16) & 0xff)) + - (0.7152f * ((rgb >> 8) & 0xff)) + - (0.0722f * (rgb & 0xff)); - int gray = Math.min( (int) ((linearLuminance + .5f) * factor + min), 255 ); - return (rgb & 0xff000000) | (gray << 16) | (gray << 8) | gray; - } - } - //---- class HoverListener ------------------------------------------------ public static class HoverListener diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/util/GrayFilter.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/util/GrayFilter.java new file mode 100644 index 00000000..00bd4850 --- /dev/null +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/util/GrayFilter.java @@ -0,0 +1,81 @@ +// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package com.formdev.flatlaf.util; + +import java.awt.image.RGBImageFilter; + +// based on https://github.com/JetBrains/intellij-community/blob/3840eab54746f5c4f301bb3ac78f00a980b5fd6e/platform/util/ui/src/com/intellij/util/ui/UIUtil.java#L253-L347 + +/** + * An image filter that turns an image into a grayscale image. + * Used for icons in disabled buttons and labels. + */ +public class GrayFilter + extends RGBImageFilter +{ + private final float brightness; + private final float contrast; + private final int alpha; + + private final int origContrast; + private final int origBrightness; + + /** + * @param brightness in range [-100..100] where 0 has no effect + * @param contrast in range [-100..100] where 0 has no effect + * @param alpha in range [0..100] where 0 is transparent, 100 has no effect + */ + public GrayFilter( int brightness, int contrast, int alpha ) { + this.origBrightness = Math.max( -100, Math.min( 100, brightness ) ); + this.origContrast = Math.max( -100, Math.min( 100, contrast ) ); + this.alpha = Math.max( 0, Math.min( 100, alpha ) ); + + this.brightness = (float) (Math.pow( origBrightness, 3 ) / (100f * 100f)); // cubic in [0..100] + this.contrast = origContrast / 100f; + + canFilterIndexColorModel = true; + } + + public GrayFilter() { + this( 0, 0, 100 ); + } + + public int getBrightness() { + return origBrightness; + } + + public int getContrast() { + return origContrast; + } + + public int getAlpha() { + return alpha; + } + + @Override + public int filterRGB( int x, int y, int rgb ) { + // use NTSC conversion formula + int gray = (int)( + 0.30 * (rgb >> 16 & 0xff) + + 0.59 * (rgb >> 8 & 0xff) + + 0.11 * (rgb & 0xff)); + + if( brightness >= 0 ) + gray = (int) ((gray + brightness * 255) / (1 + brightness)); + else + gray = (int) (gray / (1 - brightness)); + + if( contrast >= 0 ) { + if( gray >= 127 ) + gray = (int) (gray + (255 - gray) * contrast); + else + gray = (int) (gray - gray * contrast); + } else + gray = (int) (127 + (gray - 127) * (contrast + 1)); + + int a = (alpha != 100) + ? (((rgb >> 24) & 0xff) * alpha / 100) << 24 + : (rgb & 0xff000000); + + return a | (gray << 16) | (gray << 8) | gray; + } +} 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 014cf7a4..bd5a7be3 100644 --- a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatDarkLaf.properties +++ b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatDarkLaf.properties @@ -129,6 +129,7 @@ Component.disabledBorderColor=#646464 Component.focusedBorderColor=#466d94 Component.focusColor=#3d6185 Component.linkColor=#589df6 +Component.grayFilter=-20,-70,100 #---- Desktop ---- 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 c643863f..9f75255c 100644 --- a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLightLaf.properties +++ b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLightLaf.properties @@ -131,6 +131,7 @@ Component.disabledBorderColor=#cfcfcf Component.focusedBorderColor=#87afda Component.focusColor=#97c3f3 Component.linkColor=#2470B3 +Component.grayFilter=25,-25,100 #---- Desktop ---- 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 b70f564d..1136d937 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 @@ -128,6 +128,7 @@ Component.focusedBorderColor=#466d94 Component.focusColor=#97c3f3 #Component.focusWidth=5 #Component.arc=8 +Component.grayFilter=25,25,100 #---- Desktop ----