我正在使用swing来显示多个javafx Tableview
,每个javafx嵌入(感谢JFXPanel
)TabbedPane
我使用oracle doc中描述的熟知模式,以scala方式:
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()
包含_contentpane
的摇摆面板(此处为jfxPanel
}
SwingUtilities.invokeLater(new Runnable() {
public void run() {
_contentPane.add(_jfxPanel);
_contentPane.revalidate();
_contentPane.repaint(); }});
我有其他一般性问题:
javafx应用程序主线程如何管理此多个runlater()调用 当他们从不同的jfxpanel到达时?
当用户关闭标签时,如何正确关闭资源(不使用exit()平台方法关闭主javafx线程)与我的jfxpanel相关联?如果我销毁JFXPanel,那么用于展示的javafx资源会被解放吗?
使用任务来管理我的线程可以解决我的问题吗?
我的问题可能是天真的,但我开始在gui建设,我有问题了解javafx如何在不同的嵌入式面板上管理场景。
答案 0 :(得分:3)
当javafx应用程序线程从不同的jfxpanel到达时,如何管理这个多个runlater()调用?
来自Platform.runLater javadoc:
在JavaFX Application Thread上运行指定的Runnable 未来的未指定时间。这种方法可以从中调用 任何线程,都会将Runnable发布到事件队列然后返回 立即给来电者。 Runnables按顺序执行 他们被张贴了。传递给runLater方法的runnable将是 在任何Runnable传入后续调用之前执行 runLater。
此外:
当用户关闭标签时,如何正确关闭执行我的jfxpanel的线程(没有关闭主javafx线程)?
目前还不清楚你指的是哪个主题。通常,在集成JavaFX和Swing时,只需要关注两个线程 - Swing调度线程和JavaFX应用程序线程 - 这两个线程都应该由相应的底层框架管理,您不需要显式关闭。您不需要任何其他线程,除非您尝试执行某些不应在这些线程中执行的操作(例如高度CPU密集型任务或远程I / O) - 这些线程不会出现在示例代码中是这样的。
使用任务来管理我的线程可以解决我的问题吗?
除非你特别需要这样的事情,否则这种解决方案可能会使你的情况进一步复杂化而不是改善它。
我关闭第一个选项卡J1,javafx自动关闭/垃圾javafx资源关联?
如果你没有保留对相关jfxpanel中任何资源的引用,那么Java虚拟机可以垃圾收集jfxpanel和与之相关的资源 - 这只是标准的Java垃圾收集技术,这里没什么特别的
我切换到标签J1,我的标签中的显示是如何刷新的?向主线程启动隐式runnable操作以使其成为可能?
听起来不错(Java术语中的主线程是用于启动Java主要功能的线程,根本不涉及GUI编程)。您可能希望通过Platform.runLater()
提交可运行的刷新请求,以便它将在JavaFX应用程序线程上执行。
javafx如何识别要刷新的好标签?
每个swing选项卡中都有一个JavaFX JFXPanel,每个swing选项卡都知道它有哪个JFXPanel,因此当您调用Platform.runLater刷新特定面板时,将(最终)引用传递给要使用的JFXPanel。这里有一些伪造的代码,没有任何语言来说明这个概念:
on swing tab change event
final JFXPanel curPanel = tab.getJFXPanel()
Platform.runLater() {
// update curPanel here...
}
如果我有一个启动某个动作的按钮,我会在发送的javafx主线程上启动runlater()动作?
本质上我认为你在这里是正确的,我只是重写你的问题以澄清一些术语 - 让我们说它是一个挥杆按钮,并且在对挥杆按钮执行动作时,你打电话给{{1然后,runLater调用中的代码最终将在JavaFX应用程序线程上执行。
我无法回答的其他问题,因为我在Scala中不够流利,无法提供合理的答案。
老实说,如果你刚刚开始构建GUI,那么我主动提出的建议是使用Java而不是Scala并坚持使用Swing或JavaFX,但不要将它们混合在一起直到你对GUI构建过程非常熟悉 - 否则,在集成过程中可能遇到的陷阱和陷阱太多,很少有人可以帮助你。