How to add text to each face of a box [JavaFX]

天涯浪子 提交于 2019-12-03 18:10:15

问题


I create a box which I can rotate and what will do ~some action~ when clicked. The problem I'm having is display text on all the faces of this box, for example; 1 on the front, 2 on the top, 3 on the back, 4 on the bottom, 5 on the left and 6 on the right.

I understand that StackPane can be used to overlay a text box on-top of the cube but I don't think that'd really help in this scenario. Since box is essentially a pre-constructed TriangleMesh, is this possible to do? As far as seen, box doesn't have any in-built functionality to do this.

static double mousePosX;
static double mousePosY;
static double mouseOldX;
static double mouseOldY;
public static Scene testScene(Stage stage) {


    Group root = new Group();
    Scene scene = new Scene(root, stage.getWidth(), stage.getHeight(), true, SceneAntialiasing.BALANCED);
    scene.setFill(Paint.valueOf("Blue"));

    PerspectiveCamera camera = new PerspectiveCamera(true);
    camera.setNearClip(0.1);
    camera.setFarClip(10000.0);
    camera.setTranslateZ(-10);
    scene.setCamera(camera);

    Box box = new Box(1,1,1);
    box.setOnMouseClicked(e -> {
        System.out.println("Test");
    });

    Rotate rotateX = new Rotate(10, 0, 0, 0, Rotate.X_AXIS);
    Rotate rotateY = new Rotate(5, 0, 0, 0, Rotate.Y_AXIS);
    box.getTransforms().addAll(rotateX, rotateY);

    scene.setOnMousePressed(me -> {
        mouseOldX = me.getSceneX();
        mouseOldY = me.getSceneY();
    });
    scene.setOnMouseDragged(me -> {
        mousePosX = me.getSceneX();
        mousePosY = me.getSceneY();
        rotateX.setAngle(rotateX.getAngle() - (mousePosY - mouseOldY));
        rotateY.setAngle(rotateY.getAngle() + (mousePosX - mouseOldX));
        mouseOldX = mousePosX;
        mouseOldY = mousePosY;
    });

    root.getChildren().add(box);

    return scene;
}

This is the code I've got so far and any assistance would be greatly appreciated.


回答1:


This solution is based in the answer to this question, where the CuboidMesh from the FXyz library is used.

The main idea is to use an image as texture for the cube. The built-in JavaFX Box will apply this image to each of the 6 faces, so if we want to have different text in each face, we have to use the CuboidMesh, that makes use of the net image:

The cube can be generated as:

CuboidMesh cuboid = new CuboidMesh(100f, 100f, 100f);
cuboid.setTextureModeImage(getClass().getResource("net.png").toExternalForm());

The idea now is to write the text in each of the 6 faces and save the texture image that will be used later on.

This method will generate this net image:

private Image generateNet(String face1, String face2, String face3, String face4, String face5, String face6) {

    GridPane grid = new GridPane();
    grid.setAlignment(Pos.CENTER);

    Label label1 = new Label(face1);
    label1.setRotate(90);
    GridPane.setHalignment(label1, HPos.CENTER);

    Label label2 = new Label(face2);
    GridPane.setHalignment(label2, HPos.CENTER);

    Label label3 = new Label(face3);
    GridPane.setHalignment(label3, HPos.CENTER);

    Label label4 = new Label(face4);
    GridPane.setHalignment(label4, HPos.CENTER);

    Label label5 = new Label(face5);
    GridPane.setHalignment(label5, HPos.CENTER);

    Label label6 = new Label(face6);
    label6.setRotate(90);
    GridPane.setHalignment(label6, HPos.CENTER);

    grid.add(label1, 1, 0);
    grid.add(label2, 0, 1);
    grid.add(label3, 1, 1);
    grid.add(label4, 2, 1);
    grid.add(label5, 3, 1);
    grid.add(label6, 1, 2);

    grid.setGridLinesVisible(true);

    ColumnConstraints col1 = new ColumnConstraints();
    col1.setPercentWidth(25);
    ColumnConstraints col2 = new ColumnConstraints();
    col2.setPercentWidth(25);
    ColumnConstraints col3 = new ColumnConstraints();
    col3.setPercentWidth(25);
    ColumnConstraints col4 = new ColumnConstraints();
    col4.setPercentWidth(25);
    grid.getColumnConstraints().addAll(col1, col2, col3, col4);

    RowConstraints row1 = new RowConstraints();
    row1.setPercentHeight(33.33);
    RowConstraints row2 = new RowConstraints();
    row2.setPercentHeight(33.33);
    RowConstraints row3 = new RowConstraints();
    row3.setPercentHeight(33.33);
    grid.getRowConstraints().addAll(row1, row2, row3);
    grid.setPrefSize(600, 450);

    Scene tmpScene = new Scene(grid);
    tmpScene.getStylesheets().add(getClass().getResource("style.css").toExternalForm());

    return grid.snapshot(null, null);
}

where style.css contains:

.root {
    -fx-background-color: white;
}
.label {
    -fx-font-size: 6em;
}

With it, the labels size and font can be adjusted properly.

Now you can generate a net image for any text:

Image net = generateNet("1", "2", "3", "4", "5", "6");

Finally, you can apply this texture to the cuboid:

PhongMaterial mat = new PhongMaterial();
mat.setDiffuseMap(net);
cuboid.setMaterial(mat);

And you will have your text applied:



来源:https://stackoverflow.com/questions/48618329/how-to-add-text-to-each-face-of-a-box-javafx

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!