尝试使用GTKLookAndFeel在JavaFX中设置SwingNodes的样式会导致应用程序冻结。

48

我们有一个使用Swing的Java应用程序,但我们正在将其迁移到JavaFX。因此,我们将旧的Swing代码包装到SwingNode中,并逐步替换它们。

在迁移之前,Swing应用程序使用com.sun.java.swing.plaf.gtk.GTKLookAndFeel作为外观(Ubuntu上的默认值)。我们使用以下代码设置它(如果可用):

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

这种方法一开始是可以正常工作的。但在切换到JavaFX后,调用 UIManager.setLookAndFeel() 会导致应用程序冻结,什么事情也没有发生。我们需要手动设置外观和感觉,因为我们希望基于 GTKLookAndFeel 样式自己未迁移到JavaFX的Swing组件。

更多信息:这只有在使用 com.sun.java.swing.plaf.gtk.GTKLookAndFeel时才不起作用,因为当使用 javax.swing.plaf.metal.MetalLookAndFeeljavax.swing.plaf.nimbus.NimbusLookAndFeelcom.sun.java.swing.plaf.motif.MotifLookAndFeel 时它可以正常工作。

我们该怎么做才能让它与 GTKLookAndFeel 一起工作,以便在 SwingNode 中样式化我们的Swing组件?


2
你是否在正确的线程中执行代码?Swing 代码需要在 EventQueue.invokeLater 中运行。 - VGR
2
尝试在命令行上运行它,并转储所有线程堆栈。在Windows上,可以使用Ctrl-Break完成此操作;在其他系统上,可以使用SIGQUIT完成,可通过Ctrl-\或单独的“kill -3”命令实现。其中一个堆栈跟踪应指示setLookAndFeel被卡住的位置。 - VGR
1
@VGR:运行外观设置的线程似乎在com.sun.java.swing.plaf.gtk.GTKEngine.native_get_gtk_setting(Native Method)处卡住了...通过线程转储和Eclipse调试器进行了测试。 - Markus Weninger
1
你也可以使用 jstack -l 提供线程转储,它会显示是否存在死锁。你们提到线程在 native_get_gtk_setting 中卡住了,并且这个方法是同步的,所以可能另一个线程正在持有锁。这可能是因为 Swing 和 JavaFX 各自拥有自己的线程... - Hugues M.
1
抱歉@MarkusWeninger,这是我能想到的唯一建议,此时我不知道还有什么其他尝试的方法。 - Chetan Jadhav CD
显示剩余9条评论
1个回答

1

图形用户界面组件需要更新到图形用户界面线程。

尝试以下方法之一:

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

javafx.application.Platform.runLater(() -> {
//commands
});

之前尝试过两种方法,但都没有解决问题。 - Markus Weninger

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接