La barre de progression ne se met pas à jour immédiatement

J’essaie d’utiliser à la fois une barre de progression et une étiquette pour montrer la progression d’un nombre discret d’opérations. Chaque fois que je mets à jour les deux, l’étiquette se met à jour immédiatement, tandis que la barre de progression a un délai notable avant de changer .

J’ai un dialog de test où, lorsque j’appuie sur un bouton, je mets à jour le libellé et la barre de progression pour refléter une augmentation de 1. Cela se produit immédiatement dans le code sans qu’aucune boucle ou aucun thread ne soit appelé être la cause ) – juste un simple changement de valeurs. Lorsque cela se produit, l’étiquette se met à jour immédiatement, tandis que la barre de progression attend environ une demi-seconde avant la mise à jour visuelle. Cela conduit à des cas où il sera dit, par exemple, “2 sur 3” quand il montre brièvement mais sensiblement 1/3 de la barre remplie.

entrer la description de l'image ici

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(Ssortingng 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(Ssortingng.format("%s of %s", iCur, progressBar.getMaximum())); } } 

Cela se produit malgré l’utilisation de la variable interne de la barre de progression pour suivre la valeur et utiliser cette valeur pour mettre à jour l’étiquette.

Notamment, le fait de remplacer la propriété “State” de la barre de progression par “ERROR” ou “PAUSED” élimine le problème.

Est-ce une sorte de bug avec l’animation? Est-ce juste un problème avec une version spécifique de Windows , telle que Windows 7 que j’utilise? Ou s’agit-il d’autre chose?

Il semble que cela puisse être un bogue dans la version Windows de ProgressBar car le code fonctionne sous Linux et Mac OS X.

La version Windows de ProgressBar.setSelection contient du code indiquant qu’elle essaie de gérer un problème qui sonne comme cela, mais cela n’est possible que si l’état n’est pas Normal – ce qui peut être la raison pour laquelle cela fonctionne dans l’état Erreur et Pause. . Leur correction ne fait que refaire la sélection, alors peut-être qu’appeler setSelection deux fois fonctionnerait!

Vous pouvez suivre ce tutoriel , il décrit comment créer des jobs Eclipse afin d’exécuter des tâches longues en dehors de l’EDT, et ne fait que mettre à jour l’état de vos composants. J’espère que ça aide, à la vôtre!

J’ai testé le code fourni avec la dernière version de SWT (4.3 Final Release – 5 juin 2013) sous Windows 7 SP 1 et Windows XP SP3. Dans les deux cas, la barre de progression a été mise à jour sans délai. Peut-être qu’une mise à jour de la bibliothèque SWT vous aidera.

J’ai rencontré ce problème il y a quelques semaines, en utilisant un graphique à barres pour montrer la progression d’environ 500 opérations consécutives. J’ai trouvé que les processus étaient terminés bien avant que le bargraph soit à mi-chemin. J’ai utilisé le code ci-dessous comme travail autour de:

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

Où bargraph est le nom de votre object, et cible est l’endroit où vous souhaitez le déplacer.

Le bargraphe ayant un aspect graphique, l’effet de sélection, il faut du temps pour le rattraper. Même si le côté graphique peut afficher une valeur de 50, la valeur de bargraph.value pourrait être de 60! En réglant la valeur à un niveau, puis en la réduisant de un, le bargraphe met instantanément à jour le côté graphique.

MODIFIER

Comme le montre le commentaire ci-dessous, la réponse ci-dessus peut ne pas fonctionner lorsque vous essayez de définir la valeur au maximum.

Maintenant, je n’ai pas essayé cela, mais je pense que quelque chose du genre de ce qui suit fonctionnerait:

 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 

Comme je l’ai dit, non testé, mais le principe devrait fonctionner.