| author | nipkow | 
| Mon, 13 Jan 2014 07:33:51 +0100 | |
| changeset 55003 | c65fd9218ea1 | 
| parent 53853 | e8430d668f44 | 
| child 55618 | 995162143ef4 | 
| permissions | -rw-r--r-- | 
| 53783 
f5e9d182f645
clarified location of GUI modules (which depend on Swing of JFX);
 wenzelm parents: 
52859diff
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: 
53783diff
changeset | 2 | Module: PIDE-GUI | 
| 29202 | 3 | Author: Makarius | 
| 4 | ||
| 31862 
53acb8ec6c51
renamed Swing to Swing_Thread, to avoid overlap with scala.swing.Swing;
 wenzelm parents: 
29777diff
changeset | 5 | Evaluation within the AWT/Swing thread. | 
| 29202 | 6 | */ | 
| 7 | ||
| 8 | package isabelle | |
| 9 | ||
| 31942 
63466160ff27
renamed Delay to Swing_Thread.delay (action is executed within AWT thread!);
 wenzelm parents: 
31862diff
changeset | 10 | import javax.swing.{SwingUtilities, Timer}
 | 
| 
63466160ff27
renamed Delay to Swing_Thread.delay (action is executed within AWT thread!);
 wenzelm parents: 
31862diff
changeset | 11 | import java.awt.event.{ActionListener, ActionEvent}
 | 
| 
63466160ff27
renamed Delay to Swing_Thread.delay (action is executed within AWT thread!);
 wenzelm parents: 
31862diff
changeset | 12 | |
| 29202 | 13 | |
| 31862 
53acb8ec6c51
renamed Swing to Swing_Thread, to avoid overlap with scala.swing.Swing;
 wenzelm parents: 
