2009-11-13 73 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)就可以了 - 速度提高了六七倍!

我想加快它的速度。 你會建議什麼?另外,我想知道隱藏這個小部件的這個技巧是如何處理SWT(又名Linux)的非Windows實現的?

回答

19

SWT可以爲你做到這一點。當您使用SWT.VIRTUAL風格標誌時,只有在滾動到視圖中時纔會創建項目。以下是如何做到這一點:

  1. 風格SWT.VIRTUAL
  2. 使用表#setItemCount設置行數()
  3. 添加SWT.SetData監聽器,填補上需求TableItems創建表。

這裏有一個代碼片段:

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

這正是解決方案,現在填滿10萬行花費幾乎零時間,相當驚人的功能,謝謝一堆! – Dima 2010-05-12 19:58:46

+0

@ralfstx你能告訴我如何過濾這樣的表格? – 2012-10-30 12:41:30

+0

@AdamArold你可以看一下'DeferredContentProvider'(參見例如[tutorial](http://waynebeaton.wordpress.com/2008/01/16/deferredcontentprovider-my-new-favourite-thing/)) 。但是你應該知道滾動時刷新時可能會出現一些問題:https://bugs.eclipse.org/bugs/show_bug.cgi?id=146799 – hnn 2014-05-20 07:48:08

2

你想在桌面顯示上進行延遲加載。基本上,您將所有這些對象保留在內存中,然後創建少量實際的GUI表格行。當用戶滾動時,使用該滾動位置處的對象重新渲染這些行。

請參閱this article編輯:哎呀我的意思是this article)爲JFace示例。

+0

謝謝你的提示,懶惰繪圖聽起來是個好主意。雖然我不知道這個片段與我的片段有什麼不同,但它會遍歷所有項目並逐個繪製它... – Dima 2009-11-13 11:37:05

+0

哎呀!錯誤的鏈接,正確的網站!下面是一個SWT表,有一百萬行:http://www.java2s.com/Code/Java/SWT-JFace-Eclipse/CreateaSWTtablewith1000000items.htm。只需替換「添加項目」按鈕,並將其偵聽器重新實現爲一個滾動偵聽器,該偵聽器在您接近當前集合結束時加載將來的項目。祝你好運! – 2009-11-13 16:50:53

+0

太棒了,現在有道理,謝謝! – Dima 2009-11-24 07:35:17

2

1-使用setText(String [])代替setText(int,String)一次調用而不是幾次。

2 - 在加載數據期間,使用myTable.setRedraw(false)before和myTable.setRedraw(true)來停止所有重繪操作。

它更簡單,可以提高性能!

祝你好運。

在我身邊使用這個我加載2500列的20列在不到300毫秒.....在今天的標準PC上。