/******************************************************************************* * Copyright (c) 2007, 2010 Association for Decentralized Information Management * in Industry THTH ry. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ package org.simantics.utils.ui; import org.eclipse.swt.widgets.Display; /** * An overridable Runnable class that can be implemented to execute the runnable * with a specific delay. The delay is implemented using SWT's * {@link Display#timerExec(int, Runnable)}. * *

* The nice thing is that this class allows the user to schedule runs repeatedly * but guarantees that the runnable is still only ran once. *

* *

Use as follows: *

 *   DelayRunnable runnable = new DelayRunnable(display, delay) {
 *       public void perform() {
 *           // Do the things you want...
 *       }
 *   };
 * 
* After this you can do multiple schedulings of the runnable as follows, * but the Runnable will only get ran once after the specified delay. *
 * runnable.scheduleRefresh();
 * 
*

* * @author Tuukka Lehtonen */ public abstract class DelayRunnable implements Runnable { /** Default delay: 500 ms */ private static final int DEFAULT_REFRESH_DELAY_MS = 500; private int refreshDelay; private volatile boolean scheduled = false; private Display display; public DelayRunnable(Display display) { this(display, DEFAULT_REFRESH_DELAY_MS); } public DelayRunnable(Display display, int refreshDelay) { this.display = display; this.refreshDelay = refreshDelay; } protected void release() { scheduled = false; } public boolean isScheduled() { return scheduled; } public void scheduleRefresh() { synchronized (this) { if (scheduled) return; scheduled = true; } display.asyncExec(timerSync); } /** * The default implementation of run calls release first in order to allow * more schedulings of this Runnable to happen. After releasing the runnable * {@link #perform()} is called. * *

* If you need to override the release-behaviour of this DelayRunnable, you * need to override this method instead of {@link #perform()}. *

*/ public void run() { release(); perform(); } /** * The method to override for performing your own actions when this runnable * gets ran. The default implementation is empty. */ public void perform() { } /** * This exists because timerExec can only be ran from the SWT thread or the * thread that created the tree. */ private Runnable timerSync = new Runnable() { public void run() { display.timerExec(refreshDelay, DelayRunnable.this); } }; }