If
you are working with SWT, you will come across the question in mind, what is
the difference between syncExec and asyncExec, why do we require these methods
etc., In this post, I am going to explain why do we require these methods and
difference between syncExec, asyncExec with an example.
Why do we require
syncExec and asyncExec methods?
SWT
implements single threaded UI model. In this model, only the UI-thread can
invoke UI operations. If you try and access an SWT object from outside the
UI-thread, you get the exception "org.eclipse.swt.SWTException: Invalid
thread access". So to allow other threads to perform operations on objects
belonging to the UI-thread, SWT provides syncExec and asyncExec methods.
syncExec vs asyncExec
As
I said, both syncExec and asyncExec methods are used to perform operations on
objects belonging to UI thread. There is one difference between syncExec and
asyncExec methods, the thread which calls syncExec method is suspended until
the runnable completes. But in case of asyncExec mehtod, the caller of this
method continues to run in parallel, and is not notified when the runnable has
completed.
Let
me clarify it with an example.
CustomDialog.java
package com.sample.ui; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; public class CustomDialog extends Dialog { public String name; private Text text1 = null; private Button button = null; public CustomDialog(Shell parentShell) { super(parentShell); } @Override protected void okPressed() { // Do operations if you want, when ok button pressed name = text1.getText(); super.okPressed(); } @Override protected Control createDialogArea(Composite parent) { Composite composite = (Composite) super.createDialogArea(parent); GridLayout gridLayout = new GridLayout(); gridLayout.numColumns = 2; composite.setLayout(gridLayout); Label label1 = new Label(composite, SWT.NONE); label1.setText("Name:"); text1 = new Text(composite, SWT.BORDER); button = new Button(composite, SWT.CHECK); button.setText("Have you been employed in the past six months?"); GridData gridData1 = new GridData(); gridData1.widthHint = 60; label1.setLayoutData(gridData1); GridData gridData4 = new GridData(GridData.FILL_HORIZONTAL); text1.setLayoutData(gridData4); GridData gridData7 = new GridData(); gridData7.horizontalSpan = 2; button.setLayoutData(gridData7); return composite; } @Override protected void configureShell(Shell newShell) { super.configureShell(newShell); newShell.setText("My Custom Dialog"); } @Override protected Point getInitialSize() { return new Point(450, 300); } @Override public String toString() { return "CustomDialog [name=" + name + "]"; } }
Test.java
package com.sample.ui; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.swt.widgets.Display; public class Test { public static void main(String[] args) { Display.getDefault().asyncExec(new Runnable() { public void run() { Dialog dialog = new CustomDialog(Display.getDefault().getActiveShell()); dialog.open(); } }); System.out.println("I am done"); stopExitingTheUiApplication(); } /** * This stops the application from termination, when we use asyncExec method */ private static void stopExitingTheUiApplication() { while (!Display.getDefault().isDisposed()) { if (!Display.getDefault().readAndDispatch()) { Display.getDefault().sleep(); } } } }
As
you observe following snippet,
Display.getDefault().asyncExec(new Runnable() { public void run() { Dialog dialog = new CustomDialog(Display.getDefault().getActiveShell()); dialog.open(); } }); System.out.println("I am done");
I
am opening the dialog in asyncExec method of Display class. So the dialog opens
and the messages 'I am done' prints parallely.
Now
replace the asyncExec method with syncExec method.
Test.java
package com.sample.ui; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.swt.widgets.Display; public class Test { public static void main(String[] args) { Display.getDefault().syncExec(new Runnable() { public void run() { Dialog dialog = new CustomDialog(Display.getDefault().getActiveShell()); dialog.open(); } }); System.out.println("I am done"); stopExitingTheUiApplication(); } /** * This stops the application from termination, when we use asyncExec method */ private static void stopExitingTheUiApplication() { while (!Display.getDefault().isDisposed()) { if (!Display.getDefault().readAndDispatch()) { Display.getDefault().sleep(); } } } }
You
can able to see the output ‘I am done’, after you close the custom dialog
No comments:
Post a Comment