2013-09-11 5 views
7

Я пытаюсь использовать как индикатор хода и метку, чтобы показать прогресс сдержанного количества операций. Каждый раз, когда я обновляю оба значения, ярлык немедленно обновляется, а индикатор выполнения имеет заметную задержку до изменения.Progress Bar не обновляется Сразу

У меня есть тестовое диалоговое окно, где, когда я нажимаю кнопку, я обновляю как метку, так и индикатор выполнения, чтобы отразить увеличение 1. Это происходит сразу же в коде без каких-либо циклов или потоков, вызываемых (, устраняющих любые связанные с потоком вопросы как причина) - простое изменение значений. Когда это происходит, ярлык немедленно обновляется, а индикатор прогресса ожидает около половины секунды перед визуальным обновлением. Это приводит к примерам, где он скажет, например, «2 из 3», когда он кратко, но заметно показывает 1/3 заполненного бара.

enter image description here

import org.eclipse.swt.SWT; 
import org.eclipse.swt.layout.GridLayout; 
import org.eclipse.swt.widgets.Display; 
import org.eclipse.swt.widgets.Shell; 
import org.eclipse.swt.widgets.ProgressBar; 
import org.eclipse.swt.widgets.Label; 
import org.eclipse.swt.layout.GridData; 
import org.eclipse.swt.widgets.Button; 
import org.eclipse.swt.events.SelectionAdapter; 
import org.eclipse.swt.events.SelectionEvent; 

public class ProgressBarTest extends Shell { 

    private ProgressBar progressBar; 
    private Label lblXOfX; 
    private Button btnGo; 

    public static void main(String args[]) { 
     try { 
      Display display = Display.getDefault(); 
      ProgressBarTest shell = new ProgressBarTest(display); 
      shell.open(); 
      shell.layout(); 
      while (!shell.isDisposed()) { 
       if (!display.readAndDispatch()) { 
        display.sleep(); 
       } 
      } 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

    public ProgressBarTest(Display display) { 
     super(display, SWT.SHELL_TRIM); 
     createContents(); 
    } 

    protected void createContents() { 
     setText("SWT Application"); 
     setSize(450, 300); 
     setLayout(new GridLayout()); 

     progressBar = new ProgressBar(this, SWT.NONE); 
     progressBar.setMaximum(3); 
     progressBar.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); 

     lblXOfX = new Label(this, SWT.NONE); 
     lblXOfX.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1)); 
     lblXOfX.setText("x of x"); 

     btnGo = new Button(this, SWT.NONE); 
     btnGo.addSelectionListener(new SelectionAdapter() { 
      @Override 
      public void widgetSelected(SelectionEvent arg0) { 
       go(); 
      } 
     }); 
     btnGo.setText("Go"); 
    } 

    @Override 
    protected void checkSubclass() { 
     // Disable the check that prevents subclassing of SWT components 
    } 

    protected void go() { 

     int iCur = progressBar.getSelection(); 
     iCur++; 
     if (iCur > progressBar.getMaximum()) 
      iCur = 0; 

     progressBar.setSelection(iCur); 
     lblXOfX.setText(String.format("%s of %s", iCur, progressBar.getMaximum())); 
    } 

} 

Это происходит, несмотря на использование внутренней переменной прогресс бар, чтобы следить за значением, и используя это значение для обновления метки.

Примечательно, что изменяет свойство состояния «состояние» на «ERROR» или «PAUSED», устраняет проблему.

Это какая-то ошибка с анимацией? Это просто проблема с конкретной версией Windows, например Windows 7, которую я использую? Или что-то еще?

+0

Трудно сказать только с частичным фрагментом, что здесь происходит - можете ли вы представить более полный пример (который мы можем скомпилировать и запустить сами), чтобы продемонстрировать проблему? (см. http://sscce.org/) – Krease

+0

@Chris Очень хорошо, все сделано. –

+0

@Chris Я могу на самом деле сделать это намного проще. Я собираюсь переработать весь вопрос. –

ответ

4

Похоже, что это может быть ошибка в версии Windows, в ProgressBar как код работает на Linux и Mac OS X.

версия Окна ProgressBar.setSelection имеет некоторый код, который говорит, что он пытается справиться с проблема, которая звучит так, но это делается только в том случае, если состояние не является нормальным - возможно, поэтому оно работает в состоянии «Ошибка» и «Приостановлено». Их исправление просто делает выбор снова, поэтому, может быть, вызов setSelection будет работать!

+1

Я пробовал делать setSelection два раза подряд, безрезультатно. Есть ли еще трюк? –

1

Вы можете следить за this tutorial, в нем описывается, как вы можете выполнять задания Eclipse для выполнения длинных заданий, кроме EDT, и просто обновляет состояние ваших компонентов. Надеюсь, это поможет, приветствия!

+0

Маловероятно, что этот учебник поможет - если не указано иное, это не вызвано ни потоком, ни отсутствием потоковой передачи. На самом деле, причина, по которой это не показано, - это вся суть. ЕСЛИ вы чувствуете себя иначе, пожалуйста, уточните более подробно. –

1

Я тестировал код, предоставленный вами, используя последнюю версию SWT (4.3 Final Release - 5 июня 2013 г.) под Windows 7 SP 1 и Windows XP SP3. В обоих случаях индикатор выполнения обновляется без задержки. Возможно, обновление библиотеки SWT поможет.

1

Я столкнулся с этой проблемой несколько недель назад при использовании барграфа, чтобы показать ход выполнения ~ 500 операций, выполненных последовательно. Я обнаружил, что процессы были закончены задолго до того, как барграф даже попал на полпути. Я использовал код ниже как работа вокруг:

bargraph.value = (Target + 1) 
bargraph.value = (Target) 

Где Гистограмма это имя вашего объекта, и цель, где вы хотите, чтобы перейти к.

Поскольку барграф имеет графический аспект, эффект шатра, требуется время, чтобы догнать. Несмотря на то, что графическая сторона может показывать значение 50, фактическое значение барграфа может быть 60! Установив значение на уровень, а затем уменьшая его на единицу, барграф мгновенно (ish) обновляет графическую сторону.

EDIT

Как комментарий ниже показывает, выше ответ не может работать, когда вы пытаетесь установить значение максимума.

Теперь, я попытался нету этого, но я думаю, что что-то вдоль линий ниже будет работать:

if (bargraph.value <> Target) then 
    if (Target = bargraph.maximumvalue) then 
     bargraph.maximumvalue = Target + 1 
     bargraph.value = (Target + 1) 
     bargraph.value = (Target) 
     bargraph.maximumvalue = Target 
    else 
     bargraph.value = (Target + 1) 
     bargraph.value = (Target) 
    end if 
else 
end if 

Как я сказал, тестировался, но принцип должен работать.

+0

Хм, да, я тоже это заметил. Будет ли это работать в случае, когда Target является максимальным? –

+0

Я не могу вспомнить точную ошибку, но я предполагаю, что вы получите ошибку, аналогичную доступу к индексу X + 1 массива с размером X. Не пробовал это, но если вы попытаетесь изменить выше, это может сработать – Joshpbarron