snapshot and freeze

Jeff Hain jeffhain at rocketmail.com
Wed Sep 13 22:14:43 UTC 2017


Hello.


I encountered a (recoverable) freeze issue related to Canvas.snapshot(...),
when either width or height (or both) used for Scene constructor
is zero (I don't know scene width/height at construction time),
even though it's not indicated as an invalid value.
Using JDK 1.8.0_144, on Windows 7 64.


With negative values, which are considered as uninitialized,
the problem doesn't occur, so considering 0 as uninitialized
as well might fix it, even though it might not address some
deeper issue making such a freeze possible.


The following code allows to reproduce it,
as well as some workarounds:


/**
 * Action: click multiple times on the canvas.
 * Expected: content is copy-shift-pasted each time.
 */
public class JfxSnapshotMain extends Application {
    /*
     * Programmatic workarounds.
     * NB: Resizing the stage manually
     * (but not programmatically) also works,
     * but not iconifying/deiconifying it.
     */
    private static final boolean WORKAROUND_1 = false;
    private static final boolean WORKAROUND_2 = false;
    public static void main(String[] args) {
        launch(args);
    }
    @Override
    public void start(Stage stage) {
        Pane root = new Pane();
        double initWidth = 0.1;
        double initHeight = (WORKAROUND_1 ? 0.1 : 0.0);
        Scene scene = new Scene(root, initWidth, initHeight);
        double width = 200.0;
        double height = 100.0;
        Canvas canvas = new Canvas(width, height);
        canvas.addEventHandler(
                MouseEvent.MOUSE_PRESSED,
                new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                System.out.println("handle(" + event + ")");
                takeSnapshotAndDrawShifted(canvas);
                if (WORKAROUND_2) { stage.hide(); stage.show(); }
            }
        });
        root.getChildren().add(canvas);
        stage.setWidth(width);
        stage.setHeight(height);
        stage.setScene(scene);
        drawStuffs(canvas);
        stage.show();
    }
    private static void drawStuffs(Canvas canvas) {
        GraphicsContext gc = canvas.getGraphicsContext2D();
        gc.setStroke(Color.BLACK);
        gc.strokeText("Click This", 10.0, 10.0);
    }
    private static void takeSnapshotAndDrawShifted(Canvas canvas) {
        WritableImage img = canvas.snapshot(null, null);
        canvas.getGraphicsContext2D().drawImage(img, 10.0, 10.0);
    }
}


-Jeff



More information about the openjfx-dev mailing list