FlatSVGIcon: use grayFilter and graphics proxy to paint disabled icons without bitmaps

This commit is contained in:
Karl Tauber
2020-05-02 23:48:46 +02:00
parent a2541a9659
commit 464787dc1e
3 changed files with 56 additions and 25 deletions

View File

@@ -121,14 +121,10 @@ public abstract class FlatLaf
public Icon getDisabledIcon( JComponent component, Icon 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 );
}
ImageFilter filter = (grayFilter instanceof ImageFilter)
? (ImageFilter) grayFilter
: GrayFilter.createDisabledIconFilter( isDark() ); // fallback
ImageFilter filter = (ImageFilter) grayFilter;
Function<Image, Image> mapper = img -> {
ImageProducer producer = new FilteredImageSource( img.getSource(), filter );
return Toolkit.getDefaultToolkit().createImage( producer );

View File

@@ -19,6 +19,12 @@ public class GrayFilter
private final int origContrast;
private final int origBrightness;
public static GrayFilter createDisabledIconFilter( boolean dark ) {
return dark
? new GrayFilter( -20, -70, 100 )
: new GrayFilter( 25, -25, 100 );
}
/**
* @param brightness in range [-100..100] where 0 has no effect
* @param contrast in range [-100..100] where 0 has no effect

View File

@@ -20,17 +20,19 @@ 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 javax.swing.ImageIcon;
import javax.swing.Icon;
import javax.swing.LookAndFeel;
import javax.swing.UIManager;
import com.formdev.flatlaf.FlatLaf;
import com.formdev.flatlaf.ui.FlatUIUtils;
import com.formdev.flatlaf.util.Graphics2DProxy;
import com.formdev.flatlaf.util.GrayFilter;
import com.formdev.flatlaf.util.UIScale;
import com.kitfox.svg.SVGDiagram;
import com.kitfox.svg.SVGException;
@@ -40,7 +42,7 @@ import com.kitfox.svg.SVGUniverse;
* @author Karl Tauber
*/
public class FlatSVGIcon
extends ImageIcon
implements Icon
{
// use own SVG universe so that it can not be cleared from anywhere
private static final SVGUniverse svgUniverse = new SVGUniverse();
@@ -99,6 +101,16 @@ public class FlatSVGIcon
return;
Graphics2D g2 = (Graphics2D) g.create();
if( c != null && !c.isEnabled() ) {
Object grayFilter = UIManager.get( "Component.grayFilter" );
RGBImageFilter filter = (grayFilter instanceof RGBImageFilter)
? (RGBImageFilter) grayFilter
: GrayFilter.createDisabledIconFilter( dark );
g2 = new GraphicsFilter( g2, filter );
}
try {
FlatUIUtils.setRenderingHints( g2 );
g2.setRenderingHint( RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR );
@@ -134,20 +146,6 @@ 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() {
@@ -166,4 +164,35 @@ public class FlatSVGIcon
LookAndFeel lookAndFeel = UIManager.getLookAndFeel();
darkLaf = (lookAndFeel instanceof FlatLaf && ((FlatLaf)lookAndFeel).isDark());
}
//---- class GraphicsFilter -----------------------------------------------
private static class GraphicsFilter
extends Graphics2DProxy
{
private final RGBImageFilter filter;
public GraphicsFilter( Graphics2D delegate, RGBImageFilter filter ) {
super( delegate );
this.filter = filter;
}
@Override
public void setColor( Color c ) {
super.setColor( filterColor( c ) );
}
@Override
public void setPaint( Paint paint ) {
if( paint instanceof Color )
paint = filterColor( (Color) paint );
super.setPaint( paint );
}
private Color filterColor( Color color ) {
int oldRGB = color.getRGB();
int newRGB = filter.filterRGB( 0, 0, oldRGB );
return (newRGB != oldRGB) ? new Color( newRGB, true ) : color;
}
}
}