显示JOptionPane时,“解压缩”JButton

我有一种情况,我需要在单击JButton后显示JOptionPane。 JButton有一个默认图标和一个翻转图标(显示鼠标滚过按钮的时间)。 但是,单击按钮并显示JOptionPane后,翻转图标不会更改回原始图标,并继续保持此状态,直到用户在选择适当的JOptionPane选项后将鼠标带回JButton的框架。 如果单击JButton并显示JOptionPane,我将如何“取消翻转”它?

TL; DR :即使单击并显示JOptionPanel,JButton也会显示翻转图标。 我不喜欢。

这是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); } } 

注意:我发现了几个类似的问题。 但是,这个问题并不重复,因为这些问题属于与此问题略有不同的问题(例如按钮保持按下,而不是翻转)。 其中一些问题(实际上我能找到的所有问题)都是:

  • 当焦点被JOptionPane窃取时,JButton会保持按下状态
  • 显示JOptionPane后,JButton保持按下状态
  • 单击Java Applet后,JButton“保持按下”状态

翻转状态由ButtonModel管理。 您可以通过模型的setRollover(boolean b)方法重置翻转标志,该方法将图标设置回非翻转状态图标。 在您的示例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); } }); 

您可能还希望在对话框关闭后检查鼠标是否仍位于JButton上方以重置翻转标志(如果需要) – 您可以通过MouseInfo执行此操作,通过转换检索的屏幕坐标来检查JButton是否包含该点使用SwingUtilities.convertPointFromScreen从MouseInfo.getPointerInfo().getLocation()到组件坐标。

如果您可以使用不是模态的对话框,请添加

 dialog.setModal(false); 

到你的动作监听器块。