@@ -0,0 +1,3250 @@
+/*%0A *    Debrief - the Open Source Maritime Analysis Application%0A *    http://debrief.info%0A *%0A *    (C) 2000-2014, PlanetMayo Ltd%0A *%0A *    This library is free software; you can redistribute it and/or%0A *    modify it under the terms of the Eclipse Public License v1.0%0A *    (http://www.eclipse.org/legal/epl-v10.html)%0A *%0A *    This library is distributed in the hope that it will be useful,%0A *    but WITHOUT ANY WARRANTY; without even the implied warranty of%0A *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. %0A */%0Apackage info.limpet.ui;%0A%0Aimport org.eclipse.swt.widgets.Display;%0A%0A/**%0A * queue of events, where the event only gets run if another doesn't get placed on top of it before%0A * a specified time period passes%0A * %0A * @author ianmayo%0A * %0A */%0Apublic class EventStack%0A%7B%0A%0A  public static class DelayedEventRunner extends Thread%0A  %7B%0A%0A    private final int delay;%0A    private Runnable nextEvent = null;%0A    private Long eventReceivedTime = null;%0A%0A    public DelayedEventRunner(final int delay)%0A    %7B%0A      this.delay = delay;%0A      setDaemon(true);%0A    %7D%0A%0A    synchronized private void setNextEvent(final Runnable runnable)%0A    %7B%0A      // store the time we received this%0A      eventReceivedTime = System.currentTimeMillis();%0A%0A      // remember this event (over-writing any previous events)%0A      nextEvent = runnable;%0A    %7D%0A%0A    public void run()%0A    %7B%0A      while (true)%0A      %7B%0A        synchronized (this)%0A        %7B%0A          if (nextEvent != null)%0A          %7B%0A            boolean isDelayUp = false;%0A%0A            final long currentTime = System.currentTimeMillis();%0A%0A            // how long since we last received an event?%0A            final long elapsedTime = currentTime - eventReceivedTime;%0A%0A            // have we passed the required waiting time?%0A            isDelayUp = elapsedTime %3E delay;%0A%0A            if (isDelayUp)%0A            %7B%0A              Display.getDefault().asyncExec(nextEvent);%0A              // and clear the queue%0A              nextEvent = null;%0A            %7D%0A          %7D%0A        %7D%0A        try%0A        %7B%0A          Thread.sleep(10);%0A        %7D%0A        catch (final InterruptedException e)%0A        %7B%0A          // we can not do anything about it, let's ignore%0A        %7D%0A      %7D%0A    %7D%0A%0A  %7D%0A%0A  /**%0A   * a queue of events, where only the last one gets run - ideally placed for screen updates when%0A   * changing lots of properties. Normally changing the property of hundreds of items will trigger%0A   * hundreds of screen updates, this allows us to just fire the last one%0A   * %0A   * @param delay%0A   *          how (millis) long we should wait for another before running the current operation%0A   */%0A  public EventStack(final int delay)%0A  %7B%0A    _delay = delay;%0A    if (delay %3C= 0)%0A    %7B%0A      throw new RuntimeException(%22Delay has to be positive%22);%0A    %7D%0A  %7D%0A%0A  public void addEvent(final Runnable event)%0A  %7B%0A    if (event == null)%0A    %7B%0A      throw new RuntimeException(%22Event cannot be null%22);%0A    %7D%0A    getEventRunner().setNextEvent(event);%0A  %7D%0A%0A  final private int _delay;%0A%0A  private DelayedEventRunner eventRunner = null;%0A%0A  private DelayedEventRunner getEventRunner()%0A  %7B%0A    if (eventRunner == null)%0A    %7B%0A      eventRunner = new DelayedEventRunner(_delay);%0A      eventRunner.start();%0A    %7D%0A    return eventRunner;%0A  %7D%0A%0A%7D

introduce event stack