As mentioned in Stefan, the best way is to set the cache property for true nodes that you do not want to update. I want to add that StackPane does not require special attention, it can be Pane or another region (in fact, StackPane has its own way of adding new children that make you manipulate). Here is a piece of code that I used to implement LineMarker, which moves along LineChart (in my example, I had a video, and LineMarker is the time on the chart)
Basic example
Pane pane; LineChart chart; MediaPlayer mediaPlayer; // Create pane, chart (and mediaplayer for this example) pane.getChildren.add(chart); List<XYChart.Data<Number, Number> dataList; XYChart.Series series = new XYChart.Series(); // Fill the data ObservableList<XYChart.Data<Number, Number>> list; list = FXCollections.observableList(dataList); series.setData(list); chart.getData().add(series); chart.setCache(true); LineMarker lineMarker = new LineMarker(pane, (ValueAxis) chart.getXAxis(), 0, (ValueAxis) chart.getYAxis()); mediaPlayer.currentTimeProperty().addListener((v, oldValue, newValue) -> lineMarker.updateMarker(newValue.doubleValue()));
LineMarker.java
public class LineMarker extends Line{ private final DoubleProperty value = new SimpleDoubleProperty(); private Pane pane; private ValueAxis xAxis; private ValueAxis yAxis; public LineMarker(Pane pane, ValueAxis xAxis, double value, ValueAxis yAxis){ this.pane = pane; this.xAxis = xAxis; this.yAxis = yAxis; Number lowerY = yAxis.toRealValue(yAxis.getLowerBound()); double minY = yAxis.getDisplayPosition(lowerY); setStartY(getYPositionParent(minY, pane)); Number upperY = yAxis.toRealValue(yAxis.getUpperBound()); double maxY = yAxis.getDisplayPosition(upperY); setEndY(getYPositionParent(maxY, pane)); double xPosInAxis = xAxis.getDisplayPosition(value); setStartX(getXPositionParent(xPosInAxis, pane)); setEndX(getStartX()); pane.getChildren().add(this); } private double getXPositionParent(double xPosInAxis, Node parent){ double xPosInParent = xPosInAxis - xAxis.getBoundsInLocal().getMinX(); Node node = xAxis; while(!node.equals(parent)){ xPosInParent = xPosInParent + node.getBoundsInParent().getMinX(); node = node.getParent(); } return xPosInParent; } private double getYPositionParent(double yPosInAxis, Node parent){ double yPosInParent = yPosInAxis - yAxis.getBoundsInLocal().getMinY(); Node node = yAxis; while(!node.equals(parent)){ yPosInParent = yPosInParent + node.getBoundsInParent().getMinY(); node = node.getParent(); } return yPosInParent; } public void updateMarker(double value){ pane.getChildren().remove(this); double xPosInAxis = xAxis.getDisplayPosition(value); setStartX(getXPositionParent(xPosInAxis, pane)); setEndX(getStartX()); pane.getChildren().add(this); pane.requestLayout(); }
Rodmendez
source share