因此,对于我的学校项目,我正在创建一个类图制作器。我已经完成了 95%,我所需要的就是让 Jpopup 菜单出现。在核心中我有 3 个文件。扩展 JFrame 的 ApplicationModel、扩展 JPanel 的 ClassDiagram 和使矩形(如图中)出现的 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("it is");它成功在控制台上显示文本,这告诉我代码成功到达该部分,但当我右键单击文本时,弹出菜单永远不会显示(文本位于由 5 个像素空间分隔的不可见矩形内)。
我尝试了多种解决方案来解决这个问题。我什至查看了 oracle 教程和其他用户的示例,看看我的代码出了什么问题。但经过无数个小时的寻找,我未能解决这个问题。任何帮助,将不胜感激。另外,如果您需要更多信息,我将很乐意提供!谢谢。
最佳答案
几件事;
首先,弹出窗口坐标应该相对于您触发弹出窗口的组件,而不是屏幕坐标。发生的情况是,API 正在计算组件的屏幕位置并添加您传递的 x/y 值,这可能会将弹出窗口推离屏幕
fieldPopupMenu.show(me.getComponent(), me.getX(), me.getY());
其次,弹出窗口可以通过不同的事件在不同的系统上触发。您应该检查 mousePressed
、mouseReleased
甚至 mouseClicked
中的 isPopupTrigger
。
最后,弹出窗口可以由不同的鼠标按钮(甚至可能是其他条件)触发,因此只需检查 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);
}
}
}
关于java - JPopupMenu 没有显示在屏幕上?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20598686/