简体   繁体   English

悬停时在 JFrame 上增亮图像(JLabel)

[英]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:我在 JFrame 上有一个 JLabel 图像,我希望在悬停时太亮,尝试了一些方法但似乎没有任何效果,这是我当前的代码:

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:功能.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 :)如果有人知道这是如何实现的,请随时让我知道:)

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 :/问题是,你有一个Graphics上下文,你需要一个图像:/

The following is not overly optimised, but without spending a lot of time adding in PropertyChange support, this will give you the basic idea.下面没有过度优化,但是没有花很多时间添加PropertyChange支持,这会给你基本的想法。

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.本质上,当鼠标进入或存在组件时,我们设置isHover属性。 We then call repaint to trigger a new paint pass.然后我们调用repaint来触发一个新的绘制过程。

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.当组件被绘制时,如果isHovertrue ,我们会稍微接管绘制过程,生成我们自己的缓冲区并将组件绘制到它。 This gives us our base image.这为我们提供了基本图像。 From there we brighten the image and paint it to the Graphics context从那里我们使图像变亮并将其绘制到Graphics上下文

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. Java 中的参数是按值传递的,因此您必须使图像变亮的功能不会对您传递给它的图像产生影响。

You're missing the repaint() call after changing the image.更改图像后,您错过了 repaint() 调用。

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.如果悬停为真,则创建一个成员变量,并在paint方法中使用它来确定要绘制的图像。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM