X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.utils.ui%2Fsrc%2Forg%2Fsimantics%2Futils%2Fui%2FSWTUtils.java;h=6f56a587c4f607cffc291de5a7d6921104182e41;hb=HEAD;hp=7ac2ce07ff4d344fcc188060fa0380e3417875ea;hpb=969bd23cab98a79ca9101af33334000879fb60c5;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.utils.ui/src/org/simantics/utils/ui/SWTUtils.java b/bundles/org.simantics.utils.ui/src/org/simantics/utils/ui/SWTUtils.java index 7ac2ce07f..6f56a587c 100644 --- a/bundles/org.simantics.utils.ui/src/org/simantics/utils/ui/SWTUtils.java +++ b/bundles/org.simantics.utils.ui/src/org/simantics/utils/ui/SWTUtils.java @@ -1,165 +1,165 @@ -package org.simantics.utils.ui; - -import java.util.concurrent.Semaphore; -import java.util.concurrent.TimeUnit; - -import org.eclipse.swt.SWTException; -import org.eclipse.swt.custom.CTabFolder; -import org.eclipse.swt.custom.CTabItem; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.TabFolder; -import org.eclipse.swt.widgets.TabItem; -import org.eclipse.swt.widgets.Widget; -import org.simantics.utils.threads.IThreadWorkQueue; -import org.simantics.utils.threads.ThreadUtils; - -public class SWTUtils { - - /** - * When scheduling a runnable to be executed asynchronously in the SWT - * thread it is not possible to do this in a safe manner based on a - * {@link Display} instance. When invoking - * {@link Display#asyncExec(Runnable)} from a non-SWT thread, it may throw - * {@link SWTException} even if you've first checked - * {@link Display#isDisposed()}. - * - * This method will run {@link Display#asyncExec(Runnable)} using the - * display returned by the specified widget if the widget is or does not - * become disposed while trying to get the display from it. - * - * @param display the display to asyncExec with - * @param runnable the runnable to execute with - * {@link Display#asyncExec(Runnable)} - * @return true if the executable was scheduled, false - * otherwise - */ - public static boolean asyncExec(Display display, Runnable runnable) { - try { - if (display.isDisposed()) - return false; - display.asyncExec(runnable); - return true; - } catch (SWTException e) { - // widget was disposed between isDisposed and getDisplay. - return false; - } - } - - /** - * When scheduling a runnable to be executed asynchronously in the SWT - * thread it is not possible to do this in a safe manner based on a - * {@link Widget} instance. When invoking {@link Widget#getDisplay()} from a - * non-SWT thread, it may throw {@link SWTException} even if you've first - * checked {@link Widget#isDisposed()}. - * - * This method will run {@link Display#asyncExec(Runnable)} using the - * display returned by the specified widget if the widget is or does not - * become disposed while trying to get the display from it. - * - * @param widget the widget to get {@link Display} from - * @param runnable the runnable to execute with {@link Display#asyncExec(Runnable)} - * @return true if the executable was scheduled, false otherwise - */ - public static boolean asyncExec(Widget widget, Runnable runnable) { - try { - if (widget.isDisposed()) - return false; - widget.getDisplay().asyncExec(runnable); - return true; - } catch (SWTException e) { - // widget was disposed between isDisposed and getDisplay. - return false; - } - } - - /** - * Invokes a runnable in a specified thread and dispatches SWT events while - * waiting for the runnable to complete. - * - *

- * The runnable must not perform any operations that may cause more SWT - * events to be dispatched. - * - *

- * To be invoked from SWT thread only. - * - * @param control - * @param inThread - * @param invoke - * @throws InterruptedException - */ - public static void invokeAndDispatchEvents(Display display, IThreadWorkQueue inThread, final Runnable invoke) throws InterruptedException { - if (display.isDisposed()) - throw new IllegalArgumentException("display is disposed"); - final Semaphore sem = new Semaphore(0); - ThreadUtils.asyncExec(inThread, new Runnable() { - @Override - public void run() { - try { - invoke.run(); - } finally { - sem.release(); - } - } - }); - boolean done = false; - while (!done) { - done = sem.tryAcquire(10, TimeUnit.MILLISECONDS); - while (!done && display.readAndDispatch()) { - /* - * Note: readAndDispatch can cause this to be disposed. - */ - done = sem.tryAcquire(); - } - } - } - - /** - * Look for an object starting from an SWT (composite) control with a - * specific filter that can inspect the control freely. - * - * @return the first T returned by the control filter or null - * if the filter returned no results. - */ - public static T tryGetObject(Control control, ControlFilter filter) { - if (control == null || control.isDisposed()) - return null; - T t = filter.accept(control); - if (t != null) - return t; - if (control instanceof Composite) { - if (control instanceof TabFolder) { - TabFolder tf = (TabFolder) control; - for (TabItem item : tf.getSelection()) { - t = tryGetObject(item.getControl(), filter); - if (t != null) - return t; - } - } else if (control instanceof CTabFolder) { - CTabFolder tf = (CTabFolder) control; - CTabItem item = tf.getSelection(); - if (item != null) { - t = tryGetObject(item.getControl(), filter); - if (t != null) - return t; - } - } else { - Composite c = (Composite) control; - for (Control child : c.getChildren()) { - t = tryGetObject(child, filter); - if (t != null) - return t; - } - } - } - return null; - } - - @FunctionalInterface - public interface ControlFilter { - T accept(Control control); - } - -} +package org.simantics.utils.ui; + +import java.util.concurrent.Semaphore; +import java.util.concurrent.TimeUnit; + +import org.eclipse.swt.SWTException; +import org.eclipse.swt.custom.CTabFolder; +import org.eclipse.swt.custom.CTabItem; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.TabFolder; +import org.eclipse.swt.widgets.TabItem; +import org.eclipse.swt.widgets.Widget; +import org.simantics.utils.threads.IThreadWorkQueue; +import org.simantics.utils.threads.ThreadUtils; + +public class SWTUtils { + + /** + * When scheduling a runnable to be executed asynchronously in the SWT + * thread it is not possible to do this in a safe manner based on a + * {@link Display} instance. When invoking + * {@link Display#asyncExec(Runnable)} from a non-SWT thread, it may throw + * {@link SWTException} even if you've first checked + * {@link Display#isDisposed()}. + * + * This method will run {@link Display#asyncExec(Runnable)} using the + * display returned by the specified widget if the widget is or does not + * become disposed while trying to get the display from it. + * + * @param display the display to asyncExec with + * @param runnable the runnable to execute with + * {@link Display#asyncExec(Runnable)} + * @return true if the executable was scheduled, false + * otherwise + */ + public static boolean asyncExec(Display display, Runnable runnable) { + try { + if (display.isDisposed()) + return false; + display.asyncExec(runnable); + return true; + } catch (SWTException e) { + // widget was disposed between isDisposed and getDisplay. + return false; + } + } + + /** + * When scheduling a runnable to be executed asynchronously in the SWT + * thread it is not possible to do this in a safe manner based on a + * {@link Widget} instance. When invoking {@link Widget#getDisplay()} from a + * non-SWT thread, it may throw {@link SWTException} even if you've first + * checked {@link Widget#isDisposed()}. + * + * This method will run {@link Display#asyncExec(Runnable)} using the + * display returned by the specified widget if the widget is or does not + * become disposed while trying to get the display from it. + * + * @param widget the widget to get {@link Display} from + * @param runnable the runnable to execute with {@link Display#asyncExec(Runnable)} + * @return true if the executable was scheduled, false otherwise + */ + public static boolean asyncExec(Widget widget, Runnable runnable) { + try { + if (widget.isDisposed()) + return false; + widget.getDisplay().asyncExec(runnable); + return true; + } catch (SWTException e) { + // widget was disposed between isDisposed and getDisplay. + return false; + } + } + + /** + * Invokes a runnable in a specified thread and dispatches SWT events while + * waiting for the runnable to complete. + * + *

+ * The runnable must not perform any operations that may cause more SWT + * events to be dispatched. + * + *

+ * To be invoked from SWT thread only. + * + * @param control + * @param inThread + * @param invoke + * @throws InterruptedException + */ + public static void invokeAndDispatchEvents(Display display, IThreadWorkQueue inThread, final Runnable invoke) throws InterruptedException { + if (display.isDisposed()) + throw new IllegalArgumentException("display is disposed"); + final Semaphore sem = new Semaphore(0); + ThreadUtils.asyncExec(inThread, new Runnable() { + @Override + public void run() { + try { + invoke.run(); + } finally { + sem.release(); + } + } + }); + boolean done = false; + while (!done) { + done = sem.tryAcquire(10, TimeUnit.MILLISECONDS); + while (!done && display.readAndDispatch()) { + /* + * Note: readAndDispatch can cause this to be disposed. + */ + done = sem.tryAcquire(); + } + } + } + + /** + * Look for an object starting from an SWT (composite) control with a + * specific filter that can inspect the control freely. + * + * @return the first T returned by the control filter or null + * if the filter returned no results. + */ + public static T tryGetObject(Control control, ControlFilter filter) { + if (control == null || control.isDisposed()) + return null; + T t = filter.accept(control); + if (t != null) + return t; + if (control instanceof Composite) { + if (control instanceof TabFolder) { + TabFolder tf = (TabFolder) control; + for (TabItem item : tf.getSelection()) { + t = tryGetObject(item.getControl(), filter); + if (t != null) + return t; + } + } else if (control instanceof CTabFolder) { + CTabFolder tf = (CTabFolder) control; + CTabItem item = tf.getSelection(); + if (item != null) { + t = tryGetObject(item.getControl(), filter); + if (t != null) + return t; + } + } else { + Composite c = (Composite) control; + for (Control child : c.getChildren()) { + t = tryGetObject(child, filter); + if (t != null) + return t; + } + } + } + return null; + } + + @FunctionalInterface + public interface ControlFilter { + T accept(Control control); + } + +}