代码之家  ›  专栏  ›  技术社区  ›  DPM

如何在JavaFX应用程序中嵌入Canvas3D?

  •  1
  • DPM  · 技术社区  · 7 年前

    我正在开发一个JavaFX桌面应用程序。我想在其中显示一些java 3D对象。

    据我所知,实现这一点的方法是使用JavaFX的SwingNode。Java 3d也必须集成在Swing组件中。所以这是一个两步过程。

    将Java 3D对象与Java Swing集成

    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图形,但我一点也不喜欢。

    相关、未解决的问题:

    How Can I embed java3d's Canvas3d in javafx layout?

    2 回复  |  直到 7 年前
        1
  •  1
  •   DPM    7 年前

    我最终使用JCanvas3D实现了它。这项建议归功于@gouessej。非常感谢。

    这是新的 makeCanvas

       private void makeCanvas() {
          GraphicsConfigTemplate3D gCT = new GraphicsConfigTemplate3D();
          JCanvas3D jCanvas3D = new JCanvas3D(gCT);
          Dimension canvasDim = new Dimension(400, 400);
          jCanvas3D.setPreferredSize(canvasDim);
          jCanvas3D.setSize(canvasDim);
          add(jCanvas3D, BorderLayout.CENTER);          
          Canvas3D canvas3D =  jCanvas3D.getOffscreenCanvas3D(); 
    
          View view = new View();
          view.setPhysicalBody(new PhysicalBody());
          view.setPhysicalEnvironment(new PhysicalEnvironment());
          view.addCanvas3D(canvas3D);
    
          ViewPlatform vp = new ViewPlatform();
          view.attachViewPlatform(vp);
    
    
          Transform3D viewTransform = new Transform3D();
          viewTransform.setTranslation(new Vector3d(0, 0, 20)); //move "back" a little
    
          TransformGroup viewTG = new TransformGroup();
          viewTG.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
          viewTG.setTransform(viewTransform);
    
          viewTG.addChild(vp);
    
    
          viewTG.addChild(makeLight());
          viewTG.addChild(new Sphere(5));
    
          BranchGroup group = new BranchGroup();
          group.addChild(viewTG);
          group.addChild(makeLight());
          group.addChild(new Sphere(5));
    
          VirtualUniverse vu = new VirtualUniverse();
          Locale locale = new Locale(vu);  
          locale.addBranchGraph(group);
       }
    

    Canvas3D 由于无法在 JavaFX SwingNode 因为它是一个重量级组件。

    这个 SwingNode javadoc

        2
  •  0
  •   mipa    7 年前

    我只是看到你说你知道JavaFX 3D图形,但你不喜欢它。你能更具体一点说你不喜欢什么吗?