JTable popup menu example

JTable popup menu introduction

Here's a copy of a class file I created to demonstrate how to put a popup menu (JPopupMenu) on a JTable in a Java application. Actually, the intent of this particular class was to see if I could get the popup menu to work on the header cell of a JTable, but that ended up being a no-brainer.

JTable popup menu example - the JFrame code

Hmm ... if you want to use this you're going to need two Java files for this to be complete, so I'll paste them both into here.

First, here is the JFrame class that includes the JTable and JPopupMenu components:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;

/**
 * Created this prototype to see how difficult/easy it would be to put a popup
 * menu (JPopupMenu) on the header of a JTable. While I was in the 
 * neighborhood I also put the popup menu on the JTable proper.
 * 
 * Note -- Some of this is inspired from 
 * "http://www.jroller.com/page/santhosh/20050609#let_user_choose_their_favourite".
 */
public class MainFrame extends JFrame {
  JPanel contentPane;
  BorderLayout borderLayout1 = new BorderLayout();
  JScrollPane theScrollPane = new JScrollPane();
  JTable myJTable = new JTable(new DefaultTableModel(
      new String[] {"Col 1", "Col 2", "Col 3", "Col 4", "Col 5"}, 5 ));

  JPopupMenu popupMenu = new JPopupMenu();
  private static String INSERT_CMD = "Insert New Column";

  public MainFrame() {
    enableEvents(AWTEvent.WINDOW_EVENT_MASK);
    try {
      jbInit();
    }
    catch (Exception e) {
      e.printStackTrace();
    }
  }

  private void jbInit() throws Exception {
    contentPane = (JPanel)this.getContentPane();
    contentPane.setLayout(borderLayout1);
    this.setSize(new Dimension(400, 300));
    this.setTitle("Right Click Column Header Demo");
    contentPane.add(theScrollPane, BorderLayout.CENTER);
    theScrollPane.getViewport().add(myJTable, null);

    JMenuItem menuItem = new JMenuItem(INSERT_CMD);
    menuItem.addActionListener(new InsertRowsActionAdapter(this));
    popupMenu.add(menuItem);

    // add the listener to the jtable
    MouseListener popupListener = new PopupListener();
    // add the listener specifically to the header
    myJTable.addMouseListener(popupListener);
    myJTable.getTableHeader().addMouseListener(popupListener);
  }

  class PopupListener extends MouseAdapter {
    public void mousePressed(MouseEvent e) {
      showPopup(e);
    }

    public void mouseReleased(MouseEvent e) {
      showPopup(e);
    }

    private void showPopup(MouseEvent e) {
      if (e.isPopupTrigger()) {
        popupMenu.show(e.getComponent(), e.getX(), e.getY());
      }
    }
  }

  void insertColumn(ActionEvent e) {
    JOptionPane.showMessageDialog(this,"Would prompt you to enter a new column name here.");
    // do something here
  }

  protected void processWindowEvent(WindowEvent e) {
    super.processWindowEvent(e);
    if (e.getID() == WindowEvent.WINDOW_CLOSING) {
      System.exit(0);
    }
  }

} // end of class

class InsertRowsActionAdapter implements ActionListener {
  MainFrame adaptee;

  InsertRowsActionAdapter(MainFrame adaptee) {
    this.adaptee = adaptee;
  }

  public void actionPerformed(ActionEvent e) {
    adaptee.insertColumn(e);
  }
}

JTable popup menu example - driver class

Here's the second class, which is essentially the "driver" class for our JTable / JPopupMenu example. As you can tell from the Java source code, I typically stub out a lot of this stuff with JBuilder.

import javax.swing.UIManager;
import java.awt.*;

public class MainController {
  boolean packFrame = false;

  public MainController() {
    MainFrame frame = new MainFrame();

    if (packFrame) {
      frame.pack();
    }
    else {
      frame.validate();
    }

    //Center the window
    Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
    Dimension frameSize = frame.getSize();
    if (frameSize.height > screenSize.height) {
      frameSize.height = screenSize.height;
    }
    if (frameSize.width > screenSize.width) {
      frameSize.width = screenSize.width;
    }
    frame.setLocation((screenSize.width - frameSize.width) / 2, (screenSize.height - frameSize.height) / 2);
    frame.setVisible(true);
  }

  //Main method -- it all starts here
  public static void main(String[] args) {
    try {
      UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    }
    catch(Exception e) {
      e.printStackTrace();
    }
    new MainController();
  }
}