【发布时间】:2018-01-24 13:13:31
【问题描述】:
我正在开发一个 JavaFX 桌面应用程序。我想在其中显示一些 java 3D 对象。
据我所知,这样做的方法是使用 JavaFX 的 SwingNode。 Java 3d 也必须集成到 Swing 组件中。所以这是一个两步的过程。
将 Java 3D 对象与 Java Swing 集成
由我打算在 FX 应用程序中重用的面板和一个显示它有效的 JFrame 组成的完整且最小的示例:
import java.awt.BorderLayout;
import javax.swing.JFrame;
public class JFrameWithCanvas3D extends JFrame {
public JFrameWithCanvas3D() {
super("Swing JFrame Wraps Canvas3D");
setLayout(new BorderLayout());
BallPanel panel = new BallPanel();
add(panel, BorderLayout.CENTER);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setVisible(true);
}
public static void main(String[] args) {
System.setProperty("sun.awt.noerasebackground", "true");
javax.swing.SwingUtilities.invokeLater(new Runnable() {
@SuppressWarnings("unused")
@Override
public void run() {
new JFrameWithCanvas3D();
}
});
}
}
public class BallPanel extends JPanel {
public BallPanel() {
setLayout(new BorderLayout());
setPreferredSize(new Dimension(500, 500));
add(makeCanvas());
}
private static Canvas3D makeCanvas() {
BranchGroup group = new BranchGroup();
group.addChild(makeLight());
group.addChild(new Sphere(5));
Canvas3D canvas3D = new Canvas3D(SimpleUniverse.getPreferredConfiguration());
SimpleUniverse universe = new SimpleUniverse(canvas3D);
Transform3D viewTransform = new Transform3D();
viewTransform.setTranslation(new Vector3d(0, 0, 20)); //move "back" a little
universe.getViewingPlatform().getViewPlatformTransform().setTransform(viewTransform);
universe.addBranchGraph(group);
return canvas3D;
}
private static DirectionalLight makeLight() {
DirectionalLight light = new DirectionalLight(new Color3f(Color.WHITE), new Vector3f(-1.0f, -1.0f, -1.0f));
light.setInfluencingBounds(new BoundingSphere(new Point3d(0, 0, 0), 100));
return light;
}
}
在 JavaFX 应用中集成 BallPanel
public class FXAppWithSwingPanel extends Application {
@Override
public void start(Stage stage) {
final SwingNode swingNode = new SwingNode();
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
panel.setPreferredSize(new Dimension(450, 450));
panel.add(new BallPanel(), BorderLayout.CENTER);
swingNode.setContent(panel);
Pane pane = new Pane();
pane.getChildren().add(swingNode);
stage.setScene(new Scene(pane, 500, 500));
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
我看到的只是球体应该在的灰色背景。我尝试了一些不同的变化,但没有运气。无法在网上找到有关 Java 3D 类和 JavaFX 之间这种特定集成的任何信息。
我知道 JavaFX 有 3D 图形,但我不喜欢它们(一点也不)。
相关的,未解决的,问题:
【问题讨论】:
-
我不知道 Java-3D。
Canvas3D是轻量级组件(即由 Swing 呈现的组件,而不是由本机窗口工具包呈现的组件)?如果没有,您将无法在SwingNode中呈现它。另请注意,您应该通过SwingUtilities.invokeLater(...)在AWT 事件调度线程上为SwingNode创建内容:请参阅SwingNodedocs。 -
啊,原来如此。显然 Canvas3D 是一个重量级的 GUI 元素。有什么解决方法吗?
-
我不这么认为。
SwingNode旨在与“纯摇摆”组件(即轻量级组件)向后兼容,但 JavaFX 通常是从头开始设计的。如果您使用 JavaFX,您可能必须使用 JavaFX 3D。如果您想走 JavaFX 路线,José Pereda(有时会在这里发帖)可能是寻找好的 JavaFX 3d 文章的人。 -
我会推迟一段时间,因为我一般不是 3D 专家;如果以后没有人有更好的建议,我将在答案中总结这些 cmets。
-
你试过com.sun.j3d.exp.swing.JCanvas3D吗? jogamp.org/deployment/java3d/1.6.0-final/javadoc/com/sun/j3d/… OpenJFX/JavaFX 通常不能与第三方 3D API 很好地互操作,我在这里解释了原因:jogamp.org/bugzilla/show_bug.cgi?id=607
标签: java swing javafx javafx-8 java-3d