为了账号安全,请及时绑定邮箱和手机立即绑定

带有JPopupMenu的JTable

带有JPopupMenu的JTable

慕侠2389804 2019-12-04 15:13:04
我如何才能防止触发和JPopupMenu仅Mouse Cursor在选中时显示JTable'Row我的问题:是否还有其他方法可以getBounds从选定的行中确定并与Mouse位置进行比较...我的简单sscce展示了不想要的相反状态,可以选择任何行并JPopupMenu从整体上触发JTableimport 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);        }
查看完整描述

3 回答

?
慕码人2483693

TA贡献1860条经验 获得超9个赞

这是一个有趣的问题,因为它突出显示了JComponent上缺少的api :-)


众所周知,建议注册popupMenus的方法是使用componentPopupMenu属性。相关的API是


 void setComponentPopupMenu(JPopupMenu);

 JPopupMenu getComponentPopupMenu();

 Point getPopupLocation(MouseEvent);

缺少什么(此要求实际需要)是


JPopupMenu getComponentPopupMenu(MouseEvent);

这种缺失更加令人烦恼,因为在 getComponentPopup()之后调用了getPopupLocation(由LAF中的AWTEventHelper调用)。因此,像存储上次可能触发了弹出窗口的鼠标事件然后决定返回哪个弹出窗口一样,黑客没有任何余地。并且返回该位置的null只会导致在鼠标位置显示它


唯一的(肮脏的)黑客(我完全不愿被MouseListener弄脏;-)是重写getComponentPopup并根据当前的鼠标位置决定是否返回它。


    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();

        }


    };

副作用是只要鼠标在桌子上方的任何地方,弹出显示就不会由键盘触发,这可能是有问题的。


查看完整回答
反对 回复 2019-12-04
?
largeQ

TA贡献2039条经验 获得超7个赞

您可以设置可见行的最小数量,JTable以使其适合您想要的表单布局。但是,有时实际的表格内容小于此最小值,然后表格下方的JScrollPane边界内会出现一个空白区域。此空白空间不属于,JTable但是您可能需要它才能显示弹出窗口(例如,带有“创建新行...”项的弹出窗口)。请注意,我已经提到了我不记得是否Mouselistener必须将其添加到JScrollPane或中JViewport,但是除了JTable自身之外,我还需要将其添加到其他位置。

查看完整回答
反对 回复 2019-12-04
  • 3 回答
  • 0 关注
  • 530 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信