jpype-project / jpype

JPype is cross language bridge to allow Python programs full access to Java class libraries.
http://www.jpype.org
Other
1.07k stars 176 forks source link

Jframe in macos not working #906

Open vwxyzjn opened 3 years ago

vwxyzjn commented 3 years ago

Hi, I am having trouble running the GUIs using Jframe in macos. The code I am running is as follows:

import jpype
import jpype.imports

jpype.startJVM()
import java
import javax
from javax.swing import *

def createAndShowGUI():
    frame = JFrame("HelloWorldSwing")
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
    label = JLabel("Hello World")
    frame.getContentPane().add(label)
    frame.pack()
    frame.setVisible(True)

# Start an event loop thread to handling gui events
@jpype.JImplements(java.lang.Runnable)
class Launch:
    @jpype.JOverride
    def run(self):
        createAndShowGUI()
javax.swing.SwingUtilities.invokeLater(Launch())

And after running the code above, there is a python icon showing up in the task bar, but not really showing anything when I clicked on it as shown in the screenshot.

image

I can verify this is not an issue on the linux side.

If you guys have issues accessing a mac for debugging, I will be happy to provide a macos on EC2 for the purpose of debugging this issue. Feel free to contact me personally at costa.huang at outlook dot com to get the macos VNC credentials.

vsquared commented 2 weeks ago

No, there is no GUI with that method either.

Thrameos commented 2 weeks ago

Thanks for the feedback. It seems that all I can do is put documentation about the work around. There is really no way to support the same pattern that every other system has if they are going to force the event loop onto a specific thread. Python doesn't have a "resume from here" on another thread option so I can't really add an easy to use option.

I see virtually the same complaint going back 22 years in forum. So their bad design choices just live on forever. Much like the "Java doesn't like to be forked" and "Java gives UTF8 encoded UTF16 strings" these poor choices create restrictions that burn users year after year and poor library developers like me are always caught in the middle. Gee if only they had a large amount of money flowing in from a product line so that could address problems.

vsquared commented 2 weeks ago

I doubt that it will change anything, but below is boilerplate code that I have used on hundreds if not thousands of objc demos:

int main () {
 NSApplication *application = [NSApplication sharedApplication];
 AppDelegate *appDelegate = [[AppDelegate alloc] init];
 [application setDelegate:appDelegate];
 [application run];
return 0;
}

NSApp is just the approved shortcut to an instance of NSApplication.

Thrameos commented 2 weeks ago

I am going to sleep on it and consider some options. I am trying to make a "friendly" version for users that want to now have the main thread get taken, by simply launching Python in such a way that the main thread a side thread. I may request a few more tests to see if it deals with the issue.

Thanks so much for your help.

vsquared commented 2 weeks ago

Thanks so much for your help. No problem. Enjoyed working with you. Let me know if you need further testing.

Thrameos commented 2 weeks ago

I have looked through a good amount of code. OSX is very particular about what they consider to be main. Unless I go to the "jpython" solution in which we make a custom version of Python in which the Python thread is started on a non-main thread.

The key appears to be pthread_main_np() which is checked by Application main. The question is if there is any way to designate some other thread as main later? There seems like some there may be ways to hack it. But given the number of others that have fought the problem I doubt that something hasn't already found a clever solution.

I think the problem remains that doing research on this definitely is something that requires access to a platform. I will once again ping my local workgroup to see if there is anything that can be begged or borrowed.

vsquared commented 2 weeks ago

I don't know much about threading, but I came across this today and you're probably aware of it, but just in case it could be helpful: https://docs.python.org/3/library/asyncio-eventloop.html. Macos is a unix system and so is Linux. If you can control Linux one would think you could also control macos. As an aside, I just ran jpype code similar to that above in my prototypic generic editor and it produced a nice window with a button.

Addendum: Link doesn't work for some reason; you'll have to copy/paste it into a browser.