当前位置: 首页 > 知识库问答 >
问题:

插入后对JTable保存的数据进行排序

唐弘益
2023-03-14

我从数据库中填充JTableJTable中的数据根据自动生成的主键按降序排序。该表如下所示。

表中的数据由一个列表保存,该列表包含JPA实体的对象列表-list

因为我显示的数据降序由国ID(主键),列表需要排序降序国ID数据插入后和FireTableRowsInserted(size, size)方法执行之前。

在按Country Id降序对该列表进行排序后,该表看起来不稳定,如下所示。

当按下给定的添加按钮时,通过给定文本字段的值在验证后提交。

该行被添加到数据库和列表中,列表也按上述方式排序,但表中的数据并不像列表中那样显示。

请参阅前面快照中的最后两行。不显示实际创建的行。最后一行被复制,这与添加新对象和排序列表的基础列表不同。

我的AbstractTableModel如下所示。

package admin.model;

import entity.Country;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import javax.swing.table.AbstractTableModel;

public final class CountryAbstractTableModel extends AbstractTableModel
{
    private List<Country> countries;
    private List<String> columnNames;

    public CountryAbstractTableModel(List<Country> countries)
    {
        this.countries = countries;
        columnNames=getTableColumnNames();
    }

    //This is the method which sorts the list after adding a JPA entity object.

    public void add(Country country)
    {
        int size = countries.size();
        countries.add(country);

        Comparator<Country> comparator = new Comparator<Country>()
        {
            @Override
            public int compare(Country o1, Country o2)
            {
                return o2.getCountryId().compareTo(o1.getCountryId());
            }
        };

        Collections.sort(countries, comparator);
        fireTableRowsInserted(size, size);
    }


    @Override
    public String getColumnName(int column)
    {
        return columnNames.get(column);
    }

    @Override
    public Class<?> getColumnClass(int columnIndex)
    {
        switch (columnIndex)
        {
            case 0:
                return String.class;
            case 1:
                return String.class;
            case 2:
                return String.class;
            case 3:
                return String.class;
            default:
                return String.class;
        }
    }

    private List<String> getTableColumnNames()
    {
        List<String> names = new ArrayList<>();
        names.add("Index");
        names.add("Id");
        names.add("Country Name");
        names.add("Country Code");

        return names;
    }


    @Override
    public int getRowCount()
    {
        return countries.size();
    }

    @Override
    public int getColumnCount()
    {
        return 4;
    }

    public void remove(List<Long>list)
    {
        Iterator<Country> iterator = countries.iterator();
        while(iterator.hasNext())
        {
            Country country = iterator.next();
            Iterator<Long> it = list.iterator();

            while(it.hasNext())
            {
                if(country.getCountryId().equals(it.next()))
                {
                    iterator.remove();
                    int index = countries.indexOf(country);
                    fireTableRowsDeleted(index, index);
                    break;
                }
            }
        }
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex)
    {
        Country country = countries.get(rowIndex);
        switch (columnIndex)
        {
            case 0:
                return rowIndex+1;
            case 1:
                return country.getCountryId();
            case 2:
                return country.getCountryName();
            case 3:
                return country.getCountryCode();
        }
        return "";
    }

    @Override
    public void setValueAt(Object value, int rowIndex, int columnIndex)
    {
        Country country = countries.get(rowIndex);

        if(value instanceof String)
        {
            String stringValue = value.toString();
            switch(columnIndex)
            {
                case 2:
                    country.setCountryName(stringValue);
                    break;
                case 3:
                    country.setCountryCode(stringValue);
                    break;
            }
        }
        fireTableCellUpdated(rowIndex, columnIndex);
    }

    @Override
    public boolean isCellEditable(int rowIndex, int columnIndex)
    {
        return columnIndex>1?true:false;
    }
}

如果我删除给定的比较器,如代码片段中的add()方法(即排序未完成),则表将按照应该的方式更新,在表的末尾使用新创建的行(它应该在桌子的顶部。因此排序是必要的)。

为什么在对基础列表进行排序时会发生这种情况?(同样,这不会发生,当列表未排序时,它将保持不变。)


共有1个答案

后凯捷
2023-03-14

发生这种情况的原因是,您告诉模型已在“大小”位置(即列表中的最后一个位置)添加了一个元素,但由于您正在对列表进行排序,它实际上位于模型中的位置0(在本例中)。

解决这个问题的最简单方法可能是调用FireTableDataChanged(),而不用担心索引——我认为你的表必须很大才能导致性能问题。否则,您可以使用list.indexOf()找出排序后新元素的最终位置,并使用正确的索引调用FireTableRowsInserted()。

 类似资料:
  • 我有下表,目前我可以更新用户对象来添加或删除角色,但我不能在创建新用户时向其添加角色(用户的角色添加到UI上的同一表单上),因为中间表User_Role希望用户的ID为Obj,所以在插入时,我自然得到一个User.user_id=?。 有什么常见的方法可以解决这个问题吗?我在考虑也许尝试在保存后获取插入用户的ID,然后调用更新函数。我不想这样做,因为我担心性能,特别是在未来可能发生批量上传的时候。

  • 问题内容: 我正在尝试将JTable中的多行数据保存到数据库中,这是我的代码供参考: 问题是,它仅将一行数据插入数据库。有人可以帮帮我吗?:( 谢谢! 问题答案: 从循环中删除以下行代码并将其放置在循环之前 示例: 用以下代码替换您的代码 然后运行它认为它起作用。 对于批量插入示例,请参见https://my.vertica.com/docs/5.0/HTML/Master/14878.htm

  • 问题内容: 我有一个JTable的第一行为空白。现在,当我通过单击列对表进行排序时,空白行位于底部。如果我在空白行中插入内容并进行排序,则该行将相应放置。即使已排序,如何跟踪其行索引。我需要访问该行,但是如果用户进行排序,那么我将失去行索引,因为它不再是第一行。 问题答案: 您所使用的假设Java 6中新增的东西,我认为你需要看看是什么方法和在类。你会做类似的事情 从模型中找出哪个可见行索引实际上

  • 我正在通过Java查询一个MySQL数据库,从结果集中提取数据并将其放入DefaultTableModel,该Model被放入JTable,然后被放入JScrollPane中显示。 以下是该类的源代码:

  • 问题内容: 有没有办法以编程方式对JTable进行排序? 我的JTable排序工作正常(使用setRowSorter),以便当用户按任意列时,表将被排序。 我知道,SWingX JXTable可能可以工作,但我不想麻烦,因为其他所有事情现在都可以正常工作,而且我不知道NetBeans的可视化编辑器如何处理JXTable等。 编辑: 选定的答案是指我的声明(现已删除),该声明对Sun的页面的答案不起

  • 问题内容: 我有一个JTable,其属性AutoCreateRowSorter设置为true。单击时效果很好,但如果单击时仅将鼠标移动1px,则不会出现排序,这在某些情况下不舒服。如何解决这个问题? UPD我只想在释放鼠标时显示排序。 问题答案: 肮脏的方法(请阅读: 如果您不是绝对地绝望,请确切地知道自己在做什么!请不要这样做 ),方法是挂接到uiDelegate安装的MouseListener