有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何在JavaFX8中根据其特定的祖先获取节点边界?

我在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) 个答案

  1. # 1 楼答案

    您已经找到了Chart Plot background节点,要根据其祖先获取坐标,只需调用

    chartPlotArea.getBoundsInParent();
    

    如果它们之间有多个祖先,则可以得到char-plot界限 在像这样的AnchorPane坐标系中

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

    这里的一个小技巧是,在显示stage和let 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);
    

    请记住,如果要在调整大小时更改坐标,可以将其绑定到图表或chartPlotArea bound/width changes,类似这样的内容

      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()));   
    

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