src/Pure/General/swing_thread.scala
author wenzelm
Thu, 15 Oct 2009 23:28:10 +0200
changeset 32952 aeb1e44fbc19
parent 32501 41aa620885c2
child 34026 0cb44ac299f8
permissions -rw-r--r--
replaced String.concat by implode; replaced String.concatWith by space_implode; replaced (Seq.flat o Seq.map) by Seq.maps; replaced List.mapPartial by map_filter; replaced List.concat by flat; replaced (flat o map) by maps, which produces less garbage;

/*  Title:      Pure/General/swing_thread.scala
    Author:     Makarius
    Author:     Fabian Immler, TU Munich

Evaluation within the AWT/Swing thread.
*/

package isabelle

import javax.swing.{SwingUtilities, Timer}
import java.awt.event.{ActionListener, ActionEvent}


object Swing_Thread
{
  /* checks */

  def assert() = Predef.assert(SwingUtilities.isEventDispatchThread())
  def require() = Predef.require(SwingUtilities.isEventDispatchThread())


  /* main dispatch queue */

  def now[A](body: => A): A = {
    var result: Option[A] = None
    if (SwingUtilities.isEventDispatchThread()) { result = Some(body) }
    else SwingUtilities.invokeAndWait(new Runnable { def run = { result = Some(body) } })
    result.get
  }

  def later(body: => Unit) {
    if (SwingUtilities.isEventDispatchThread()) body
    else SwingUtilities.invokeLater(new Runnable { def run = body })
  }


  /* delayed actions */

  private def delayed_action(first: Boolean)(time_span: Int)(action: => Unit): () => Unit =
  {
    val listener =
      new ActionListener { override def actionPerformed(e: ActionEvent) { action } }
    val timer = new Timer(time_span, listener)
    timer.setRepeats(false)

    def invoke() { if (first) timer.start() else timer.restart() }
    invoke _
  }

  // delayed action after first invocation
  def delay_first = delayed_action(true) _

  // delayed action after last invocation
  def delay_last = delayed_action(false) _
}