Уничтожить JPopupMenu в Java Swing

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

Теперь мне нужно уничтожить всплывающее меню, отображаемое в этой ситуации 2:

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

Я решил эту проблему, сохранив в ArrayList текущие видимые всплывающие окна, и вручную сделал их невидимыми, когда произошла одна из двух предыдущих ситуаций.

Итак, я хотел бы знать 2 вещи:

  1. Есть ли более чистый способ сделать это без ручного получения ссылки на все активные всплывающие окна? (возможно, это достигается какой-либо функцией Swing?)
  2. Достаточно ли сделать всплывающее окно невидимым, не имея больше ссылок на этот объект, чтобы освободить выделенную ему память? Или я должен использовать такой метод, как dispose ? (в JPopupMenu не определен метод удаления)

Немного сложно показать мой реальный код, потому что он немного сложный. В любом случае он делает следующее:

public EditorPopupMenu getPopupMenu() {
    this.popupMenu = new EditorPopupMenu();

    EditorMenuItem copy = GuiConcreteFactory.getInstance().createMenuItem(Gui.getInstance().copyItemAction);
    EditorMenuItem cut = GuiConcreteFactory.getInstance().createMenuItem(Gui.getInstance().cutItemAction);
    EditorMenuItem paste = GuiConcreteFactory.getInstance().createMenuItem(Gui.getInstance().pasteItemAction);

    this.popupMenu.add(copy);
    this.popupMenu.add(cut);
    this.popupMenu.add(paste);

    this.popupMenu.addSeparator();

    EditorMenuItem settings = GuiConcreteFactory.getInstance().createMenuItem(
                                                new ApplicationShowDialogAction("settings",null, 
                                                        new EditorAreaDialog (this)) );
    this.popupMenu.add(settings);
    return popupMenu;
}

Где EditorPopupMenu расширяет JPopupMenu. Предыдущий код вызывается MouseListener, когда происходит щелчок по определенному объекту, и указанный объект создает свое всплывающее меню и возвращает его.

Изнутри MouseListener:

if (me.getModifiers() == InputEvent.BUTTON3_MASK){
                // //System.out.println("ResizableMouseAdapter: BUTTON_3_MASK");


                 EditorPopupMenu popupMenu = sourceComp.getType().getPopupMenu();
                 if ( popupMenu!= null){
                     //System.out.println("COMPONENT HAS A POPUP MENU");
                     popupMenu.setLocation( sourceComp.getLocationOnScreen().x + me.getX(),
                                            sourceComp.getLocationOnScreen().y + me.getY());
                     popupMenu.setVisible(true);
                     Gui.getInstance().addActivePopup(popupMenu);
                 }

             }

Это все. С этим кодом мой JPopupMenu не исчезает должным образом.


person Heisenbug    schedule 03.04.2011    source источник
comment
Я мог бы быть немного тупым этим утром, но разве это не именно то поведение, которое Swing делает по умолчанию? Я много раз использовал JPopupMenu, и мне никогда не приходилось скрывать его вручную.   -  person I82Much    schedule 03.04.2011
comment
@ I82Much: Кажется, нет. Я думал, что то, что я описал, тоже было поведением по умолчанию, но это не так.   -  person Heisenbug    schedule 03.04.2011
comment
Не могли бы вы предоставить код? Я только что проверил это, и то, что вы описываете, происходит на самом деле (для меня)   -  person Tedil    schedule 03.04.2011
comment
@I82Much @Tedil: я отредактировал свой пост. Проверьте это и спасибо за внимание   -  person Heisenbug    schedule 03.04.2011
comment
Пользователь щелкает где-то еще на экране (закрывает всплывающее окно, ничего не делая): зачем вам такое поведение?   -  person mre    schedule 03.04.2011
comment
@noob: потому что предположим, что пользователь щелкает и показывает всплывающее окно, но он не хочет продолжать выбор одного из действий, отображаемых во всплывающем окне, само всплывающее окно должно быть закрыто. Самый простой способ - щелкнуть где-нибудь еще на экране.   -  person Heisenbug    schedule 03.04.2011
comment
@Overbose: Верно, извините... Я думал о JDialog. Но, как сказал camickr, this is the default behavior.   -  person mre    schedule 03.04.2011
comment
@ 0verbose Я думаю, что ссылка, опубликованная camickr, показывает метод public void mouseReleased(MouseEvent e) {, внутри этого метода вы можете установить что угодно для JPopupMenu (до popup#maybeShowPopup(e);)   -  person mKorbel    schedule 13.05.2011


Ответы (2)


Это поведение по умолчанию.

Прочтите раздел руководства Swing по Вызов всплывающего меню для объяснения и рабочего примера.

person camickr    schedule 03.04.2011
comment
кажется, должно быть поведение по умолчанию. Ты прав. Во всяком случае, это не работает для меня. Я разместил код. Есть идеи? - person Heisenbug; 03.04.2011
comment
@Overbose, какой-то код не помогает. Мы не можем сказать контекст того, как/где используется ваш код. Я дал вам ссылку на учебник Swing, который содержит рабочий пример. Учитесь на примере. - person camickr; 04.04.2011

Используйте метод show вместо метода setVisible.

person Rayne    schedule 13.05.2011