scyjava icon indicating copy to clipboard operation
scyjava copied to clipboard

Add convenience functions for running Python code on the EDT

Open ctrueden opened this issue 6 years ago • 2 comments

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.

ctrueden avatar Dec 16 '19 22:12 ctrueden

CC @hanslovsky

ctrueden avatar Dec 16 '19 22:12 ctrueden

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.

hanslovsky avatar Dec 17 '19 11:12 hanslovsky