gpt4 book ai didi

java - JPopupMenu 没有显示在屏幕上?

转载 作者:行者123 更新时间:2023-12-01 13:42:32 25 4
gpt4 key购买 nike

因此,对于我的学校项目,我正在创建一个类图制作器。我已经完成了 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());

其次,弹出窗口可以通过不同的事件在不同的系统上触发。您应该检查 mousePressedmouseReleased 甚至 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com