2009-11-13 12 views
11

¿Qué le parecería mostrar una gran cantidad de filas en la tabla SWT? Enorme es algo más de 20K filas, 20 columnas. No me preguntes por qué necesito mostrar tantos datos, no es el punto. El punto es cómo hacer que funcione lo más rápido posible para que el usuario final no se aburra esperando. Cada fila muestra una instancia de algún objeto, las columnas son sus propiedades (algunas). Pensé usar el patrón del proveedor de contenido/etiqueta de JFace, pero temía que fuera incluso más lento que tocar directamente la tabla con los datos. Así es como va:Poblar una tabla enorme en la aplicación 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()); 
       ..... 
      } 
     }); 

Dibujar 20k registros en mi computadora dura unos 20 sec. El mayor problema de rendimiento que he visto en Windows se debe a la increíble cantidad de mensajes de ventanas nativas enviados por SWT cuando se creó un nuevo elemento de tabla y se rellenó con texto. He encontrado una gran solución para esto: ocultar la tabla antes de poblar, y luego mostrarla cuando haya terminado. Simplemente llamando a table.setVisible (falso) antes del bucle y table.setVisible (true) después de que el bucle hace maravillas, ¡la velocidad aumenta seis o siete veces!

Me gustaría acelerarlo aún más. ¿Qué sugerirías? Además, me pregunto cómo funcionaría este truco para ocultar el widget en implementaciones de SWT (también conocidas como Linux) que no sean Windows.

Respuesta

19

SWT puede hacer eso por usted. Cuando utiliza el indicador de estilo SWT.VIRTUAL, los elementos solo se crean cuando se despliega a la vista. Así es como se hace:

  1. crear la tabla con SWT.VIRTUAL estilo
  2. Establecer el número de filas usando la Tabla # setItemCount()
  3. añadir un detector SWT.SetData que llena los TableItems bajo demanda.

He aquí un fragmento de código:

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

Esta es exactamente la solución, ahora completar 100k filas requiere casi cero tiempo, una característica bastante sorprendente, ¡muchas gracias! – Dima

+0

@ralfstx ¿Puede decirme cómo puedo filtrar una tabla como esta? –

+0

@AdamArold Para esto, puede ver 'DeferredContentProvider' (consulte, por ejemplo, este [tutorial] (http://waynebeaton.wordpress.com/2008/01/16/deferredcontentprotentr-my-new-favourite-thing/)) . Pero debe tener en cuenta que puede haber algunos problemas con la actualización cuando se desplaza: https://bugs.eclipse.org/bugs/show_bug.cgi?id=146799 – hnn

2

Desea hacer lazy-loading en la pantalla de la tabla. Básicamente, mantiene todos estos objetos fuera de la pantalla en la memoria, y luego crea solo un puñado de filas reales de la tabla de la GUI. A medida que el usuario se desplaza, vuelve a renderizar estas filas con los objetos en esa ubicación de desplazamiento.

Ver this article (EDITAR: oops quería decir this article) para un ejemplo JFace.

+0

Gracias por la pista, dibujo perezoso suena como una buena idea. Aunque no veo cómo este fragmento es diferente al mío, se ejecuta sobre todos los elementos y lo dibuja uno por uno ... – Dima

+0

¡Ooops! ¡Enlace incorrecto, sitio correcto! Aquí está el de una tabla SWT con un millón de filas: http://www.java2s.com/Code/Java/SWT-JFace-Eclipse/CreateaSWTtablewith1000000items.htm.Simplemente reemplace el botón "Agregar elementos" y vuelve a implementar su oyente como un oyente de desplazamiento que carga los artículos futuros una vez que se acerca al final del conjunto actual. ¡Buena suerte! –

+0

Genial, esto tiene sentido ahora, ¡gracias! – Dima

2

1 - use setText (String []) en lugar de setText (int, String) una llamada en lugar de varias.

2 - use myTable.setRedraw (falso) antes y myTable.setRedraw (true) después del proceso para detener todas las operaciones de redibujado durante la carga de datos.

¡es más simple y puede mejorar el rendimiento!

buena suerte.

en mi lado usando esto cargo 2500 líneas de 20 columnas en menos de 300ms ..... en una PC estándar de hoy.

Cuestiones relacionadas