5

I'm trying to display an JButton with an image on it, but I can't figure out how to get Mousehover work on this. The normal display of the image is working, tough. Also it would be nice, if the text drawn on the button could be centered.

import java.awt.*;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JFrame;

public class ImageButtonTest {

    private static JButton imageButton;

    public static void main(String[] args) throws IOException {
        JFrame frm = new JFrame();
        frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frm.setSize(90, 27);
        frm.setLocation(50, 50);
        Image image = ImageIO.read(new URL("http://i.imgur.com/bitgM6l.png"));
        Image imageHover = ImageIO.read(new URL("http://i.imgur.com/dt81BWk.png"));
        imageButton = new ImageButton(image, imageHover);
        imageButton.setText("Download");
        frm.add(imageButton);
        frm.pack();
        frm.setVisible(true);
    }

    static class ImageButton extends JButton {
        private Image image, imageHover;
        private boolean hover;

        ImageButton(Image image, Image imageHover) {
            this.image = image;
            this.hover = false;


            addMouseListener(new java.awt.event.MouseAdapter() {  
                @Override
                public void mouseEntered(java.awt.event.MouseEvent evt) {
                    hover = true;
                    repaint();
                }

                @Override
                public void mouseExited(java.awt.event.MouseEvent evt) {
                    hover = false;
                    repaint();
                }
            });
        };

        @Override
        protected void paintComponent(Graphics g) {

            if(isEnabled()) {
                Graphics2D g2 = (Graphics2D) g.create();
                g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
                g2.setFont(new Font("Arial", Font.PLAIN, 12));
                g2.setColor(Color.WHITE);

                if(hover) {
                    g2.drawImage(imageHover, 0, 0, getWidth(), getHeight(), this);
                } else {
                    g2.drawImage(image, 0, 0, getWidth(), getHeight(), this);
                }
                g2.drawString(getText(), 20, getHeight() / 2 + 5);

                g2.dispose();
            } else {
                super.paintComponent(g);
            }

        }

    }

}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Marius
  • 309
  • 1
  • 5
  • 16
  • 2
    Use [`setRolloverIcon(Icon)`](http://docs.oracle.com/javase/7/docs/api/javax/swing/AbstractButton.html#setRolloverIcon%28javax.swing.Icon%29). There are also method for disabled icon, pressed icon.. See the docs. – Andrew Thompson Sep 02 '13 at 13:30
  • 1
    Possible duplicate of [how to change icon image of button on mouse entered and Mouse exit in java](http://stackoverflow.com/questions/11536200/how-to-change-icon-image-of-button-on-mouse-entered-and-mouse-exit-in-java) or [this one](http://stackoverflow.com/a/12875475/418556) or [this one](http://stackoverflow.com/a/17296454/418556).. – Andrew Thompson Sep 02 '13 at 13:30

1 Answers1

6

Image image = ImageIO.read(new URL("https://i.stack.imgur.com/poKAr.png")); Image imageHover = ImageIO.read(new URL("https://i.stack.imgur.com/AstP8.png"));

you can to use standard methods implemented in

JButton API

//button.setBorderPainted(false);
//button.setBorder(null);
//button.setFocusable(false);
//button.setMargin(new Insets(0, 0, 0, 0));
button.setContentAreaFilled(false);
button.setIcon(icon());
button.setRolloverIcon(iconA());
button.setPressedIcon(iconB());
button.setDisabledIcon(iconC());

JButton.getModel().addChangeListener()

    JButton.getModel().addChangeListener(new ChangeListener() {
        @Override
        public void stateChanged(ChangeEvent e) {
            ButtonModel model = (ButtonModel) e.getSource();
            if (model.isRollover()) {
                button.setIcon(icon());
            } else {
                button.setIcon(iconA());
            } etc ...//  if (model.isPressed()) {
         }
    });
mKorbel
  • 109,525
  • 20
  • 134
  • 319
  • I need the background to be repeated on the X-Axis. Is this possible? – Marius Sep 02 '13 at 14:40
  • put Icons to queue, no idea whats `background to be repeated on the X-Axis` – mKorbel Sep 02 '13 at 14:50
  • I need the Icon to repeat / stretch on my button. Do I have to edit the Icon before applying it? – Marius Sep 02 '13 at 14:56
  • how are you talking about Icon resizable with JButton, yes is possible no issue – mKorbel Sep 02 '13 at 15:00
  • This approach is a bit problematic, as it doesn't apply the hover effect when the mouse cursor is initially hovering over the button. I recommend using addMouseListener + mouseEntered() + mouseExited() instead. – Brikowski Jun 14 '16 at 19:07
  • @Brikowski wrong decision, because Mouse and KeyEvents are impolemented in JButton and its model and they are implemented correctly – mKorbel Jun 14 '16 at 19:09