如何检测鼠标悬停在从 paintComponent 的 drawImage() 绘制的图像上;方法

How to detect mouse hover on an image drawn from paintComponent's drawImage(); method

我是 Java 的新手,需要帮助。我正在使用 photoshop 制作的图像为应用程序制作 GUI,并希望使用图像创建菜单,当用户将鼠标悬停在图像上时突出显示。我已经通过获取鼠标 x、y 坐标尝试了 mouseEntered(); 方法,但它不起作用。这是代码。

public class GUI extends JComponent{

    public void paintComponent(Graphics g){

        super.paintComponent(g);
        ImageIcon exitBtnImg = new ImageIcon("src/images/userInterface/exitBtn.png");
        g.drawImage(exitBtnImg.getImage(), 0, 5, this);
        mouseHandler handler = new mouseHandler();
        addMouseListener(handler);
    }
}


public class mouseHandler implements MouseListener{

    @Override
    public void mouseClicked(MouseEvent e) {

   }

    @Override
    public void mousePressed(MouseEvent e) {

    }

    @Override
    public void mouseReleased(MouseEvent e) {

    }

    @Override
    public void mouseEntered(MouseEvent e) {
        if((e.getX()>100&&e.getX()<300)&&(e.getY()>50&&e.getY()<196)){

            repaint();
        }
    }

    @Override
   public void mouseExited(MouseEvent e) {

    }

}
  1. 不要在 paintComponent 中加载资源,您的绘制方法应该 运行 尽可能快
  2. 不要在 paint 方法中添加侦听器,这会被调用很多次,所以每次绘制组件时都只是重复添加新的侦听器
  3. 使用 MouseMotionListener 而不是 MouseListener,您需要 mouseMoved 事件
  4. 您需要一些方法来了解图像的绘制位置,以便确定鼠标是否在其范围内移动。

查看 How to Write a Mouse-Motion Listener and Painting in AWT and Swing 了解更多详情。

此示例使用简单的 Rectangle 来定义图像绘制的位置,当鼠标在该 Rectangle 的范围内移动时,将设置一个标志并重新绘制组件,在图像上绘制基于 alpha 的高光效果

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Example {

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

    public Example() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                        ex.printStackTrace();
                    }

                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.add(new TestPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        });
    }

    public class TestPane extends JPanel {

        private BufferedImage img;
        private Rectangle drawRectangle;
        private boolean highlight = false;

        public TestPane() throws IOException {
            img = ImageIO.read(...);
            addMouseMotionListener(new MouseAdapter() {

                @Override
                public void mouseMoved(MouseEvent e) {
                    highlight = drawRectangle.contains(e.getPoint());
                    repaint();
                }

            });

            int width = getPreferredSize().width;
            int height = getPreferredSize().height;

            int x = (width - img.getWidth()) / 2;
            int y = (height - img.getHeight()) / 2;

            drawRectangle = new Rectangle(x, y, img.getWidth(), img.getHeight());
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(400, 400);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            g2d.drawImage(img, drawRectangle.x, drawRectangle.y, this);
            if (highlight) {
                g2d.setColor(Color.RED);
                g2d.setComposite(AlphaComposite.SrcOver.derive(0.5f));
                g2d.fill(drawRectangle);
            }
            g2d.dispose();
        }

    }

}

现在,说了这么多,您最好使用 JButtonrollover 功能,它们基本上可以做同样的事情。

有关详细信息,请参阅 How to Use Buttons, Check Boxes, and Radio Buttons