JavaFX z Arią - powrót do strony głównej
Gdy pracujemy z klasą Subscene i elementami 3D, możemy potrzebować specjalnego tła dla aplikacji, do którego użytkownik nie powinien mieć dostępu.

Klasa Listing11c_18c.java
package rozdzial11c;

import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Bounds;
import javafx.scene.*;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Box;
import javafx.scene.shape.Cylinder;
import javafx.scene.shape.Sphere;
import javafx.scene.transform.Translate;
import javafx.stage.Stage;
import javafx.util.Duration;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;

public class Listing11_18c extends Application {
    private Timeline timeline;
    private BufferedInputStream bis;

    public static void main(String[] args) {
        Application.launch(args);
    }
    @Override
    public void init() {
        try {
            FileInputStream is = new FileInputStream(
                    "rozdzial11c/src/rozdzial11c/kwiatek.jpg");
            bis = new BufferedInputStream(is);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

    }


    @Override
    public void start(Stage stage) {
       //--------------- subScene -----------------------
        Image image = new Image(bis);
        ImageView iv = new ImageView();
        iv.setImage(image);
        iv.setFitWidth(256);
        iv.setFitHeight(192);
        iv.setSmooth(true);
        iv.setCache(true);
        iv.relocate(100, 75);
        Pane sroot = new Pane();
        sroot.getChildren().addAll(iv);
        SubScene s = new SubScene(sroot,500, 400);
        //---------------------- 3d -----------------------
        Group group = new Group();
        Sphere sphere = new Sphere(50);
        Translate trans1 = new Translate(-100, 0, 100);
        sphere.getTransforms().add(trans1);
        Cylinder cyli = new Cylinder(30, 100);
        Translate trans2 = new Translate(20, 0, 100);
        cyli.getTransforms().add(trans2);
        Box box = new Box(100, 100, 100);
        Translate trans3 = new Translate(140, 0, 100);
        box.getTransforms().add(trans3);
        PointLight al = new PointLight();
        al.setColor(Color.RED);
        group.getChildren().addAll(sphere, box, cyli, al);
        //---------------------- all ----------------------
        StackPane mroot = new StackPane();
        mroot.getChildren().addAll(s, group);
        Scene scene = new Scene(mroot, 500, 400,
                false, SceneAntialiasing.BALANCED);
        stage.setTitle("Bouncing Image");
        stage.setScene(scene);
        stage.show();

        EventHandler<ActionEvent> ev = new EventHandler<>() {
            double dx = 5;
            double dy = 3;

            @Override
            public void handle(ActionEvent t) {
                iv.setLayoutX(iv.getLayoutX() + dx);
                iv.setLayoutY(iv.getLayoutY() + dy);
                Bounds bounds = sroot.getBoundsInLocal();
                if (iv.getLayoutX() <= (bounds.getMinX())
                        || iv.getLayoutX() >=
                        (bounds.getMaxX() - iv.getFitWidth())) {
                    dx = -dx;
                }
                if (iv.getLayoutY() >=
                        (bounds.getMaxY() - iv.getFitHeight())
                        || iv.getLayoutY() <=
                        (bounds.getMinY() )) {
                    dy = -dy;
                }
            }
        };
        timeline = new Timeline(new KeyFrame(
                Duration.millis(40),ev));
        timeline.setCycleCount(Timeline.INDEFINITE);
        timeline.play();
    }
    @Override
    public void stop() {
    timeline.stop();
    }
}
Klasa module-info.java
module rozdzial11c {
    requires java.desktop;
    requires javafx.graphics;
    requires javafx.controls;
    requires javafx.swing;

    exports rozdzial11c to javafx.graphics;
}

Po uruchomieniu kodu zobaczymy nieruchome bryły 3D, a za nimi samodzielną animację – poruszający się obrazek. Użytkownik nie ma możliwości sterowania tłem.

Podładka dla tła
Podkładka dla tła