JPopupMenu ошибка / сбой (?) При отображении подменю - PullRequest
3 голосов
/ 10 октября 2010

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

Вот несколько скриншотов: Вот так это должно выглядеть

alt text

А вот так выглядит ошибка при появлении ошибки:

alt text

Итак, этот глюк на втором изображении - это то место, где должно быть подменю.

Что могло вызвать это? Нет никаких исключений, это не похоже на платформу, поэтому я не знаю, как это сузить. Пожалуйста, помогите.

РЕДАКТИРОВАТЬ Ниже приводится сцена, которая воспроизводит проблему:

import javax.swing.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

public class Test {
    private static Popup popup;

    public static void main(String[] args) {
        final JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.getContentPane().addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                showMenu(e);
            }

            @Override
            public void mouseReleased(MouseEvent e) {
                showMenu(e);
            }

            private void showMenu(final MouseEvent e) {
                if (e.isPopupTrigger()) {
                    JPopupMenu menu = new JPopupMenu();
                    JMenu subMenu = new JMenu("SubMenu");
                    menu.add(subMenu);

                    subMenu.add("Item 1");
                    subMenu.add("Item 2").addMouseMotionListener(new MouseAdapter() {
                        @Override
                        public void mouseMoved(MouseEvent e) {
                            hidePopup();
                            // this is where I call the hide twice, in my case it was
                            // caused by some action or mouse listener calling it twice
                            hidePopup();
                            showPopup(e, frame);
                        }
                    });
                    subMenu.add("Item 3");

                    menu.show(frame.getContentPane(), e.getX(), e.getY());
                }
            }

            private void showPopup(MouseEvent e, JFrame frame) {
                PopupFactory popupFactory = PopupFactory.getSharedInstance();
                JToolTip toolTip = new JToolTip();
                toolTip.setTipText("wfkwdlpfhd ");
                popup = popupFactory.getPopup(frame, toolTip, e.getXOnScreen(), e.getYOnScreen());
                popup.show();
            }

            private void hidePopup() {
                if (popup != null)
                    popup.hide();
            }
        });

        frame.setSize(300, 300);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}

Ответы [ 2 ]

2 голосов
/ 10 октября 2010

Благодаря одному из моих пользователей я обнаружил проблему.

На тот случай, если кто-то взломает свингом больше, чем должен - вот что произошло: в одной части моей программы я показываю всплывающее сообщение на JProgressBar, показывающее положение, когда пользователь перемещает большой палец индикатора выполнения. Для этого я создаю Popup, используя PopupFactory. Затем, используя слушателей мыши, я показываю и скрываю всплывающее окно. После того, как я позвонил hide(), я не установил для всплывающего объекта значение null, что может привести к двойному вызову hide() или удержанию всплывающего окна в gc - точно не знаю. Но, очевидно, это испортило механизм всплывающих окон JPopupMenu.

Цитата из Popup.hide() JavaDoc объясняет это лучше:

Скрывает и удаляет всплывающее окно. После удаления всплывающего окна вы больше не должны вызывать методы для него. Уничтоженное всплывающее окно может быть восстановлено и позже использовано на основе PopupFactory. Таким образом, если вы вызываете методы в удаленном всплывающем окне, это приведет к неопределенному поведению.

0 голосов
/ 10 октября 2010

Я не уверен, поможет ли это с вашей проблемой, но обычно всплывающее меню должно быть добавлено таким образом:

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