2

I create some buttons with only their image visible:

public static JButton createImageButton(ImageIcon image) {
    JButton btn = new JButton(image);
    btn.setContentAreaFilled(false);
    btn.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
    return btn;
}

This gives me the following output:

enter image description here

While pressing the button I usually get:

enter image description here

But when I change the LaF to Nimbus, this won't happen.

Is there any possibility to configure Nimbus to darken the icon while pressing a button ?

I've already tried to change some of the button defaults like this:

UIManager.getLookAndFeelDefaults()
.put("Button[Pressed].backgroundPainter", new CustomPainter());

But I'm not sure how to write a CustomPainter class or if this solves the problem at all...

mKorbel
  • 109,525
  • 20
  • 134
  • 319
Marek
  • 263
  • 1
  • 5
  • 13
  • 3
    for better help sooner post an `MCVE` / `SSCCE`, short, runnable, compilable by using embeded `Icons` in JVM, e.g. `private Icon loadIcon = UIManager.getIcon("OptionPane.errorIcon");` – mKorbel Sep 02 '16 at 17:19
  • `While pressing the button I usually get` and `But when I change the LaF to Nimbus, this won't happen.`, this funcionality is the same (Mouse and KeyEvent in JButton / AbstractButton), by using all standard L&F in Win OS, doesn't matter if is there backgroundPainter or not, voting to close too – mKorbel Sep 02 '16 at 17:25
  • 1
    Create a darkened icon and set the pressed icon of the JButton to this icon See http://stackoverflow.com/questions/12468203/how-to-change-jbutton-icon-when-selected – copeg Sep 02 '16 at 17:49
  • @copeg yeah, I'll probably go for this. Although I hoped there'd be a more generic way to solve the problem – Marek Sep 02 '16 at 18:02

1 Answers1

0

Solved the problem by having a look at the source code of the Aqua LaF (GitHub)

I found a suitable method and based on this method I adapted my source code as follows:

public static JButton createImageButton(ImageIcon image) {
    JButton btn = new JButton(image);
    btn.setContentAreaFilled(false);
    btn.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
    btn.setPressedIcon(new ImageIcon(generatePressedDarkImage(image.getImage())));
    return btn;
}

private static Image generatePressedDarkImage(final Image image) {
    final ImageProducer prod = new FilteredImageSource(image.getSource(), new RGBImageFilter() {

        @Override
        public int filterRGB(int x, int y, int rgb) {
            final int red = (rgb >> 16) & 0xff;
            final int green = (rgb >> 8) & 0xff;
            final int blue = rgb & 0xff;
            final int gray = (int)((0.30 * red + 0.59 * green + 0.11 * blue) / 4);

            return (rgb & 0xff000000) | (grayTransform(red, gray) << 16) | (grayTransform(green, gray) << 8) | (grayTransform(blue, gray) << 0);
        }

         private int grayTransform(final int color, final int gray) {
                int result = color - gray;
                if (result < 0) result = 0;
                if (result > 255) result = 255;
                return result;
        }
    });
    return Toolkit.getDefaultToolkit().createImage(prod);
}

This provides me with a generic way to darken images in the same manner as the Aqua LaF would darken them by default:

enter image description here

Marek
  • 263
  • 1
  • 5
  • 13