Skip to content

Instantly share code, notes, and snippets.

@rherrmann
Created October 5, 2014 13:52
Show Gist options
  • Save rherrmann/43a9b3645694a2febef8 to your computer and use it in GitHub Desktop.
Save rherrmann/43a9b3645694a2febef8 to your computer and use it in GitHub Desktop.
Helper class to periodically run code that updates SWT widgets
/***************************************************************************************************
* Copyright (c) 2014 Rüdiger Herrmann
* 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:
* Rüdiger Herrmann - initial API and implementation
**************************************************************************************************/
package com.codeaffine.util;
import static com.google.common.collect.Iterables.toArray;
import static com.google.common.collect.Lists.newLinkedList;
import java.util.Collection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Widget;
/**
* With this helper class, periodic UI updates can be scheduled.
* <p>
* This example will update the text if the labels every Minute until the shell gets disposed of.
* </p>
* <pre>
* Shell shell = new Shell( ... );
* Label label1 = new Label( shell, SWT.NONE );
* Label label2 = new Label( shell, SWT.NONE );
* Runnable runnable = new Runnable() {
* public void run() {
* label1.setText( ... );
* label2.setText( ... );
* }
* };
* PeriodicUIUpdater.registerRunnable( shell, runnable );
* </pre>
*/
public class PeriodicUIUpdater {
public static void registerRunnable( Widget widget, Runnable runnable ) {
forDisplay( widget.getDisplay() ).addRunnable( widget, runnable );
}
private static final String DISPLAY_DATA = PeriodicUIUpdater.class.getName();
static final int TIMER_INTERVAL = 60 * 1000;
static PeriodicUIUpdater forDisplay( Display display ) {
PeriodicUIUpdater result = ( PeriodicUIUpdater )display.getData( DISPLAY_DATA );
if( result == null ) {
result = new PeriodicUIUpdater( display );
}
return result;
}
private final Display display;
private final Runnable timerRunnable;
private final Collection<Runnable> runnables;
private PeriodicUIUpdater( Display display ) {
this.display = display;
this.display.setData( DISPLAY_DATA, this );
this.runnables = newLinkedList();
this.timerRunnable = new TimerRunnable();
scheduleTimerRunnable();
}
void addRunnable( Widget widget, Runnable runnable ) {
runnables.add( runnable );
widget.addListener( SWT.Dispose, new WidgetDisposeListener( runnable ) );
}
void removeRunnable( Runnable runnable ) {
runnables.remove( runnable );
if( runnables.isEmpty() ) {
dispose();
}
}
void dispose() {
display.timerExec( -1, timerRunnable );
display.setData( DISPLAY_DATA, null );
}
void updateUI() {
runRunnables();
scheduleTimerRunnable();
}
private void scheduleTimerRunnable() {
display.timerExec( TIMER_INTERVAL, timerRunnable );
}
private void runRunnables() {
Runnable[] runnablesCopy = toArray( runnables, Runnable.class );
for( Runnable runnable : runnablesCopy ) {
runnable.run();
}
}
class TimerRunnable implements Runnable {
@Override
public void run() {
updateUI();
}
}
private class WidgetDisposeListener implements Listener {
private final Runnable runnable;
WidgetDisposeListener( Runnable runnable ) {
this.runnable = runnable;
}
@Override
public void handleEvent( Event event ) {
removeRunnable( runnable );
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment