如何使用带标签的形状位置

时间:2017-11-02 15:59:09

标签: java javafx javafx-8 shapes

如果我显示一个具有特定x和y坐标的圆圈,它可以正常工作:

public class FxApplication extends Application {
    @Override
    public void start(Stage primaryStage) throws Exception {
        Group group = new Group();

        Circle circle = new Circle(100, 100, 2);
        group.getChildren().add(circle);

        Pane pane = new Pane(group);
        ScrollPane scrollPane = new ScrollPane(pane);
        BorderPane borderPane = new BorderPane(scrollPane);
        Scene scene = new Scene(borderPane);
        primaryStage.setScene(scene);
        primaryStage.show();
    }
}

only circle

但如果我在圆圈上添加标签,则会忽略圆圈的位置。

public class FxApplication extends Application {
    @Override
    public void start(Stage primaryStage) throws Exception {
        Group group = new Group();

        Circle circle = new Circle(100, 100, 2);
        Label label = new Label("test", circle);
        group.getChildren().add(label);

        Pane pane = new Pane(group);
        ScrollPane scrollPane = new ScrollPane(pane);
        BorderPane borderPane = new BorderPane(scrollPane);
        Scene scene = new Scene(borderPane);
        primaryStage.setScene(scene);
        primaryStage.show();
    }
}

with label

如何保持圆圈的位置,只添加标签或如何设置包含标签的正确圆圈位置?

例如,有效的是:

Circle circle = new Circle(circle_center_x, circle_center_y, 3);
Text label = new Text("test");
double halfLabelHeight = label.getLayoutBounds().getHeight() / 2;
label.relocate(circle_center_x + 10, circle_center_y - halfLabelHeight);
this.getChildren().addAll(circle , label);

但我正在寻找更加集成的解决方案。我认为Label对象可能有些聪明并且可以自己做,但是它采用圆x和y位置并将其应用于它自己的空间而不是父空间。

1 个答案:

答案 0 :(得分:1)

您实际上需要立即重新定位标签,而不是仅仅告诉圆圈在哪里显示。当您指定new Circle(100,100,2)时,您告诉圆形对象位于其父级的x = 100和y = 100处。在第一种情况下,其父级是group,但在第二种情况下,其父级现在是Label。要在组内找到标签x,y = 100,100,您需要调用:

label.relocate(100, 100);

现在不需要Circle初始化。即使你将Circle放在0,0,它仍然会显示在Label旁边,因为标签将管理Node位置。

PS。您可以将NodeOrientation从LEFT_TO_RIGHT更改为RIGHT_TO_LEFT label.setNodeOrientation(NodeOrientation.RIGHT_TO_LEFT);,或者如果您想更改“形状”位置,可以执行label.setContentDisplay(ContentDisplay.TOP);(或BOTTOM等)

我不确定我是否理解你在这里想要达到的目标是什么,但我想你想让Circle和Label彼此相邻。此外,您希望根据圆圈位置标注以高度为中心。如果先前的假设是正确的,那么这是实现该目的的代码:

import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;

public class FxApplication extends Application {

    private Group group;

    @Override
    public void start(Stage primaryStage) throws Exception {
        group = new Group();

        addCustomNode(100, 100, new Circle(2), new Label("Test"));

        Pane pane = new Pane(group);
        ScrollPane scrollPane = new ScrollPane(pane);
        BorderPane borderPane = new BorderPane(scrollPane);
        Scene scene = new Scene(borderPane);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private void addCustomNode(int x, int y, Circle circle, Label label) {

        double labelDimensions[] = getLabelDimensions(label);

        circle.setCenterX(100);
        circle.setCenterY(100);

        label.relocate(circle.getCenterX() + labelDimensions[0] / 2.0, circle.getCenterY() - labelDimensions[1] / 2.0);

        group.getChildren().addAll(circle, label);

    }

    // find the height and width before we
    // add the label to the stage
    private double[] getLabelDimensions(Label label) {
        HBox h = new HBox();
        Label l = new Label("Hello");
        h.getChildren().add(l);
        Scene s = new Scene(h);
        l.impl_processCSS(true);

        return new double[] { l.prefWidth(-1), l.prefHeight(-1) };
    }

    public static void main(String[] args) {
        launch(args);
    }
}