Плагин Eclipse: как асинхронно добавлять элементы в TableViewer?

В моем плагине Eclipse у меня есть TableViewer, который показывает некоторые данные. Эти данные извлекаются из удаленной службы REST. Поэтому для извлечения всех элементов требуется несколько секунд. Вот почему я хотел добавить элементы в TableViewer ContentProvider, как только я их получу. Я делаю свой запрос REST в отдельном потоке:

Thread retrieveThread = new RetrieveThread();
retrieveThread.run();

В этой теме я добавляю предметы в свой TableViewer:

MyView.instance.addItems(items);

И тот же метод в классе MyView:

public void addItems(List<Result> items) {
    ModelProvider.INSTANCE.addItems(items);
    resultLabel.setText(ModelProvider.INSTANCE.getItems().size() + " items");
    PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {

        @Override
        public void run() {
            viewer.refresh();
        }
    });
}

Я ожидал, что эта процедура добавит элементы в мой TableViewer, а затем обновит представление. Но что происходит сейчас, так это то, что мой Eclipse зависает и добавляет все элементы одновременно. Как я могу сделать это более отзывчивым способом?


person Community    schedule 12.05.2012    source источник
comment
Можете ли вы добавить сюда исходный код ваших RetrieveThread и MyView?   -  person nnhthuan    schedule 12.05.2012


Ответы (1)


Проблема в том, что вы напрямую вызываете метод run вашего потока. Это не порождает новый поток, он просто вызывает встроенный метод запуска. retrieveThread.start() даст вам поведение, которое вы ищете.

Однако есть лучший способ сделать это (по крайней мере, более «дружественный к eclipse»), а именно использовать Eclipse Job вместо необработанного Thread.

    Job retrieveJob = new Job("Retrieving Data") 
    {           
        @Override
        protected IStatus run(IProgressMonitor monitor) {
            // do your REST call
            ModelProvider.INSTANCE.addItems(items);
            // if something goes wrong - don't return ok, obviously 
            return Status.OK_STATUS;                
        }
    };
    retrieveJob.addJobChangeListener(new JobChangeAdapter() {

        @Override
        public void done(IJobChangeEvent event) {
            if(event.getResult().isOK())
            {
                resultLabel.setText(ModelProvider.INSTANCE.getItems().size() + " items");
                viewer.refresh();
            }
        }           
    });
    // this will run in a background thread 
    // and nicely integrate with the UI
    retrieveJob.schedule(); 
person Malcolm Smith    schedule 12.05.2012