◐ Shell
clean mode source ↗

Add convenience functions for running Python code on the EDT

Let's add scyjava.awt.invoke(python_function) as a shortcut for EventQueue.invokeAndWait(java_runnable_object), and scyjava.awt.queue(python_function) as a shortcut for EventQueue.invokeLater(java_runnable_object). Internally it would work like this:

from jnius import PythonJavaClass, java_method

class JavaRunnable(PythonJavaClass):
    __javainterfaces__ = ['java/lang/Runnable']

    def __init__(self, f):
        super(JavaRunnable, self).__init__()
        self._f = f

    @java_method('()V')
    def run(self):
        _f()

EventQueue = autoclass('java.awt.EventQueue')
EventQueue.invokeLater(JavaRunnable(lambda: ij.ui().showDialog('hello')))

Where ij.ui().showDialog('hello') is something that—at least on macOS—hangs the Python process when run from the wrong native thread.

As part of this work, we may want to enhance the to_java method to accept Python functions and have it wrap them as Runnables.