mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2026-02-11 06:27:13 -06:00
Reworked how the FlatSVGIcon filters work. Filters are now set using the ColorFilter class and can work globally too. Added related demo components to flatlaf-demo extras tab.
This commit is contained in:
@@ -18,8 +18,10 @@ package com.formdev.flatlaf.demo.extras;
|
|||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import com.formdev.flatlaf.extras.*;
|
import com.formdev.flatlaf.extras.*;
|
||||||
|
import com.formdev.flatlaf.extras.FlatSVGIcon.ColorFilter;
|
||||||
import com.formdev.flatlaf.extras.components.FlatTriStateCheckBox;
|
import com.formdev.flatlaf.extras.components.FlatTriStateCheckBox;
|
||||||
import net.miginfocom.swing.*;
|
import net.miginfocom.swing.*;
|
||||||
|
import java.awt.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
@@ -27,6 +29,8 @@ import net.miginfocom.swing.*;
|
|||||||
public class ExtrasPanel
|
public class ExtrasPanel
|
||||||
extends JPanel
|
extends JPanel
|
||||||
{
|
{
|
||||||
|
public int counter = 0;
|
||||||
|
|
||||||
public ExtrasPanel() {
|
public ExtrasPanel() {
|
||||||
initComponents();
|
initComponents();
|
||||||
|
|
||||||
@@ -69,6 +73,12 @@ public class ExtrasPanel
|
|||||||
label2 = new JLabel();
|
label2 = new JLabel();
|
||||||
svgIconsPanel = new JPanel();
|
svgIconsPanel = new JPanel();
|
||||||
label3 = new JLabel();
|
label3 = new JLabel();
|
||||||
|
separator1 = new JSeparator();
|
||||||
|
label5 = new JLabel();
|
||||||
|
label6 = new JLabel();
|
||||||
|
label7 = new JLabel();
|
||||||
|
rainbowIcon = new JLabel();
|
||||||
|
toggleButton1 = new JToggleButton();
|
||||||
|
|
||||||
//======== this ========
|
//======== this ========
|
||||||
setLayout(new MigLayout(
|
setLayout(new MigLayout(
|
||||||
@@ -81,6 +91,9 @@ public class ExtrasPanel
|
|||||||
"[]para" +
|
"[]para" +
|
||||||
"[]" +
|
"[]" +
|
||||||
"[]" +
|
"[]" +
|
||||||
|
"[]" +
|
||||||
|
"[]" +
|
||||||
|
"[]" +
|
||||||
"[]"));
|
"[]"));
|
||||||
|
|
||||||
//---- label4 ----
|
//---- label4 ----
|
||||||
@@ -119,9 +132,55 @@ public class ExtrasPanel
|
|||||||
//---- label3 ----
|
//---- label3 ----
|
||||||
label3.setText("The icons may change colors when switching to another theme.");
|
label3.setText("The icons may change colors when switching to another theme.");
|
||||||
add(label3, "cell 1 3 2 1");
|
add(label3, "cell 1 3 2 1");
|
||||||
|
|
||||||
|
add(separator1, "cell 1 4, grow");
|
||||||
|
|
||||||
|
//---- label5 ----
|
||||||
|
label5.setText("Color filters can be also applied to icons. Globally or for each instance.");
|
||||||
|
add(label5, "cell 1 5");
|
||||||
|
|
||||||
|
//---- label6 ----
|
||||||
|
label6.setText( "Rainbow color filter" );
|
||||||
|
add(label6, "cell 1 6");
|
||||||
|
|
||||||
|
//---- rainbowIcon ----
|
||||||
|
rainbowIcon = createRainbowIcon("informationDialog.svg");
|
||||||
|
add(rainbowIcon, "cell 1 6");
|
||||||
|
|
||||||
|
//---- label7 ----
|
||||||
|
label7.setText( "Global icon color filter" );
|
||||||
|
add(label7, "cell 1 7");
|
||||||
|
|
||||||
|
// ---- button1 ----
|
||||||
|
toggleButton1.setText( "Toggle red" );
|
||||||
|
add(toggleButton1, "cell 1 7");
|
||||||
|
|
||||||
|
// ---- toggleButton1 ----
|
||||||
|
toggleButton1.addActionListener( (e) -> {
|
||||||
|
if (toggleButton1.isSelected())
|
||||||
|
FlatSVGIcon.ColorFilter.getInstance().setFilter( color -> Color.RED );
|
||||||
|
else
|
||||||
|
FlatSVGIcon.ColorFilter.getInstance().setFilter( null );
|
||||||
|
SwingUtilities.getRootPane( toggleButton1 ).repaint();
|
||||||
|
} );
|
||||||
|
|
||||||
// JFormDesigner - End of component initialization //GEN-END:initComponents
|
// JFormDesigner - End of component initialization //GEN-END:initComponents
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private JLabel createRainbowIcon(String name) {
|
||||||
|
FlatSVGIcon rainbowIcon = new FlatSVGIcon( "com/formdev/flatlaf/demo/extras/svg/" + name);
|
||||||
|
rainbowIcon.setFilter( new ColorFilter( (color) -> {
|
||||||
|
counter+=1;
|
||||||
|
counter%=255;
|
||||||
|
return Color.getHSBColor(counter/255f, 1, 1);
|
||||||
|
}) );
|
||||||
|
JLabel label = new JLabel(rainbowIcon);
|
||||||
|
new Timer(30, (e) -> {
|
||||||
|
label.repaint();
|
||||||
|
}).start();
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
|
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
|
||||||
private JLabel label4;
|
private JLabel label4;
|
||||||
private JLabel label1;
|
private JLabel label1;
|
||||||
@@ -130,5 +189,11 @@ public class ExtrasPanel
|
|||||||
private JLabel label2;
|
private JLabel label2;
|
||||||
private JPanel svgIconsPanel;
|
private JPanel svgIconsPanel;
|
||||||
private JLabel label3;
|
private JLabel label3;
|
||||||
|
private JLabel label5;
|
||||||
|
private JLabel label6;
|
||||||
|
private JLabel label7;
|
||||||
|
private JSeparator separator1;
|
||||||
|
private JLabel rainbowIcon;
|
||||||
|
private JToggleButton toggleButton1;
|
||||||
// JFormDesigner - End of variables declaration //GEN-END:variables
|
// JFormDesigner - End of variables declaration //GEN-END:variables
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,23 +0,0 @@
|
|||||||
package com.formdev.flatlaf.extras;
|
|
||||||
|
|
||||||
import java.awt.*;
|
|
||||||
import java.awt.image.RGBImageFilter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A simplified RGBImageFilter that presents individual rgba components as a Color object.
|
|
||||||
* Can be used to modify the color of a {@link FlatSVGIcon}-
|
|
||||||
*/
|
|
||||||
public abstract class FlatRGBFilter extends RGBImageFilter
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public int filterRGB(int x, int y, int rgb) {
|
|
||||||
return filterRGB(new Color(rgb)).getRGB();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param c Original color
|
|
||||||
* @return Modified color
|
|
||||||
*/
|
|
||||||
public abstract Color filterRGB(Color c);
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -66,7 +66,7 @@ public class FlatSVGIcon
|
|||||||
private final boolean disabled;
|
private final boolean disabled;
|
||||||
private final ClassLoader classLoader;
|
private final ClassLoader classLoader;
|
||||||
|
|
||||||
private RGBImageFilter userFilter = null;
|
private ColorFilter userColorFilter = null;
|
||||||
|
|
||||||
private SVGDiagram diagram;
|
private SVGDiagram diagram;
|
||||||
private boolean dark;
|
private boolean dark;
|
||||||
@@ -161,7 +161,7 @@ public class FlatSVGIcon
|
|||||||
this( name, -1, -1, scale, false, classLoader );
|
this( name, -1, -1, scale, false, classLoader );
|
||||||
}
|
}
|
||||||
|
|
||||||
private FlatSVGIcon( String name, int width, int height, float scale, boolean disabled, ClassLoader classLoader ) {
|
protected FlatSVGIcon( String name, int width, int height, float scale, boolean disabled, ClassLoader classLoader ) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.classLoader = classLoader;
|
this.classLoader = classLoader;
|
||||||
this.width = width;
|
this.width = width;
|
||||||
@@ -171,16 +171,29 @@ public class FlatSVGIcon
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets an RGBImageFilter to be used when painting the icon.
|
* Sets a color filter that can freely modify colors of this icon during painting.<br>
|
||||||
* For simple RGB modifications you can use the {@link FlatRGBFilter}.
|
* <br>
|
||||||
* @param filter
|
* This method accepts a {@link ColorFilter}. Usually you would want to use a ColorFilter created using the
|
||||||
|
* {@link ColorFilter#ColorFilter(Function)} constructor.<br>
|
||||||
|
* <br>
|
||||||
|
* This can be used to brighten colors of the icon:
|
||||||
|
* <pre>icon.setFilter( new FlatSVGIcon.ColorFilter( color -> color.brighter() ) );</pre><br>
|
||||||
|
* <br>
|
||||||
|
* Using a filter, icons can also be turned monochrome (painted with a single color):
|
||||||
|
* <pre>icon.setFilter( new FlatSVGIcon.ColorFilter( color -> Color.RED ) );</pre><br>
|
||||||
|
* <br>
|
||||||
|
* Note: If a filter is already set, it will be replaced.
|
||||||
|
* @param filter The color filter
|
||||||
*/
|
*/
|
||||||
public void setFilter(RGBImageFilter filter) {
|
public void setFilter(ColorFilter filter) {
|
||||||
this.userFilter = filter;
|
this.userColorFilter = filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RGBImageFilter getFilter() {
|
/**
|
||||||
return userFilter;
|
* @return The currently active {@link ColorFilter} or null.
|
||||||
|
*/
|
||||||
|
public ColorFilter getFilter() {
|
||||||
|
return userColorFilter;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -318,7 +331,7 @@ public class FlatSVGIcon
|
|||||||
: GrayFilter.createDisabledIconFilter( dark );
|
: GrayFilter.createDisabledIconFilter( dark );
|
||||||
}
|
}
|
||||||
|
|
||||||
Graphics2D g2 = new GraphicsFilter( (Graphics2D) g.create(), ColorFilter.getInstance(), grayFilter, this.userFilter );
|
Graphics2D g2 = new GraphicsFilter( (Graphics2D) g.create(), ColorFilter.getInstance(), grayFilter, this.userColorFilter );
|
||||||
|
|
||||||
try {
|
try {
|
||||||
FlatUIUtils.setRenderingHints( g2 );
|
FlatUIUtils.setRenderingHints( g2 );
|
||||||
@@ -416,37 +429,139 @@ public class FlatSVGIcon
|
|||||||
|
|
||||||
//---- class ColorFilter --------------------------------------------------
|
//---- class ColorFilter --------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A color filter that can modify colors of a painted {@link FlatSVGIcon}.<br>
|
||||||
|
* <br>
|
||||||
|
* The ColorFilter modifes color in two ways.<br>
|
||||||
|
* Either using a color map, where specific colors are mapped to different ones.<br>
|
||||||
|
* And/or by modifying the colors directly, applying a modification to their rgba values.<br>
|
||||||
|
* <br>
|
||||||
|
* When filtering a color. Mappings are applied first, then an rgb color filter is applied.<br>
|
||||||
|
* <br>
|
||||||
|
* Global {@link FlatSVGIcon} ColorFilter can be retrieved using the {@link ColorFilter#getInstance()} methods.
|
||||||
|
*
|
||||||
|
* @see ColorFilter#ColorFilter(Function)
|
||||||
|
* @see ColorFilter#ColorFilter(boolean)
|
||||||
|
*/
|
||||||
public static class ColorFilter
|
public static class ColorFilter
|
||||||
{
|
{
|
||||||
private static ColorFilter instance;
|
private static ColorFilter instance;
|
||||||
|
|
||||||
|
//Color maps
|
||||||
private final Map<Integer, String> rgb2keyMap = new HashMap<>();
|
private final Map<Integer, String> rgb2keyMap = new HashMap<>();
|
||||||
private final Map<Color, Color> color2colorMap = new HashMap<>();
|
private final Map<Color, Color> color2colorMap = new HashMap<>();
|
||||||
|
|
||||||
|
//Color modification
|
||||||
|
private Function<Color, Color> colorFilter = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the global ColorFilter instance. If one doesn't exist, a new one is created.
|
||||||
|
*/
|
||||||
public static ColorFilter getInstance() {
|
public static ColorFilter getInstance() {
|
||||||
|
return(getInstance(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the global ColorFilter instance. If one doesn't exist, a new one is created.
|
||||||
|
* @param createDefaultColorMaps If true, default FlatLaf color maps are created.
|
||||||
|
*/
|
||||||
|
public static ColorFilter getInstance(boolean createDefaultColorMaps) {
|
||||||
if( instance == null )
|
if( instance == null )
|
||||||
instance = new ColorFilter();
|
instance = new ColorFilter();
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a color filter with default color mappings.
|
||||||
|
*/
|
||||||
public ColorFilter() {
|
public ColorFilter() {
|
||||||
for( FlatIconColors c : FlatIconColors.values() )
|
this(true);
|
||||||
rgb2keyMap.put( c.rgb, c.key );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a color filter. Default color maps can be optionally created.
|
||||||
|
* @param createDefaultColorMaps If true, default FlatLaf color maps are created.
|
||||||
|
*/
|
||||||
|
public ColorFilter(boolean createDefaultColorMaps) {
|
||||||
|
if (createDefaultColorMaps) {
|
||||||
|
for( FlatIconColors c : FlatIconColors.values() )
|
||||||
|
rgb2keyMap.put( c.rgb, c.key );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a color modifying function that changes painted colors.<br>
|
||||||
|
* The {@link Function} gets passed the original color and returns a modified one.
|
||||||
|
* <br>
|
||||||
|
* Examples:
|
||||||
|
* A ColorFilter can be used to brighten colors of the icon:
|
||||||
|
* <pre>new ColorFilter( color -> color.brighter() );</pre>
|
||||||
|
* <br>
|
||||||
|
* Using a ColorFilter, icons can also be turned monochrome (painted with a single color):
|
||||||
|
* <pre>new ColorFilter( color -> Color.RED );</pre>
|
||||||
|
* <br>
|
||||||
|
* @param filter The color filter function
|
||||||
|
*/
|
||||||
|
public ColorFilter(Function<Color, Color> filter) {
|
||||||
|
setFilter(filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a color modifying function that changes painted colors.<br>
|
||||||
|
* The {@link Function} gets passed the original color and returns a modified one.
|
||||||
|
* <br>
|
||||||
|
* Examples:
|
||||||
|
* A ColorFilter can be used to brighten colors of the icon:
|
||||||
|
* <pre>filter.setFilter( color -> color.brighter() );</pre>
|
||||||
|
* <br>
|
||||||
|
* Using a ColorFilter, icons can also be turned monochrome (painted with a single color):
|
||||||
|
* <pre>filter.setFilter( color -> Color.RED );</pre>
|
||||||
|
* <br>
|
||||||
|
* @param filter The color filter function
|
||||||
|
*/
|
||||||
|
public void setFilter(Function<Color, Color> filter) {
|
||||||
|
this.colorFilter = filter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a color mappings.
|
||||||
|
*/
|
||||||
public void addAll( Map<Color, Color> from2toMap ) {
|
public void addAll( Map<Color, Color> from2toMap ) {
|
||||||
color2colorMap.putAll( from2toMap );
|
color2colorMap.putAll( from2toMap );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a color mapping.
|
||||||
|
*/
|
||||||
public void add( Color from, Color to ) {
|
public void add( Color from, Color to ) {
|
||||||
color2colorMap.put( from, to );
|
color2colorMap.put( from, to );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes a specific color mapping.
|
||||||
|
*/
|
||||||
public void remove( Color from ) {
|
public void remove( Color from ) {
|
||||||
color2colorMap.remove( from );
|
color2colorMap.remove( from );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes all color mappings.
|
||||||
|
*/
|
||||||
|
public void removeAll() {
|
||||||
|
for ( Color from : color2colorMap.keySet()) {
|
||||||
|
color2colorMap.remove( from );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Color filter( Color color ) {
|
public Color filter( Color color ) {
|
||||||
|
color = filterMappings( color );
|
||||||
|
if (colorFilter != null) {
|
||||||
|
color = colorFilter.apply( color );
|
||||||
|
}
|
||||||
|
return color;
|
||||||
|
};
|
||||||
|
|
||||||
|
protected Color filterMappings( Color color ) {
|
||||||
Color newColor = color2colorMap.get( color );
|
Color newColor = color2colorMap.get( color );
|
||||||
if( newColor != null )
|
if( newColor != null )
|
||||||
return newColor;
|
return newColor;
|
||||||
@@ -462,7 +577,7 @@ public class FlatSVGIcon
|
|||||||
return (newColor.getAlpha() != color.getAlpha())
|
return (newColor.getAlpha() != color.getAlpha())
|
||||||
? new Color( (newColor.getRGB() & 0x00ffffff) | (color.getRGB() & 0xff000000) )
|
? new Color( (newColor.getRGB() & 0x00ffffff) | (color.getRGB() & 0xff000000) )
|
||||||
: newColor;
|
: newColor;
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//---- class GraphicsFilter -----------------------------------------------
|
//---- class GraphicsFilter -----------------------------------------------
|
||||||
@@ -472,9 +587,9 @@ public class FlatSVGIcon
|
|||||||
{
|
{
|
||||||
private final ColorFilter colorFilter;
|
private final ColorFilter colorFilter;
|
||||||
private final RGBImageFilter grayFilter;
|
private final RGBImageFilter grayFilter;
|
||||||
private final RGBImageFilter userFilter;
|
private final ColorFilter userFilter;
|
||||||
|
|
||||||
public GraphicsFilter( Graphics2D delegate, ColorFilter colorFilter, RGBImageFilter grayFilter, RGBImageFilter userFilter) {
|
public GraphicsFilter( Graphics2D delegate, ColorFilter colorFilter, RGBImageFilter grayFilter,ColorFilter userFilter) {
|
||||||
super( delegate );
|
super( delegate );
|
||||||
this.colorFilter = colorFilter;
|
this.colorFilter = colorFilter;
|
||||||
this.grayFilter = grayFilter;
|
this.grayFilter = grayFilter;
|
||||||
@@ -494,11 +609,8 @@ public class FlatSVGIcon
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Color filterColor( Color color ) {
|
private Color filterColor( Color color ) {
|
||||||
if( userFilter != null ) {
|
if( userFilter != null )
|
||||||
int oldRGB = color.getRGB();
|
color = userFilter.filter( color );
|
||||||
int newRGB = userFilter.filterRGB( 0, 0, oldRGB );
|
|
||||||
color = (newRGB != oldRGB) ? new Color( newRGB, true ) : color;
|
|
||||||
}
|
|
||||||
if( colorFilter != null )
|
if( colorFilter != null )
|
||||||
color = colorFilter.filter( color );
|
color = colorFilter.filter( color );
|
||||||
if( grayFilter != null ) {
|
if( grayFilter != null ) {
|
||||||
|
|||||||
Reference in New Issue
Block a user