2009-11-13 7 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)의 비 Windows 구현에서 어떻게 작동 할까?

답변

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 테이블 행을 소수만 만듭니다. 사용자가 스크롤 할 때 스크롤 위치에있는 객체로이 행을 다시 렌더링합니다.

this article (편집 : 죄송합니다 나는 this article 의미) 참조하십시오 JFace는의 예를 들어.

+0

감사합니다, 게으른 그림은 좋은 생각처럼 들린다. 이 스 니펫이 내 것과 어떻게 다른지 보지 않지만, 모든 항목을 실행하고 하나씩 가져옵니다. – Dima

+0

Ooops! 잘못된 링크, 바로 사이트! 다음은 수백만 행의 SWT 테이블을위한 것입니다 : http://www.java2s.com/Code/Java/SWT-JFace-Eclipse/CreateaSWTtablewith1000000items.htm."Add Items"버튼을 바꾸고 현재 리스너가 끝나면 미래의 항목을로드하는 스크롤 리스너로 리스너를 다시 구현하십시오. 행운을 빕니다! –

+0

위대한,이 지금은 감사, 감사합니다! – Dima

2

1 - 몇 가지 대신 하나의 setText (int, String) 대신 setText (String [])를 사용하십시오.

2 - myTable.setRedraw (false)를 사용하고 myTable.setRedraw (true)를 사용하면 데이터를로드하는 동안 작업을 다시 그리는 모든 작업을 중지 할 수 있습니다.

더 간단하고 성능을 향상시킬 수 있습니다!

행운을 비네.

이쪽을 사용하면 표준 오늘의 PC에서 300ms 미만의 시간에 2500 줄의 20 열을로드 할 수 있습니다.