src/Pure/GUI/swing_thread.scala
author wenzelm
Tue, 22 Apr 2014 23:49:15 +0200
changeset 56662 f373fb77e0a4
parent 55618 995162143ef4
child 56770 e160ae47db94
permissions -rw-r--r--
avoid "Adaptation of argument list by inserting ()" -- deprecated in scala-2.11.0;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
53783
f5e9d182f645 clarified location of GUI modules (which depend on Swing of JFX);
wenzelm
parents: 52859
diff changeset
     1
/*  Title:      Pure/GUI/swing_thread.scala
53853
e8430d668f44 more quasi-generic PIDE modules (NB: Swing/JFX needs to be kept separate from non-GUI material);
wenzelm
parents: 53783
diff changeset
     2
    Module:     PIDE-GUI
29202
2454172eddae Swing utilities.
wenzelm
parents:
diff changeset
     3
    Author:     Makarius
2454172eddae Swing utilities.
wenzelm
parents:
diff changeset
     4
31862
53acb8ec6c51 renamed Swing to Swing_Thread, to avoid overlap with scala.swing.Swing;
wenzelm
parents: 29777
diff changeset
     5
Evaluation within the AWT/Swing thread.
29202
2454172eddae Swing utilities.
wenzelm
parents:
diff changeset
     6
*/
2454172eddae Swing utilities.
wenzelm
parents:
diff changeset
     7
2454172eddae Swing utilities.
wenzelm
parents:
diff changeset
     8
package isabelle
2454172eddae Swing utilities.
wenzelm
parents:
diff changeset
     9
55618
995162143ef4 tuned imports;
wenzelm
parents: 53853
diff changeset
    10
31942
63466160ff27 renamed Delay to Swing_Thread.delay (action is executed within AWT thread!);
wenzelm
parents: 31862
diff changeset
    11
import javax.swing.{SwingUtilities, Timer}
63466160ff27 renamed Delay to Swing_Thread.delay (action is executed within AWT thread!);
wenzelm
parents: 31862
diff changeset
    12
import java.awt.event.{ActionListener, ActionEvent}
63466160ff27 renamed Delay to Swing_Thread.delay (action is executed within AWT thread!);
wenzelm
parents: 31862
diff changeset
    13
29202
2454172eddae Swing utilities.
wenzelm
parents:
diff changeset
    14
31862
53acb8ec6c51 renamed Swing to Swing_Thread, to avoid overlap with scala.swing.Swing;
wenzelm
parents: 29777
diff changeset
    15
