1

I want to display a small context menu when a user right clicks a table row in my application. My plan was to use a custom made MouseListener for this that calls the show() method. Here is my code:

import java.awt.Point;
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.JTable;
import javax.swing.SwingUtilities;

class TableMouseListener extends MouseAdapter {
public void mousePressed(MouseEvent e) {
    JTable table = (JTable)(e.getSource());
    Point p = e.getPoint();
    int row = table.rowAtPoint(p);
    int col = table.columnAtPoint(p);

// The autoscroller can generate drag events outside the Tables range.
if ((col == -1) || (row == -1)) {
        return;
}

    if (SwingUtilities.isRightMouseButton(e)) {
        JPopupMenu pop = new JPopupMenu("Row "+row);
        JMenuItem menu1 = new JMenuItem("Wijzigen");
        menu1.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e){
                //do things, still have to make that
            }
        });
        pop.show(menu1, p.x, p.y);

    }
}
}

Now my problem is: when i run my application, and I right click a table row, it pops out this error:

Exception in thread "AWT-EventQueue-0" java.awt.IllegalComponentStateException: component must be showing on the screen to determine its location
at java.awt.Component.getLocationOnScreen_NoTreeLock(Unknown Source)
at java.awt.Component.getLocationOnScreen(Unknown Source)
at javax.swing.JPopupMenu.show(Unknown Source)
at TableMouseListener.mousePressed(TableMouseListener.java:34)

What exactly is going wrong here?

mKorbel
  • 109,525
  • 20
  • 134
  • 319
Harold Holsappel
  • 266
  • 4
  • 15

2 Answers2

4

You are trying to display JPopupMenu (pop) relatively to the JMenuItem (menu1) component. But JMenuItem is not visible in the moment when you call popupmenu show method and it fails to determine JMenuItem location on screen (ofcourse, it is not shown on the screen yet).

You have to use some visible component in the popupmenu show method as the first argument (for example some button that is added to displayed frame or any other actually visible component). You can also pass null to place the popup menu relatively to the (0;0) coordinate (upper-left screen corner).

Mikle Garin
  • 10,083
  • 37
  • 59
  • Hmmm i must be messing up bigtime then. What i actually want to do is show the JPopupMenu with the JMenuItem in it, at the location of my mousepointer... :| – Harold Holsappel Oct 31 '12 at 15:35
  • @HaroldHolsappel so basically you want to overwrite default sub-menu location and use the mouse location instead of the default right-sided positioning? And yes, your code indeed does something really messy :) – Mikle Garin Oct 31 '12 at 15:47
  • Yes, because by default, the submenu pops up in the upper left corner of the screen. My general idea was to just have a context menu pop up when a user right-clicks a table row. I want the menu to show the option to edit the table row data. This opens another small frame with one textfield and a button that says 'send'. I hope you understand what I mean. – Harold Holsappel Nov 01 '12 at 07:42
  • @HaroldHolsappel in that case you should have opened the JPopupMenu relative to your table and just pass the table cell coordinates. Just that simple :) – Mikle Garin Nov 01 '12 at 09:33
  • Yes i got it all working by following mKorbels link he mentioned above. But thanks for your help as well :) – Harold Holsappel Nov 01 '12 at 11:20
2
  • JMenuItem isn't added to the JPopup, then JMenuItem shoudn't be isDisplayable

  • prepare this container, dont't to create on fly ,

  • create whole popup container as local variable or as returns from class, void, whatever

    a) prepare with JMenuItems too

    b) override maybeShowPopup, then there you can manage whatever (must be done on EDT)

  • rest of importantn methods

Community
  • 1
  • 1
mKorbel
  • 109,525
  • 20
  • 134
  • 319