Trying to style SwingNodes in JavaFX with GTKLookAndFeel freezes application
Asked Answered
R

1

48

We have a Java application that used Swing, but we are migrating it to JavaFX. Therefore, we wrap the old Swing code into SwingNodes and replace them step-by-step.

Before migrating, the Swing application used com.sun.java.swing.plaf.gtk.GTKLookAndFeel as look-and-feel (default on Ubuntu). We used following code to set it (if available):

for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
  if (info.getClassName().equals("com.sun.java.swing.plaf.gtk.GTKLookAndFeel")) {
    UIManager.setLookAndFeel(info.getClassName());
  }
}

This worked fine. Yet, after switching to JavaFX, the call to UIManager.setLookAndFeel() freezes the application, and nothing happens. The manual setting of the look-and-feel is needed since we want to still style the Swing components that have not been migrated to JavaFX based on the GTKLookAndFeel.

Further info: This only does not work with com.sun.java.swing.plaf.gtk.GTKLookAndFeel, since it works when using javax.swing.plaf.metal.MetalLookAndFeel, javax.swing.plaf.nimbus.NimbusLookAndFeel or com.sun.java.swing.plaf.motif.MotifLookAndFeel.

What can we do to make it work with GTKLookAndFeel to style our Swing components in the SwingNodes?

Raeraeann answered 4/5, 2017 at 15:28 Comment(14)
Are you doing it in the correct thread? Swing code needs to be run inside EventQueue.invokeLater.Greasewood
@VGR: Didn't do that before, changed it now, but still does not change the behavior. Still freezes the application.Raeraeann
Try running it on the command line, and dumping all thread stacks. On Windows, this is done with Ctrl-Break; on other systems, SIGQUIT will do it, accomplished with Ctrl-\ or a separate kill -3 command. One of the stack traces should indicate where setLookAndFeel is stuck.Greasewood
@VGR: The thread that is running the look-and-feel setting seems to be stuck at com.sun.java.swing.plaf.gtk.GTKEngine.native_get_gtk_setting(Native Method)... Tested this with a thread dump and the eclipse debugger.Raeraeann
Can you provide a minimal sample? I'm running this snippet pastebin.com/wnLFqD6i on Xfce with the latest GTK and Java 8 u121, it runs fine. Looking at native_get_gtk_setting‌, there's a synchronize block, seems suspicious. By the way, have you tried -Dswing.defaultlaf=com.sun.java.swing.plaf.gtk.GTKLookAndFeel?Slovenia
@AndreLDM: Okay, your example also works on my machine. We have a JTabbedPane that gets set as a SwingNode's content in our view's controller's initialize method, and we are currently investigating if it has something to do with that. It seems that the constructor call of JTabbedPane hangs the application. I will try to create a minimal example.Raeraeann
You can also provide a thread dump with jstack -l, it will show you if there is a deadlock. You guys mentioned that the thread was stuck in native_get_gtk_setting‌​, and that this method is synchronized, so maybe another thread is holding the lock. And that might happen because Swing and JavaFX each have their own thread...Ashjian
Is the installed version of GTK >=2.2? I know this is an old question, just wanted to find out if you found a solution to this issue.Subway
@ChetanJadhavCD: I have access to the PC again tomorrow, then I can check. I know the OS is a default Ubuntu 16.04 LTS install.Raeraeann
@ChetanJadhavCD dpkg -s libgtk2.0-0|grep '^Version' returns Version: 2.24.30-1ubuntu1.16.04.2 and dpkg -s libgtk-3-0|grep '^Version' returns Version: 3.18.9-1ubuntu3.3Raeraeann
Sorry @MarkusWeninger that was the only thing I had in mind that I could suggest, I dunno what else to try at this point.Subway
I came across similar scenario with only the swing components and I think this is a problem with the GKT deadlocking. These posts bugs.eclipse.org/bugs/show_bug.cgi?id=341538 and bugs.eclipse.org/bugs/show_bug.cgi?id=341799 helped me solve the issue by calling gdk_threads_leave() before Swing/AWT dispatches the threads.Vizza
@hari Thank you for your help. In the meantime since I asked this question we ported all SwingNodes. If I find the time, I will set up an example application to test it.Raeraeann
Also: shouldn't there be a break statement in your if ?Aindrea
C
1

Gui components need to be updated into gui threads.

Try one of the following:

SwingUtilities.invokeLater(() -> {
//commands
});

javafx.application.Platform.runLater(() -> {
//commands
});
Coquelicot answered 7/2, 2018 at 17:53 Comment(1)
Tried both before, and both do not resolve the problem.Raeraeann

© 2022 - 2024 — McMap. All rights reserved.