Java CustomTableModel 无法正确排序

Java CustomTableModel can't sort properly

我将项目添加到链接到 table 的模型中。当我 select 这个 table 中的一个项目时,事情的发生取决于它是什么项目。现在我只有 System.out 告诉我项目名称。

如果我有两个名为 'A' 和 'B' 的项目,当我 select 它们各自的名称按预期写入控制台时,但是,如果我按名称对它们进行排序, 因此 'B' 被放置在 'A' 上方的行中,排序从未在内部发生,而只是在视觉上发生。所以如果我现在 select 'A',控制台打印出 'B',反之亦然。

排序器在主类中声明,itemList是一个JTableitemList.setAutoCreateRowSorter(true);

显然,我一定没有包含此排序器功能所需的一些默认方法。 "default methods" 在代码片段的末尾声明,从方法 'getColumnName'.

开始和之后
class ItemModel extends AbstractTableModel
{
    ArrayList<MCItem> items = new ArrayList<MCItem>();
    private int currentMaxRows = 0;
    private String[] columnNames = {"Item", "Total Units", "In Sorter"};
    private Class[] types = {String.class, Integer.class, Integer.class};
    private Object[][] data = new Object[currentMaxRows][getColumnCount()];

    public ArrayList<MCItem> getItems()
    {
        return items;
    }
    public void readdItems(Main m, ArrayList<MCItem> tempItems)
    {
        for(MCItem mci : tempItems)
        {
            mci.setMain(m);
            addRow(mci);
        }
    }
    public void emptyMe()
    {
        currentMaxRows = 0;
        items.clear();
        data = new Object[currentMaxRows][getColumnCount()];
        fireTableDataChanged();
    }
    public boolean isDuplicate(String s)
    {
        for(MCItem ci : items)
            if(ci.getName().equalsIgnoreCase(s))
                return true;
        return false;
    }
    public void updateItem(String id)
    {
        try
        {
            int foundRow = -1;
            for(int i = 0;i < currentMaxRows;i++)
                if(getValueAt(i, 0).toString().equalsIgnoreCase(id))
                {
                    foundRow = i;
                    break;
                }
            for(MCItem ii : items)
                if(ii.getName().equalsIgnoreCase(id))
                {
                    setItem(foundRow, ii);
                    fireTableDataChanged();
                    return;
                }
        }
        catch(NullPointerException e){}
    }
    public void addRow(MCItem item)
    {
        //check if we need to expand the dataArray
        if(currentMaxRows == items.size())
        {
            if(currentMaxRows == 0)
                data = new Object[++currentMaxRows][getColumnCount()];
            else
            {
                Object[][] tempArr = data;
                data = new Object[++currentMaxRows][getColumnCount()];

                for(int x = 0; x < tempArr.length; x++)
                    for(int y = 0; y < getColumnCount(); y++)
                        data[x][y] = tempArr[x][y];
            }
        }
        setItem(items.size(), item);
        items.add(item);
        fireTableDataChanged();
    }
    public void changeItem(int row, String name)
    {
        String originalName = (String) data[row][0];
        data[row][0] = name;
        for(MCItem ii : items)
            if(ii.getName().toString().equalsIgnoreCase(originalName))
            {
                ii.setName(name);
                return;
            }
        fireTableDataChanged();
    }
    public void removeItem(String id)
    {
        for(MCItem ii : items)
            if(ii.getName().toString().equalsIgnoreCase(id))
            {
                items.remove(ii);
                redoList();
                return;
            }
        fireTableDataChanged();
    }
    private void redoList()
    {
        ArrayList<MCItem> tempArr = (ArrayList<MCItem>) items.clone();
        emptyMe();
        for(MCItem ii : tempArr)
            addRow(ii);
    }
    private void setItem(int row, MCItem item)
    {
        int counter = 0;
        data[row][counter++] = item.getName();
        data[row][counter++] = item.getCount();
        data[row][counter++] = item.getSorterCount();
        fireTableDataChanged();
    }
    MCItem getMCItem(String name)
    {
        for(MCItem i : items)
            if(i.getName().equals(name))
                return i;
        return null;
    }
    public String getColumnName(int col)
    {
        return columnNames[col].toString();
    }
    public int getRowCount() 
    {
        return data.length;
    }
    public int getColumnCount() 
    {
        return columnNames.length;
    }
    public Object getValueAt(int row, int col) 
    {
        return data[row][col];
    }
    public Class getColumnClass(int columnIndex) 
    {
        return this.types[columnIndex];
    }
    public boolean isCellEditable(int row, int col)
    {
        return false;
    }
    public void setValueAt(Object value, int row, int col)
    {
        data[row][col] = value;
        fireTableCellUpdated(row, col);
    }
}

* 回答 * 问题从来都不是 table 模型,而是 JTable 本身。当我想根据 selected 项呈现信息时,我调用了

currentMCItem = model.getMCItem(model.getValueAt(itemList.getSelectedRow(), 0).toString()); 它正确地返回了 JTable 中的索引,但是当对所有索引进行排序时,所有的索引都被弄乱了,只有视图发生了变化,所以我不得不将该行重做为

currentMCItem = model.getMCItem(model.getValueAt(itemList.convertRowIndexToModel(itemList.getSelectedRow()), 0).toString());

因此,关键是调用 JTable.convertRowIndexToModel(SELECTED INDEX IN TABLE) 以获得正确的索引,并将其用作 selectedRow。

您在 JTable 中有一组转换方法需要使用。例如,convertColumnIndexToModel 获取一个视图索引并返回模型中相应的列索引。转换它们然后得到值。