Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swing: Show/hide button on mouse over

So I want to put a button in a JPanel, but I want to keep it invisible/hidden unless the mouse pointer hovers over it. At this point, the button should be made visible, react to clicks and so on. When the mouse leaves the area, it should be hidden again.

I tried adding a MouseListener to my JButton and use setVisible(), but when I hide the button (setVisible(false)), then the listener doesn't work anymore - the application behaves as if the button is not there at all.

What's the correct way to implement this behavior?

Edit: I am using an absolute layout (setLayout(null)) and I am manually placing my component using setBounds(x, y, width, height).

like image 314
async Avatar asked Jan 19 '13 01:01

async


People also ask

Which method is used to have rollover icon?

The setRolloverSelectedIcon method lets you specify the rollover icon when the button is selected — this is useful for two-state buttons such as toggle buttons. Setting the rollover icon automatically calls setRollover(true) , enabling rollover.

What is toggle button in Java Swing?

A Toggle Button is a two state button. It is either pressed or not pressed. Following example showcase how to modify the default appearance of a Button in a Java Swing application.


2 Answers

Use icons to reveal (colored) or hide (transparent) the button respectively.

enter image description here

import java.awt.*;
import java.awt.image.BufferedImage;
import javax.swing.*;

class InvisiButton {

    public static void main(String[] args) {
        Runnable r = new Runnable() {

            @Override
            public void run() {
                int size = 30;
                JPanel gui = new JPanel(new GridLayout(4,10,4,4));
                for (int ii=0; ii<40; ii++) {
                    JButton b = new JButton();
                    b.setContentAreaFilled(false);
                    b.setIcon(new ImageIcon(
                        new BufferedImage(size,size,BufferedImage.TYPE_INT_RGB)));
                    b.setRolloverIcon(new ImageIcon(
                        new BufferedImage(size,size,BufferedImage.TYPE_INT_ARGB)));
                    b.setBorder(null);
                    gui.add(b);
                }

                JOptionPane.showMessageDialog(null, gui);
            }
        };
        // Swing GUIs should be created and updated on the EDT
        // http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html
        SwingUtilities.invokeLater(r);
    }
}
like image 96
Andrew Thompson Avatar answered Sep 30 '22 13:09

Andrew Thompson


One approach is to give the button no text, no border, and an empty icon sized to match a real rollover icon.

Addendum: This updated example relies on @Andrew's succinct empty icon seen here.

import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.image.BufferedImage;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;

/** @see https://stackoverflow.com/a/14410594/230513 */
public class RollButton {

    private static final int N = 64;

    private void display() {
        JFrame f = new JFrame("RollButton");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JPanel p = new JPanel(new GridLayout());
        p.setBorder(BorderFactory.createEmptyBorder(N, N, N, N));
        p.add(createButton(UIManager.getIcon("OptionPane.errorIcon")));
        f.add(p);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    private JButton createButton(Icon icon) {
        JButton b = new JButton();
        b.setBorderPainted(false);
        b.setText("");
        // https://stackoverflow.com/a/14410597/230513
        b.setIcon(new ImageIcon(new BufferedImage(icon.getIconWidth(),
            icon.getIconHeight(), BufferedImage.TYPE_INT_ARGB)));
        b.setRolloverEnabled(true);
        b.setRolloverIcon(icon);
        return b;
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new RollButton().display();
            }
        });
    }
}
like image 21
trashgod Avatar answered Sep 30 '22 12:09

trashgod