Search code examples
javaswingjtablejpopupmenu

Dynamic (real) context menu for jtable row


I want different menu items in the context menu depending on the row I clicked in the JTable

most of examples do not really show a context menu (supposed to be populated depending on the context - the selected row)

I tried this:

    popupMenu = new JPopupMenu(){
         @Override
        public void show(Component invoker, int x, int y) {
            int rowAtPoint = table.rowAtPoint(SwingUtilities.convertPoint(this, new Point(x, y), table));
                FilesManager.this.generateTablePopupMenu(rowAtPoint);
            super.show(invoker, x, y);
        }
    };

where generateTablePopupMenu is adding/removing menuitems depending on the row data

but it does not work, the index (rowAtPoint) does not return correct values


Solution

  • JPopupMenu#show(int, int) (Java Platform SE 8)

    public void show(Component invoker, int x, int y)

    Displays the popup menu at the position x,y in the coordinate space of the component invoker.

    Parameters:

    • invoker - the component in whose space the popup menu is to appear
    • x - the x coordinate in invoker's coordinate space at which the popup menu is to be displayed
    • y - the y coordinate in invoker's coordinate space at which the popup menu is to be displayed

    Therefore, it is not necessary to convert the coordinates using the SwingUtilities.convertPoint(...) method.

    import java.awt.*;
    import javax.swing.*;
    import javax.swing.table.*;
    
    public class JTablePopupMenuTest {
      public JComponent makeUI() {
        JTable table = new JTable(new DefaultTableModel(5, 3));
        table.setFillsViewportHeight(true);
        JPopupMenu popupMenu = new JPopupMenu() {
          @Override
          public void show(Component invoker, int x, int y) {
            //int rowAtPoint = table.rowAtPoint(
            //    SwingUtilities.convertPoint(this, new Point(x, y), table));
            //FilesManager.this.generateTablePopupMenu(rowAtPoint);
            int rowAtPoint = table.rowAtPoint(new Point(x, y));
            System.out.println(rowAtPoint);
            super.show(invoker, x, y);
          }
        };
        table.setComponentPopupMenu(popupMenu);
    
        JPanel p = new JPanel(new BorderLayout());
        p.add(new JScrollPane(table));
        return p;
      }
      public static void main(String... args) {
        EventQueue.invokeLater(() -> {
          JFrame f = new JFrame();
          f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
          f.getContentPane().add(new JTablePopupMenuTest().makeUI());
          f.setSize(320, 240);
          f.setLocationRelativeTo(null);
          f.setVisible(true);
        });
      }
    }