Java CustomTableModel无法正确排序

时间:2015-08-18 11:15:48

标签: java sorting jtable

我将项目添加到链接到表格的模型中。当我在此表中选择一个项目时,会发生一些事情,具体取决于它是什么项目。现在我只有一个System.out告诉我项目名称。

如果我有两个名为' A'和' B'当我选择他们各自的名字时会按预期写入控制台,但是,如果我按名称对它们进行排序,那么' B'排在' A'的排中,排序从未在内部发生,但只是在视觉上。因此,如果我现在选择' A',控制台会打印出' B'反之亦然。

分类器在mainclass中声明,itemList是JTable itemList.setAutoCreateRowSorter(true);

显然,我必须未能包含此分拣机功能所需的一些默认方法。 "默认方法"在代码片段中,在方法' 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);
    }
}

*回答* 问题从来不是tablemodel,而是JTable本身。当我想根据所选项目提供信息时,我打电话给

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一样。

1 个答案:

答案 0 :(得分:1)

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