This is strange. The JPopMenu works as expected when I use mouse right click. But when I try to show it using Menu key on keyboard the highlight jumps a few rows before or after.
I've used PopupMenuListener so that I can highlight a row directly when using right click:
popupMenu.addPopupMenuListener(new PopupMenuListener() {
@Override
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
Point point = SwingUtilities.convertPoint(popupMenu, new Point(0, 0), table);
int currentRow = table.rowAtPoint(point);
int currentColumn = table.columnAtPoint(point);
table.changeSelection(currentRow, currentColumn, false, false);
}
});
}
@Override
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
// TODO Auto-generated method stub
}
@Override
public void popupMenuCanceled(PopupMenuEvent e) {
// TODO Auto-generated method stub
}
});
Here is the full program:
import java.awt.Point;
import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
public class Test {
private JFrame frame;
private JTable table;
private JScrollPane scrollpane;
public Test() {
initialize();
}
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
String[] head = {"ID","NAME","DOB"};
String[][] data = {
{"1", "Peter", "2001/03/24"},
{"2", "Carlos", "1996/09/02"},
{"3", "Ahmed", "1999/07/07"},
{"4", "John", "1993/10/15"},
{"5", "Kumar", "1991/11/08"}
};
table = new JTable(data, head);
scrollpane = new JScrollPane(table);
table.setDefaultEditor(Object.class, null);
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
JPopupMenu popupMenu = new JPopupMenu();
JMenuItem edit = new JMenuItem("Edit");
JMenuItem delete = new JMenuItem("Delete");
popupMenu.add(edit);
popupMenu.add(delete);
table.setComponentPopupMenu(popupMenu);
popupMenu.addPopupMenuListener(new PopupMenuListener() {
@Override
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
Point point = SwingUtilities.convertPoint(popupMenu, new Point(0, 0), table);
int currentRow = table.rowAtPoint(point);
int currentColumn = table.columnAtPoint(point);
table.changeSelection(currentRow, currentColumn, false, false);
}
});
}
@Override
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
// TODO Auto-generated method stub
}
@Override
public void popupMenuCanceled(PopupMenuEvent e) {
// TODO Auto-generated method stub
}
});
frame.getContentPane().add(scrollpane);
}
public void setVisible(boolean state) {
frame.setVisible(state);
}
}