Как упомянуто Stefan, наилучшим способом является присвоение cache
объектов true
узлов, которые вы не хотите обновлять. Я хочу добавить, что StackPane
не требует особого внимания, это может быть Pane
или другой регион (на самом деле StackPane имеет свой собственный способ добавления новых детей, которые заставляют вас манипулировать). Вот фрагмент кода, который я использовал для реализации LineMarker, которая двигается вдоль LineChart
(в моем примере я имел видео и LineMarker следовало время на графике)
Главного Пример
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();
}