您将如何在 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 实现上工作?

有帮助吗?

解决方案

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();
}

其他提示

您想要在表格显示上进行延迟加载。基本上,您将所有这些对象保留在屏幕外的内存中,然后仅创建少量实际的 GUI 表行。当用户滚动时,您将使用该滚动位置处的对象重新渲染这些行。

本文 (编辑:哎呀我的意思是 本文)作为 JFace 示例。

1 - 使用 setText(String[]) 而不是 setText(int, String) 一次调用而不是多次调用。

2 - 在进程之前和之后使用 myTable.setRedraw(false) 和 myTable.setRedraw(true) 来停止加载数据期间的所有重绘操作。

它更简单并且可以提高性能!

祝你好运。

在我这边,使用这个我在不到 300 毫秒的时间内加载了 20 列的 2500 行......在当今的标准 PC 上。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top