使用JPopupMenu的JTable [英] JTable with JPopupMenu
问题描述
如果鼠标光标
超过选定的,我怎么能阻止触发并显示
JPopupMenu
JTable'Row
how can I prevent triggering and showing JPopupMenu
only if is Mouse Cursor
over selected JTable'Row
我的问题:如果有另一种选择 getBounds
来自选中行并确定/与鼠标
位置进行比较...
my question: if is there another way as getBounds
from selected row and determine/compare that with Mouse
position...
我的简单sscce演示了不想要的对立状态,可以选择任何行, JPopupMenu
从整个 JTable
my simple sscce demonstrated just un-wanted opposite status, any row could be selected and JPopupMenu
is triggered from whole JTable
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;
public class TableCheckBox extends JFrame {
private static final long serialVersionUID = 1L;
private JTable table;
public TableCheckBox() {
Object[] columnNames = {"Type", "Company", "Shares", "Price", "Boolean"};
Object[][] data = {
{"Buy", "IBM", new Integer(1000), new Double(80.50), false},
{"Sell", "MicroSoft", new Integer(2000), new Double(6.25), true},
{"Sell", "Apple", new Integer(3000), new Double(7.35), true},
{"Buy", "Nortel", new Integer(4000), new Double(20.00), false}
};
DefaultTableModel model = new DefaultTableModel(data, columnNames);
table = new JTable(model) {
private static final long serialVersionUID = 1L;
@Override
public Class getColumnClass(int column) {
return getValueAt(0, column).getClass();
}
};
table.setPreferredScrollableViewportSize(table.getPreferredSize());
JScrollPane scrollPane = new JScrollPane(table);
add(scrollPane);
createPopupMenu();
}
private void createPopupMenu() {
JPopupMenu popup = new JPopupMenu();
JMenuItem myMenuItem1 = new JMenuItem("cccccccccccccccccccccc");
JMenuItem myMenuItem2 = new JMenuItem("bbbbbbbbbbbbbbbbbbbbbb");
popup.add(myMenuItem1);
popup.add(myMenuItem2);
MouseListener popupListener = new PopupListener(popup);
table.addMouseListener(popupListener);
}
private class PopupListener extends MouseAdapter {
private JPopupMenu popup;
PopupListener(JPopupMenu popupMenu) {
popup = popupMenu;
}
@Override
public void mousePressed(MouseEvent e) {
maybeShowPopup(e);
}
@Override
public void mouseReleased(MouseEvent e) {
if (table.getSelectedRow() != -1) {
maybeShowPopup(e);
}
}
private void maybeShowPopup(MouseEvent e) {
if (e.isPopupTrigger()) {
popup.show(e.getComponent(), e.getX(), e.getY());
}
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
TableCheckBox frame = new TableCheckBox();
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.pack();
frame.setLocation(150, 150);
frame.setVisible(true);
}
});
}
}
推荐答案
这是一个有趣的问题,因为它突出了JComponent上缺少的api :-)
It's an interesting question, because it highlights missing api on JComponent :-)
众所周知,注册popupMenus的推荐方法是使用componentPopupMenu属性。相关的api是
As we all know, the recommended way to register popupMenus is to use the componentPopupMenu property. Related api is
void setComponentPopupMenu(JPopupMenu);
JPopupMenu getComponentPopupMenu();
Point getPopupLocation(MouseEvent);
缺少的(此要求实际需要的)是
what is missing (and actually needed for this requirement) is
JPopupMenu getComponentPopupMenu(MouseEvent);
因为getPopupLocation被调用(由LAF深处的AWTEventHelper),这种缺乏更令人讨厌在 getComponentPopup()之后。因此,存储没有余地,例如存储可能触发弹出窗口的最后一个鼠标事件,然后决定哪个/是否返回弹出窗口。并且为该位置返回null只会导致在鼠标位置显示它
this lack is all the more annoying, as the getPopupLocation is called (by AWTEventHelper deep in the LAF) after getComponentPopup(). So there's no leeway for a hack like storing the last mouse event which might have triggered the popup and then decide which/if to return popup. And returning null for the location will only result in showing it at the mouse location
唯一(脏)黑客(我完全不愿意弄脏MouseListener) ;-)是覆盖getComponentPopup并决定是否根据当前鼠标位置返回它
The only (dirty) hack (around my utter reluctance to get my hands dirty with a MouseListener ;-) is to override getComponentPopup and decide there whether or not to return it based on current mouse position
table = new JTable(model) {
/**
* @inherited <p>
*/
@Override
public JPopupMenu getComponentPopupMenu() {
Point p = getMousePosition();
// mouse over table and valid row
if (p != null && rowAtPoint(p) >= 0) {
// condition for showing popup triggered by mouse
if (isRowSelected(rowAtPoint(p))) {
return super.getComponentPopupMenu();
} else {
return null;
}
}
return super.getComponentPopupMenu();
}
};
副作用是弹出显示不是由键盘触发,只要鼠标在任何地方在表格上方,这可能是也可能不是问题。
the side-effect is that popup showing isn't triggered by keyboard as long as the mouse is anywhere above the table, which might or not be a problem.
这篇关于使用JPopupMenu的JTable的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!