问题
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
回答1:
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.
回答2:
If you can live with your dialog box not being modal, add
dialog.setModal(false);
to your action listener block.
来源:https://stackoverflow.com/questions/30581812/un-rollover-a-jbutton-when-a-joptionpane-is-displayed