Reputation: 13
I've been working in JavaFX for the first time to try to make an app which I can use to demonstrate a simple animation with button controls. To do this I've used a BoarderPane for the primary stage, with both the left,right, and bottom using Gridpanes.
However, for the center I need to be able to draw a sphere with a line within it which I can rotate for different views while simultaneously being able to animated, or at the very least snap-move, the line within.
I've tried using a Pane for the center which doesn't work. I've tried making it it's own scene and sub scene which doesn't work. And I can't use a canvas as that is only for 2D animation.
Is there a way I can animate the line or rotate the camera while maintaining the BoarderPane layout I've created?
I've tried looking at the following before to understand what I could do but most just seem incompatible with the BoarderPane:
JavaFX Rotating Camera Around a Pivot
JavaFX Canvas rotate image with fixed center (and without bouncing)
Upvotes: 1
Views: 1177
Reputation: 45456
Whenever you want to mix 2D and 3D (and camera) you have to use a SubScene
container for the 3D content:
SubScene provides separation of different parts of a scene, each of which can be rendered with a different camera, depth buffer, or scene anti-aliasing. A SubScene is embedded into the main scene or another sub-scene.
If you have a BorderPane container, you can perfectly add the subScene to its center.
For a similar use case, you can check the Qubit3D
class from here, which is mainly a group that holds a sub scene with an Sphere and a cylinder (both from the FXyz 3D library).
You can add this group easily to your 2D scene:
private final Rotate rotate = new Rotate(0, 0, 0, 0, javafx.geometry.Point3D.ZERO.add(1, 1, 1));
@Override
public void start(Stage primaryStage) throws Exception {
final Timeline timeline = new Timeline(
new KeyFrame(Duration.seconds(10),
new KeyValue(rotate.angleProperty(), 360)));
final Qubit3D qubit = new Qubit3D();
final BorderPane root = new BorderPane(qubit);
final Button buttonAnimate = new Button("Animate");
buttonAnimate.setOnAction(e -> {
rotate.setAngle(0);
timeline.playFromStart();
});
root.setLeft(new StackPane(buttonAnimate));
final Button buttonStop = new Button("Stop");
buttonStop.setOnAction(e -> timeline.stop());
root.setRight(new StackPane(buttonStop));
Scene scene = new Scene(root, 600, 400, true, SceneAntialiasing.BALANCED);
scene.setFill(Color.BISQUE);
primaryStage.setScene(scene);
primaryStage.setTitle("Qubit3D Sample");
primaryStage.show();
qubit.rotateRod(rotate);
}
The only modification I've added to Qubit3D is:
public void rotateRod(Rotate rotate) {
rodSphere.getTransforms().setAll(rotate);
}
If you run it:
Note that you can interact with the sphere (via mouse dragged events), while you can also start/stop a full rotation of sphere and rod.
Upvotes: 3