我正在研究 JavaFX 2.2 中折线图的值标记。因此,我在stackoverflow上使用了一个现有问题的答案,并且 Sergey Grinev 的示例运行良好。但是,如果我想使用 FXML 添加图表而不是添加硬编码,我在确定图表背景的大小时会遇到问题。
我将chart
和的初始化valueMarker
移到initialize()
了 FXMLLoader 在处理完根元素后自动调用的方法(请参阅JavaFX 文档中的注释)。但是,如果我现在使用以下代码来确定图表背景的大小,它会为每个绑定值返回 0.0:
Node chartArea = chart.lookup(".chart-plot-background");
Bounds chartAreaBounds = chartArea.localToScene(chartArea.getBoundsInLocal());
该方法中完全相同的代码在updateMarker()
第二次调用时返回确定的图表背景大小。在第一次调用时设置了界限,但 minX 不正确。这是我的代码:
public class LineChartValueMarker extends Application {
@FXML
private LineChart<Number, Number> chart;
@FXML
private Line valueMarker;
@FXML
private NumberAxis yAxis;
private XYChart.Series<Number, Number> series = new XYChart.Series<>();
private void updateMarker() {
Node chartArea = chart.lookup(".chart-plot-background");
Bounds chartAreaBounds = chartArea.localToScene(chartArea
.getBoundsInLocal());
// SIZE OF THE CHART IS DETERMINED
System.out.println(chartAreaBounds);
valueMarker.setStartX(chartAreaBounds.getMinX());
valueMarker.setEndX(chartAreaBounds.getMaxX());
}
public void initialize() {
series.getData().add(new XYChart.Data(0, 0));
series.getData().add(new XYChart.Data(10, 20));
chart.getData().addAll(series);
// add new value on mouseclick for testing
chart.setOnMouseClicked(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent t) {
series.getData().add(
new XYChart.Data(series.getData().size() * 10,
30 + 50 * new Random().nextDouble()));
updateMarker();
}
});
// find chart area Node
Node chartArea = chart.lookup(".chart-plot-background");
Bounds chartAreaBounds = chartArea.localToScene(chartArea
.getBoundsInLocal());
// SIZE AND POSITION OF THE CHART IS 0.0
System.out.println(chartAreaBounds);
}
@Override
public void start(Stage stage) throws IOException {
FXMLLoader loader = new FXMLLoader();
InputStream in = this.getClass().getResourceAsStream(
"LineChartValueMarker.fxml");
loader.setBuilderFactory(new JavaFXBuilderFactory());
loader.setLocation(this.getClass().getResource(
"LineChartValueMarker.fxml"));
Pane pane = (Pane) loader.load(in);
Scene scene = new Scene(pane);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
}
我在代码中打印边界的位置添加了大写注释(并且我删除了 Y 坐标的更新valueMarker
)。这是输出:
BoundingBox [minX:0.0, minY:0.0, minZ:0.0, width:0.0, height:0.0, depth:0.0, maxX:0.0, maxY:0.0, maxZ:0.0]
BoundingBox [minX:45.0, minY:15.0, minZ:0.0, width:441.0, height:318.0, depth:0.0, maxX:486.0, maxY:333.0, maxZ:0.0]
BoundingBox [minX:37.0, minY:15.0, minZ:0.0, width:449.0, height:318.0, depth:0.0, maxX:486.0, maxY:333.0, maxZ:0.0]
第一个输出行来自initialize()
方法,第二行来自第一次调用updateMarker()
(第一次鼠标点击图表),第三行来自第二次调用updateMarker()
(第二次鼠标点击图表),最终返回图表的正确边界值背景。
现在我的问题是:如何或何时可以确定图表背景的正确大小(最好的initialize()
方法)?我希望有人可以提供帮助,因为我无法解释这种行为。谢谢!