当JOptionPane显示时,“取消”JButton的选中状态

10

我有一个情况,需要在单击JButton后显示JOptionPane。JButton具有默认图标和鼠标悬停图标(当鼠标滑过按钮时显示)。但是,一旦单击该按钮并出现JOptionPane,悬停图标就不会改回原本的默认图标,直到用户在选择适当的JOptionPane选项后将鼠标带回JButton的框架中。当JButton被点击且JOptionPane被显示时,如何“取消悬停”JButton?

简而言之: 即使在被点击和JOptionPane出现时,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);
  }

}

NB: 我已经发现了几个与此类似的问题。然而,这个问题不是重复的,因为那些问题涉及与此问题略有不同的问题(例如按钮保持按下状态,而不是滚动)。我能找到的其中一些问题(实际上是所有我能找到的问题)包括:

2个回答

6

鼠标悬停状态由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来实现,通过将从MouseInfo.getPointerInfo().getLocation()获取的屏幕坐标转换为组件坐标,使用SwingUtilities.convertPointFromScreen来检查JButton是否包含该点。


+1:非常感谢!这很好地完成了它。我一直在寻找JButton本身上的setRollover()函数,而不是在ButtonModel上。 - aspiring_sarge

1
如果您可以接受对话框不是模态的情况,请添加
dialog.setModal(false);

将其添加到您的操作监听器块中。

+1:这是一个相当不错的解决方法。但当然,我更喜欢通过强制用户立即做出决定来获得绝对控制...嘿嘿嘿嘿... - aspiring_sarge

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接