当前位置: 首页 > 知识库问答 >
问题:

选择仅限于2行的JTable

司徒骞尧
2023-03-14

我想将JTable中的行选择限制为仅2行。如果用户尝试选择第三行(Ctrl单击),则应通过编程方式取消选择表中最早的选择。为了实现这一点,我在表中添加了一个ListSelectionListener。在下面的示例中,“clearSelection()”似乎不起作用。

如果有更简单或更优雅的方法来达到同样的效果,请给出建议。

package test;

import java.util.Arrays;
import java.util.Vector;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

public class JTableDemo {
    public static void main(String[] argv) {
        Vector rowData = new Vector();
        for (int i = 0; i < 10; i++) {
            Vector colData = new Vector(Arrays.asList("row" + (i + 1)));
            rowData.add(colData);
        }

        String[] columnNames = { "header" };

        Vector columnNamesV = new Vector(Arrays.asList(columnNames));

        JTable table = new JTable(rowData, columnNamesV);
        table.getSelectionModel().setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
        table.setColumnSelectionAllowed(false);
        SelectionListener listener = new SelectionListener(table);
        table.getSelectionModel().addListSelectionListener(listener);

        JFrame f = new JFrame();
        f.setSize(300, 300);
        f.add(new JScrollPane(table));
        f.setVisible(true);
    }

    private static class SelectionListener implements ListSelectionListener {
        JTable table;
        int prevSelectedRow;
        int oldSelectedRow = -1;

        SelectionListener(JTable table) {
            this.table = table;
        }

        public void valueChanged(ListSelectionEvent e) {

            if (e.getValueIsAdjusting()) {
                return;
            }
            if (e.getSource() == table.getSelectionModel() && table.getRowSelectionAllowed()) {

                int[] selectedRows = table.getSelectedRows();

                if (selectedRows.length == 1) {
                    prevSelectedRow = selectedRows[0];
                    return;
                }

                if (selectedRows.length > 1) {
                    int currentSelectedRow = -1;
                    System.out.println("The first and last indexes are : " + e.getFirstIndex() + ", " + e.getLastIndex());

                    if (oldSelectedRow == -1) {
                        for (int i = 0; i < selectedRows.length; i++) {
                            if (prevSelectedRow != selectedRows[i]) {
                                currentSelectedRow = selectedRows[i];
                                break;
                            }
                        }
                        table.getSelectionModel().removeListSelectionListener(this);
                        table.clearSelection();
                        table.setRowSelectionInterval(prevSelectedRow, prevSelectedRow);
                        oldSelectedRow = prevSelectedRow;
                        prevSelectedRow = currentSelectedRow;
                        table.addRowSelectionInterval(currentSelectedRow, currentSelectedRow);
                        table.getSelectionModel().addListSelectionListener(this);
                    } else {
                        for (int i = 0; i < selectedRows.length; i++) {
                            if (prevSelectedRow != selectedRows[i] && oldSelectedRow != selectedRows[i]) {
                                currentSelectedRow = selectedRows[i];
                                break;
                            }
                        }

                        table.getSelectionModel().removeListSelectionListener(this);
                        table.clearSelection();
                        table.setRowSelectionInterval(prevSelectedRow, prevSelectedRow);
                        oldSelectedRow = prevSelectedRow;
                        prevSelectedRow = currentSelectedRow;
                        table.addRowSelectionInterval(currentSelectedRow, currentSelectedRow);
                        table.getSelectionModel().addListSelectionListener(this);
                    }

                }

            }

        }
    }
}

共有2个答案

苗征
2023-03-14

谢谢你的回复。我试图覆盖"addSseltionInterval(...)"方法,但无法解决我的问题。

我没有使用clear选择(),而是使用了删除RowSseltionInterval(...),这看起来像预期的那样工作。

