我在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();
}
}
Run Code Online (Sandbox Code Playgroud)
所以问题是如何在我的情况下根据它的祖先获得节点或图表的界限,无论有多少?
您已经找到了 Chart-Plot 背景节点,要根据其祖先获取它的坐标,您只需调用
chartPlotArea.getBoundsInParent();
Run Code Online (Sandbox Code Playgroud)
如果它们之间有多个祖先,您可以在 AnchorPane 坐标系中获得字符图边界,如下所示
Bounds bounds =
anchorPane.sceneToLocal(chartPlotArea.localToScene(chartPlotArea.getBoundsInLocal()));
Run Code Online (Sandbox Code Playgroud)
这里有一个小技巧,它们将是 0,直到你显示 stage 并让 javaFX 布局节点,所以你需要在.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);
Run Code Online (Sandbox Code Playgroud)
请记住,如果您希望在调整大小时改变坐标,您可以将其绑定到图表或图表区域边界/宽度更改,如下所示
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);
});
Run Code Online (Sandbox Code Playgroud)
编辑:如果您有多个祖先,您可以这样做以接收anchorPane坐标系中的字符图边界
Bounds bounds =
anchorPane.sceneToLocal(chartPlotArea.localToScene(chartPlotArea.getBoundsInLocal()));
Run Code Online (Sandbox Code Playgroud)
即使他们之间有多个祖先,这也会起作用