Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"Un-rollover" a JButton when a JOptionPane is displayed

I have a situation where I need to display a JOptionPane after clicking on a JButton. The JButton has a default icon, and a rollover icon (which displays when, well, the mouse rolls-over the button). However, once the button is clicked and a JOptionPane appears, the rollover icon does not change back to the original, and continues to remain so until the user brings the mouse back to the JButton's frame after selecting an appropriate JOptionPane choice. How would I "un-rollover" the JButton when it is clicked and the JOptionPane is displayed?

TL;DR: JButton displays rollover icon even when being clicked and JOptionPanel is displayed. Me no likey.

Here's the SSCCE:

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.UIManager;


public class ButtonUnrollover {

  public static void main(String[] args) {
    JFrame f = new JFrame();
    final JPanel p = new JPanel();
    JButton b = new JButton();
    b.setIcon(UIManager.getIcon("OptionPane.informationIcon"));
    b.setRolloverIcon(UIManager.getIcon("OptionPane.errorIcon"));
//    b.setSelectedIcon(UIManager.getIcon("OptionPane.informationIcon"));
//    b.setRolloverSelectedIcon(UIManager.getIcon("OptionPane.informationIcon"));
//    b.setPressedIcon(UIManager.getIcon("OptionPane.informationIcon"));
    p.add(b);
    b.addActionListener(new ActionListener() {

      @Override
      public void actionPerformed(ActionEvent e) {
        JOptionPane jOP = new JOptionPane("Dummy message");
        JDialog dialog = jOP.createDialog(p, null);
        dialog.setVisible(true);
      }
    });

    f.add(p);
    f.pack();
    f.setVisible(true);
  }

}

NB: I have found several similar questions to this one. However, this question is not a duplicate because those questions pertain to an issue slightly different from this one (such as the button staying pressed, not rolled-over). A few of these questions (well, actually all of them I could find) are:

  • JButton stays pressed when focus stolen by JOptionPane
  • JButton stays pressed after a JOptionPane is displayed
  • JButton “stay pressed” after click in Java Applet
like image 301
aspiring_sarge Avatar asked Jun 01 '15 19:06

aspiring_sarge


2 Answers

The rollover state is managed by the ButtonModel. You can reset the rollover flag via the model's setRollover(boolean b) method, which will set the Icon back to the non-rollover state Icon. Implemented in your example ActionListener:

b.addActionListener(new ActionListener() {

  @Override
  public void actionPerformed(ActionEvent e) {
    b.getModel().setRollover(false);//reset the rollover flag
    JOptionPane jOP = new JOptionPane("Dummy message");
    JDialog dialog = jOP.createDialog(p, null);
    dialog.setVisible(true);
  }
});

You might also wish to check if the Mouse is still located over the JButton after the dialog is closed to reset the rollover flag (if necessary) - you can do so via MouseInfo, checking if the JButton contains the point by converting the Screen coordinates retrieved from MouseInfo.getPointerInfo().getLocation() to component coordinates using SwingUtilities.convertPointFromScreen.

like image 70
copeg Avatar answered Oct 16 '22 10:10

copeg


If you can live with your dialog box not being modal, add

dialog.setModal(false);

to your action listener block.

like image 33
swingMan Avatar answered Oct 16 '22 12:10

swingMan