Pregunta

I'm creating a game in which I create custom racing tracks and storing them in a database as strings. I do this by drawing on Canvas, creating a WritableImage by using snapshot, and then using a PixelReader to read the pixels one by one, storing a different character for every color (which in the game, is a different object eg. starting point, finish line, wall etc).

Everything is working fine on every first racing track I create, but on the other times I press the button to save a racing track (even if I exited the stage I was before and I'm in a new stage), I get this exception:

java.lang.IllegalStateException: Resource obsoleted too many times at com.sun.prism.impl.ManagedResource.contentsNotUseful(ManagedResource.java:461) at com.sun.prism.impl.BaseTexture.contentsNotUseful(BaseTexture.java:278) at com.sun.javafx.sg.prism.NGCanvas.renderStream(NGCanvas.java:819) at com.sun.javafx.sg.prism.NGCanvas.renderContent(NGCanvas.java:578) at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2043) at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1951) at com.sun.javafx.tk.quantum.QuantumToolkit$18.draw(QuantumToolkit.java:1318) at com.sun.javafx.tk.quantum.QuantumToolkit$18.run(QuantumToolkit.java:1354) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308) at com.sun.javafx.tk.RenderJob.run(RenderJob.java:58) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.run(QuantumRenderer.java:129) at java.lang.Thread.run(Thread.java:745)

I think it has to do with the snapshot not being full rendered but I don't know how to fix the issue.

I've tried starting a new thread and used "Thread.sleep(1000)" just to give it some time to finish rendering as I saw in https://community.oracle.com/thread/2579185 but it doesn't change anything.

Edit: Here's an SSCCE

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.control.Button;
import javafx.scene.image.PixelWriter;
import javafx.scene.image.WritableImage;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

public class ExceptionClass extends Application {

    Canvas c;
    GraphicsContext gc;
    WritableImage temp;
    int x = 0, y = 0;

    @Override
    public void start(Stage primaryStage) {
        c = new Canvas(400, 400);
        gc = c.getGraphicsContext2D();
        gc.setStroke(Color.BLACK);
        gc.setLineWidth(5.0);
        temp = c.snapshot(null, temp);
        Button btn = new Button("Damn you, stupid exception!");
        btn.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                System.out.println("Altering the canvas...");
                gc.strokeOval(x, y, 20, 20);
                PixelWriter pr = gc.getPixelWriter();
                pr.setColor(x + 10, y + 10, Color.RED);
                temp = c.snapshot(null, temp);
                x += 20;
                y += 20;
            }
        });
        StackPane root = new StackPane();
        root.getChildren().addAll(c, btn);

        Scene scene = new Scene(root, 800, 800);

        primaryStage.setTitle("Exception!");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

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

}

My assumption was wrong. It turns out that the PixelWriter I create is causing this exception. I didn't mention it before because I thought it was irrelevant, it's job is to just change the color of 1 pixel to indicate the starting point of my game, that's why it has to be called only when I save a track. I would still like to know why this exception is thrown :)

¿Fue útil?

Solución

This is reported as RT-33294. According to the bug report, it's a regression in 8.0.0, so it should work fine with releases prior to that, as well as 8.0.0_20 and later.

The suggested workaround for 8.0.0 and 8.0.0_05 is to call setPixels instead of setColor:

                PixelWriter pr = gc.getPixelWriter();
//                pr.setColor(x + 10, y + 10, Color.RED);
                pr.setPixels(x + 10, y + 10, 1, 1, PixelFormat.getIntArgbInstance(), new int[] { 0xffff0000 }, 0, 1);
                temp = c.snapshot(null, temp);
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top