java如何在javafx中嵌入PApplet?
所以我用java编写了处理代码。但现在我想把它嵌入JavaFX中,用于我的GUI。我该怎么做? 我尝试使用以下代码,但似乎不起作用
package testprocessing;
import javafx.application.Application;
import javafx.embed.swing.SwingNode;
import javafx.scene.*;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javax.swing.JApplet;
import javax.swing.SwingUtilities;
import java.awt.Dimension;
import java.util.concurrent.*;
import processing.core.*;
public class JavaFxApplet extends Application {
private PApplet applet = new MyProcessingSketch();
private Dimension appletSize;
@Override public void init() throws ExecutionException, InterruptedException {
applet.init();
FutureTask<Dimension> sizingTask = new FutureTask<>(() ->
applet.getRootPane().getPreferredSize()
);
SwingUtilities.invokeLater(sizingTask);
appletSize = sizingTask.get();
}
@Override public void start(Stage stage) {
final SwingNode swingNode = new SwingNode();
SwingUtilities.invokeLater(() ->
swingNode.setContent(applet.getRootPane())
);
stage.setScene(
new Scene(
new Group(swingNode),
appletSize.getWidth(), appletSize.getHeight(),
Color.BLACK
)
);
stage.show();
}
@Override public void stop() {
applet.stop();
applet.destroy();
}
public static void main(String[] args) {
launch(args);
}
}
我在getRootPane()上遇到错误。你能推荐一个替代方案吗
# 1 楼答案
为什么要获取小程序的根窗格?只需将小程序添加到JPanel,然后将JPanel添加到SwingNode:
# 2 楼答案
背景
《处理3》中引入了一种JavaFX渲染模式,使我们可以在草图中包含JavaFX。我们不必从头开始创建自己的JavaFX窗口,然后将草图嵌入其中,我们可以修改PApplet类在JavaFX模式下初始化时构建的窗口,并在其中添加新的JavaFX元素
在JavaFX模式下初始化期间,PApplet类创建一个
javafx.scene.canvas.Canvas
对象,并将其作为子对象添加到javafx.scene.layout.StackPane
对象中。然后,用stackPane对象作为参数来构造javafx.scene.Scene
对象。最后,PApplet类创建一个javafx.stage.Stage
对象,并将其场景设置为场景对象,以提供PApplet实例——草图因此,就JavaFX元素而言,PApplet窗口由以下层次结构中的四个元素初始化:
Stage > Scene > StackPane > Canvas
,其中画布是草图的图形画布(即处理绘制到的对象)要创建我们自己的GUI,我们可以将任何
javafx.scene.Node
对象(这是JavaFX图形元素的超类)添加到stackPane对象中。或者,您可以构建一个新的场景,将处理的画布添加到其中,并替换阶段的现有场景什么似乎不起作用
在不指定渲染模式的情况下,处理默认为
JAVA2D
模式。在这种模式下,PApplet类创建一个PApplet实例,其中包含画布和窗口的java.awt
版本(分别是java.awt.Canvas
和java.awt.Frame
)。理论上,可以将java.awt.Frame
强制转换为javax.swing.JFrame
,将其嵌入javafx.embed.swing.SwingNode
对象,最后将其添加到JavaFX阶段。然而,我一直没能让它发挥作用还有
P2D
&P3D
模式。在这些模式中,画布是com.jogamp.newt.opengl.GLWindow
对象。我再次尝试在com.jogamp.opengl.awt.GLJPanel
的帮助下将其嵌入到Swing节点中,但没有成功实施
在调用
size()
的过程FX2D
渲染模式下初始化草图:size([width], [height], FX2D);
然后,我们可以通过重复转换来公开初始化过程中创建的四个JavaFX元素:
我们现在可以选择如何添加JavaFX元素:
1)添加到现有的堆栈窗格
我们可以使用以下方法将JavaFX元素(
javafx.scene.Node
对象)添加到初始化期间创建的堆栈窗格:2)创建新场景(推荐)
或者(建议使用stackPane,除非您希望将其作为顶级对齐器),我们可以创建一个新的场景对象(而不是使用初始化过程中创建的场景和stackPane对象),并向其添加JavaFX元素
在初始化过程中,画布的维度绑定到堆栈窗格的维度。如果我们希望在运行时更改窗口内处理画布的大小,我们必须包括以下内容:
现在,我们可以自由调用
canvas.setHeight()
和canvas.setWidth()
来调整JavaFX窗口(后台)中处理画布的大小范例
让我们在窗口中添加一个
javafx.scene.control.MenuBar
。注意,我在initSurface()
方法中初始化JavaFX元素,而不是在setup()
方法中初始化,因为这样更安全在本例中,stackPane被替换为
javafx.scene.layout.VBox
,首先是使菜单栏位于画布的顶部,其次是确保stage在启动时是正确的高度(菜单栏高度和画布高度之和)结果