这是此question的延续。
我试图用一个AnchorPane来覆盖图表绘图,我称之为buffer。
下面是一个代码示例。
package launcher;
import javafx.application.Application;
import javafx.geometry.Bounds;
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<Number, Number> chart = new LineChart<>(numberAxis, new NumberAxis());
chart.getYAxis().setSide(Side.RIGHT);
AnchorPane buffer = new AnchorPane();
buffer.setStyle("-fx-background-color: gray;" +
"-fx-opacity: 0.5");
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, buffer);
Scene scene = new Scene(anchorPane);
primaryStage.setScene(scene);
primaryStage.setMaximized(true);
primaryStage.show();
resetBuffer(chart, buffer, anchorPane);
anchorPane.widthProperty().addListener((observable, oldValue, newValue) -> {
resetBuffer(chart, buffer, anchorPane);
});
}
private void resetBuffer(LineChart<Number, Number> chart, AnchorPane buffer,
AnchorPane anchorPane) {
Node chartPlot = chart.lookup(".chart-plot-background");
Bounds bounds = anchorPane.sceneToLocal(
chartPlot.localToScene(chartPlot.getBoundsInLocal()));
buffer.setPrefWidth(bounds.getWidth());
buffer.setPrefHeight(bounds.getHeight());
AnchorPane.setLeftAnchor(buffer, bounds.getMinX());
AnchorPane.setTopAnchor(buffer, bounds.getMinY());
}
}
在我调整舞台大小之前,一切都很好。当我调整大小时,AnchorPane (缓冲区)没有正确覆盖图表绘图。也就是说,它不适合尺寸。
如何修复它或以适当的方式做它?
发布于 2018-10-23 21:40:08
希望这能解决这个问题:
第一种解决方案:
double sideSizeWidth = (anchorPane.getWidth()-bounds.getWidth());
double sideSizeHeight= (anchorPane.getHeight()-bounds.getHeight());
buffer.prefWidthProperty().bind(Bindings.add(
chart.widthProperty(),
-sideSizeWidth
));
buffer.prefHeightProperty().bind(Bindings.add(
chart.heightProperty(),
-sideSizeHeight
));
(它需要在resetBuffer
中,并且只需要在primaryStage.show()
之后的开头调用一次)
第二种解决方案:
scene.widthProperty().addListener(new ChangeListener<Number>() {
@Override
public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
double dif =oldValue.doubleValue()-newValue.doubleValue();
buffer.setPrefWidth(buffer.getWidth()-(dif));
}
});
scene.heightProperty().addListener(new ChangeListener<Number>() {
@Override
public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
double dif =oldValue.doubleValue()-newValue.doubleValue();
buffer.setPrefHeight(buffer.getHeight()-(dif));
}
});
它基于这样一个事实,即宽度和高度在轴标签和图例中是永久的,所以我们只需要计算应用于buffer
的scene
大小的差异。
所有代码:
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
NumberAxis numberAxis = new NumberAxis();
LineChart<Number, Number> chart = new LineChart<>(numberAxis, new NumberAxis());
chart.getYAxis().setSide(Side.RIGHT);
AnchorPane buffer = new AnchorPane();
buffer.setStyle("-fx-background-color: gray;" +
"-fx-opacity: 0.5");
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, buffer);
Scene scene = new Scene(anchorPane);
primaryStage.setScene(scene);
primaryStage.setMaximized(true);
primaryStage.show();
resetBuffer(chart, buffer, anchorPane,scene);
}
private void resetBuffer(LineChart<Number, Number> chart, AnchorPane buffer,
AnchorPane anchorPane,Scene scene) {
Node chartPlot = chart.lookup(".chart-plot-background");
Bounds bounds = anchorPane.sceneToLocal(
chartPlot.localToScene(chartPlot.getBoundsInLocal()));
buffer.setPrefWidth(bounds.getWidth());
buffer.setPrefHeight(bounds.getHeight());
AnchorPane.setLeftAnchor(buffer, bounds.getMinX());
AnchorPane.setTopAnchor(buffer, bounds.getMinY());
scene.widthProperty().addListener(new ChangeListener<Number>() {
@Override
public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
double dif =oldValue.doubleValue()-newValue.doubleValue();
buffer.setPrefWidth(buffer.getWidth()-(dif));
}
});
scene.heightProperty().addListener(new ChangeListener<Number>() {
@Override
public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
double dif =oldValue.doubleValue()-newValue.doubleValue();
buffer.setPrefHeight(buffer.getHeight()-(dif));
}
});
}
}
发布于 2018-10-23 20:16:18
只需将对resetBuffer
的调用封装在Platform.runLater
中,如下所示:
anchorPane.widthProperty().addListener((observable, oldValue, newValue) -> {
Platform.runLater(() -> {
resetBuffer(chart, buffer, anchorPane);
});
});
这样,您就可以确保在图表布局完成后执行代码
https://stackoverflow.com/questions/52897993
复制相似问题