On Jun 3, 2009, at 2:40 AM, Meikel Brandmeyer wrote:
Hi Stephen, uh? I didn't notice you put up a swing-utils in contrib. I have a set of little macros + helper, which might also be interesting:
I like them!
(import 'javax.swing.SwingUtilities) (defn do-swing* "Run the given thunk in the Swing event thread according to the given schedule. - :later => just schedule the execution and return - :now => wait until the execution of the thunk completed." [schedule thunk] (cond (SwingUtilities/isEventDispatchThread) (thunk) (= schedule :later) (SwingUtilities/invokeLater thunk) (= schedule :now) (SwingUtilities/invokeAndWait thunk)))
I'm concerned about the first clause in the cond. Both invokeLater and invokeAndWait defer execution until all pending AWT Events have been processed. This suggests to me that they are implemented as events that go on the end of the queue. It seems to me there might be subtle bugs associated with executing the thunk immediately if we're already in the dispatch thread, but after pending events are processed if we're not.
Given that, I would suggest: (cond (= schedule :later) (SwingUtilities/invokeLater thunk) (= schedule :now) (SwingUtilities/invokeAndWait thunk))) or for better safety: (cond (= schedule :later) (SwingUtilities/invokeLater thunk) (= schedule :now) (if (SwingUtilities/isEventDispatchThread) (throwf "Cannot invokeAndWait from the Event Dispatch Thread") (SwingUtilities/invokeAndWait thunk))))With this implementation, all do-swing* thunks would operate the same way (or throw an exception) no matter which thread do-swing* is called from.
Alternatively, one might be willing to accept that something executed synchronously shouldn't need to wait in the queue for pending events to finish. We could implement that more along the lines of your original as:
(cond (= schedule :later) (SwingUtilities/invokeLater thunk) (= schedule :now) (if (SwingUtilities/isEventDispatchThread) (thunk) (SwingUtilities/invokeAndWait thunk))) nil)I do think it's an improvement for the :later case always to return immediately and for its thunk always to wait in the queue.
I added the nil at the end so the do-swing*'s return value is always nil, even in the (thunk) case.
Any thoughts?
I'm also working on some two little Action and Menu DSLs to ease the programmatic generation of Menu, Toolbars, etc. However this is not finished, yet. I'll post some code when I'm done.
I look forward to seeing them! Cheers, --Steve
smime.p7s
Description: S/MIME cryptographic signature