这是该question的延续。
我试图用AnchorPane覆盖图表图,我称它为缓冲区。
这是一个代码示例。
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(缓冲区)没有正确覆盖图表。即它不适合大小。
如何修复或以正确的方式进行?
答案 0 :(得分:2)
希望这可以解决它:
第一个解决方案:
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));
}
});
它基于宽度和高度在轴标签和图例中是永久不变的事实,因此我们只需要计算scene
大小的差异,然后应用于buffer
。
所有代码:
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));
}
});
}
}
答案 1 :(得分:0)
更新:不是将监听器添加到widthProperty中,而是将监听器添加到prefWidthProperty中,例如:
anchorPane.prefWidthProperty().addListener((observable, oldValue, newValue) -> {
resetBuffer(chart, buffer, anchorPane);
});
OLD
您可以尝试将缓冲区prefWidth和prefHeight与anchorPane的prefWidth和prefHeight绑定 例如
buffer.prefWidthProperty().bind(anchorPane.widthProperty());
buffer.prefHeightProperty().bind(anchorPane.heightProperty());
它将绑定buffers的宽度和高度与anchorPane的宽度和高度,因此,每当anchorPane的大小改变时,缓冲区的大小也会改变。您也不需要调整大小缓冲区,只需在您的类中使用此代码
@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();
buffer.prefWidthProperty().bind(anchorPane.widthProperty());
buffer.prefHeightProperty().bind(anchorPane.heightProperty());
}
答案 2 :(得分:0)
只需将对resetBuffer
的呼叫包装到Platform.runLater
中,如下所示:
anchorPane.widthProperty().addListener((observable, oldValue, newValue) -> {
Platform.runLater(() -> {
resetBuffer(chart, buffer, anchorPane);
});
});
这样,您将确保在布局图表之后执行代码