2009-11-13 11 views
11

SWTテーブルに大量の行を表示するにはどうしますか? 20K行、20列を超えるものは巨大です。なぜ私は多くのデータを表示する必要があるのか​​聞かないでください、それはポイントではありません。要点は、エンドユーザーが飽きることがないようにできるだけ速く動作させる方法です。各行はあるオブジェクトのインスタンスを表示し、列はそのプロパティ(あるもの)です。私はJFaceのコンテンツ/ラベルプロバイダのパターンを使用すると思っていましたが、データを直接テーブルに当てるよりもさらに遅くなる恐れがあります。これは次のようになります。SWT/JFace RCPアプリケーションに大きなテーブルを挿入する

Display.getDefault().asyncExec(new Runnable() { 
     public void run() { 
      List<MyObject> objects = model.getViewData(); 
      for(MyObject object: objects){ 
      TableItem item = new TableItem(table, SWT.NULL); 
      item.setImage(0, img1); 
      item.setBackground(color1); 
       item.setText(0, object.getProperty0()); 
       item.setText(1, object.getProperty1()); 
       item.setText(2, object.getProperty2()); 
       ..... 
      } 
     }); 

自分のコンピュータに20kレコードを描画するのに約20秒かかります。 Windowsで見たパフォーマンスの最大の問題は、新しいテーブル項目が作成され、テキストが入力されたときにSWTによって送信される膨大な量のネイティブウィンドウメッセージによるものです。私はこのための大きな回避策を見つけました - 移入する前に表を非表示にして、それが完了したら表示してください。ループの前にtable.setVisible(false)を呼び出し、ループの後にtable.setVisible(true)を呼び出すだけで、速度は6〜7倍になります!

私はさらにスピードアップしたいと思います。 あなたは何をお勧めしますか?また、ウィジェットを隠しているこのトリックがSWT(別名Linux)の非ウィンドウ実装でどのように動作するのだろうか?

答えて

19

SWTでも可能です。 SWT.VIRTUALスタイルフラグを使用すると、項目はスクロールされて表示されるときにのみ作成されます。ここでそれを行う方法は次のとおりです。

  1. スタイルSWT.VIRTUAL表#setItemCountを(使用して行数を設定し
  2. を持つテーブルを作成します)
  3. オンデマンドでTableItemsを埋めSWT.SetDataリスナーを追加します。

は、ここでは、コードスニペットです:ヒントの

public static void main(String[] args) { 
    Display display = new Display(); 
    Shell shell = new Shell(display); 
    shell.setLayout(new FillLayout()); 
    final Table table = new Table(shell, SWT.VIRTUAL); 
    table.setItemCount(10000); 
    table.addListener(SWT.SetData, new Listener() { 
     public void handleEvent(Event event) { 
      TableItem item = (TableItem)event.item; 
      item.setText("Item " + table.indexOf(item)); 
     } 
    }); 
    shell.setSize(300, 500); 
    shell.open(); 
    while(!shell.isDisposed()) { 
     if(!display.readAndDispatch()) { 
      display.sleep(); 
     } 
    } 
    display.dispose(); 
} 
+0

これはまさに解決策ですが、100k行を埋めるのはほぼゼロ時間です。非常に驚くべき機能です。ありがとうございました! – Dima

+0

@ralfstxどうすればこのようなテーブルをフィルタリングできますか? –

+0

@AdamAroldこれについては、「DeferredContentProvider」を参照してください(例:this [tutorial](http://waynebeaton.wordpress.com/2008/01/16/deferredcontentprovider-my-new-favourite-thing/)を参照してください) 。しかし、スクロール時にリフレッシュに関するいくつかの問題があるかもしれないことに注意する必要があります:https://bugs.eclipse.org/bugs/show_bug.cgi?id=146799 – hnn

2

テーブル表示に遅延ロードを行いたいとします。基本的には、これらのオブジェクトをすべてオフスクリーンのままメモリに残し、実際のGUIテーブル行をほんの一握り作成します。ユーザーがスクロールすると、そのスクロール位置のオブジェクトでこれらの行が再描画されます。 JFaceの例のために:

this article(おっと、私はthis articleを意味EDIT)を参照してください。

+0

おかげで、怠惰な図面は良いアイデアのように聞こえます。このスニペットが私とどのように違うのか分かりませんが、それはすべての項目を実行し、1つ1つを描画します... – Dima

+0

Ooops!間違ったリンク、正しいサイト!これは、100万行のSWTテーブル用のものです:http://www.java2s.com/Code/Java/SWT-JFace-Eclipse/CreateaSWTtablewith1000000items.htm。「アイテムの追加」ボタンを置き換え、そのリスナーをスクロールリスナーとして再実装すると、現在のセットの最後に近づいたときに将来のアイテムをロードできます。がんばろう! –

+0

偉大な、これは今感謝します、ありがとう! – Dima

2

1 - setText(int、String)の代わりにsetText(String [])を使用します。

2 - myTable.setRedraw(false)beforeとmyTable.setRedraw(true)を使用して、データのロード中にすべての再描画オペレーションを停止します。

パフォーマンスが向上します。

幸運。

これを使用して私は標準の今日のPCで300ms未満で2500行をロードします。

関連する問題