Java Swing JTable -排序后得到正确的rowindex



我遇到了Java中的一个问题。显示问题的图片

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

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

这工作,但我得到的问题是,当:

  1. 用户选中多个复选框,
  2. 然后排序表
  3. 然后尝试选中几乎所有的复选框

将导致如图所示的列的混乱。

在我的示例图片中,你可以看到另外的2列:列行,这是在开始时给出的,其中表没有排序和列rowindextommodel,它显示了行的位置,但转换为向量内的行,好吧,我认为,但似乎不是这样。

下面是示例类:

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代码,这样你就可以自己复制粘贴代码来查看问题了

我发现我的例子显示假值,因为:

当我用

转换行时
tbl.convertRowIndexToModel(row);

我得到错误的行索引。

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