'How to detect mouse hover on an image drawn from paintComponent's drawImage(); method
I am new to Java and need help. I am making a GUI for an application using images made from photoshop, and want to create a menu using images which highlights when user hover mouse over them. I have tried mouseEntered(); method by getting mouse x, y co-ordinates but it's not working. Here is the code.
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) {
}
}
Solution 1:[1]
- Don't load resources in
paintComponent, your paint method should run as fast as it can - Don't add listeners within the
paintmethods, this will get called a lot, so you're just repeatedly adding new listeners each time your component is painted - Use a
MouseMotionListenerinstead of aMouseListener, you want themouseMovedevent - You need some way to know where the image is painted, so you can determine if the mouse moved within it's bounds.
Have a look at How to Write a Mouse-Motion Listener and Painting in AWT and Swing for more details.
This example uses a simple Rectangle to define the location that the image is painted within, when the mouse moves within the confines of that Rectangle, a flag is set and the component is repainted, which paints a alpha based highlight effect over the image
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();
}
}
}
Now, having said all that, you might be better off using the rollover capabilities of JButton, which will basically do the same thing.
See How to Use Buttons, Check Boxes, and Radio Buttons for more details
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | MadProgrammer |

