Basically, this creates a popup menu and registers it using the JComponent#setComponentPopupMenu . This means that I no longer need to track mouse events or make decisions about when to show the popup.
Then I override JComponent#getPopupLocation and compute the location where I want the popup to appear.
Basically, I get JComponent#getComponentPopupMenu , get its preferred size and calculate the corresponding offset, so that the bottom left corner now appears in the center of the component ...

import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Graphics; import java.awt.Point; import java.awt.event.MouseEvent; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JMenuItem; import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; public class TestPopup02 { public static void main(String[] args) { new TestPopup02(); } public TestPopup02() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { } JFrame frame = new JFrame("Testing"); 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() { JPopupMenu menu = new JPopupMenu(); menu.add(new JMenuItem("Edit Playlist")); menu.addSeparator(); menu.add(new JMenuItem("Check for Available Downloads...")); menu.addSeparator(); menu.add(new JMenuItem("Export...")); menu.add(new JMenuItem("Burn Playlist to Disc")); menu.add(new JMenuItem("Copy To Play Order")); menu.addSeparator(); menu.add(new JMenuItem("Delete")); setComponentPopupMenu(menu); } @Override public Point getPopupLocation(MouseEvent event) {
Mac Update

Button Example
It is unlikely that you will ever find a solution that meets your needs. One of the greatest skills that any developer can develop is the ability to think and shape it there.
The previous example contains everything you need, you just need to make the transition from concept to solution.
getPopupLocation is part of the component’s API, so either overriding the method or calling it is probably not quite what you need (if you don’t have a dedicated button for the task, which can be good) so you will need to adapt the solution to your needs ...

import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Graphics; import java.awt.GridBagLayout; import java.awt.Point; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseEvent; import javax.swing.JButton; 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 TestPopup02 { public static void main(String[] args) { new TestPopup02(); } public TestPopup02() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { } JFrame frame = new JFrame("Testing"); 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 { private JButton button; private JPopupMenu popup; public TestPane() { popup = new JPopupMenu(); popup.add(new JMenuItem("Edit Playlist")); popup.addSeparator(); popup.add(new JMenuItem("Check for Available Downloads...")); popup.addSeparator(); popup.add(new JMenuItem("Export...")); popup.add(new JMenuItem("Burn Playlist to Disc")); popup.add(new JMenuItem("Copy To Play Order")); popup.addSeparator(); popup.add(new JMenuItem("Delete")); setLayout(new GridBagLayout()); button = new JButton("+"); button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { popup.pack(); Point pos = new Point();
source share