Asperger
Asperger

Reputation: 3222

Simple Java square animation with JavaFX is not smooth, why?

So I noticed something about the framerate / smoothness of my animation. The Animation is somewhat choppy. However, after doing soing testing I noticed that it becomes smooth again as soon as I trigger a resize event, be it only 0.1 px. I have the newest Java installed.

I cant work with vsync unless its opengl and it seems javafx is using a triple bugger or something. Either way the performance is really bad. My windows machine is pretty good and on the newest version.

So after my the call of the show() function I added:

Window.setWidth(Window.getWidth() + 0.1)

Problem was solved but of course I want to know what is going on under the hood and how to I truly solve this without resorting to such primitive hacks?

JavaFX Canvas Double Buffering

My code is below:

import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.util.Duration;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.layout.GridPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.scene.control.Button;

public class Gui extends Application{

    Stage Window;

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {

        Window = primaryStage;
        Window.setTitle("Gui Tester");

        Group root = new Group();
        Rectangle box = new Rectangle(0, 0, 50,50);
        box.setFill(Color.GREEN);
        KeyValue x = new KeyValue(box.xProperty(), 900);
        KeyFrame keyFrame = new KeyFrame(Duration.millis(3000), x);
        Timeline timeline = new Timeline();
        timeline.setCycleCount(Timeline.INDEFINITE);
        timeline.setAutoReverse(true);
        timeline.getKeyFrames().add(keyFrame);
        timeline.play();
        root.getChildren().add(box);

        GridPane grid = new GridPane();
        grid.setVgap(8);

        root.getChildren().add(grid);

        Button newGame = new Button("START NEW GAME");

        GridPane.setConstraints(newGame, 1, 1);

        Button continueGame = new Button("CONTINUE");
        GridPane.setConstraints(continueGame, 1, 2);

        grid.getChildren().addAll(newGame, continueGame);

        Scene scene = new Scene(root, 1000, 1000);
        scene.getStylesheets().add("tester.css");
        Window.setScene(scene);
        Window.show();
        Window.setWidth(Window.getWidth() + 0.1)
    }
}

Upvotes: 4

Views: 1760

Answers (1)

trashgod
trashgod

Reputation: 205775

Tested on Mac OS X 10.11.4, Java 1.8.0_92, NVIDIA GeForce 9400, no energy saving.

Both the example shown, using Timeline, and this example, using PathTransition, start out choppy. Subsequently, they both smooth out after about one auto-reverse cycle. Using the -Xint option, which "Runs the application in interpreted-only mode" as shown here, significantly diminishes the initial stuttering, especially after a second run. Delays due to just-in-time compiler overhead may be exaggerated if the application remains confined to a single core or the animation creates a busy loop that fails to reach a safepoint, as illustrated here.

Upvotes: 1

Related Questions