1

データベースからデータを入力しJTableます。のデータはJTable、自動生成された主キーに基づいて降順に並べ替えられます。表は次のようになります

ここに画像の説明を入力

テーブル内のデータは、JPA エンティティーのオブジェクトのリストを含むリストによって保持されますList<Country>

(主キー)で降順にデータを表示するので、データが挿入された後、メソッドが実行される前countryIdに、リストを降順でソートする必要があります。countryIdfireTableRowsInserted(size, size)

このリストを で降順にソートするcountryIdと、表は次のように不安定に見えます

ここに画像の説明を入力

指定された追加ボタンが押されると、指定されたテキスト フィールドの値が検証後に送信されます。

行はデータベースとリストに追加され、リストも前述のようにソートされますが、テーブル内のデータはリストにあるため表示されません。

前のスナップショットの最後の 2 行を参照してください。作成された実際の行は表示されません。代わりに最後の行が複製されます。これは、新しいオブジェクトが追加され、リストもソートされた基になるリストとは異なります。


私の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;
    }
}

Comparatorコードスニペットのメソッドで指定された asを削除するとadd()(つまり、並べ替えが行われない)、テーブルの最後に新しく作成された行 (テーブルの一番上にある必要があります) でテーブルが更新されます。 . したがって、ソートが必要です)。

基礎となるリストがソートされていると、なぜこれが起こるのですか? (これも起こりません。リストがソートされていない場合は、そのまま残ります。)

4

1 に答える 1

2

これは、要素が位置 'size' (つまり、リストの最後の位置) に追加されたことをモデルに伝えているために発生していますが、リストを並べ替えているため、実際にはモデルの位置 0 にあります (この例では)。 .

おそらくこれを修正する最も簡単な方法は、 fireTableDataChanged() を呼び出すことであり、インデックスを気にする必要はありません.パフォーマンスの問題を引き起こすには、テーブルがかなり大きくなければならないと思います. それ以外の場合は、 list.indexOf() を使用して、並べ替え後に新しい要素がどこにあるのかを調べ、正しいインデックスで fireTableRowsInserted() を呼び出すことができます。

于 2013-09-14T21:32:02.540 に答える