我可以将3D几何对象放在JavaFXCollection中吗?

时间:2016-05-20 08:29:26

标签: javafx fxml shape javafx-3d

我有几个3D几何对象,如球体,管,立方体等。我使用常规方式在FXML内部使用SphereCylinderBox等类生成FXMLcontroller中的菜单。这意味着对象box1@FXMLmakeCube方法的本地方法。

现在我希望在此控制器内的另一个方法中执行一些操作,如布尔操作,复制,镜像等。我想在JavaFXCollection排序列表中保留所有创建的几何,以便我可以从任何其他方法内部调用这些几何的句柄。

我的问题是我该怎么做?如何在同一FXMLController内的其他方法中引用此句柄?

我没有在网上找到确切的问题。

1 个答案:

答案 0 :(得分:1)

您可以将所有这些3D对象放在一个集合中,因为它们都从Shape3D延伸。

您可以创建一个ObservableList<Shape3D>集合,并在创建它时将每个对象添加到它。然后,您可以收听集合中的更改,并将所有新对象添加到场景/子场景中。

这是一个带有四个按钮的控制器示例,您可以在其中创建随机BoxSphere 3D对象,将它们添加到集合中,并将它们放在子场景中。

此外,您可以使用完整集合执行操作(在这种情况下翻译或旋转它们)。

public class FXMLDocumentController {

    @FXML
    private Pane pane;

    private Group pane3D;
    private PerspectiveCamera camera;
    private ObservableList<Shape3D> items;

    @FXML
    void createBox(ActionEvent event) {
        Box box = new Box(new Random().nextInt(200), new Random().nextInt(200), new Random().nextInt(200));
        box.setMaterial(new PhongMaterial(new Color(new Random().nextDouble(), 
                new Random().nextDouble(), new Random().nextDouble(), new Random().nextDouble())));
        box.setTranslateX(-100 + new Random().nextInt(200));
        box.setTranslateY(-100 + new Random().nextInt(200));
        box.setTranslateZ(new Random().nextInt(200));
        items.add(box);
    }

    @FXML
    void createSphere(ActionEvent event) {
        Sphere sphere = new Sphere(new Random().nextInt(100));
        sphere.setMaterial(new PhongMaterial(new Color(new Random().nextDouble(), 
                new Random().nextDouble(), new Random().nextDouble(), new Random().nextDouble())));
        sphere.setTranslateX(-100 + new Random().nextInt(200));
        sphere.setTranslateY(-100 + new Random().nextInt(200));
        sphere.setTranslateZ(new Random().nextInt(200));
        items.add(sphere);
    }

    public void initialize() {
        camera = new PerspectiveCamera(true);
        camera.setNearClip(0.1);
        camera.setFarClip(10000);
        camera.setTranslateZ(-1000);
        pane3D = new Group(camera);
        SubScene subScene = new SubScene(pane3D, 400, 400, true, SceneAntialiasing.BALANCED);
        subScene.setFill(Color.ROSYBROWN);
        subScene.setCamera(camera);
        pane.getChildren().add(subScene);

        items = FXCollections.observableArrayList();

        items.addListener((ListChangeListener.Change<? extends Shape3D> c) -> {
            while (c.next()) {
                if (c.wasAdded()) {
                    c.getAddedSubList().forEach(i -> pane3D.getChildren().add(i));
                }
            }
        });

    }    

    @FXML
    void rotateAll(ActionEvent event) {
        items.forEach(s -> {
            s.setRotate(new Random().nextInt(360));
            s.setRotationAxis(new Point3D(-100 + new Random().nextInt(200), 
                    -100 + new Random().nextInt(200), new Random().nextInt(200)));
        });
    }

    @FXML
    void translateAll(ActionEvent event) {
        items.forEach(s -> {
            s.setTranslateX(-100 + new Random().nextInt(200));
            s.setTranslateY(-100 + new Random().nextInt(200));
            s.setTranslateZ(new Random().nextInt(200));
        });

    }
}

subscene