#java #nullpointerexception #listener #actionlistener #mouselistener
#java #исключение nullpointerexception #прослушиватель #actionlistener #mouselistener
Вопрос:
Я пытаюсь заставить мое приложение сворачиваться на панели задач и восстанавливаться при двойном щелчке на 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) amp;amp; e.getClickCount()>1)
{ // DOUBLE LEFT MOUSE CLICK
// Do something
}
}
// Rest of the code
}
Restore
Опция всплывающего меню работает нормально, однако, когда я дважды щелкаю по trayIcon
в системном трее, я получаю Null Pointer Exception
строку at if(e.getActionCommand().equals("Restore"))
Как я могу устранить это и, если возможно, объединить обоих слушателей в один?
Комментарии:
1. Зачем вам вообще нужен прослушиватель мыши или проверка команды action? Прослушиватель действий вызывается только при двойном щелчке / выборе клавиатуры
2. Я проверяю ActionEvent, потому что у меня есть более одного пункта меню, и мне нужно различать их, однако я опустил код для остальных. ActionListener также вызывается, когда я выбираю один из пунктов меню. Однако вы правы насчет MouseListener, на самом деле я ищу способ реализовать MouseListener в ActionListener.
3. Мне лично не нравится практика использования одного
ActionListener
для разных действий. Одна из причин заключается в том, что он выдает одну и ту же информацию во всех событиях, даже если это неприменимо. Это один из таких случаев — TrayIcon просто не заполняетActionCommand
. Решение, которое я реализовал, состояло в использовании singleRestoreListener
, который просто восстановил фрейм без каких-либо проверок, и поместил этот прослушиватель в только пункт меню restore и TrayIcon.4. Хорошо, я сделал, как вы сказали, и это работает с небольшим недостатком. Теперь, когда я дважды щелкаю по значку TrayIcon, окно восстанавливается, однако у него нет фокуса, в отличие от опции «Восстановить», которая восстанавливает окно и обеспечивает фокус, хотя они оба выполняют по существу один и тот же код. Есть обходные пути?
5. Интересно… К сожалению, я не смогу протестировать какие-либо решения до понедельника, но: вы пытались
requestFocus()
использовать фрейм черезWindowListener
?
Ответ №1:
Примечание. Этот ответ взят из беседы с 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()
его.