首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用JPopupMenu的JTable

使用JPopupMenu的JTable
EN

Stack Overflow用户
提问于 2011-09-15 06:02:57
回答 2查看 13.6K关注 0票数 10

如何防止仅当在选定的JPopupMenu上使用Mouse Cursor时才触发和显示JTable'Row

我的问题是:如果有另一种方法作为getBounds从选定的行,并确定/比较它与Mouse位置...

我的简单sscce演示了不想要的相反状态,可以选择任何行,并且从整个JTable触发JPopupMenu

代码语言:javascript
复制
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);
            }
        });
    }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-09-15 16:16:01

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

众所周知,注册popupMenus的推荐方式是使用componentPopupMenu属性。相关接口为

代码语言:javascript
复制
 void setComponentPopupMenu(JPopupMenu);
 JPopupMenu getComponentPopupMenu();
 Point getPopupLocation(MouseEvent);

缺少的(也是这个需求实际需要的)是

代码语言:javascript
复制
JPopupMenu getComponentPopupMenu(MouseEvent);

这种缺失更让人恼火,因为getPopupLocation是在getComponentPopup()之后调用的(由LAF中的AWTEventHelper调用)。因此,对于类似于存储可能触发弹出窗口的最后一个鼠标事件,然后再决定返回哪一个/是否返回弹出窗口这样的黑客行为,是没有回旋余地的。,并且为该位置返回null只会导致在鼠标位置显示该位置。

唯一的(肮脏的)技巧(除了我非常不愿意使用MouseListener ;-)是覆盖getComponentPopup,并根据当前鼠标位置决定是否返回它

代码语言:javascript
复制
    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();
        }

    };

副作用是,只要鼠标位于桌面上方,弹出窗口就不会被键盘触发,这可能是个问题,也可能不是问题。

票数 8
EN

Stack Overflow用户

发布于 2011-09-15 06:16:04

你是在找这样的东西吗?

仅在选定行上显示弹出窗口

代码语言:javascript
复制
  private void maybeShowPopup(MouseEvent e) {
     if (e.isPopupTrigger()) {

        // get row that pointer is over
        int row = table.rowAtPoint(e.getPoint());

        // if pointer is over a selected row, show popup
        if (table.isRowSelected(row)) {
           popup.show(e.getComponent(), e.getX(), e.getY());
        }
     }
  }

反之亦然,以防止弹出窗口仅显示在选定的行上:

代码语言:javascript
复制
  private void maybeShowPopup(MouseEvent e) {
     if (e.isPopupTrigger()) {
        int row = table.rowAtPoint(e.getPoint());
        int[] selectedRows = table.getSelectedRows();

        if (!table.isRowSelected(row)) {
           popup.show(e.getComponent(), e.getX(), e.getY());
        }
     }
票数 12
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7423533

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档