--- /dev/null
+/*******************************************************************************\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