Reputation: 164
This is a continuation of this question.
I am trying to cover chart plot with an AnchorPane, i called it buffer.
Here is a code example.
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());
}
}
Everything works fine until I resize the stage. When I resize the AnchorPane (buffer) is not covering a chart plot properly. i.e. it is not fitting the size.
How to fix it or do it in proper way?
Upvotes: 7
Views: 370
Reputation: 323
Simply wrap your call to resetBuffer
in a Platform.runLater
, like this:
anchorPane.widthProperty().addListener((observable, oldValue, newValue) -> {
Platform.runLater(() -> {
resetBuffer(chart, buffer, anchorPane);
});
});
This way you will be sure that your code is executed after the chart has been laid out
Upvotes: 0
Reputation: 927
Hope this will solve it:
First solution:
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
));
(it need to be in resetBuffer
and it needs to call only one time at the beginning of course after primaryStage.show()
)
Second solution:
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));
}
});
it base on the fact that width and hight is permanent in the axis label and legend, so we just need to calculate the diffrent on the scene
size an apply on buffer
.
the all code:
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));
}
});
}
}
Upvotes: 2
Reputation: 3862
Update: Instead of Adding Listener to widthProperty add Listener to prefWidthProperty e.g:
anchorPane.prefWidthProperty().addListener((observable, oldValue, newValue) -> {
resetBuffer(chart, buffer, anchorPane);
});
OLD
you can try to bind buffer prefWidth and prefHeight with anchorPane's prefWidth and prefHeight e.g
buffer.prefWidthProperty().bind(anchorPane.widthProperty());
buffer.prefHeightProperty().bind(anchorPane.heightProperty());
It will bind the buffers width and height with anchorPane's width and height so whenever the size of anchorPane change buffer's size also changes. You also dont need resize buffer just use this code in your class
@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());
}
Upvotes: 0