Заполнение огромного стола в приложении SWT / JFace RCP - PullRequest
11 голосов
/ 13 ноября 2009

Как бы вы отобразили огромное количество строк в таблице SWT? Огромный это что-то выше 20К строк, 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());
               ..... 
            }
       });

Создание 20 КБ записей на моем компьютере занимает около 20 секунд. Самая большая проблема с производительностью, которую я видел в Windows, вызвана невероятным количеством собственных оконных сообщений, отправляемых SWT, когда новый элемент таблицы создается и заполняется текстом. Я нашел отличный обходной путь для этого - спрячьте таблицу перед заполнением, а затем покажите ее, когда закончите. Просто вызывая table.setVisible (false) перед циклом и table.setVisible (true) после цикла, творит чудеса - скорость возрастает в шесть-семь раз!

Я бы хотел ускорить это еще больше. Что ты предлагаешь ? Кроме того, мне интересно, как этот трюк, скрывающий виджет, будет работать в не-оконных реализациях SWT (иначе Linux)?

Ответы [ 3 ]

19 голосов
/ 05 мая 2010

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();
}
2 голосов
/ 23 ноября 2009

1 - использовать setText (String []) вместо setText (int, String) один вызов вместо нескольких.

2 - используйте myTable.setRedraw (false) до и myTable.setRedraw (true) после процесса, чтобы остановить все операции перерисовки во время загрузки данных.

это проще и может улучшить производительность !!

удачи.

со своей стороны, используя это, я загружаю 2500 строк из 20 столбцов менее чем за 300 мс ..... на стандартном современном ПК.

2 голосов
/ 13 ноября 2009

Вы хотите сделать ленивую загрузку на табличном дисплее. По сути, вы сохраняете все эти объекты за кадром в памяти, а затем создаете только несколько фактических строк таблицы GUI. Когда пользователь прокручивает, вы повторно визуализируете эти строки с объектами в этом месте прокрутки.

См. эту статью ( РЕДАКТИРОВАТЬ: упс, я имел в виду эту статью ) для примера JFace.

...