Multithreading 在swing选项卡窗格中管理多个嵌入式javafx JFXPanel

Multithreading 在swing选项卡窗格中管理多个嵌入式javafx JFXPanel,multithreading,swing,scala,thread-safety,javafx,Multithreading,Swing,Scala,Thread Safety,Javafx,我使用swing来显示多个javafxTableview,每个javafx都嵌入到swingTabbedPane中 我以scala的方式使用oracle文档中描述的众所周知的模式: implicit def fun2Run[T](x: ⇒ T) = new Runnable { def run = x } def myTabbedScene():Scene = { val root = new StackPane root.getChildren.add(new

我使用swing来显示多个javafx
Tableview
,每个javafx都嵌入到swing
TabbedPane

我以scala的方式使用oracle文档中描述的众所周知的模式:

implicit def fun2Run[T](x: ⇒ T) = new Runnable {
    def run = x
  }

  def myTabbedScene():Scene = {
    val root = new StackPane
    root.getChildren.add(new Label("Hello world!"))
    new Scene(root, 300, 300)
  }

  def initFxPanel(fxPanel: JFXPanel, s: ⇒ Scene) = {
    fxPanel.setScene(s)
  }

  def initSwingGui(panel: PluginPanel) = {
    val fxPanel = new JFXPanel()
   // code to add panel to JPanel
    panel.peer.add(fxPanel)
    Platform runLater initFxPanel(fxPanel,myTabbedScene())
  }

  val jfxSwingPanel = new PluginPanel("wrap 2") {
    var jtemp = new JPanel()
    contents += jtemp
  }

  SwingUtilities invokeLater initSwingGui(jfxSwingPanel)
每次用户打开新的swing选项卡时都会执行此代码(只有场景方法不同),但我不确定这是管理线程的最佳方法:-/

当我关闭或打开选项卡时,我的应用程序中存在一些不一致的状态,并且在显示过程中出现错误

我的用例示例和一些相关问题:

  • 我打开第一个选项卡J1,调用runlater,我的场景显示在选项卡中没有问题

  • 我打开第二个选项卡J2,在javafx线程上调用一个新的runlater

  • 切换到选项卡J1,如何刷新选项卡中的显示?一个隐式的
    runnable
    操作被启动到主线程以使这成为可能javafx如何识别要刷新的良好选项卡?如果我有一个按钮来启动一些操作,我会在javafx主线程上启动一个
    runlater()
    操作,哪个调度

更新:

我找到了一个可以帮助读者了解这一点的代码源,您可以
revalidate()
或/和
repaint()
您的swing面板(此处
\u contentpane
),其中包含您的
jfxPanel

   SwingUtilities.invokeLater(new Runnable() { 
    public void run() { 
    _contentPane.add(_jfxPanel); 
    _contentPane.revalidate(); 
    _contentPane.repaint(); }});
  • 我关闭第一个选项卡J1,javafx是否自动关闭/垃圾处理关联的javafx资源
我还有很多其他一般性问题:

  • javafx应用程序主线程如何管理此多个runlater()调用 他们什么时候从不同的jfxpanel到达

  • 当用户关闭选项卡时,如何正确关闭与jfxpanel关联的资源(不使用exit()平台方法关闭主javafx线程)?如果我销毁JFXPanel,用于显示的javafx资源会被释放吗

  • 使用任务管理线程可以解决我的问题吗

我的问题可能很幼稚,但我从gui构建开始,我很难理解javafx如何在不同的嵌入式面板上管理场景

当javafx应用程序线程从swing中的不同jfxpanel到达时,如何管理这个多个runlater()调用

从Platform.runLater javadoc:

在某个时间在JavaFX应用程序线程上运行指定的Runnable 未指定未来的时间。此方法,可从调用 任何线程都会将Runnable发布到事件队列,然后返回 立即给打电话的人打电话。可运行项按顺序执行 它们被贴上了。传入runLater方法的runnable将 在任何Runnable传递到对的后续调用之前执行 晚点

进一步:

当用户关闭选项卡时,如何正确关闭执行jfxpanel的线程(不关闭主javafx线程)

不清楚你指的是哪条线索。一般来说,在集成JavaFX和Swing时,只需要关注两个线程——Swing调度线程和JavaFX应用程序线程——这两个线程都应该由各自的底层框架管理,不需要显式关闭。您不需要任何其他线程,除非您正在尝试执行一些不应在这些线程中的任何一个线程上执行的操作(例如高度CPU密集型任务或远程I/O)-从您的示例代码来看,情况似乎并非如此

使用任务管理线程可以解决我的问题吗

除非你对这样的事情有特殊的需求,否则这样的解决方案可能会使你的情况更加复杂,而不是改善它

我关闭第一个选项卡J1,javafx是否自动关闭/垃圾处理关联的javafx资源

如果您没有保留对相关jfxpanel中任何资源的引用,那么Java虚拟机可以对jfxpanel及其相关资源进行垃圾收集—这只是标准的Java垃圾收集技术,这里没有什么特别之处

切换到选项卡J1,如何刷新选项卡中的显示?一个隐式的可运行操作被启动到主线程以使这成为可能

听起来是个坏主意(Java术语中的主线程是用于启动Java主功能的线程,根本不涉及GUI编程)。您可能希望通过
Platform.runLater()
提交可运行刷新请求,以便在JavaFX应用程序线程上执行该请求

javafx如何识别要刷新的良好选项卡

每个swing选项卡中都有一个JavaFX JFXPanel,每个swing选项卡都知道它有哪个JFXPanel,因此当您调用Platform.runLater刷新特定面板时,将(最终)引用传递给要使用的JFXPanel。以下是一些不使用任何语言的psuedo代码来说明这一概念:

on swing tab change event
  final JFXPanel curPanel = tab.getJFXPanel()
  Platform.runLater() {
    // update curPanel here...
  }
如果我有一个按钮来启动一些操作,我会在javafx主线程上启动runlater()操作,哪个调度

本质上,我认为您在这里是正确的,我将重写您的问题以澄清一些术语-假设它是一个swing按钮,在swing按钮上执行操作时,您调用
平台。runLater
,然后runLater调用中的代码最终将在JavaFX应用程序线程上执行


其他问题我无法回答,因为我对Scala不够流利,无法提供合理的答案


老实说,如果您刚刚开始GUI构建,那么我不请自来的建议是使用Java而不是Scala,并坚持使用Swing或JavaFX,但是,在您真正熟悉GUI构建过程之前,不要将它们混合在一起,否则在集成过程中可能会遇到太多陷阱和陷阱,很少有人能够帮助您解决这些问题。

在完成了大量这两项工作之后,我可以证明GUI构建