一尘不染

在SWT / JFace RCP应用程序中填充大表

java

您将如何在SWT表中显示大量行?巨大的东西超过20K行20列。不要问我为什么我需要显示这么多数据,这不是重点。关键是如何使其尽可能快地工作,以使最终用户不会感到无聊的等待。每行显示一个对象的实例,列是其属性(某些)。我以为使用JFace内容/标签提供程序模式,但担心它比直接用数据命中表还要慢。它是这样的:

    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实现中如何工作?


阅读 212

收藏
2020-12-03

共1个答案

一尘不染

SWT可以为您做到这一点。当您使用SWT.VIRTUAL样式标志时,仅当滚动到视图时才创建项目。方法如下:

  1. 创建样式为SWT.VIRTUAL的表
  2. 使用Table#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();
}
2020-12-03