29777diff
changeset | 14 | object Swing_Thread | 
| 29202 | 15 | {
 | 
| 32494 | 16 | /* checks */ | 
| 17 | ||
| 52859 | 18 | def assert[A](body: => A) = | 
| 19 |   {
 | |
| 20 | Predef.assert(SwingUtilities.isEventDispatchThread()) | |
| 21 | body | |
| 22 | } | |
| 32494 | 23 | |
| 52859 | 24 | def require[A](body: => A) = | 
| 25 |   {
 | |
| 26 | Predef.require(SwingUtilities.isEventDispatchThread()) | |
| 27 | body | |
| 28 | } | |
| 52477 | 29 | |
| 32494 | 30 | |
| 31942 
63466160ff27
renamed Delay to Swing_Thread.delay (action is executed within AWT thread!);
 wenzelm parents: 
31862diff
changeset | 31 | /* main dispatch queue */ | 
| 
63466160ff27
renamed Delay to Swing_Thread.delay (action is executed within AWT thread!);
 wenzelm parents: 
31862diff
changeset | 32 | |
| 34026 | 33 | def now[A](body: => A): A = | 
| 34 |   {
 | |
| 48000 
880f1693299a
further attempts to simplify/robustify Swing_Thread.now, to avoid spurious physical race conditions on Java 6 / Mac OS X;
 wenzelm parents: 
47989diff
changeset | 35 | 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: 
47989diff
changeset | 36 |     else {
 | 
| 
880f1693299a
further attempts to simplify/robustify Swing_Thread.now, to avoid spurious physical race conditions on Java 6 / Mac OS X;
 wenzelm parents: 
47989diff
changeset | 37 |       lazy val result = { assert(); Exn.capture(body) }
 | 
| 
880f1693299a
further attempts to simplify/robustify Swing_Thread.now, to avoid spurious physical race conditions on Java 6 / Mac OS X;
 wenzelm parents: 
47989diff
changeset | 38 |       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: 
47989diff
changeset | 39 | 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: 
47989diff
changeset | 40 | } | 
| 29649 
8b0c1397868e
more robust treatment of SwingUtilities.isEventDispatchThread;
 wenzelm parents: 
29202diff
changeset | 41 | } | 
| 29202 | 42 | |
| 34299 
68716caa7745
Swing_Thread.future: plain Future.value if this is already Swing;
 wenzelm parents: 
34217diff
changeset | 43 | def future[A](body: => A): Future[A] = | 
| 
68716caa7745
Swing_Thread.future: plain Future.value if this is already Swing;
 wenzelm parents: 
34217diff
changeset | 44 |   {
 | 
| 
68716caa7745
Swing_Thread.future: plain Future.value if this is already Swing;
 wenzelm parents: 
34217diff
changeset | 45 | if (SwingUtilities.isEventDispatchThread()) Future.value(body) | 
| 
68716caa7745
Swing_Thread.future: plain Future.value if this is already Swing;
 wenzelm parents: 
34217diff
changeset | 46 |     else Future.fork { now(body) }
 | 
| 
68716caa7745
Swing_Thread.future: plain Future.value if this is already Swing;
 wenzelm parents: 
34217diff
changeset | 47 | } | 
| 34026 | 48 | |
| 34299 
68716caa7745
Swing_Thread.future: plain Future.value if this is already Swing;
 wenzelm parents: 
34217diff
changeset | 49 | def later(body: => Unit) | 
| 
68716caa7745
Swing_Thread.future: plain Future.value if this is already Swing;
 wenzelm parents: 
34217diff
changeset | 50 |   {
 | 
| 32494 | 51 | if (SwingUtilities.isEventDispatchThread()) body | 
| 29649 
8b0c1397868e
more robust treatment of SwingUtilities.isEventDispatchThread;
 wenzelm parents: 
29202diff
changeset | 52 |     else SwingUtilities.invokeLater(new Runnable { def run = body })
 | 
| 
8b0c1397868e
more robust treatment of SwingUtilities.isEventDispatchThread;
 wenzelm parents: 
29202diff
changeset | 53 | } | 
| 31942 
63466160ff27
renamed Delay to Swing_Thread.delay (action is executed within AWT thread!);
 wenzelm parents: 
31862diff
changeset | 54 | |
| 
63466160ff27
renamed Delay to Swing_Thread.delay (action is executed within AWT thread!);
 wenzelm parents: 
31862diff
changeset | 55 | |
| 
63466160ff27
renamed Delay to Swing_Thread.delay (action is executed within AWT thread!);
 wenzelm parents: 
31862diff
changeset | 56 | /* delayed actions */ | 
| 
63466160ff27
renamed Delay to Swing_Thread.delay (action is executed within AWT thread!);
 wenzelm parents: 
31862diff
changeset | 57 | |
| 49195 | 58 | abstract class Delay extends | 
| 31942 
63466160ff27
renamed Delay to Swing_Thread.delay (action is executed within AWT thread!);
 wenzelm parents: 
31862diff
changeset | 59 |   {
 | 
| 49195 | 60 | def invoke(): Unit | 
| 61 | 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: 
49195diff
changeset | 62 | def postpone(time: Time): Unit | 
| 49195 | 63 | } | 
| 64 | ||
| 49249 | 65 | private def delayed_action(first: Boolean)(time: => Time)(action: => Unit): Delay = | 
| 49195 | 66 |     new Delay {
 | 
| 67 | private val timer = new Timer(time.ms.toInt, null) | |
| 68 | timer.setRepeats(false) | |
| 69 |       timer.addActionListener(new ActionListener {
 | |
| 70 |         override def actionPerformed(e: ActionEvent) {
 | |
| 71 | assert() | |
| 49249 | 72 | timer.setInitialDelay(time.ms.toInt) | 
| 49195 | 73 | action | 
| 74 | } | |
| 75 | }) | |
| 76 | ||
| 77 | def invoke() | |
| 78 |       {
 | |
| 79 | require() | |
| 80 | if (first) timer.start() else timer.restart() | |
| 81 | } | |
| 82 | ||
| 83 | def revoke() | |
| 84 |       {
 | |
| 85 | require() | |
| 86 | timer.stop() | |
| 49249 | 87 | timer.setInitialDelay(time.ms.toInt) | 
| 49195 | 88 | } | 
| 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: 
49195diff
changeset | 89 | |
| 
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: 
49195diff
changeset | 90 | 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: 
49195diff
changeset | 91 |       {
 | 
| 
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: 
49195diff
changeset | 92 | require() | 
| 
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: 
49195diff
changeset | 93 |         if (timer.isRunning) {
 | 
| 49251 | 94 | 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: 
49195diff
changeset | 95 | 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: 
49195diff
changeset | 96 | } | 
| 
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: 
49195diff
changeset | 97 | } | 
| 38223 | 98 | } | 
| 32501 | 99 | |
| 100 | // delayed action after first invocation | |
| 101 | def delay_first = delayed_action(true) _ | |
| 102 | ||
| 103 | // delayed action after last invocation | |
| 104 | def delay_last = delayed_action(false) _ | |
| 29202 | 105 | } |