]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.utils.ui/src/org/simantics/utils/ui/DelayRunnable.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.utils.ui / src / org / simantics / utils / ui / DelayRunnable.java
diff --git a/bundles/org.simantics.utils.ui/src/org/simantics/utils/ui/DelayRunnable.java b/bundles/org.simantics.utils.ui/src/org/simantics/utils/ui/DelayRunnable.java
new file mode 100644 (file)
index 0000000..4969f6b
--- /dev/null
@@ -0,0 +1,112 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.utils.ui;\r
+\r
+import org.eclipse.swt.widgets.Display;\r
+\r
+/**\r
+ * An overridable Runnable class that can be implemented to execute the runnable\r
+ * with a specific delay. The delay is implemented using SWT's\r
+ * {@link Display#timerExec(int, Runnable)}.\r
+ * \r
+ * <p>\r
+ * The nice thing is that this class allows the user to schedule runs repeatedly\r
+ * but guarantees that the runnable is still only ran once.\r
+ * </p>\r
+ * \r
+ * <p>Use as follows:\r
+ * <pre>\r
+ *   DelayRunnable runnable = new DelayRunnable(display, delay) {\r
+ *       public void perform() {\r
+ *           // Do the things you want...\r
+ *       }\r
+ *   };\r
+ * </pre>\r
+ * After this you can do multiple schedulings of the runnable as follows,\r
+ * but the Runnable will only get ran once after the specified delay.\r
+ * <pre>\r
+ * runnable.scheduleRefresh();\r
+ * </pre>\r
+ * </p>\r
+ * \r
+ * @author Tuukka Lehtonen\r
+ */\r
+public abstract class DelayRunnable implements Runnable {\r
+\r
+    /** Default delay: 500 ms */\r
+    private static final int DEFAULT_REFRESH_DELAY_MS = 500; \r
+    \r
+    private int refreshDelay;\r
+    \r
+    private volatile boolean scheduled = false;\r
+    \r
+    private Display display;\r
+\r
+    public DelayRunnable(Display display) {\r
+        this(display, DEFAULT_REFRESH_DELAY_MS);\r
+    }\r
+\r
+    public DelayRunnable(Display display, int refreshDelay) {\r
+        this.display = display;\r
+        this.refreshDelay = refreshDelay;\r
+    }\r
+\r
+    protected void release() {\r
+        scheduled = false;\r
+    }\r
+    \r
+    public boolean isScheduled() {\r
+        return scheduled;\r
+    }\r
+\r
+    public void scheduleRefresh() {\r
+        synchronized (this) {\r
+            if (scheduled)\r
+                return;\r
+            scheduled = true;\r
+        }\r
+        display.asyncExec(timerSync);\r
+    }\r
+\r
+    /**\r
+     * The default implementation of run calls release first in order to allow\r
+     * more schedulings of this Runnable to happen. After releasing the runnable\r
+     * {@link #perform()} is called.\r
+     * \r
+     * <p>\r
+     * If you need to override the release-behaviour of this DelayRunnable, you\r
+     * need to override this method instead of {@link #perform()}.\r
+     * </p>\r
+     */\r
+    public void run() {\r
+        release();\r
+        perform();\r
+    }\r
+    \r
+    /**\r
+     * The method to override for performing your own actions when this runnable\r
+     * gets ran. The default implementation is empty.\r
+     */\r
+    public void perform() {\r
+    }\r
+    \r
+    /**\r
+     * This exists because timerExec can only be ran from the SWT thread or the\r
+     * thread that created the tree.\r
+     */\r
+    private Runnable timerSync = new Runnable() {\r
+        public void run() {\r
+            display.timerExec(refreshDelay, DelayRunnable.this);\r
+        }\r
+    };\r
+    \r
+}\r