...
if (selectedRows.length > 1) {
    int currentSelectedRow = -1;
    System.out.println("The first and last indexes are : " + e.getFirstIndex() + ", " + e.getLastIndex());

    if (oldSelectedRow == -1) {
        for (int i = 0; i < selectedRows.length; i++) {
            if (prevSelectedRow != selectedRows[i]) {
                currentSelectedRow = selectedRows[i];
                break;
            }
        }
        table.getSelectionModel().removeListSelectionListener(this);
        //table.clearSelection();
        table.setRowSelectionInterval(prevSelectedRow, prevSelectedRow);
        oldSelectedRow = prevSelectedRow;
        prevSelectedRow = currentSelectedRow;
        table.addRowSelectionInterval(currentSelectedRow, currentSelectedRow);
        table.getSelectionModel().addListSelectionListener(this);
    } else {
        for (int i = 0; i < selectedRows.length; i++) {
            if (prevSelectedRow != selectedRows[i] && oldSelectedRow != selectedRows[i]) {
                currentSelectedRow = selectedRows[i];
                break;
            }
        }

        table.getSelectionModel().removeListSelectionListener(this);
        //table.clearSelection();
        table.removeRowSelectionInterval(oldSelectedRow, oldSelectedRow);
        table.setRowSelectionInterval(prevSelectedRow, prevSelectedRow);
        oldSelectedRow = prevSelectedRow;
        prevSelectedRow = currentSelectedRow;
        table.addRowSelectionInterval(currentSelectedRow, currentSelectedRow);
        table.getSelectionModel().addListSelectionListener(this);
    }
}
...
梁渊
2023-03-14

如果有更简单或更优雅的方法来达到同样的效果,请给出建议。

您可以扩展DefaultListSseltionModel并覆盖addSseltionInterval(...)方法,然后将自定义选择模型添加到表中。

 类似资料:
  • 问题内容: 我有一个将两个选择子句与UNION结合使用的查询。我只想选择第一行。我如何使用Union来做到这一点? 问题答案:

  • 问题内容: 我想使用第二列(art_count)仅显示那些包含总art_count的X%的行。 我的资料: 到目前为止我的查询: 使用SUM进行了尝试,但未成功。 问题答案: 您需要为插入一个值

  • 问题内容: 嘿,我在PostgreSql中有2个表: 和一些数据: 文件: 更新: 因此,所有更新都指向同一文档,但是所有更新的日期都不同。 我想做的是从文档表中进行选择,但还要包括基于日期的最新更新。 这样的查询应如何显示?这是我目前拥有的,但我列出的是所有更新,而不是我需要的最新更新: 包括; 我在查询中需要这个的原因是我想按更新模板中的日期排序! 编辑:此脚本已大大简化,因此我应该能够创建一

  • 问题内容: 我有下表,其中包含两个字段,即a和b,如下所示: 插入一些记录: 注意 :现在我要向员工显示唯一且仅属于部门和部门的员工。因此,根据条件,只应显示雇员,因为他仅属于部门和部门。但是员工不应因为属于而出现。 预期结果 : 如果条件为:,则结果应为: 如果条件为:,则结果应为: 如果条件是:,并且随后的结果应该是: 注意 :我只想在子句中执行此操作(不想使用and子句),因为我还将在另一个

  • 我正在使用日历视图来选择产品交付日期。我想在日历视图中仅显示当前日期的一个完整月份? 比如说: 今天的日期:2019年4月4日-日历视图应仅显示至2019年5月31日,不应显示上个月。 另一个例子:如果今天的日期是:2019年8月15日——日历视图应该只显示到2019年9月30日,而不应该显示上个月。 这可能吗?如果是这样的话,当我点击箭头时,如何显示默认日历视图是显示所有年份的正负?

  • 我试图用vba做一个按钮来删除Excel表中的一行,但当我按下按钮并选择不止一行或许多单元格时,我想限制从E到I的选择(和行的数量无关)这里是我的代码,非常感谢,希望你能帮助我,我还没有找到任何类似的东西。