What's preferred size of the JPopupMenu
before showing?
Get JPopupMenu size before it is shown
-
01-07-2022 - |
Вопрос
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);
}
});
}
}
Решение 2
Другие советы
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);
Probably you can determine the width of context menu as the highest preferred width of ist elements?
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);
}
});