FlatSVGIcon: icons were not painted in disabled labels and disabled tabs (issue #205)

This commit is contained in:
Karl Tauber
2020-11-10 11:22:34 +01:00
parent 7c08489cb3
commit 847b41752c
5 changed files with 249 additions and 14 deletions

View File

@@ -52,6 +52,8 @@ FlatLaf Change Log
#188; regression in 0.42 in fix for #164)
- IntelliJ Themes: Added suffix "(Material)" to names of all Material UI Lite
themes to avoid duplicate theme names. (issue #201)
- Extras: `FlatSVGIcon` icons were not painted in disabled labels and disabled
tabs. (issue #205)
## 0.43

View File

@@ -170,6 +170,9 @@ public abstract class FlatLaf
@Override
public Icon getDisabledIcon( JComponent component, Icon icon ) {
if( icon instanceof DisabledIconProvider )
return ((DisabledIconProvider)icon).getDisabledIcon();
if( icon instanceof ImageIcon ) {
Object grayFilter = UIManager.get( "Component.grayFilter" );
ImageFilter filter = (grayFilter instanceof ImageFilter)
@@ -762,4 +765,24 @@ public abstract class FlatLaf
super( image );
}
}
//---- interface DisabledIconProvider -------------------------------------
/**
* A provider for disabled icons.
* <p>
* This is intended to be implemented by {@link javax.swing.Icon} implementations
* that provide the ability to paint disabled state.
* <p>
* Used in {@link FlatLaf#getDisabledIcon(JComponent, Icon)} to create a disabled icon from an enabled icon.
*/
public interface DisabledIconProvider
{
/**
* Returns an icon with a disabled appearance.
*
* @return a disabled icon
*/
Icon getDisabledIcon();
}
}

View File

@@ -20,18 +20,22 @@ import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Paint;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.awt.image.RGBImageFilter;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.UIManager;
import com.formdev.flatlaf.FlatIconColors;
import com.formdev.flatlaf.FlatLaf;
import com.formdev.flatlaf.FlatLaf.DisabledIconProvider;
import com.formdev.flatlaf.ui.FlatUIUtils;
import com.formdev.flatlaf.util.Graphics2DProxy;
import com.formdev.flatlaf.util.GrayFilter;
@@ -46,7 +50,8 @@ import com.kitfox.svg.SVGUniverse;
* @author Karl Tauber
*/
public class FlatSVGIcon
implements Icon
extends ImageIcon
implements DisabledIconProvider
{
// use own SVG universe so that it can not be cleared from anywhere
private static final SVGUniverse svgUniverse = new SVGUniverse();
@@ -55,6 +60,7 @@ public class FlatSVGIcon
private final int width;
private final int height;
private final float scale;
private final boolean disabled;
private final ClassLoader classLoader;
private SVGDiagram diagram;
@@ -70,7 +76,7 @@ public class FlatSVGIcon
* @see ClassLoader#getResource(String)
*/
public FlatSVGIcon( String name ) {
this( name, -1, -1, 1, null );
this( name, -1, -1, 1, false, null );
}
/**
@@ -85,7 +91,7 @@ public class FlatSVGIcon
* @see ClassLoader#getResource(String)
*/
public FlatSVGIcon( String name, ClassLoader classLoader ) {
this( name, -1, -1, 1, classLoader );
this( name, -1, -1, 1, false, classLoader );
}
/**
@@ -99,7 +105,7 @@ public class FlatSVGIcon
* @see ClassLoader#getResource(String)
*/
public FlatSVGIcon( String name, int width, int height ) {
this( name, width, height, 1, null );
this( name, width, height, 1, false, null );
}
/**
@@ -115,7 +121,7 @@ public class FlatSVGIcon
* @see ClassLoader#getResource(String)
*/
public FlatSVGIcon( String name, int width, int height, ClassLoader classLoader ) {
this( name, width, height, 1, classLoader );
this( name, width, height, 1, false, classLoader );
}
/**
@@ -130,7 +136,7 @@ public class FlatSVGIcon
* @see ClassLoader#getResource(String)
*/
public FlatSVGIcon( String name, float scale ) {
this( name, -1, -1, scale, null );
this( name, -1, -1, scale, false, null );
}
/**
@@ -147,15 +153,16 @@ public class FlatSVGIcon
* @see ClassLoader#getResource(String)
*/
public FlatSVGIcon( String name, float scale, ClassLoader classLoader ) {
this( name, -1, -1, scale, classLoader );
this( name, -1, -1, scale, false, classLoader );
}
private FlatSVGIcon( String name, int width, int height, float scale, ClassLoader classLoader ) {
private FlatSVGIcon( String name, int width, int height, float scale, boolean disabled, ClassLoader classLoader ) {
this.name = name;
this.classLoader = classLoader;
this.width = width;
this.height = height;
this.scale = scale;
this.disabled = disabled;
}
/**
@@ -166,7 +173,10 @@ public class FlatSVGIcon
* @return a new icon
*/
public FlatSVGIcon derive( int width, int height ) {
FlatSVGIcon icon = new FlatSVGIcon( name, width, height, scale, classLoader );
if( width == this.width && height == this.height )
return this;
FlatSVGIcon icon = new FlatSVGIcon( name, width, height, scale, false, classLoader );
icon.diagram = diagram;
icon.dark = dark;
return icon;
@@ -179,7 +189,26 @@ public class FlatSVGIcon
* @return a new icon
*/
public FlatSVGIcon derive( float scale ) {
FlatSVGIcon icon = new FlatSVGIcon( name, width, height, scale, classLoader );
if( scale == this.scale )
return this;
FlatSVGIcon icon = new FlatSVGIcon( name, width, height, scale, false, classLoader );
icon.diagram = diagram;
icon.dark = dark;
return icon;
}
/**
* Creates a new icon with disabled appearance, which is derived from this icon.
*
* @return a new icon
*/
@Override
public Icon getDisabledIcon() {
if( disabled )
return this;
FlatSVGIcon icon = new FlatSVGIcon( name, width, height, scale, true, classLoader );
icon.diagram = diagram;
icon.dark = dark;
return icon;
@@ -264,7 +293,7 @@ public class FlatSVGIcon
// get gray filter
RGBImageFilter grayFilter = null;
if( c != null && !c.isEnabled() ) {
if( disabled ) {
Object grayFilterObj = UIManager.get( "Component.grayFilter" );
grayFilter = (grayFilterObj instanceof RGBImageFilter)
? (RGBImageFilter) grayFilterObj
@@ -316,6 +345,20 @@ public class FlatSVGIcon
g.fillRect( x, y, getIconWidth(), getIconHeight() );
}
@Override
public Image getImage() {
update();
BufferedImage image = new BufferedImage( getIconWidth(), getIconHeight(), BufferedImage.TYPE_INT_ARGB );
Graphics2D g = image.createGraphics();
try {
paintIcon( null, g, 0, 0 );
} finally {
g.dispose();
}
return image;
}
private static Boolean darkLaf;
private static boolean isDarkLaf() {

View File

@@ -58,6 +58,23 @@ public class FlatExtrasTest
addSVGIcon( "errorDialog.svg" );
addSVGIcon( "informationDialog.svg" );
addSVGIcon( "warningDialog.svg" );
FlatSVGIcon icon = new FlatSVGIcon( "com/formdev/flatlaf/demo/extras/svg/warningDialog.svg" );
Icon disabledIcon = icon.getDisabledIcon();
disabledLabel.setIcon( icon );
disabledButton.setIcon( icon );
disabledTabbedPane.addTab( "tab", null );
disabledTabbedPane.setIconAt( 0, icon );
disabledLabel2.setIcon( icon );
disabledLabel2.setDisabledIcon( disabledIcon );
disabledButton2.setIcon( icon );
disabledButton2.setDisabledIcon( disabledIcon );
disabledTabbedPane2.addTab( "tab", null );
disabledTabbedPane2.setIconAt( 0, icon );
disabledTabbedPane2.setDisabledIconAt( 0, disabledIcon );
disabledChanged();
}
private void addSVGIcon( String name ) {
@@ -72,6 +89,31 @@ public class FlatExtrasTest
triStateLabel2.setText( triStateCheckBox2.getState().toString() );
}
private void disabledChanged() {
boolean enabled = !disabledCheckBox.isSelected();
disabledLabel.setEnabled( enabled );
disabledButton.setEnabled( enabled );
disabledTabbedPane.setEnabledAt( 0, enabled );
disabledLabel2.setEnabled( enabled );
disabledButton2.setEnabled( enabled );
disabledTabbedPane2.setEnabledAt( 0, enabled );
}
@Override
public void updateUI() {
super.updateUI();
if( disabledLabel == null )
return;
// clear automatically created disabled icons when switching Laf
disabledLabel.setDisabledIcon( null );
disabledButton.setDisabledIcon( null );
disabledTabbedPane.setDisabledIconAt( 0, null );
}
private void initComponents() {
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
label1 = new JLabel();
@@ -82,6 +124,16 @@ public class FlatExtrasTest
label2 = new JLabel();
svgIconsPanel = new JPanel();
label3 = new JLabel();
label4 = new JLabel();
disabledLabel = new JLabel();
disabledButton = new JButton();
disabledTabbedPane = new JTabbedPane();
label5 = new JLabel();
disabledCheckBox = new JCheckBox();
disabledLabel2 = new JLabel();
disabledButton2 = new JButton();
disabledTabbedPane2 = new JTabbedPane();
label6 = new JLabel();
//======== this ========
setLayout(new MigLayout(
@@ -94,6 +146,9 @@ public class FlatExtrasTest
"[]" +
"[]" +
"[]" +
"[]" +
"[]" +
"[]" +
"[]"));
//---- label1 ----
@@ -139,6 +194,45 @@ public class FlatExtrasTest
//---- label3 ----
label3.setText("The icons may change colors when switching to another theme.");
add(label3, "cell 1 3 2 1");
//---- label4 ----
label4.setText("Disabled SVG Icons:");
add(label4, "cell 0 4");
//---- disabledLabel ----
disabledLabel.setText("label");
add(disabledLabel, "cell 1 4 2 1");
//---- disabledButton ----
disabledButton.setText("button");
add(disabledButton, "cell 1 4 2 1");
add(disabledTabbedPane, "cell 1 4 2 1");
//---- label5 ----
label5.setText("only setIcon()");
label5.setEnabled(false);
add(label5, "cell 1 4 2 1,gapx 20");
//---- disabledCheckBox ----
disabledCheckBox.setText("disabled");
disabledCheckBox.setSelected(true);
disabledCheckBox.setMnemonic('D');
disabledCheckBox.addActionListener(e -> disabledChanged());
add(disabledCheckBox, "cell 0 5,alignx left,growx 0");
//---- disabledLabel2 ----
disabledLabel2.setText("label");
add(disabledLabel2, "cell 1 5 2 1");
//---- disabledButton2 ----
disabledButton2.setText("button");
add(disabledButton2, "cell 1 5 2 1");
add(disabledTabbedPane2, "cell 1 5 2 1");
//---- label6 ----
label6.setText("setIcon() and setDisabledIcon()");
label6.setEnabled(false);
add(label6, "cell 1 5 2 1,gapx 20");
// JFormDesigner - End of component initialization //GEN-END:initComponents
}
@@ -151,5 +245,15 @@ public class FlatExtrasTest
private JLabel label2;
private JPanel svgIconsPanel;
private JLabel label3;
private JLabel label4;
private JLabel disabledLabel;
private JButton disabledButton;
private JTabbedPane disabledTabbedPane;
private JLabel label5;
private JCheckBox disabledCheckBox;
private JLabel disabledLabel2;
private JButton disabledButton2;
private JTabbedPane disabledTabbedPane2;
private JLabel label6;
// JFormDesigner - End of variables declaration //GEN-END:variables
}

View File

@@ -1,4 +1,4 @@
JFDML JFormDesigner: "7.0.2.0.298" Java: "14" encoding: "UTF-8"
JFDML JFormDesigner: "7.0.2.0.298" Java: "15" encoding: "UTF-8"
new FormModel {
contentType: "form/swing"
@@ -6,7 +6,7 @@ new FormModel {
add( new FormContainer( "com.formdev.flatlaf.testing.FlatTestPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "ltr,insets dialog,hidemode 3"
"$columnConstraints": "[][][left]"
"$rowConstraints": "[][][][]"
"$rowConstraints": "[][][][][][][]"
} ) {
name: "this"
add( new FormComponent( "javax.swing.JLabel" ) {
@@ -65,9 +65,72 @@ new FormModel {
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 3 2 1"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label4"
"text": "Disabled SVG Icons:"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 4"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "disabledLabel"
"text": "label"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 4 2 1"
} )
add( new FormComponent( "javax.swing.JButton" ) {
name: "disabledButton"
"text": "button"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 4 2 1"
} )
add( new FormContainer( "javax.swing.JTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) {
name: "disabledTabbedPane"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 4 2 1"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label5"
"text": "only setIcon()"
"enabled": false
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 4 2 1,gapx 20"
} )
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "disabledCheckBox"
"text": "disabled"
"selected": true
"mnemonic": 68
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "disabledChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 5,alignx left,growx 0"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "disabledLabel2"
"text": "label"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 5 2 1"
} )
add( new FormComponent( "javax.swing.JButton" ) {
name: "disabledButton2"
"text": "button"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 5 2 1"
} )
add( new FormContainer( "javax.swing.JTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) {
name: "disabledTabbedPane2"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 5 2 1"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label6"
"text": "setIcon() and setDisabledIcon()"
"enabled": false
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 5 2 1,gapx 20"
} )
}, new FormLayoutConstraints( null ) {
"location": new java.awt.Point( 0, 0 )
"size": new java.awt.Dimension( 500, 300 )
"size": new java.awt.Dimension( 595, 300 )
} )
}
}