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.
CC @hanslovsky
Thanks @ctrueden
def run(self):
_f()
should be
def run(self):
self._f()
We could even provide convenience classes like this for all classes in the java.util.function package that would live at the top level of scijava, or maybe we could just put it at scijava.function. Unfortunately, we cannot auto map python functions/lambdas because we can only check the number of arguments but not the types, e.g. Function vs LongFunction and we do not know if anything is being returned (Consumer vs Function).
That would be quite a bit of work but is something that is probably very suitable for a student.