Сделать JPopupMenu действительно всплывающим

У меня есть JFrame, который выглядит как обычное окно чата. Для подключения и отключения от сервера я реализовал JPopupMenu и добавил MouseListener в главное окно.
Однако всплывающее меню не появляется.

Various JComponents in the main window:

  • JTextArea в пределах JScrollPane
  • JTextField для ввода сообщения
  • кнопка Send
  • JScrollPane и ArrayList для отображения пользователей

  • The popup is supposed to appear no matter where you right click. Be it on the JTextArea or the field to enter your message.
    To which all components do I add listeners and what listener do I add ?

    Код

    Переменные:

        private static A_Chat_Client chatClient;
        public static String userName = "Anonymous";
    
    //------------------------------------------------------------------------------
        public static JFrame mainFrame = new JFrame();
        public static JTextArea textArea = new JTextArea(30,30);
        public static JScrollPane pane = new JScrollPane(textArea);
        public static JTextField message = new JTextField(10);
        public static JButton send = new JButton("Send");
    
        public static JPopupMenu popup = new JPopupMenu();
        public static JMenuItem connect = new JMenuItem("Connect");
        public static JMenuItem disconnect = new JMenuItem("Disconnect");
        public static JMenuItem help = new JMenuItem("Help");
    
        public static JList usersOnline = new JList();
        public static JScrollPane userPane = new JScrollPane(usersOnline);  
    

    Основной метод

    public static void main(String[] args) {
            buildMainWindow();
            initialize();
            addListeners();
            popup.show(mainFrame, 0, 0); //forcefully popup
        }  
    

    добавить слушателей()

    public static void addListeners(){
    
            mainFrame.addMouseListener(new MouseHandler());
    
            send.addActionListener(new ActionListener(){
                @Override
                public void actionPerformed(ActionEvent e){
                    actionSend();
                }
            });
            connect.addActionListener(new ActionListener(){
                @Override
                public void actionPerformed(ActionEvent e){
                    actionConnect();
                }
            });
            disconnect.addActionListener(new ActionListener(){
                @Override
                public void actionPerformed(ActionEvent e){
                    actionDisconnect();
                }
            });
            help.addActionListener(new ActionListener(){
                @Override
                public void actionPerformed(ActionEvent e){
                    actionHelp();
                }
            });
        }  
    

    класс MouseHandler

    private static class MouseHandler extends MouseAdapter{
            @Override
            public void mouseClicked(MouseEvent e){
                if(e.isPopupTrigger()){
                    popup.show(mainFrame, e.getX(), e.getY());
                }
            }
        }
    

    person An SO User    schedule 15.01.2013    source источник
    comment
    Пожалуйста, покажите какой-нибудь код, чтобы мы имели представление о том, в чем проблема.   -  person tckmn    schedule 15.01.2013
    comment
    @Doorknob добавил туда код, только соответствующую часть :)   -  person An SO User    schedule 15.01.2013


    Ответы (1)


    Вы можете прикрепить AWTEventListener к основная очередь событий с использованием Toolkit#addAWTEventListener

    Затем вам нужно будет проверить тип события, которое вы получаете, и проверить, является ли оно всплывающим событием.

    введите здесь описание изображения

    public class TestGlobalPopup {
    
        public static void main(String[] args) {
            new TestGlobalPopup();
        }
    
        public TestGlobalPopup() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    }
    
                    JFrame frame = new JFrame();
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.setLayout(new BorderLayout());
                    frame.add(new TestPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class TestPane extends JPanel {
    
            public TestPane() {
                Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {
                    @Override
                    public void eventDispatched(AWTEvent event) {
                        if (event instanceof MouseEvent) {
                            MouseEvent me = (MouseEvent) event;
                            if (me.isPopupTrigger()) {
                                Component component = me.getComponent();
                                JPopupMenu popup = new JPopupMenu();
                                popup.add(new JLabel("Clicked on " + component.getClass().getName()));
                                popup.show(component, me.getX(), me.getY());
                            }
                        }
                    }
                }, AWTEvent.MOUSE_EVENT_MASK);
    
                setLayout(new GridBagLayout());
                GridBagConstraints gbc = new GridBagConstraints();
                gbc.gridx = 0;
                gbc.gridy = 0;
                add(new JLabel("Label: "), gbc);
                gbc.gridx++;
                add(new JTextField(10), gbc);
    
                gbc.gridy++;
                gbc.gridx = 0;
                gbc.gridwidth = 2;
                add(new JScrollPane(new JTextArea(5, 20)), gbc);
            }
    
        }
    
    }
    
    person MadProgrammer    schedule 15.01.2013
    comment
    @MadProgrammer Спасибо за это, но что не так с моим кодом? :) Все события правильно передаются, когда я нажимаю на принудительно всплывающее окно, но оно не работает при щелчке правой кнопкой мыши :) - person An SO User; 15.01.2013
    comment
    @littlechild Всплывающее окно может возникать при щелчке, нажатии или отпускании, в зависимости от платформы. - person MadProgrammer; 15.01.2013
    comment
    @MadProgrammer, поэтому я должен, как правило, также реализовывать ту же функциональность в mousePressed() для кроссплатформенной совместимости? - person An SO User; 15.01.2013
    comment
    @littlechild mousePressed, mouseClicked и mouseReleased - person MadProgrammer; 15.01.2013