右键单击多项选择和JPopupMenu

时间:2012-01-03 15:25:50

标签: java swing popup jtable selectionmodel

我遇到JTable上的弹出菜单问题,以及这个JTable允许多个间隔选择的事实。 我将详细解释我的情况,希望尽可能清楚。

我有一个基本数据类,我们称之为Item,带有字符串id(名称)和两个布尔字段onlineactive(带有相对的getter)。
JTable背后的想法是,对于数据集中的每个项目,它将在第一列中显示其名称,在第二列中显示其状态,其中“status”我的意思是,它将显示“ACTIVE / NOT ACTIVE”如果项目在线,否则将显示“离线”。 我已经实现了一个可以完成工作的TableModel。它可以工作。

我还想要,当用户右键单击一行时,会出现一个弹出窗口(如果所选项目处于联机状态),允许激活/取消激活该项目,具体取决于其状态。 只要选择模型是单一选择,这种方法就完美无缺,但是当我将其改为多个间隔选择时,我再也无法正常工作了。

我想要的行为是,在右键单击时,会出现一个弹出窗口,其中执行单击,行将添加到选择并突出显示,所有以前选择的行保持选中状态!这是我无法做到的!

以下是我在MouseListener中的代码:

tblModel.addMouseListener(new MouseAdapter() {
    void showPopup(MouseEvent e){
            int r = tblModel.rowAtPoint(e.getPoint());
            if (r >= 0 && r < tblModel.getRowCount()) {
                    //tblModel.setRowSelectionInterval(r, r);
                } else {
                    tblModel.clearSelection();
                }   
            int[] viewRowIndexes = tblModel.getSelectedRows();          
            int rowViewIndex = tblModel.getSelectedRow();

            if (rowViewIndex < 0)
                return;

            int rowModelIndex = tblModel.convertRowIndexToModel(rowViewIndex);
            if (e.isPopupTrigger() && e.getComponent() instanceof JTable) {
                Action changeActiveAction;
                Action changeInactiveAction;
                List<String> actives = new ArrayList<String>();
                List<String> inactives = new ArrayList<String>();
                DefaultListSelectionModel selectionModel = (DefaultListSelectionModel) tblModel.getSelectionModel();

                for (int viewRowIndex : viewRowIndexes) {
                    int modelRowIndex = tblModel.convertRowIndexToModel(viewRowIndex);
                    if (selectionModel.isSelectedIndex(viewRowIndex)) {
                        boolean online = ((MyTableModel) tblModel.getModel()).isItemOnline(modelRowIndex);
                        if (!online)
                            continue;

                        boolean active = ((MyTableModel) tblModel.getModel()).isItemActive(modelRowIndex);
                        String idItem = (String) ((MyTableModel) tblModel.getModel()).getValueAt(modelRowIndex,0);
                        if (active) {
                            actives.add(idItem);
                        } else {
                            inactives.add(idItem);
                        }
                    }
                }

                if (actives.size() > 0 || inactives.size() > 0) {
                    popup = new JPopupMenu();
                    if (actives.size() > 0) {
                        changeActiveAction = new ChangeAction("Deactivate ACTIVE Items","This will deactivate all the selected ACTIVE items",actives, false);
                        popup.add(new JMenuItem(changeActiveAction));
                    }
                    if (inactives.size() > 0) {
                        changeInactiveAction = new ChangeAction("Activate INACTIVE Items","This will activate all the selected INACTIVE items",inactives, true);
                        popup.add(new JMenuItem(changeInactiveAction));
                    }
                    popup.show(e.getComponent(), e.getX(),e.getY());
                }
            }
    }
    @Override
    public void mousePressed(MouseEvent e) {
        showPopup(e);
    }

    @Override   
    public void mouseReleased(MouseEvent e) {   
        showPopup(e);   
    }
};

行为在功能上是正确的,但行的选择不起作用。 评论了这一行

//tblModel.setRowSelectionInterval(r, r);

当我右键单击一行时,会出现一个弹出窗口,但它会忽略我点击的行。

另一方面,如果取消注释,该行将仅选择所单击的行,从而丢失所有剩余的选择....

我很抱歉这篇长篇文章,但我不知道如何解释我的问题而不提供我的情况的所有细节.... 希望这是一件微不足道的事情,你可以告诉我如何修复/改变它。

提前谢谢。

1 个答案:

答案 0 :(得分:3)

答案的一部分是:

if (tblModel.isSelectedIndex(r)) {
   tblModel.removeSelectionInterval(r, r);
} else {
   tblModel.addSelectionInterval(r, r);
}