如何根据JavaFX 8中的特定祖先获取节点边界?

时间:2018-10-18 09:21:53

标签: java javafx

我在AnchorPane中添加了一个图表,我想获取其图的边界(图表,我用青色标记了该图),以便可以在其上添加一些文本它的顶部,但我应该根据其祖先知道它的确切范围。如果我手动执行此操作,则在调整大小等更改节点的填充大小时,我可能会失败。

import javafx.application.Application;
import javafx.geometry.Side;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception {

        NumberAxis numberAxis = new NumberAxis();
        LineChart chart = new LineChart(numberAxis, new NumberAxis());
        chart.getYAxis().setSide(Side.RIGHT);
        Node chartPlotArea = chart.lookup(".chart-plot-background");
        chartPlotArea.setStyle("-fx-background-color: cyan");
        AnchorPane anchorPane = new AnchorPane(chart);
        AnchorPane.setTopAnchor(chart, 0.0);
        AnchorPane.setRightAnchor(chart, 0.0);
        AnchorPane.setBottomAnchor(chart, 0.0);
        AnchorPane.setLeftAnchor(chart, 0.0);

        Scene scene = new Scene(anchorPane);
        primaryStage.setScene(scene);
        primaryStage.setMaximized(true);
        primaryStage.show();
    }
}

enter image description here

所以问题是,不管有多少个节点,在我的情况下如何根据其祖先获得边界?

1 个答案:

答案 0 :(得分:3)

您已经找到了Chart-Plot背景节点,并且要根据其祖先获得坐标,只需调用

chartPlotArea.getBoundsInParent();

,如果它们之间有一个以上的祖先,则可以得到字符图解边界 在这样的AnchorPane坐标系统中

Bounds bounds =
            anchorPane.sceneToLocal(chartPlotArea.localToScene(chartPlotArea.getBoundsInLocal()));

这里的一个小技巧是在您显示stage并让javaFX布局节点之前,它们将为0,因此您需要在.show()方法之后对其进行更新,因此结果可能如下所示:

 NumberAxis numberAxis = new NumberAxis();
    LineChart chart = new LineChart(numberAxis, new NumberAxis());
    chart.getYAxis().setSide(Side.RIGHT);
    Node chartPlotArea = chart.lookup(".chart-plot-background");
    chartPlotArea.setStyle("-fx-background-color: cyan");

    Text text = new Text();
    text.setText("Text");


    AnchorPane anchorPane = new AnchorPane();
    AnchorPane.setTopAnchor(chart, 0.0);
    AnchorPane.setRightAnchor(chart, 0.0);
    AnchorPane.setBottomAnchor(chart, 0.0);
    AnchorPane.setLeftAnchor(chart, 0.0);


    anchorPane.getChildren().addAll(chart, text);

    Scene scene = new Scene(anchorPane);
    primaryStage.setScene(scene);
    primaryStage.setMaximized(true);


    primaryStage.show();

        Bounds bounds =
            anchorPane.sceneToLocal(chartPlotArea.localToScene(chartPlotArea.getBoundsInLocal()));

    double textRelativeX = (bounds.getMinX() + bounds.getMaxX()) / 2 - text.getLayoutBounds().getWidth() / 2;
    double textRelativeY = bounds.getMinY() - text.getLayoutBounds().getHeight() / 2;

    AnchorPane.setLeftAnchor(text, textRelativeX);
    AnchorPane.setTopAnchor(text, textRelativeY);

请记住,如果要在调整大小时更改坐标,可以将其绑定到chart或chartPlotArea绑定/宽度更改,类似这样

  chart.layoutBoundsProperty().addListener((observable, oldValue, newValue) -> {
        double textRelativeXz = (newValue.getMinX() + newValue.getMaxX()) / 2 - text.getLayoutBounds().getWidth() / 2;
        double textRelativeYz = newValue.getMinY() - text.getLayoutBounds().getHeight() / 3;

        AnchorPane.setLeftAnchor(text, textRelativeXz);
        AnchorPane.setTopAnchor(text, textRelativeYz);
    });

编辑:如果您有多个祖先,您可以这样做以在anchorPane坐标系中接收字符图解边界

     Bounds bounds =
            anchorPane.sceneToLocal(chartPlotArea.localToScene(chartPlotArea.getBoundsInLocal()));   

即使它们之间有一个以上的祖先,这也将起作用