(Java) JPopupMenu не закроется, если я нажму за пределами него - PullRequest
6 голосов
/ 18 апреля 2010

Я создал приложение Java Swing, у которого нет видимого главного окна, но которое управляется через иконку в трее нажатием правой кнопки мыши.

Я использую JPopupMenu для этого, но когда я щелкаю за пределами всплывающего меню (например, в окне другого приложения или на рабочем столе), JPopupMenu не исчезает, что не является ожидаемым поведением.

Первоначально я использовал popupMenu, который работал, как и ожидалось, но это не позволило мне иметь значки в меню.

Как заставить его закрыться, когда я нажму в другом месте, как и ожидалось?

Спасибо!

Ответы [ 3 ]

6 голосов
/ 21 февраля 2013
//_Popup is your JPopupMenu, call this method before setting your popup to visible
public void armPopup()
{
    if(_Popup != null)
    {
        Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener()
        {
            @Override
            public void eventDispatched(AWTEvent event) {

                if(event instanceof MouseEvent)
                {
                    MouseEvent m = (MouseEvent)event;
                    if(m.getID() == MouseEvent.MOUSE_CLICKED)
                    {
                        _Popup.setVisible(false);
                        Toolkit.getDefaultToolkit().removeAWTEventListener(this);
                    }
                }
                if(event instanceof WindowEvent)
                {
                    WindowEvent we = (WindowEvent)event;
                    if(we.getID() == WindowEvent.WINDOW_DEACTIVATED || we.getID() == WindowEvent.WINDOW_STATE_CHANGED)
                    {
                        _Popup.setVisible(false);
                        Toolkit.getDefaultToolkit().removeAWTEventListener(this);
                    }
                }
            }

        }, AWTEvent.MOUSE_EVENT_MASK | AWTEvent.WINDOW_EVENT_MASK);

    }
}
2 голосов
/ 19 апреля 2010

В конце концов, я «решил» это, взломав проблему. Как указывает Camickr, JPopupMenu довольно глючит. Однако это единственная реализация всплывающего меню Swing, которая позволяет иметь значок рядом с каждым элементом меню.

Мое решение состояло в том, чтобы реализовать прослушиватель в jpopupmenu, который, если пользователь наведет курсор мыши на меню, через 3 секунды будет установлен на .isVisible (false), если пользователь не наведет курсор мыши на меню в течение этого времени.

Чтобы добиться этого, мне пришлось использовать отдельный поток, который постоянно проверял, было ли всплывающее меню активным. Если это так, проверьте, была ли мышь над ним, используя прослушиватель событий, и установите для видимости значение false, если пользователь не вводил его снова в течение 3 секунд.

Это не идеальное решение, так как пользователь все еще должен ждать 3 секунды, чтобы меню исчезло (оно должно быть мгновенным, если он / она щелкает), и оно исчезнет, ​​даже если оно находится в фокусе (не должно, если пользователь щелкает прочь). Тем не менее, он чувствовал себя «достаточно хорошо», чтобы быть принятым.

Надеюсь, это поможет.

2 голосов
/ 18 апреля 2010

При использовании JPopupMen есть известные ошибки: JTrayIcon: поддержка Swing JPopupMenus для значков в трее . Ближе к концу есть ссылка на возможное решение. Я не пробовал, поэтому не знаю, решит ли это вашу проблему или нет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...