SWT mise à jour / redessiner / layout problème
Je sais que beaucoup de gens l'expérience de ce problème, mais les solutions que j'ai trouvé en ligne ne semble pas résoudre le mien. J'ai un composite qui dispose de trois boutons. Ce que je veux est la suivante :
Lorsque je clique sur un bouton, je veux un autre bouton pour être grisé ( setEnabled(false) ) et après un certain temps (après l'exécution de la méthode), je veux que le bouton soit activé à nouveau.
Beaucoup de ces problèmes sont résolus par l'appel de mise en page() la méthode sur le conteneur parent, ou cette très similaire est résolu en appelant Affichage.getCurrent().mise à jour();
Simplement, mon code pourrait être résumées 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();
}
}
}
}
Ce qui se passe, le bouton est désactivé après la fin de widgetSelected() la méthode est atteint. Toutefois, l'étiquette est mis à jour fréquemment sans aucun problème (même si l'étiquette.méthode update() n'est pas là)
Informations supplémentaires : Dire, j'ai désactiver le bouton, puis mettre un Fil.sleep (), puis activer le bouton ; il dort d'abord, puis rapidement se désactive et active le bouton. Je crois donc que toutes ces demandes de peinture sont mis en file d'attente et sont traitées à la fin de l'exécution.
informations Utiles: j'ai réalisé que quand je créer et afficher une MessageBox juste après mon affichage change l'affichage des changements se produisent. Donc, si je fais la modification suivante dans mon widgetSelected méthode :
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 le widgetSelected() la méthode est appelée. Ce qui me fait croire ma solution se trouve dans l'Affichage.getCurrent() méthodes. Cependant, j'ai essayé
D'affichage.getCurrent().getActiveShell().redraw() D'affichage.getCurrent().getActiveShell().mise à jour() D'affichage.getCurrent().getActiveShell().layout()
méthodes et ils n'ont pas de résoudre mon problème.
Grâce,
Ege
OriginalL'auteur | 2009-07-24
Vous devez vous connecter pour publier un commentaire.
Ok, j'ai corrigé la réponse de ginu:
New Runnable().run() ne fait pas beaucoup à de rien, mais l'idée est bonne:
Vous avez besoin d'un nouveau thread pour faire votre travail. Le problème est, à partir de ce fil, vous ne pouvez pas appeler setEnabled sur les boutons, parce que cela ne peut être fait à partir de l'intérieur de la SWT-Événement de fil.
Si vous avez besoin d'un autre exécutable pour réinitialiser les boutons. La deuxième exécutable est passé à l'Affichage.callAsync et retourne avant qu'il soit exécuté, mais qui n'a pas d'importance ici. Vous pouvez également utiliser l'Affichage.callSync( Runnable ), cet appel pourrait bloquer votre thread appelant jusqu'à ce que l'exécutable retourne.
Testé dans Eclipse, semble bon jusqu'ici.
Edit: Btw, la raison de l'appel de mise en page() ou l'Affichage.mise à jour() ne fonctionne pas, c'est que vous êtes en train de blocage de la SWT-Fil avec votre travail, de sorte que les appels à la mise en page/mise à jour sont en attente et n'est exécutée que lorsque vous quittez le gestionnaire d'événements. Ne jamais bloquer un gestionnaire d'événement à faire long travail. 🙂
}
OriginalL'auteur derBiggi
Il n'apparaît pas que votre extrait de code est complet, mais un peu de choses sont venues à l'esprit au sujet de votre problème. Vous pouvez probablement utiliser setEnabled comme on le voit dans l'extrait ci-dessous. Pour plus d'avance de choses que vous pourriez regarder GridLayout et GridData avec le .exclut les biens en conjonction avec setVisible. Pour référence, la SWT Extraits de page est vraiment génial.
OriginalL'auteur
Je ne suis pas vraiment sûr si vous avez un problème avec l'activation /désactivation des boutons, ou de mettre le délai entre le flux d'exécution.
J'ai modifié Jared code ci-dessus pour effectuer ces deux opérations mentionnées. Jetez un oeil à tout ça et laissez-moi savoir si ce que vous recherchez.
Acclamations. 🙂
OriginalL'auteur