【问题标题】:ActionListener & MouseListener conflictionActionListener 和 MouseListener 冲突
【发布时间】:2014-07-04 17:59:59
【问题描述】:

我正在尝试使我的应用程序在任务栏上最小化,并在我双击 trayIcon 时恢复。我还有一个弹出菜单,其中有一个项目可以在单击时恢复窗口。

    trayIcon = new TrayIcon(image, "Anything", popup);
    trayIcon.addActionListener(actionListener);
    trayIcon.addMouseListener(mouseListener);
    sysTray.add(trayIcon);

这是actionListener和mouseListener的代码:

private ActionListener actionListener = new ActionListener()
{
   @Override
   public void actionPerformed(ActionEvent e) 
   {
      if (e.getActionCommand().equals("Restore"))
      { // RIGHT CLICK -> RESTORE
        // Do something
      }
   }
};

private MouseListener mouseListener = new MouseListener()
{
   @Override
   public void mouseClicked(MouseEvent e) 
   {
       if (javax.swing.SwingUtilities.isLeftMouseButton(e) && e.getClickCount()>1)                                                  
       {  // DOUBLE LEFT MOUSE CLICK
          // Do something
       }
    }
    // Rest of the code
 }

弹出菜单的Restore 选项工作正常,但是当我双击系统托盘上的trayIcon 时,我在if(e.getActionCommand().equals("Restore")) 行得到Null Pointer Exception

我怎样才能消除这种情况,如果可能的话将两个听众合并为一个?

【问题讨论】:

  • 为什么你甚至需要鼠标监听器或检查动作命令?动作监听器仅在双击/键盘选择时调用
  • 我正在检查 ActionEvent,因为我有多个菜单项,我需要区分它们,但我省略了其余的代码。当我选择菜单的一项时,也会调用 ActionListener。但是您对 MouseListener 是正确的,实际上我正在寻找一种将 MouseListener 实现到 ActionListener 中的方法。
  • 我个人不喜欢使用单个ActionListener 执行不同操作的做法。原因之一是它在所有事件中强制使用相同的信息,即使它不适用。这是其中一种情况——trayIcon 根本不填充ActionCommand。我实施的解决方案是使用单个 RestoreListener 来恢复框架而无需任何检查,并将该侦听器放在恢复菜单项和托盘图标上 only。
  • 好的,我按照你说的做了,它有一个小缺陷。现在,当我双击托盘图标时,窗口 is 已恢复,但它没有焦点,这与“恢复”选项不同,它恢复窗口 并且 提供焦点,尽管它们本质上都运行相同的代码。有什么解决方法吗?
  • 有趣... 不幸的是,直到星期一我才能实际测试任何解决方案,但是:您是否尝试通过 WindowListener 在框架上 requestFocus()?

标签: java nullpointerexception listener actionlistener mouselistener


【解决方案1】:

注意这个答案是在cmets中与OP的对话中得出的,其中一些解决方案来自OP

TrayIcon 在触发事件时不会填充ActionCommand 字段,因此代码会因 NPE 而死。

由于托盘图标仅在双击或类似操作(通过键盘)时才调用其ActionListener,因此您可以创建一个根本不检查该条件且仅与托盘一起使用的RestoreListener图标和“恢复”菜单项。

private ActionListener restoreListener = new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        // Do the actual restoration
    }
};

实际上将它添加到项目中......

trayIcon = new TrayIcon(image, "Anything", popup);
trayIcon.addActionListener(restoreListener);

MenuItem restoreMenuItem = new MenuItem(...);
restoreMenuItem.addActionListener(restoreListener);

这似乎与MouseListener 的行为略有不同,它没有将窗口放在顶部,这可以通过调用toTop() 来解决。

【讨论】:

    猜你喜欢
    • 2012-12-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-28
    • 2012-09-27
    • 1970-01-01
    • 2019-08-27
    • 2012-09-10
    • 2012-08-24
    相关资源
    最近更新 更多