-2

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) {

    }

}
Marko Popovic
  • 3,999
  • 3
  • 22
  • 37
New Coder
  • 117
  • 2
  • 12
  • First of all, don't load resources in `paintComponent`, your paint method should run as fast as it can, second, don't add listeners within the `paint` methods, this will get called a lot, so you're just repeatedly adding new listeners each time your component is painted – MadProgrammer Dec 25 '15 at 08:20
  • 1
    *"want to create a menu using images which highlights when user hover mouse over them"* Put the images (normal and hover) into a `JButton` that has had the extra space and borders removed. It will be much simpler, and probably better. E.G. as seen in [this answer](http://stackoverflow.com/a/10862262/418556) .. – Andrew Thompson Dec 25 '15 at 08:25

1 Answers1

4
  1. Don't load resources in paintComponent, your paint method should run as fast as it can
  2. Don't add listeners within the paint methods, this will get called a lot, so you're just repeatedly adding new listeners each time your component is painted
  3. Use a MouseMotionListener instead of a MouseListener, you want the mouseMoved event
  4. 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

Hover

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

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • Thanks for your reply the hover problem is solved , How can i use images in paintComponent if it is not correct to load them in paintcomponent ? where should i load them ? actually whole frame will be repainted after any event occur. – New Coder Dec 25 '15 at 12:02
  • I loaded mine in the classes constructor – MadProgrammer Dec 25 '15 at 21:22