【问题标题】:Java Swing JTable - get right rowindex after sortJava Swing JTable - 排序后获得正确的rowindex
【发布时间】:2017-04-01 15:02:07
【问题描述】:

我在 Java 中遇到了一个问题。 Image showing the Problem

问题是: 我有一个带有 2 列的 JTable(在图 4 中用于测试目的):一个是复选框,第二个是字符串。 每当用户选中复选框时,位置列都会向上计数,因此第一个选中的复选框将获得位置“1”,第二个选中的复选框将获得位置“2”,依此类推。

当用户签出一个复选框时,假设 10 个项目中的位置为 5,位置为 6 及以上的行将向下计数,而位置为 5 的单元格将设置为空字符串("")。

这可行,但我遇到的问题是:

  1. 用户选中多个复选框,
  2. 然后对表格进行排序
  3. 然后尝试检查几乎所有复选框

这将导致如图所示的列搞砸。

在我的示例图片中,您还可以看到另外 2 列: 列行,在开始时给出,表未排序 和 Column RowIndexToModel,它显示了行的位置,但转换为向量内的行,我是这么认为的,但似乎不是这样。

这是示例类

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

@SuppressWarnings("serial")
public class Example extends JFrame {
    private JTable tbl;

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                Example frame = new Example();
                frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
                frame.pack();
                frame.setVisible(true);
            }
        });
    }
    public Example() {
        Object[] colNames = {"Checkbox", "Position"};
        Object[][] rows = {{false, ""}, {false, ""},{false, ""},{false, ""},{false, ""},{false, ""},{false, ""}};
        DefaultTableModel model = new DefaultTableModel(rows, colNames);
        getContentPane().setLayout(new GridBagLayout());

        tbl = new JTable(model)
        {
            @Override
            public Class getColumnClass(int column) {
                switch (column) {
                    case 0:
                        return Boolean.class;
                    case 1:
                        return String.class;
                    default:
                        return String.class;
                }
            }
        };
        tbl.setAutoCreateRowSorter(true);
        tbl.getModel().addTableModelListener(new TableModelListener() {
            @Override
            public void tableChanged(TableModelEvent e) {
                int row = e.getFirstRow();
                row = tbl.convertRowIndexToModel(row);
                if (e.getColumn() == 0) {
                    TableModel model = (TableModel) e.getSource();
                    Boolean checked = (Boolean) model.getValueAt(row, 0);//getting if boolean got checked or not
                    if (checked) {
                        int maxCount = 0;
                        for (int i = 0; i < model.getRowCount(); i++) {
                            String curValue = (String)model.getValueAt(i, 1);
                            if(curValue != null && !curValue.equals("") && Integer.valueOf(curValue) > maxCount)
                                maxCount = Integer.valueOf(curValue); //get highest number in tbl
                        }
                        maxCount++;
                        model.setValueAt(String.valueOf(maxCount),row, 1); //set highest number + 1
                    } else {
                        String columnString = (String)model.getValueAt(row, 1); //getting position
                        int tmpPos = Integer.valueOf(columnString);

                        for (int index = 0; index < model.getRowCount(); index++) {
                            int indexSorted = tbl.convertRowIndexToModel(index);
                            String curValue = (String)model.getValueAt(indexSorted, 1);
                            //get if current number is higher than unchecked value
                            if (curValue != null && !curValue.equals("") && Integer.valueOf(curValue) > tmpPos) {
                                int curValueToChange = Integer.valueOf(curValue) - 1;
                                model.setValueAt(String.valueOf(curValueToChange),indexSorted, 1); 
                            }
                        }
                        model.setValueAt("",row, 1); 
                    }
                }
            }
        });
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.fill = GridBagConstraints.BOTH;
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.weightx = 1;
        gbc.weighty = 1;
        JScrollPane scrollPane = new JScrollPane(tbl);
        getContentPane().add(scrollPane, gbc);
    }
}

PS:代码是为这个示例编写的,所以请不要怀疑它不遵循一般的编码标准。对不起,如果我的代码让你的眼睛流血。 ;)

感谢您的帮助!

编辑:我试图构建我的问题以便更好地概述问题并使代码更易于阅读(我认为),如果难以理解,抱歉,如果有问题我会尝试回答。

EDIT2:添加了一个简单 JFrame 的代码,以便您可以复制和粘贴代码以自己查看问题

【问题讨论】:

  • 如需尽快获得更好的帮助,请发帖minimal reproducible exampleShort, Self Contained, Correct Example
  • 请重新阅读@AndrewThompson 在他的评论中给你的重要链接,因为我认为你可能错过了在那里找到的最重要的点。为了获得最佳帮助,您需要发布一个小型可编译和可运行 程序。这些代码足够小,可以将其作为代码格式的文本完整地发布在此处,这些代码我们可以复制到我们的 IDE 中,可以编译,可以为我们运行,并且可以为我们演示您的问题。
  • 补充@HovercraftFullOfEels 的建议。如果一个 MCVE/SSCCE 有 200 行代码,所有这些都是为了使它能够干净地编译并运行来演示问题,那么它就是 IMO 一个 MCVE/SSCCE。单词最小/简短开始这些描述的唯一原因是人们经常留下大量与问题无关的代码区域。通常删除不必要的代码会间接导致提出问题的人自己发现问题。但是,如果代码在没有明确问题的情况下被磨练到最小/简短 - 最重要的部分就是......
  • .. 如相应短语的 rest 中所述。让它成为我们都可以复制、粘贴、运行并实际看到问题的代码,而无需任何进一步的更改或添加。如果您在这两个链接中读到的任何内容对您来说不清楚,请不要害怕问。我们中的任何一个人,以及其他许多人,都可以进一步解释。
  • @AndrewThompson 谢谢你所做的一切,我发现我的问题是我误解了“convertRowIndexToModel”,没有它,它可以正常工作。

标签: java swing sorting checkbox jtable


【解决方案1】:

我发现我的示例显示错误值,因为:

当我用

转换行时
tbl.convertRowIndexToModel(row);

我得到了错误的行索引。

在我删除了转换行索引的 2 行后,我得到了正确的值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-31
    相关资源
    最近更新 更多