I'm currently working on a project and I should display 3D boxes on a Pane and I'm using javafx 3D for that. First I draw a big box, called container in my project and create a camera. Then with buttons added to the scene I draw other smaller boxes in the big container. However for some reason the small boxes affect each other and change their coordinates. More explanation with pictures:
This is box1, which I draw with key "X":
This is box2, which I draw with key "C":
If I only add box1 and restart my application and then draw box2, the output is image 1 and image 2, accordingly. However, if I don't restart the application each time and I wish to draw another box, I get the following output.
Output of box2, if before it box1 is drawn:
Output of box1, if before it box2 is drawn:
If I first draw box1, box1 looks okay, but image 3 is the output of box2. If I first draw box2, box1 output will change to image 4.
import javafx.scene.Camera;
import javafx.scene.Group;
import javafx.scene.Parent;
import javafx.scene.PerspectiveCamera;
import javafx.scene.SceneAntialiasing;
import javafx.scene.SubScene;
import javafx.scene.paint.Color;
import javafx.scene.paint.PhongMaterial;
import javafx.scene.shape.Box;
import javafx.scene.shape.CullFace;
import javafx.scene.shape.DrawMode;
import javafx.scene.transform.Rotate;
import javafx.scene.transform.Translate;
public class ContainerPane extends Parent {
//size of big container
private final double CONTAINER_DEPTH = 16.5;
private final double CONTAINER_WIDTH = 2.5;
private final double CONTAINER_HEIGHT = 4.0;
//group in which the box, container and camera are added
private Group root;
//coordiantes of box 1, row one is the actual coordinates and row two is the width, height, depth
private double[][] box1 = {{0, 4, 30},
{1, 2, 1.5}};
//coordiantes of box 2, row one is the actual coordinates and row two is the width, height, depth
private double[][] box2 = {{0, 6, 28},
{1.5, 1, 2}};
public ContainerPane(int Scene_Width, int Scene_Length){
//create the group
root = new Group();
root.setAutoSizeChildren(false);
//creating container
Box container = new Box(CONTAINER_WIDTH , CONTAINER_HEIGHT, CONTAINER_DEPTH);
container.setCullFace(CullFace.NONE);
//drawing the container with only lines
container.setDrawMode(DrawMode.LINE);
//setting the color of the container
PhongMaterial material = new PhongMaterial(Color.ORANGE);
container.setMaterial(material);
root.getChildren().add(container);
//create a camera
PerspectiveCamera camera = new PerspectiveCamera(true);
//add possible rotations and position of camera
camera.getTransforms().addAll(new Translate(0, 0, -35));
root.getChildren().add(camera);
//create a Scene from the group
SubScene subScene = new SubScene(root, Scene_Width, Scene_Length, true, SceneAntialiasing.BALANCED);
//set a camera for the scene
subScene.setCamera(camera);
getChildren().add(subScene);
}
public void drawBox1(){
//clear everything from root except container and camera
try{
root.getChildren().remove(2);
}
catch(Exception exception){
}
//create box1
Box box = new Box(box1[1][0], box1[1][1], box1[1][2]);
box.setDrawMode(DrawMode.FILL);
box.setMaterial(new PhongMaterial(Color.BLUE));
box.setTranslateX(-CONTAINER_WIDTH/2 + box.getWidth()/2 + 0.5*box1[0][0]);
box.setTranslateY(-CONTAINER_HEIGHT/2 + box.getHeight()/2 + 0.5*box1[0][1]);
box.setTranslateZ(CONTAINER_DEPTH/2 - box.getDepth()/2 - 0.5*box1[0][2]);
//add it to the group
root.getChildren().add(box);
}
public void drawBox2(){
try{
root.getChildren().remove(2);
}
catch(Exception exception){
}
Box box = new Box(box2[1][0], box2[1][1], box2[1][2]);
box.setDrawMode(DrawMode.FILL);
box.setMaterial(new PhongMaterial(Color.BLUE));
box.setTranslateX(-CONTAINER_WIDTH/2 + box.getWidth()/2 + 0.5*box2[0][0]);
box.setTranslateY(-CONTAINER_HEIGHT/2 + box.getHeight()/2 + 0.5*box2[0][1]);
box.setTranslateZ(CONTAINER_DEPTH/2 - box.getDepth()/2 - 0.5*box2[0][2]);
root.getChildren().add(box);
}
}
Main file, where I create an instance of the class.
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.stage.Stage;
public class Error extends Application {
@Override
public void start(Stage primaryStage) {
ContainerPane container = new ContainerPane(750, 750);
Scene scene = new Scene(container);
scene.addEventFilter(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>(){
@Override
public void handle(KeyEvent event){
if(event.getCode() == KeyCode.X){
container.drawBox1();
}
if(event.getCode() == KeyCode.C){
container.drawBox2();
}
}});
primaryStage.setScene(scene);
primaryStage.show();
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}