Adam Hill
Adam Hill

Reputation: 1

Brighten Image(JLabel) on a JFrame on hover

I have a JLabel image on a JFrame that I want too brighten upon hovering, have tried a few things however nothing seems to be working, here's my current code:

public class DivinationLogo extends JLabel {
private BufferedImage logo;
public DivinationLogo() {

    super();
    try {
        logo = ImageIO.read(getClass().getResourceAsStream("/assets/images/logo.png"));
    } catch (IOException e) {
        e.printStackTrace();
    }
   // setIcon(new ImageIcon(logo));
    setIconTextGap(0);
    setBorder(null);
    setText(null);

    addMouseListener(new MouseAdapter() {
        @Override
        public void mouseClicked(MouseEvent e) {
            Functions.openWebPage(Config.website);
        }

        @Override
        public void mouseEntered(MouseEvent e) {
           Functions.brightnessControl(logo, .3F);
        }

        @Override
        public void mouseExited(MouseEvent e) {
            Functions.brightnessControl(logo, 1.0F);
        }
    });
    setBounds(-5, 1, 247, 106);
}

@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    g.drawImage(logo, -5, 1, null);
 }
}

Functions.brightnessControl:

public static Image brightnessControl(Image image, float brightness) {
    BufferedImage bi = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_ARGB);
    Graphics bg = bi.getGraphics();

    if (bi.getColorModel().hasAlpha()) {
        System.out.println("Image has got an alpha channel");
    }

    bg.drawImage(image, 0, 0, null);
    bg.dispose();
    RescaleOp rescaleOp = new RescaleOp(brightness, 0, null);
    rescaleOp.filter(bi, bi);
    image = bi;
    return bi;
}

Currently, it does nothing which confuses me. If anyone knows how this is achieved, please feel free too let me know :)

Upvotes: 0

Views: 99

Answers (2)

Charlie
Charlie

Reputation: 9153

Arguments in java are passed by value so your the function you have to brighten the image doesn't have an effect on the image you passed to it.

You're missing the repaint() call after changing the image.

You definitely don't want to prepare the hover image every time you hover over the image. Pre-calculate the hover in the constructor and assign it to a separate image.

Create a member variable for if hover is true and use that in the paint method to figure out which image to paint.

Upvotes: 0

MadProgrammer
MadProgrammer

Reputation: 347332

Ok, so the basic idea is, when the mouse enters the component, you want to generate a "bright" version of the component (I know, obvious, but bear with me)

The problem is, you have a Graphics context and you need a image :/

The following is not overly optimised, but without spending a lot of time adding in PropertyChange support, this will give you the basic idea.

import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.awt.image.RescaleOp;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;

class Main {

    public static void main(String[] args) {
        new Main();
    }

    public Main() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    JFrame frame = new JFrame();
                    frame.setLayout(new GridBagLayout());
                    JLabel label = new BrightLabel();
                    label.setIcon((new ImageIcon(ImageIO.read(Main.class.getResource("background.png")))));
                    frame.add(label);
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        });
    }

    public class BrightLabel extends JLabel {

        private MouseAdapter mouseHandler;
        private boolean isHover = false;

        @Override
        public void addNotify() {
            super.addNotify();
            mouseHandler = new MouseAdapter() {
                @Override
                public void mouseEntered(MouseEvent e) {
                    isHover = true;
                    repaint();
                }

                @Override
                public void mouseExited(MouseEvent e) {
                    isHover = false;
                    repaint();
                }
            };

            System.out.println("...");
            addMouseListener(mouseHandler);
        }

        @Override
        public void removeNotify() {
            super.removeNotify();
            if (mouseHandler != null) {
                removeMouseListener(mouseHandler);
            }
            mouseHandler = null;
        }

        @Override
        protected void paintComponent(Graphics g) {
            if (!isHover) {
                super.paintComponent(g);
                return;
            }

            BufferedImage img = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);
            Graphics2D g2d = img.createGraphics();
            super.paintComponent(g2d);
            g2d.dispose();

            Image bright = brightnessControl(img, 1.3f);
            g.drawImage(bright, 0, 0, this);
        }

        public Image brightnessControl(Image image, float brightness) {
            BufferedImage bi = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_ARGB);
            Graphics bg = bi.getGraphics();

            if (bi.getColorModel().hasAlpha()) {
                System.out.println("Image has got an alpha channel");
            }

            bg.drawImage(image, 0, 0, null);
            bg.dispose();
            RescaleOp rescaleOp = new RescaleOp(brightness, 0, null);
            rescaleOp.filter(bi, bi);
            image = bi;
            return bi;
        }

    }

}

Essentially, when the mouse enters or exists the component, we set the isHover property. We then call repaint to trigger a new paint pass.

When the component is painted, if isHover is true, we take over the painting process slightly, generating our own buffer and painting the component to it. This gives us our base image. From there we brighten the image and paint it to the Graphics context

Upvotes: 1

Related Questions