I’m currently designing a Swing app with a custom “yellow on black” Look and Feel, and it seems SynthLookAndFeel is the way to go.
All my buttons consist of an ImageIcon (no text), for example:
When buttons are disabled, I would like the icons to turn to a faded yellow:
However, the default disabled icons are just greyscale versions of the “enabled” ones, and that breaks the yellow feel:
I read in this answer that disabled icons are generated internally by getDisabledIcon()
, but I find no place to control it from synth’s XML file.
I also read about SynthLookAndFeel’s SynthPainter class, but it doesn’t seem to address the question of disabled icons.
Is there a way to control that “getDisabledIcon” behaviour using SynthLookAndFeel, or am I asking too much ? In the latter case, what would be the best suited look and feel to use or extend for easy definition of button backgrounds, shapes, etc ?
Any hint is welcome.
Advertisement
Answer
OK, I think I found a clean way.
I was hesitating between finding a way with SynthLookAndFeel or subclassing another L&F… But didn’t think of subclassing SynthLookAndFeel itself 🙂
I’ve now got an implementation of SynthLookAndFeel that does exactly what I want, meaning the “disabled” icon is not a greyscale one, it’s a desaturated, dimmed, color version:
Here we go for the full code:
import javax.swing.*; import javax.swing.plaf.synth.SynthLookAndFeel; import java.awt.*; import java.awt.image.FilteredImageSource; import java.awt.image.ImageProducer; import java.awt.image.RGBImageFilter; public class MySynthLookAndFeel extends SynthLookAndFeel { @Override public Icon getDisabledIcon(JComponent component, Icon icon) { if (icon instanceof ImageIcon) { return new ImageIcon(createDisabledImage(((ImageIcon)icon).getImage())); } return null; } private static Image createDisabledImage(Image i) { ImageProducer prod = new FilteredImageSource(i.getSource(), new RGBImageFilter() { public int filterRGB(int x, int y, int rgb) { // extract alpha mask int alphamask = rgb & 0xFF000000; // convert to HSB float[] hsb = Color.RGBtoHSB((rgb >> 16) & 0xff, (rgb >> 8) & 0xff, rgb & 0xff, null); // desaturate (half saturation) hsb[1] *= 0.5; // dim (half brightness) hsb[2] *= 0.5; // convert back to RGB int rgbval = Color.HSBtoRGB(hsb[0], hsb[1], hsb[2]); // reapply alpha rgbval = rgbval & 0x00FFFFFF | alphamask; return rgbval; } }); return Toolkit.getDefaultToolkit().createImage(prod); } }
Much simpler than I thought, in the end.