2010-12-14 16 views
1

クライアント/サーバマルチユーザアーキテクチャがあるとします。ユーザはいつでも、彼のJTableに新しいTableRowを追加することができます。サーバーは通知を受け、すべてのクライアントにメッセージを送信し、そのデータ(テーブルビューを意味する)も更新されます。これは、ユーザーが現在そのテーブルの行を編集していない限り、updateEventになるまでは問題なく動作します。行の編集中にJTableの受信データを処理する方法は?

新しいtableRowが現在の編集済み行の上にある場合、それぞれのセルも同様に変更されますが、tableEditorはこれに気付かず、間違った行が編集されて変更されます。

私は私に従うことが容易であるかもしれないので、コードのいくつかの行まで、この問題を打破するために、小さな例を作成しました:

public class TableEventHandlingExample extends JPanel 
{ 
    static JFrame frame; 
    JTable  table; 

    public TableEventHandlingExample() 
    { 
    table = new JTable(new StandardTableModel(createTestData())); 

    final Thread thread = new Thread(new Runnable() 
    { 
     @Override 
     public void run() 
     { 
     try 
     { 
      while (true) 
      { 
      Thread.sleep(5000); 
      ((StandardTableModel) table.getModel()).addRow(new Data(4, "Vier"), 0); 
      } 
     } 
     catch (InterruptedException e) 
     { 
      e.printStackTrace(); 
     } 
     } 
    }); 

    thread.start(); 

    add(new JScrollPane(table)); 
    } 

    private List<Data> createTestData() 
    { 
    Data data1 = new Data(1, "Eins"); 
    Data data2 = new Data(2, "Zwei"); 
    Data data3 = new Data(3, "Drei"); 

    List<Data> dataList = new ArrayList<Data>(); 

    dataList.add(data1); 
    dataList.add(data2); 
    dataList.add(data3); 

    return dataList; 
    } 

    public static void main(String[] args) 
    { 
    frame = new JFrame(); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frame.setLayout(new BorderLayout()); 
    frame.setBounds(400, 400, 500, 500); 
    frame.add(new TableEventHandlingExample()); 
    frame.setVisible(true); 
    } 
} 


class StandardTableModel extends AbstractTableModel 
{ 
    List<Data> dataList; 

    public StandardTableModel(List<Data> dataList) 
    { 
    this.dataList = dataList; 
    } 

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

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

    @Override 
    public boolean isCellEditable(int rowIndex, int columnIndex) 
    { 
    return true; 
    } 

    @Override 
    public Class<?> getColumnClass(int columnIndex) 
    { 
    if (columnIndex == 0) 
     return Integer.class; 
    return String.class; 
    } 

    @Override 
    public Object getValueAt(int rowIndex, int columnIndex) 
    { 
    if (columnIndex == 0) 
     return dataList.get(rowIndex).getId(); 

    return dataList.get(rowIndex).getName(); 
    } 

    @Override 
    public void setValueAt(Object aValue, int rowIndex, int columnIndex) 
    { 
    Data data = dataList.get(rowIndex); 

    if (columnIndex == 0) 
     data.setId((Integer) aValue); 
    else 
     data.setName((String) aValue); 
    } 

    public void addRow(Data data, int index) 
    { 
    if (index > dataList.size()) 
    { 
     return; 
    } 

    dataList.add(index, data); 
    fireTableRowsInserted(index, index); 
    } 
} 


class Data 
{ 
    private int id; 
    private String name; 

    public Data(int id, String name) 
    { 
    this.id = id; 
    this.name = name; 
    } 

    public int getId() 
    { 
    return id; 
    } 

    public void setId(int id) 
    { 
    this.id = id; 
    } 

    public String getName() 
    { 
    return name; 
    } 

    public void setName(String name) 
    { 
    this.name = name; 
    } 

    @Override 
    public String toString() 
    { 
    return getName(); 
    } 
} 

私は追加のスレッドを使用偽の着信データ、イベントに5秒ごとにポジション1に新しい行が追加されます。問題が何であるかを示すのに十分です。

これを処理する方法はありますか?テーブルが編集され、後でupdateEventsが実行される限り、updateEventsを許可しないでください。しかし、ユーザーが5分間の編集モードにいるとき、私は何をしますか?彼が見逃したすべての更新イベントを追放すると、ちょっと痛いかもしれません。多分あなたは他のアイデアを持っていますか?

ありがとうございます! ymene

答えて

2

あなただけの正しいものに編集中のセルを設定することを検討していますか?あなたは常に、任意の挿入が行われている場合については0

while (true) { 
     Thread.sleep(5000); 
     table.setEditingRow(table.getEditingRow() + 1); 
     ((StandardTableModel) table.getModel()).addRow(new Data(4, "Vier"), 0); } 

で新しいセルを追加しているので、あなたの例では、それはかなり簡単です(行0でない)、あなたは行があれば、チェックを追加する必要があります挿入されているのは現在編集中のものの上か下です

+0

そのような単純なことは信じられません。ありがとう、このソリューションは私に多くの回避策を保存します!不幸にも私はまだあなたに報いることができません。私はそれをさらに19時間待たなければならないと言います。しかし、私はそれを忘れることはありません! – crusam

+0

心配はいりません。それはあなたのために働いてうれしい:) –

0

SwingWorkerを使用することをお勧めします。

EDT以外の仕事をすることができます。その後、他のユーザーが行を追加すると、JTableがリアルタイムで更新されます。

敬具

+0

ありがとうございます。どの時点でそれらを使用することを提案しますか?テーブルをリフレッシュするには、イベントが来たら?スイングワーカーにupdateEventsを入れても意味がありますが、テーブルをリフレッシュしている間に行を編集しても変更されないので、問題を解決する方法はわかりません。 – crusam

関連する問題