Je sais que beaucoup de gens connaissent ce problème, mais les solutions que j'ai trouvées en ligne ne semblent pas résoudre le mien. J'ai un composite qui a trois boutons. Ce que je veux est la suivante: Lorsque je clique sur un bouton, je veux qu'un autre bouton soit grisé (setEnabled (faux)) et après un moment (après l'exécution d'une méthode), je veux que le bouton soit à nouveau activé.SWT update/redraw/layout prblem
Beaucoup de ces problèmes sont résolus en appelant la méthode layout() sur le conteneur parent, ou this very similar one est résolu en appelant Display.getCurrent(). Update();
Simplement, mon code pourrait se résumer comme suit:
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Button;
public class app1 {
protected Shell shell;
/**
* Launch the application.
* @param args
*/
public static void main(String[] args) {
try {
app1 window = new app1();
window.open();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Open the window.
*/
public void open() {
Display display = Display.getDefault();
createContents();
shell.open();
shell.layout();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
}
/**
* Create contents of the window.
*/
Button button1 , button2 , button3;
Label label;
protected void createContents() {
shell = new Shell();
shell.setSize(450, 300);
shell.setText("SWT Application");
shell.setLayout(new GridLayout(1,false));
{
final Composite composite = new Composite(shell, SWT.NONE);
composite.setLayout(new GridLayout(3,false));
GridData gd_composite = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL);
gd_composite.grabExcessHorizontalSpace = true;
gd_composite.horizontalSpan = 10; //?
gd_composite.verticalIndent = 5;
composite.setLayoutData(gd_composite);
GridData gd_button;
{
button1 = new Button(composite, SWT.NONE);
button1.setText("Button 1");
gd_button = new GridData(SWT.FILL, GridData.BEGINNING, false, false);
gd_button.horizontalSpan = 1;
button1.setLayoutData(gd_button);
button1.addSelectionListener(new SelectionListener(){
public void widgetSelected(SelectionEvent e){
try{
button2.setEnabled(false);
button2.redraw();
button2.update();
//composite.redraw();
//composite.update();
//composite.layout();
shell.redraw();
shell.update();
shell.layout();
Display.getCurrent().update();
} catch (Exception e2) {
System.err.println("exception e : " + e2.toString());
}
System.out.println("basla");
try {
System.out.println("sleep1");
Thread.sleep(100);
} catch (InterruptedException e1) {
e1.printStackTrace();
} catch (Throwable th) {
System.err.println("th: " + th.toString());
}
try {
System.out.println("sleep2");
Thread.sleep(100);
} catch (InterruptedException e1) {
e1.printStackTrace();
} catch (Throwable th) {
System.err.println("th: " + th.toString());
}
try {
System.out.println("sleep3");
Thread.sleep(100);
} catch (InterruptedException e1) {
e1.printStackTrace();
} catch (Throwable th) {
System.err.println("th: " + th.toString());
}
for(int i=0 ; i < 10000 ; i++)
{
System.out.println(i);
}
}
public void widgetDefaultSelected(SelectionEvent e) {
System.err.println("widgetDefault !");
}
});
}
{
button2 = new Button(composite, SWT.NONE);
button2.setText("Button 2");
gd_button = new GridData(SWT.FILL, GridData.CENTER, false, false);
gd_button.horizontalSpan = 1;
button2.setLayoutData(gd_button);
button2.addSelectionListener(new SelectionListener(){
public void widgetSelected(SelectionEvent e){
button1.setEnabled(false);
composite.layout();
for (int i=1; i<=100; i++) {
try {
Thread.sleep(10);
} catch (Throwable th) {}
label.setText(i + " %");
label.update();
}
}
public void widgetDefaultSelected(SelectionEvent e) {}
});
}
{
label = new Label(composite , SWT.NONE);
label.setText("0 %");
label.update();
}
}
}
}
Qu'advient est, le bouton désactivé obtient après la fin de la méthode widgetSelected() est atteinte. Cependant, l'étiquette est mise à jour fréquemment sans aucun problème (même lorsque la méthode label.update() n'est pas là)
Informations supplémentaires: Dites, je désactiver le bouton, puis mettre un Thread.sleep(), puis activer le bouton ; il dort d'abord puis désactive rapidement et active le bouton. Donc, je crois que toutes ces demandes de peinture sont en file d'attente et sont traitées à la fin de l'exécution.
Informations utiles: J'ai réalisé que, lorsque je crée et affiche un MessageBox juste après que mon affichage change, l'affichage change. Donc, si je fais le changement suivant dans ma méthode widgetSelected:
button2.setEnabled(false)
MessageBox mBox = new MessageBox(Display.getCurrent().getActiveShell(), SWT.ICON_INFORMATION | SWT.OK);
mBox.setText("Information");
mBox.setMessage("Buttons updated!");
mBox.open();
le bouton sera grisé dès que la méthode widgetSelected() est appelée. Cela me fait croire que ma solution se trouve dans les méthodes Display.getCurrent(). Cependant, j'ai essayé
Display.getCurrent().getActiveShell().redraw() Display.getCurrent().getActiveShell().update() Display.getCurrent().getActiveShell().layout()
et ils n'ont pas résolu mon problème.
Merci, Ege
Merci beaucoup, ça marche. Cependant, je ne pouvais toujours pas obtenir votre explication à 100%. Je sais qu'il n'est pas possible d'effectuer des actions SWT dans un thread différent du thread SWT. Lorsque j'écris un SelectionAdapter que désactive d'abord tous les boutons puis effectue un sommeil (dans le même thread, sans créer un nouveau thread) puis active tous les boutons il montre un comportement indéterministe. Parfois, il désactive le 3ème bouton, dort puis les active tous. Parfois, il désactive le 2ème bouton, dort puis les active tous, etc. Pourriez-vous m'expliquer ce comportement indéterministe? Merci encore. –