简体   繁体   English

Java CustomTableModel无法正确排序

[英]Java CustomTableModel can't sort properly

I add items to a model that is linked to a table. 我将项目添加到链接到表的模型中。 When I select an item in this table, things happen depending on what item it is. 当我在此表中选择一个项目时,事情会根据它是什么而发生。 For now I just have a System.out telling me the items name. 现在,我只有一个System.out告诉我项目名称。

If I have two items called 'A' and 'B', when I select either their respective name is written to the console as expected, however, if I sort them by name, so that 'B' is placed in the row over 'A', the sorting never happened internally but only visually. 如果我有两个名为“ A”和“ B”的项目,则当我选择将它们各自的名称按预期方式写入控制台时,但是,如果我按名称对它们进行排序,则将“ B”放在“ A',排序从未在内部发生过,而是在视觉上发生过。 So if I now select 'A', the console prints out 'B', and vice versa. 因此,如果我现在选择“ A”,则控制台将打印出“ B”,反之亦然。

The sorter is declared in the mainclass, itemList is a JTable itemList.setAutoCreateRowSorter(true); 排序器在主类中声明,itemList是一个JTable itemList.setAutoCreateRowSorter(true);

Apparently I must have failed to include some default method that's needed for this sorterfunctionality. 显然,我必须未能包括此排序功能所需的一些默认方法。 "default methods" is declared towards the end in the code-snippet, from and after the method 'getColumnName'. 在“代码段”的结尾处,从“ 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);
    }
}

* Answer * The issue was never the tablemodel, but the JTable itself. *答案*问题从来不是表模型,而是JTable本身。 When I want to present information based on the item selected, I called 当我想根据所选项目显示信息时,我打电话给

currentMCItem = model.getMCItem(model.getValueAt(itemList.getSelectedRow(), 0).toString()); which returned the index in the JTable correctly, however when sorting all the indexes gets messed up and it's only the view that changes, so I had to redo that line to 正确返回了JTable中的索引,但是在对所有索引进行排序时,都弄糟了,并且只有视图改变了,因此我不得不将该行重做为

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

So, the key is to call JTable.convertRowIndexToModel(SELECTED INDEX IN TABLE) in order to get the correct index, and use that as if it was the selectedRow. 因此,关键是调用JTable.convertRowIndexToModel(SELECTED INDEX IN TABLE)以获取正确的索引,并像使用selectedRow一样使用它。

You have a set of convert methods in JTable that you need to use. 您需要在JTable中使用一组转换方法。 For example, convertColumnIndexToModel takes a view index and gives you back a corresponding column index in the model. 例如, convertColumnIndexToModel获取视图索引,并为您提供模型中的相应列索引。 Convert them and then get the values. 转换它们,然后获取值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM