Reputation: 7212
I have the JPopupMenu
shown on right mouse click. I want JPopupMenu'
top right corner to be at the click location
(not top left one, as default). To perform this, I need to set the X
coordinate as mouseEvent.getX() - popupMenu.getWidth()
. The problem is, before popup is shown first time, its width equals 0.
SSCCE:
public class PopupTest2 {
public static void main(String[] a) {
final JFrame frame = new JFrame();
frame.setSize(500, 500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final JPanel panel = new JPanel(new BorderLayout());
panel.setBorder(BorderFactory.createLineBorder(Color.RED));
final JPopupMenu menu = new JPopupMenu();
for (int i = 0; i < 10; i++) {
JMenuItem item = new JMenuItem("Item #"+String.valueOf(i));
menu.add(item);
}
panel.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON3) {
// first time works wrong
menu.show(panel, e.getX() - menu.getWidth(), e.getY());
}
}
});
frame.setContentPane(panel);
frame.setUndecorated(true);
frame.setBackground(new Color(50, 50, 50, 200));
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
frame.setVisible(true);
}
});
}
}
Upvotes: 4
Views: 2051
Reputation: 3125
Using popup.getPreferredSize().width
and popup.getPreferredSize().height
you can get popup size before it is shown.
This is an example locating the popup menu at the top of a button:
but_menu = new JButton("");
but_menu.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
Point p = but_menu.getLocation();
Point dest = new Point();
dest.x = 0 - popup.getPreferredSize().width + but_menu.getWidth();
dest.y = 0 - popup.getPreferredSize().height;
popup.show(but_menu,dest.x,dest.y);
}
});
Upvotes: 1
Reputation: 51535
Using the preferredSize (as already mentioned) is the way to go for getting the location.
But (being on a quest here :-): manually showing the popup is not the recommended approach. A really clean implementation will use the componentPopupMenu property and implement getPopupLocation as needed, something like
JPanel panel = new JPanel(new BorderLayout()) {
@Override
public Point getPopupLocation(MouseEvent event) {
JPopupMenu menu = getComponentPopupMenu();
if (menu == null || event == null) return null;
return new Point(event.getX() - menu.getPreferredSize().width, event.getY());
}
};
JPopupMenu menu = new JPopupMenu();
panel.setComponentPopupMenu(menu);
Upvotes: 5
Reputation: 11327
Probably you can determine the width of context menu as the highest preferred width of ist elements?
Upvotes: 1