So for my school project I am creating a Class Diagram maker. I am 95% done with it and all I need is to make the Jpopup menu appear. In the core I have 3 files. The ApplicationModel which extends the JFrame, ClassDiagram which extends the JPanel and ClassModel which makes the Rectangles (in the picture) appear. The core of the rendering is on Rectangle objects and the text inside the middle and bottom rectangles are surrounded by another invisible rectangle, which is right-clickable.
This is what the program looks like (Minus the paint editting) Now for the file that handles the clicking is DiagramMouseListener, here is the code for it.
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());
}
}
}
}
At line 118 where it says System.out.println("it is"); It successfully displays the text on console, which tells me the code successfully reached that part, but the popup menu is never displayed when I right click the text (which is inside invisible Rectangles separated by 5 pixels of space).
I tried multiple solutions to this problem. I even looked at the oracle tutorials and other user's examples to see what was wrong with my code. But after countless hours of searching, I failed to fix the problem. Any help would be appreciated. Also if you need more information, I will be glad to provide! Thanks.
Several things;
First off, the popup coordinates should be relative to the component you are triggering the popup on, not the screen coordinates. What is happening is, the API is calculating the screen location of the component and adding the x/y values you pass, which is possibly pushing the popup off the screen
Secondly, popups can be triggered on different systems by different events. You should be checking for
isPopupTrigger
inmousePressed
,mouseReleased
and evenmouseClicked
.Lastly, popups can be triggered by different mouse buttons (and even possibly other conditions), so should only need to check
isPopupTrigger
Additionally, you could just use
JComponent#setComponentPopupMenu
Updated with
setComponentPopupMenu
exampleUpdated with
MouseListener
example