object Swing_Thread
29202
2454172eddae Swing utilities.
wenzelm
parents:
diff changeset
    16
{
32494
4ab2292e452a explicit checks;
wenzelm
parents: 31942
diff changeset
    17
  /* checks */
4ab2292e452a explicit checks;
wenzelm
parents: 31942
diff changeset
    18
52859
f31624cc4467 tuned signature;
wenzelm
parents: 52477
diff changeset
    19
  def assert[A](body: => A) =
f31624cc4467 tuned signature;
wenzelm
parents: 52477
diff changeset
    20
  {
f31624cc4467 tuned signature;
wenzelm
parents: 52477
diff changeset
    21
    Predef.assert(SwingUtilities.isEventDispatchThread())
f31624cc4467 tuned signature;
wenzelm
parents: 52477
diff changeset
    22
    body
f31624cc4467 tuned signature;
wenzelm
parents: 52477
diff changeset
    23
  }
32494
4ab2292e452a explicit checks;
wenzelm
parents: 31942
diff changeset
    24
52859
f31624cc4467 tuned signature;
wenzelm
parents: 52477
diff changeset
    25
  def require[A](body: => A) =
f31624cc4467 tuned signature;
wenzelm
parents: 52477
diff changeset
    26
  {
f31624cc4467 tuned signature;
wenzelm
parents: 52477
diff changeset
    27
    Predef.require(SwingUtilities.isEventDispatchThread())
f31624cc4467 tuned signature;
wenzelm
parents: 52477
diff changeset
    28
    body
f31624cc4467 tuned signature;
wenzelm
parents: 52477
diff changeset
    29
  }
52477
025b3777e592 tuned signature;
wenzelm
parents: 49251
diff changeset
    30
32494
4ab2292e452a explicit checks;
wenzelm
parents: 31942
diff changeset
    31
31942
63466160ff27 renamed Delay to Swing_Thread.delay (action is executed within AWT thread!);
wenzelm
parents: 31862
diff changeset
    32
  /* main dispatch queue */
63466160ff27 renamed Delay to Swing_Thread.delay (action is executed within AWT thread!);
wenzelm
parents: 31862
diff changeset
    33
34026
0cb44ac299f8 added future;
wenzelm
parents: 32501
diff changeset
    34
  def now[A](body: => A): A =
0cb44ac299f8 added future;
wenzelm
parents: 32501
diff changeset
    35
  {
48000
880f1693299a further attempts to simplify/robustify Swing_Thread.now, to avoid spurious physical race conditions on Java 6 / Mac OS X;
wenzelm
parents: 47989
diff changeset
    36
    if (SwingUtilities.isEventDispatchThread()) body
880f1693299a further attempts to simplify/robustify Swing_Thread.now, to avoid spurious physical race conditions on Java 6 / Mac OS X;
wenzelm
parents: 47989
diff changeset
    37
    else {
56662
f373fb77e0a4 avoid "Adaptation of argument list by inserting ()" -- deprecated in scala-2.11.0;
wenzelm
parents: 55618
diff changeset
    38
      lazy val result = { assert { Exn.capture(body) } }
48000
880f1693299a further attempts to simplify/robustify Swing_Thread.now, to avoid spurious physical race conditions on Java 6 / Mac OS X;
wenzelm
parents: 47989
diff changeset
    39
      SwingUtilities.invokeAndWait(new Runnable { def run = result })
880f1693299a further attempts to simplify/robustify Swing_Thread.now, to avoid spurious physical race conditions on Java 6 / Mac OS X;
wenzelm
parents: 47989
diff changeset
    40
      Exn.release(result)
880f1693299a further attempts to simplify/robustify Swing_Thread.now, to avoid spurious physical race conditions on Java 6 / Mac OS X;
wenzelm
parents: 47989
diff changeset
    41
    }
29649
8b0c1397868e more robust treatment of SwingUtilities.isEventDispatchThread;
wenzelm
parents: 29202
diff changeset
    42
  }
29202
2454172eddae Swing utilities.
wenzelm
parents:
diff changeset
    43
34299
68716caa7745 Swing_Thread.future: plain Future.value if this is already Swing;
wenzelm
parents: 34217
diff changeset
    44
  def future[A](body: => A): Future[A] =
68716caa7745 Swing_Thread.future: plain Future.value if this is already Swing;
wenzelm
parents: 34217
diff changeset
    45
  {
68716caa7745 Swing_Thread.future: plain Future.value if this is already Swing;
wenzelm
parents: 34217
diff changeset
    46
    if (SwingUtilities.isEventDispatchThread()) Future.value(body)
68716caa7745 Swing_Thread.future: plain Future.value if this is already Swing;
wenzelm
parents: 34217
diff changeset
    47
    else Future.fork { now(body) }
68716caa7745 Swing_Thread.future: plain Future.value if this is already Swing;
wenzelm
parents: 34217
diff changeset
    48
  }
34026
0cb44ac299f8 added future;
wenzelm
parents: 32501
diff changeset
    49
34299
68716caa7745 Swing_Thread.future: plain Future.value if this is already Swing;
wenzelm
parents: 34217
diff changeset
    50
  def later(body: => Unit)
68716caa7745 Swing_Thread.future: plain Future.value if this is already Swing;
wenzelm
parents: 34217
diff changeset
    51
  {
32494
4ab2292e452a explicit checks;
wenzelm
parents: 31942
diff changeset
    52
    if (SwingUtilities.isEventDispatchThread()) body
29649
8b0c1397868e more robust treatment of SwingUtilities.isEventDispatchThread;
wenzelm
parents: 29202
diff changeset
    53
    else SwingUtilities.invokeLater(new Runnable { def run = body })
8b0c1397868e more robust treatment of SwingUtilities.isEventDispatchThread;
wenzelm
parents: 29202
diff changeset
    54
  }
31942
63466160ff27 renamed Delay to Swing_Thread.delay (action is executed within AWT thread!);
wenzelm
parents: 31862
diff changeset
    55
63466160ff27 renamed Delay to Swing_Thread.delay (action is executed within AWT thread!);
wenzelm
parents: 31862
diff changeset
    56
63466160ff27 renamed Delay to Swing_Thread.delay (action is executed within AWT thread!);
wenzelm
parents: 31862
diff changeset
    57
  /* delayed actions */
63466160ff27 renamed Delay to Swing_Thread.delay (action is executed within AWT thread!);
wenzelm
parents: 31862
diff changeset
    58
49195
9d10bd85c1be more explicit Delay operations;
wenzelm
parents: 48000
diff changeset
    59
  abstract class Delay extends
31942
63466160ff27 renamed Delay to Swing_Thread.delay (action is executed within AWT thread!);
wenzelm
parents: 31862
diff changeset
    60
  {
49195
9d10bd85c1be more explicit Delay operations;
wenzelm
parents: 48000
diff changeset
    61
    def invoke(): Unit
9d10bd85c1be more explicit Delay operations;
wenzelm
parents: 48000
diff changeset
    62
    def revoke(): Unit
49196
1d63ceb0d177 postpone update of text overview panel after incoming session edits, to improve reactivity of editing massive theories like src/HOL/Multivariate_Analysis;
wenzelm
parents: 49195
diff changeset
    63
    def postpone(time: Time): Unit
49195
9d10bd85c1be more explicit Delay operations;
wenzelm
parents: 48000
diff changeset
    64
  }
9d10bd85c1be more explicit Delay operations;
wenzelm
parents: 48000
diff changeset
    65
49249
c763444b34ad dynamic evaluation of time (e.g. via options);
wenzelm
parents: 49196
diff changeset
    66
  private def delayed_action(first: Boolean)(time: => Time)(action: => Unit): Delay =
49195
9d10bd85c1be more explicit Delay operations;
wenzelm
parents: 48000
diff changeset
    67
    new Delay {
9d10bd85c1be more explicit Delay operations;
wenzelm
parents: 48000
diff changeset
    68
      private val timer = new Timer(time.ms.toInt, null)
9d10bd85c1be more explicit Delay operations;
wenzelm
parents: 48000
diff changeset
    69
      timer.setRepeats(false)
9d10bd85c1be more explicit Delay operations;
wenzelm
parents: 48000
diff changeset
    70
      timer.addActionListener(new ActionListener {
9d10bd85c1be more explicit Delay operations;
wenzelm
parents: 48000
diff changeset
    71
        override def actionPerformed(e: ActionEvent) {
56662
f373fb77e0a4 avoid "Adaptation of argument list by inserting ()" -- deprecated in scala-2.11.0;
wenzelm
parents: 55618
diff changeset
    72
          assert {}
49249
c763444b34ad dynamic evaluation of time (e.g. via options);
wenzelm
parents: 49196
diff changeset
    73
          timer.setInitialDelay(time.ms.toInt)
49195
9d10bd85c1be more explicit Delay operations;
wenzelm
parents: 48000
diff changeset
    74
          action
9d10bd85c1be more explicit Delay operations;
wenzelm
parents: 48000
diff changeset
    75
        }
9d10bd85c1be more explicit Delay operations;
wenzelm
parents: 48000
diff changeset
    76
      })
9d10bd85c1be more explicit Delay operations;
wenzelm
parents: 48000
diff changeset
    77
9d10bd85c1be more explicit Delay operations;
wenzelm
parents: 48000
diff changeset
    78
      def invoke()
9d10bd85c1be more explicit Delay operations;
wenzelm
parents: 48000
diff changeset
    79
      {
56662
f373fb77e0a4 avoid "Adaptation of argument list by inserting ()" -- deprecated in scala-2.11.0;
wenzelm
parents: 55618
diff changeset
    80
        require {}
49195
9d10bd85c1be more explicit Delay operations;
wenzelm
parents: 48000
diff changeset
    81
        if (first) timer.start() else timer.restart()
9d10bd85c1be more explicit Delay operations;
wenzelm
parents: 48000
diff changeset
    82
      }
9d10bd85c1be more explicit Delay operations;
wenzelm
parents: 48000
diff changeset
    83
9d10bd85c1be more explicit Delay operations;
wenzelm
parents: 48000
diff changeset
    84
      def revoke()
9d10bd85c1be more explicit Delay operations;
wenzelm
parents: 48000
diff changeset
    85
      {
56662
f373fb77e0a4 avoid "Adaptation of argument list by inserting ()" -- deprecated in scala-2.11.0;
wenzelm
parents: 55618
diff changeset
    86
        require {}
49195
9d10bd85c1be more explicit Delay operations;
wenzelm
parents: 48000
diff changeset
    87
        timer.stop()
49249
c763444b34ad dynamic evaluation of time (e.g. via options);
wenzelm
parents: 49196
diff changeset
    88
        timer.setInitialDelay(time.ms.toInt)
49195
9d10bd85c1be more explicit Delay operations;
wenzelm
parents: 48000
diff changeset
    89
      }
49196
1d63ceb0d177 postpone update of text overview panel after incoming session edits, to improve reactivity of editing massive theories like src/HOL/Multivariate_Analysis;
wenzelm
parents: 49195
diff changeset
    90
1d63ceb0d177 postpone update of text overview panel after incoming session edits, to improve reactivity of editing massive theories like src/HOL/Multivariate_Analysis;
wenzelm
parents: 49195
diff changeset
    91
      def postpone(alt_time: Time)
1d63ceb0d177 postpone update of text overview panel after incoming session edits, to improve reactivity of editing massive theories like src/HOL/Multivariate_Analysis;
wenzelm
parents: 49195
diff changeset
    92
      {
56662
f373fb77e0a4 avoid "Adaptation of argument list by inserting ()" -- deprecated in scala-2.11.0;
wenzelm
parents: 55618
diff changeset
    93
        require {}
49196
1d63ceb0d177 postpone update of text overview panel after incoming session edits, to improve reactivity of editing massive theories like src/HOL/Multivariate_Analysis;
wenzelm
parents: 49195
diff changeset
    94
        if (timer.isRunning) {
49251
cd28155bb7d5 uniform operation on initial delay;
wenzelm
parents: 49249
diff changeset
    95
          timer.setInitialDelay(timer.getInitialDelay max alt_time.ms.toInt)
49196
1d63ceb0d177 postpone update of text overview panel after incoming session edits, to improve reactivity of editing massive theories like src/HOL/Multivariate_Analysis;
wenzelm
parents: 49195
diff changeset
    96
          timer.restart()
1d63ceb0d177 postpone update of text overview panel after incoming session edits, to improve reactivity of editing massive theories like src/HOL/Multivariate_Analysis;
wenzelm
parents: 49195
diff changeset
    97
        }
1d63ceb0d177 postpone update of text overview panel after incoming session edits, to improve reactivity of editing massive theories like src/HOL/Multivariate_Analysis;
wenzelm
parents: 49195
diff changeset
    98
      }
38223
2a368e8e0a80 more explicit treatment of Swing thread context;
wenzelm
parents: 36676
diff changeset
    99
    }
32501
41aa620885c2 refined delay into delay_first/delay_last;
wenzelm
parents: 32494
diff changeset
   100
41aa620885c2 refined delay into delay_first/delay_last;
wenzelm
parents: 32494
diff changeset
   101
  // delayed action after first invocation
41aa620885c2 refined delay into delay_first/delay_last;
wenzelm
parents: 32494
diff changeset
   102
  def delay_first = delayed_action(true) _
41aa620885c2 refined delay into delay_first/delay_last;
wenzelm
parents: 32494
diff changeset
   103
41aa620885c2 refined delay into delay_first/delay_last;
wenzelm
parents: 32494
diff changeset
   104
  // delayed action after last invocation
41aa620885c2 refined delay into delay_first/delay_last;
wenzelm
parents: 32494
diff changeset
   105
  def delay_last = delayed_action(false) _
29202
2454172eddae Swing utilities.
wenzelm
parents:
diff changeset
   106
}