]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.utils.ui/src/org/simantics/utils/ui/DelayRunnable.java
Sync git svn branch with SVN repository r33269.
[simantics/platform.git] / bundles / org.simantics.utils.ui / src / org / simantics / utils / ui / DelayRunnable.java
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
3  * in Industry THTH ry.\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.utils.ui;\r
13 \r
14 import org.eclipse.swt.widgets.Display;\r
15 \r
16 /**\r
17  * An overridable Runnable class that can be implemented to execute the runnable\r
18  * with a specific delay. The delay is implemented using SWT's\r
19  * {@link Display#timerExec(int, Runnable)}.\r
20  * \r
21  * <p>\r
22  * The nice thing is that this class allows the user to schedule runs repeatedly\r
23  * but guarantees that the runnable is still only ran once.\r
24  * </p>\r
25  * \r
26  * <p>Use as follows:\r
27  * <pre>\r
28  *   DelayRunnable runnable = new DelayRunnable(display, delay) {\r
29  *       public void perform() {\r
30  *           // Do the things you want...\r
31  *       }\r
32  *   };\r
33  * </pre>\r
34  * After this you can do multiple schedulings of the runnable as follows,\r
35  * but the Runnable will only get ran once after the specified delay.\r
36  * <pre>\r
37  * runnable.scheduleRefresh();\r
38  * </pre>\r
39  * </p>\r
40  * \r
41  * @author Tuukka Lehtonen\r
42  */\r
43 public abstract class DelayRunnable implements Runnable {\r
44 \r
45     /** Default delay: 500 ms */\r
46     private static final int DEFAULT_REFRESH_DELAY_MS = 500; \r
47     \r
48     private int refreshDelay;\r
49     \r
50     private volatile boolean scheduled = false;\r
51     \r
52     private Display display;\r
53 \r
54     public DelayRunnable(Display display) {\r
55         this(display, DEFAULT_REFRESH_DELAY_MS);\r
56     }\r
57 \r
58     public DelayRunnable(Display display, int refreshDelay) {\r
59         this.display = display;\r
60         this.refreshDelay = refreshDelay;\r
61     }\r
62 \r
63     protected void release() {\r
64         scheduled = false;\r
65     }\r
66     \r
67     public boolean isScheduled() {\r
68         return scheduled;\r
69     }\r
70 \r
71     public void scheduleRefresh() {\r
72         synchronized (this) {\r
73             if (scheduled)\r
74                 return;\r
75             scheduled = true;\r
76         }\r
77         display.asyncExec(timerSync);\r
78     }\r
79 \r
80     /**\r
81      * The default implementation of run calls release first in order to allow\r
82      * more schedulings of this Runnable to happen. After releasing the runnable\r
83      * {@link #perform()} is called.\r
84      * \r
85      * <p>\r
86      * If you need to override the release-behaviour of this DelayRunnable, you\r
87      * need to override this method instead of {@link #perform()}.\r
88      * </p>\r
89      */\r
90     public void run() {\r
91         release();\r
92         perform();\r
93     }\r
94     \r
95     /**\r
96      * The method to override for performing your own actions when this runnable\r
97      * gets ran. The default implementation is empty.\r
98      */\r
99     public void perform() {\r
100     }\r
101     \r
102     /**\r
103      * This exists because timerExec can only be ran from the SWT thread or the\r
104      * thread that created the tree.\r
105      */\r
106     private Runnable timerSync = new Runnable() {\r
107         public void run() {\r
108             display.timerExec(refreshDelay, DelayRunnable.this);\r
109         }\r
110     };\r
111     \r
112 }\r