0

JTableインスタンスの行の選択に問題があります。

これが私が
やりたいことです。行に同じデータを持つ2つの等しいテーブルが必要です。最初のテーブルの行、たとえば3番目の行を選択するとき、2番目のテーブルの3番目の行も自動的に選択されるようにします。ListSelectionListener選択した値を保持するだけのクラスを更新するをJTableに追加することで、これを解決しました。次に、そのクラスは、最初から選択された値で他のJTableをトリガーします。

私の問題は次
のとおりです。 ユーザーがテーブルの1つで行を並べ替えると、問題が発生します。次に、ビューは変更されますが、モデル内の基になるオブジェクトは変更されません。これは、以前と同じ順序です。

アプリケーションを起動すると、テーブルが次のようになっているとしましょう。

Column_1_header_in_table_1            Column_1_header_in_table_2
   Peter                                    Peter  
   John                                     John
   Steve                                    Steve

(Peterである)の最初の行を選択するとき、table 1Peterを含む行が選択され、その上table 2に最初の行もあります。
しかし、列ヘッダーを押して列table 1を並べ替えると、そのテーブルのビューは次のように変わります。

Column_1_header_in_table_1            Column_1_header_in_table_2
   John                                     Peter  
   Steve                                    John
   Peter                                    Steve 

ここで、の最初のtable 1(つまり、ジョン)を選択すると、の最初の行table 2(つまり、ピーター)が選択されます。ただし、で同じ名前の行をtable 1選択する必要があります。table 2これは、の行2table 2です。

この問題に取り組むために使用できるアプローチはありますか?


編集

わかりました、私はエディターなしで書いた以下のコードで私の解決策を説明しようとします、それで私はいくつかのエラーを含むかもしれません。しかし、私はそれが今どのように機能するかを概念的に示したいだけです。まず、MyTableが実装するこのインターフェイスを実行しました。

public interface TableUpdater {
    public void updateTable(int age);
}

PersonH​​olderクラスは、最後に選択された値を保持し、最初から新しい値が選択されたときに他のテーブルをトリガーします。

public class PersonHolder {
    private static int age;
    private List<TableUpdater> tables = new ArrayList<>();

    public static void subscribe(TableUpdater table){
         tables.add(table);
    }


    public static void setValue(int value){
        age = value;
        for(TableUpdater table : tables) {
            table.updateTable(age);
        } 
    }
    public static int getValue(){
        return age;
    }
}

次に、テーブル自体があります。

public class MyTable extends JTable implements TableUpdater {
    public MyTable {
        table.getSelectionModel().addListSelectionListener(new MySelectionListener());
        PersonHolder.subscribe(this);
    }
...
     @Override
     public void updateTable(int age) {
           this.getSelectionModel().setSelectionInterval(age, age);
     }
     private class MySelectionListener implements ListSelectionListener {
           public void valueChanged(ListSelectionEvent e) {
               Person p = (Person)getValueAt(e.getLastIndex(), 0);
               PersonHolder.setValue(p.getAge());
           }
     }
}
4

1 に答える 1

5

次を使用する必要があります:javax.swing.JTable.convertRowIndexToModel(int)現在の選択インデックスをモデルインデックス値に変換してから、他のテーブルでモデルインデックスをビューインデックスに変換し直し、javax.swing.JTable.convertRowIndexToView(int)そのインデックスを選択された行として設定します(これは両方のテーブルのモデルを想定しています)は同じか同等です。それ以外の場合は、値に基づいてルックアップを行う必要があります)。

これが私が考えていることの例です(私は両方のJTableのbaseModelをシャッフルし、もう一方のJTableでインデックスルックアップを実行しました):

import java.awt.BorderLayout;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.AbstractTableModel;

public class TestSortedTable {

    class MyTableModel extends AbstractTableModel {

        private List<Person> baseModel;

        public MyTableModel(List<Person> baseModel) {
            super();
            this.baseModel = new ArrayList<Person>(baseModel);
        }

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

        @Override
        public String getColumnName(int column) {
            switch (column) {
            case 0:
                return "First Name";
            case 1:
                return "Last Name";
            }
            return null;
        }

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

        @Override
        public Object getValueAt(int rowIndex, int columnIndex) {
            switch (columnIndex) {
            case 0:
                return getPersonAtIndex(rowIndex).getFirstName();
            case 1:
                return getPersonAtIndex(rowIndex).getLastName();
            }
            return null;
        }

        public Person getPersonAtIndex(int rowIndex) {
            return baseModel.get(rowIndex);
        }

        public int getIndexOfPerson(Person person) {
            return baseModel.indexOf(person);
        }

    }

    protected void initUI() {
        List<Person> personModel = new ArrayList<TestSortedTable.Person>();
        personModel.add(new Person("John", "Smith"));
        personModel.add(new Person("Peter", "Donoghan"));
        personModel.add(new Person("Amy", "Peterson"));
        personModel.add(new Person("David", "Anderson"));
        JFrame frame = new JFrame(TestSortedTable.class.getSimpleName());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Collections.shuffle(personModel);
        final MyTableModel table1Model = new MyTableModel(personModel);
        final JTable table1 = new JTable(table1Model);
        table1.setAutoCreateRowSorter(true);
        Collections.shuffle(personModel);
        final MyTableModel table2Model = new MyTableModel(personModel);
        final JTable table2 = new JTable(table2Model);
        table2.setAutoCreateRowSorter(true);
        table1.getSelectionModel().addListSelectionListener(new ListSelectionListener() {

            @Override
            public void valueChanged(ListSelectionEvent e) {
                if (e.getValueIsAdjusting()) {
                    return;
                }
                int index = table1.getSelectedRow();
                if (index > -1) {
                    int table1ModelIndex = table1.convertRowIndexToModel(table1.getSelectedRow());
                    Person p = table1Model.getPersonAtIndex(table1ModelIndex);
                    int table2ModelIndex = table2Model.getIndexOfPerson(p);
                    int indexInTable2 = table2.convertRowIndexToView(table2ModelIndex);
                    table2.getSelectionModel().setSelectionInterval(indexInTable2, indexInTable2);
                }
            }
        });
        table2.getSelectionModel().addListSelectionListener(new ListSelectionListener() {

            @Override
            public void valueChanged(ListSelectionEvent e) {
                if (e.getValueIsAdjusting()) {
                    return;
                }
                int index = table2.getSelectedRow();
                if (index > -1) {
                    int table2ModelIndex = table2.convertRowIndexToModel(table2.getSelectedRow());
                    Person p = table2Model.getPersonAtIndex(table2ModelIndex);
                    int table1ModelIndex = table1Model.getIndexOfPerson(p);
                    int indexInTable1 = table1.convertRowIndexToView(table1ModelIndex);
                    table1.getSelectionModel().setSelectionInterval(indexInTable1, indexInTable1);
                }
            }
        });
        frame.add(new JScrollPane(table1), BorderLayout.WEST);
        frame.add(new JScrollPane(table2), BorderLayout.EAST);
        frame.pack();
        frame.setVisible(true);
    }

    public class Person {
        private final String firstName;
        private final String lastName;

        public Person(String firstName, String lastName) {
            this.firstName = firstName;
            this.lastName = lastName;
        }

        public String getFirstName() {
            return firstName;
        }

        public String getLastName() {
            return lastName;
        }
    }

    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException,
            UnsupportedLookAndFeelException {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new TestSortedTable().initUI();
            }
        });
    }

}
于 2013-01-31T19:50:17.163 に答える