JPopupMenu没有在屏幕上显示?

时间:2013-12-15 19:21:13

标签: java swing awt jmenuitem jpopupmenu

因此,对于我的学校项目,我正在创建一个Class Diagram制造商。我完成了95%,我只需要显示Jpopup菜单。在核心我有3个文件。 ApplicationModel扩展了JFrame,ClassDiagram扩展了JPanel和ClassModel,使得矩形(在图片中)出现。渲染的核心是Rectangle对象,中间和底部矩形内的文本被另一个不可见的矩形包围,可以右键单击。

This is what the program looks like (Minus the paint editting) 现在,处理点击的文件是DiagramMouseListener,这里是代码。

package edu.mville.cs.classdiagram;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.SwingUtilities;

public class DiagramMouseListener extends MouseAdapter
{
    ClassDiagram diagram;
    Field field;
    Method method;
    int x;
    int y;
    ClassModel elementBeingDragged;

    JPopupMenu fieldPopupMenu = new JPopupMenu();
    JPopupMenu methodPopupMenu = new JPopupMenu();

    JMenuItem editFieldNameItem;
    JMenuItem createFieldItem;
    JMenuItem deleteFieldItem;

    JMenuItem editMethodNameItem;
    JMenuItem createMethodItem;
    JMenuItem deleteMethodItem;

    public DiagramMouseListener(ClassDiagram diagram) { this.diagram = diagram; }

    public void addPopupMenu()
    {
        editFieldNameItem = new JMenuItem("Edit Field Name");
        createFieldItem = new JMenuItem("New Field");
        deleteFieldItem = new JMenuItem("Delete Field");

        editMethodNameItem = new JMenuItem("Edit Method Name");
        createMethodItem = new JMenuItem("New Method");
        deleteMethodItem = new JMenuItem("Delete Method");

        methodPopupMenu.add(editMethodNameItem);
        methodPopupMenu.add(createMethodItem);
        methodPopupMenu.add(deleteMethodItem);

        fieldPopupMenu.add(editFieldNameItem);
        fieldPopupMenu.add(createFieldItem);
        fieldPopupMenu.add(deleteFieldItem);

        editFieldNameItem.addActionListener(new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent ae)
            {

            }
        });
        /*
        createFieldItem.addActionListener(this);
        deleteFieldItem.addActionListener(this);
        editMethodNameItem.addActionListener(this);
        createMethodItem.addActionListener(this);
        deleteMethodItem.addActionListener(this);
        */
    }

    @Override
    public void mouseClicked(MouseEvent me)
    {        
        if(SwingUtilities.isLeftMouseButton(me) && me.getClickCount() == 2)
        {
            diagram.doubleClick(me.getPoint());
        }
    }

    @Override
    public void mousePressed(MouseEvent e)
    {
        x = e.getX();
        y = e.getY();

        DiagramElement elt = diagram.containsPoint(e.getPoint());
        if (elt instanceof ClassModel)
        {
            elementBeingDragged = (ClassModel) elt;
        }
    }

    @Override
    public void mouseDragged(MouseEvent e)
    {
        int dx = e.getX() - x;
        int dy = e.getY() - y;

        if (elementBeingDragged != null)
        {
            elementBeingDragged.move(dx, dy);

            diagram.repaint();
        }

        x += dx;
        y += dy;
    }

    @Override
    public void mouseReleased(MouseEvent me)
    {
        elementBeingDragged = null;

        DiagramElement de = diagram.containsPoint(me.getPoint());

        if (SwingUtilities.isRightMouseButton(me) && me.getClickCount() == 1 && de instanceof Field)
        {
            if (me.isPopupTrigger())
            {
                System.out.println("it is");
                fieldPopupMenu.show(me.getComponent(), me.getX(), me.getY());
            }
        }
        else if (SwingUtilities.isRightMouseButton(me) && me.getClickCount() == 1 && de instanceof Method)
        {
            if (me.isPopupTrigger())
            {
                System.out.println("it is");
                methodPopupMenu.show(me.getComponent(), me.getX(), me.getY());
            }
        }  
    }
}

在第118行,它显示System.out.println(“它是”);它成功地在控制台上显示文本,告诉我代码成功到达该部分,但是当我右键单击文本时(在不可见的矩形内部,由5个像素的空格分隔),弹出菜单永远不会显示。

我尝试了多个解决方案来解决这个问题。我甚至查看了oracle教程和其他用户的示例,看看我的代码出了什么问题。但经过无数次的搜索,我没能解决问题。任何帮助,将不胜感激。如果您需要更多信息,我很乐意提供!感谢。

1 个答案:

答案 0 :(得分:1)

有几件事;

首先,弹出坐标应该是您触发弹出窗口的组件,而不是屏幕坐标。发生的事情是,API正在计算组件的屏幕位置并添加您传递的x / y值,这可能会将弹出窗口推离屏幕

fieldPopupMenu.show(me.getComponent(), me.getX(), me.getY());

其次,弹出窗口可以通过不同的事件在不同的系统上触发。您应该在isPopupTriggermousePressed甚至mouseReleased中检查mouseClicked

最后,弹出窗口可以由不同的鼠标按钮(甚至可能是其他条件)触发,因此只需要检查isPopupTrigger

此外,您可以使用JComponent#setComponentPopupMenu

已更新为setComponentPopupMenu示例

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class PopupMenuTest {

    public static void main(String[] args) {
        new PopupMenuTest();
    }

    public PopupMenuTest() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private JPopupMenu popupMenu;

        public TestPane() {
            popupMenu = new JPopupMenu();
            popupMenu.add(new JMenuItem("Open..."));
            popupMenu.add(new JMenuItem("Save..."));
            popupMenu.add(new JMenuItem("Close..."));
            popupMenu.add(new JMenuItem("Give Blood..."));
            popupMenu.add(new JMenuItem("Give Money..."));

            setComponentPopupMenu(popupMenu);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

    }

}

已更新为MouseListener示例

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class PopupMenuTest {

    public static void main(String[] args) {
        new PopupMenuTest();
    }

    public PopupMenuTest() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private JPopupMenu popupMenu;

        public TestPane() {
            popupMenu = new JPopupMenu();
            popupMenu.add(new JMenuItem("Open..."));
            popupMenu.add(new JMenuItem("Save..."));
            popupMenu.add(new JMenuItem("Close..."));
            popupMenu.add(new JMenuItem("Give Blood..."));
            popupMenu.add(new JMenuItem("Give Money..."));

            addMouseListener(new MouseAdapter() {

                protected void doPopup(MouseEvent evt) {
                    if (evt.isPopupTrigger()) {
                        popupMenu.show(evt.getComponent(), evt.getX(), evt.getY());
                    }
                }

                @Override
                public void mouseClicked(MouseEvent e) {
                    doPopup(e);
                }

                @Override
                public void mousePressed(MouseEvent e) {
                    doPopup(e);
                }

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

            });
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

    }

}