Search code examples
cssjavafx-2java-8

JavaFx style 3D object with css


I know that it is possible to style 2D elements in JavaFx with Css. I was wondering if it is possible to achieve the same for the 3D objects.

I believe it is a good practice to keep the styling code away from the java (logic) code.

Question: Could anyone provide some sample code where the styling of 3D object in JavaFx is done with Css please?

Thanks.


Solution

  • The CSS functionality of JavaFX is mainly for styling of controls (which are 2D).

    Generally, you don't style 3D objects using CSS. Instead, you load the objects up from mesh models. These kinds of 3D objects based upon MeshView or other Shape3D objects cannot be styled using CSS (at least as far as doing anything stylistic useful is concerned). For example, you could not style the color of a Shape3D using CSS, because the color of the shape is determined via lighting and the shape material, neither of which may be styled using CSS. There are other formats for describing 3D models (e.g. obj, stl, etc), which are specifically designed for 3D and provide a better alternative for styling 3D objects than CSS.

    If you are taking 2D scenes and displaying them in 3D space, then you can style your 2D scene with CSS. Here is an example. I don't think it's really what you are looking for though.

    3d style

    import javafx.application.Application;
    import javafx.geometry.Insets;
    import javafx.scene.*;
    import javafx.scene.control.*;
    import javafx.scene.image.*;
    import javafx.scene.layout.*;
    import javafx.scene.paint.Color;
    import javafx.scene.transform.Rotate;
    import javafx.stage.Stage;
    
    public class ThreeDStyle extends Application {
        @Override
        public void start(Stage stage) {
            // create label.
            final Label label = new Label(TEXT);
            label.setGraphic(new ImageView(new Image(IMAGE_LOC)));
            label.setStyle(DEFAULT_STYLE);
    
            // create 3D rotation transform on label.
            Rotate rotate = new Rotate(-30, Rotate.Y_AXIS);
            label.getTransforms().setAll(
                rotate
            );
    
            // layout scene.
            VBox root = new VBox(10,
                    createControls(label, rotate),
                    new Group(label)
            );
            root.setStyle("-fx-background-color: null; -fx-padding: 10px;");
    
            // create a 3D scene with perspective capability.
            Scene scene = new Scene(root, 525, 400, true, SceneAntialiasing.BALANCED);
            scene.setCamera(new PerspectiveCamera());
            scene.setFill(Color.MIDNIGHTBLUE);
            stage.setScene(scene);
    
            stage.show();
        }
    
        private Node createControls(Label label, Rotate rotate) {
            TextArea style = new TextArea(label.getStyle());
    
            Button apply = new Button("Apply Style");
            apply.setMinSize(Button.USE_PREF_SIZE, Button.USE_PREF_SIZE);
            apply.setDefaultButton(true);
            apply.setOnAction(event -> label.setStyle(style.getText()));
    
            Slider rotateSlider = new Slider(0, 60, rotate.getAngle() * -1);
            rotate.angleProperty().bind(rotateSlider.valueProperty().multiply(-1));
    
            VBox controlPanel = new VBox(10,
                    new HBox(10, style, apply),
                    new HBox(new Label("Rotate"), rotateSlider)
            );
            controlPanel.setPadding(new Insets(10));
            controlPanel.setStyle("-fx-background-color: antiquewhite;");
    
            return controlPanel;
        }
    
        private static final String TEXT =
                "O for a Muse of fire, that would ascend\n" +
                "The brightest heaven of invention,\n" +
                "A kingdom for a stage, princes to act\n" +
                "And monarchs to behold the swelling scene!\n" +
                "Then should the warlike Harry, like himself,\n" +
                "Assume the port of Mars; and at his heels,\n" +
                "Leash'd in like hounds, should famine, sword and fire\n" +
                "Crouch for employment";
    
        private static final String IMAGE_LOC =
                "http://ia.media-imdb.com/images/M/MV5BMTI1ODg1Mjk5NF5BMl5BanBnXkFtZTcwNzQyNjUxMQ@@._V1_SX214_AL_.jpg";
    
        private static final String DEFAULT_STYLE =
                "-fx-background-color: mediumseagreen;\n" +
                "-fx-background-radius: 10px;\n" +
                "-fx-padding: 10px;\n" +
                "-fx-graphic-text-gap: 10px;\n" +
                "-fx-font-family: 'American Typewriter';\n" +
                "-fx-font-size: 18px;";
    
        public static void main(String[] args) {
            launch(args);
        }
    }