JTable 与 JPopupMenu
仅当 Mouse Cursor
位于选定的 JTable'Row
上时,如何防止触发和显示 JPopupMenu
我的问题:是否还有另一种方式 getBounds
从选定的行中确定/比较鼠标位置...
我的简单 sscce 演示了不需要的相反状态,可以选择任何行并JPopupMenu
由整个 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);
}
});
}
}
how can I prevent triggering and showing JPopupMenu
only if is Mouse Cursor
over selected JTable'Row
my question: if is there another way as getBounds
from selected row and determine/compare that with Mouse
position...
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);
}
});
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您也许正在寻找这样的东西吗?
仅在选定的行上显示弹出窗口
或者相反,以防止弹出窗口仅在选定的行上显示:
Are you looking for something like this perhaps?
To show popup over selected row(s) only
Or the converse, to prevent popup from showing over selected rows only:
这是一个有趣的问题,因为它突出显示了 JComponent 上缺少的 api :-)
众所周知,注册 popupMenus 的推荐方法是使用 componentPopupMenu 属性。相关 api 是
缺少的(并且实际上是此要求所需要的),
这种缺少更加烦人,因为 getPopupLocation 是在 getComponentPopup() 之后调用的(由 AWTEventHelper 在 LAF 深处)。因此,对于黑客来说,没有余地,比如存储可能触发弹出窗口的最后一个鼠标事件,然后决定返回哪个/是否返回弹出窗口。返回 null 的位置只会导致在鼠标位置显示它
唯一的(肮脏的)黑客(围绕我完全不愿意用 MouseListener 弄脏我的手;-)是重写 getComponentPopup 并决定是否返回它基于当前鼠标位置,
副作用是只要鼠标位于表格上方的任何位置,键盘就不会触发弹出窗口显示,这可能是也可能不是问题。
It's an interesting question, because it highlights missing api on JComponent :-)
As we all know, the recommended way to register popupMenus is to use the componentPopupMenu property. Related api is
what is missing (and actually needed for this requirement) is
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
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
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.