2009-03-04 14 views
0

タイムカウンタは、テーブル内の1行の経過時間を秒単位で示します。理想的には、毎秒1回更新されます。私はテーブルモデルで適切なデータを増やしたり、イベント(行ごとに1つ)を発生させたりすることができるのは分かっています。より良い、より軽い方法がありますか?JTableセルにタイムカウンタを表示する効率的な方法

答えて

2

は何が必要です:

  • あなたのテーブルモデル内の行の「年齢」をモデル化する方法。これは暗に行われるのが最善です。行の作成時間を一度保存​​し、セル値が要求された時の年齢を計算するだけです(Object getValueAt(row、column))。
  • テーブル変更イベントを毎秒起動するA(デーモン)スレッド。行ごとに1つのイベントを発生させる必要はありませんが、列全体の更新を通知するイベントを発生させることができます。

ここでテーブルモデルのいくつかの擬似コードです:

public Object getValueAt (int rowIndex, int columnIndex) { 

    // if it's the column with the 'row age', calculate the age and return it 
    long rowAgeMs = System.currentTimeMs() - getCreationTime(rowIndex); 

    // return the age in milliseconds, or a date, or a formatted time string 
} 

それは、行の時代」列に変更イベントを発射できるように、テーブルモデルは、その後も、スレッドのための方法を提供する必要があります:

パブリッククラスMyTableModelにするTableModelを実装{

private final List<TableModelListener> listeners = new LinkedList<TableModelListener>(); 

    public void addTableModelListener (TableModelListener l) { 
      listeners.add(l); 
    } 

    public void removeTableModelListener (TableModelListener l) { 
      listeners.remove(l); 
    } 

    public void updateColumn (int column) { 
      TableModelEvent evt = new TableModelEvent(this, 0, Math.max(0, getRowCount() - 1), column); 
      for (TableModelListener listener : listeners) { 
       listener.tableChanged(evt); 
      } 
    } 

次いでだけupdateColumnをトリガするスレッド(..)メソッドEA 「行の年齢」列の2番目の数字です。このメソッドの呼び出しは、EventDispatchThreadで行う必要があります。これは、SwingUtilities.invokeAndWait(..)またはSwingUtilities.invokeLater(..)を使用して行います。

Thread rowAgeUpdater = new Thread() { 

     @Override 
     public void run() { 
      while (isAlive()) { 
       try { 

        long time = System.currentTimeMillis(); 
        long sleepTime = (time/1000 + 1) * 1000 - time; 
        Thread.sleep(sleepTime); 

        SwingUtilities.invokeAndWait(new Runnable() { 
         public void run() { 
          model.updateColumn(ROW_AGE_COLUMN_INDEX); 
         } 
        }); 

       } catch (Exception e) { 
        return; 
       } 

      } 
     } 
    }; 
    rowAgeUpdater.setDaemon(true); 
    rowAgeUpdater.setPriority(Thread.MIN_PRIORITY); 
    rowAgeUpdater.start(); 

限りTableModelEventの粒度だけ更新する必要がある細胞(あなたの場合:行年齢とともに列のみ)をカバーとして、それはこれを実現するための最も効率的な方法です。

関連する問題