Reputation: 722
I have background (Rectangle
) and Group
added into root
of canvas. I add smaller Rectangle
(player) into group and then move rectangle by AnimationTimer (custom without thread sleep). When small Rectangle
arrive centrain X position I want to remove this Rectangle from scene. After deletion, rectangle remains in canvas until I move/resize window. How to refresh canvas to make deleted rectangle disappear?
public class Test extends Application {
public static final int TILE_SIZE = 50;
public static final int WIDTH = 15;
public static final int HEIGHT = 15;
public static final int FRAMERATE = 30;
private Pane root;
private Group group = new Group();
private Rectangle player;
private Parent createContent() {
root = new Pane();
root.setPrefSize(500, 500);
Rectangle bg = new Rectangle(500, 500);
bg.setFill(Color.RED);
root.getChildren().addAll(bg, group);
AnimationTimer timer = new AnimationTimer() {
@Override
public void handle(long now) {
onUpdate();
}
};
timer.start();
player = new Rectangle(20, 20);
player.setFill(Color.GREEN);
group.getChildren().add(player);
return root;
}
public void onUpdate() {
if (player.getTranslateY() > 100) {
group.getChildren().remove(player);
} else {
player.setTranslateX(player.getTranslateX() + 1);
player.setTranslateY(player.getTranslateY() + 1);
}
}
@Override
public void start(Stage primaryStage) throws Exception {
Scene scene = new Scene(createContent());
primaryStage.setTitle("Test");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Upvotes: 3
Views: 404
Reputation: 209320
This is a known bug, which is still unresolved.
The workarounds suggested in the bug report are to disable dirty region optimizations, which you can do by providing the JVM option -Dprism.dirtyopts=false
, i.e. run it as
java -Dprism.dirtyopts=false Test
You can also set this programmatically if your main
method is in a class separate to the Application
subclass (because you need to set it before the Application
class is loaded):
import javafx.application.Application;
public class App {
public static void main(String[] args) {
System.setProperty("prism.dirtyopts", "false");
Application.launch(Test.class, args);
}
}
(and then just run the App
class in the usual way).
Another workaround seems to be to ensure there is a more complex change to the group's list of child nodes, but this is not likely to be very robust. For example, the following seems to work in this particular case.
public void onUpdate() {
if (player.getTranslateY() > 100) {
Rectangle dummy = new Rectangle();
group.getChildren().add(dummy);
group.getChildren().remove(player);
group.getChildren().remove(dummy);
} else {
player.setTranslateX(player.getTranslateX() + 1);
player.setTranslateY(player.getTranslateY() + 1);
}
}
Upvotes: 4