Canvas JavaFX快照异常:资源过时太多次

Canvas JavaFX快照异常:资源过时太多次,canvas,javafx,render,snapshot,illegalstateexception,Canvas,Javafx,Render,Snapshot,Illegalstateexception,我正在创建一个游戏,在这个游戏中我创建了自定义的赛道,并将它们作为字符串存储在数据库中。我在画布上画画,使用快照创建一个可写图像,然后使用像素阅读器逐个读取像素,为每种颜色存储不同的字符(在游戏中,它是不同的对象,例如起点、终点、墙等) 在我创建的第一条赛道上,一切都很正常,但在其他时候,我按下按钮保存赛道(即使我退出了之前的阶段,并且处于新阶段),我会遇到以下异常: java.lang.IllegalStateException:资源过时太多次 位于com.sun.prism.impl.Ma

我正在创建一个游戏,在这个游戏中我创建了自定义的赛道,并将它们作为字符串存储在数据库中。我在画布上画画,使用快照创建一个可写图像,然后使用像素阅读器逐个读取像素,为每种颜色存储不同的字符(在游戏中,它是不同的对象,例如起点、终点、墙等)

在我创建的第一条赛道上,一切都很正常,但在其他时候,我按下按钮保存赛道(即使我退出了之前的阶段,并且处于新阶段),我会遇到以下异常:

java.lang.IllegalStateException:资源过时太多次
位于com.sun.prism.impl.ManagedResource.contentsnotusive(ManagedResource.java:461)
位于com.sun.prism.impl.BaseTexture.contentsnotusive(BaseTexture.java:278)
位于com.sun.javafx.sg.prism.NGCanvas.renderStream(NGCanvas.java:819)
位于com.sun.javafx.sg.prism.NGCanvas.renderContent(NGCanvas.java:578)
com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2043)
位于com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1951)
com.sun.javafx.tk.quantum.QuantumToolkit$18.draw(QuantumToolkit.java:1318)
com.sun.javafx.tk.quantum.QuantumToolkit$18.run(QuantumToolkit.java:1354)
位于java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)上的

位于com.sun.javafx.tk.RenderJob.run(RenderJob.java:58)
位于java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
位于java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
位于com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.run(QuantumRenderer.java:129)
java.lang.Thread.run(Thread.java:745)上的

我认为这与快照未完全渲染有关,但我不知道如何解决该问题

我尝试启动一个新线程,并使用“thread.sleep(1000)”只是为了给它一些时间来完成渲染,正如我在中看到的那样 但这并没有改变任何事情

编辑:这是一个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);
    }

}
导入javafx.application.application;
导入javafx.event.ActionEvent;
导入javafx.event.EventHandler;
导入javafx.scene.scene;
导入javafx.scene.canvas.canvas;
导入javafx.scene.canvas.GraphicsContext;
导入javafx.scene.control.Button;
导入javafx.scene.image.PixelWriter;
导入javafx.scene.image.WritableImage;
导入javafx.scene.layout.StackPane;
导入javafx.scene.paint.Color;
导入javafx.stage.stage;
公共类ExceptionClass扩展应用程序{
帆布c;
GraphicsContext gc;
可写映像温度;
int x=0,y=0;
@凌驾
公共无效开始(阶段primaryStage){
c=新画布(400400);
gc=c.getGraphicsContext2D();
gc.设定行程(颜色为黑色);
gc.设定线宽(5.0);
temp=c.snapshot(null,temp);
按钮btn=新按钮(“该死的,愚蠢的例外!”);
btn.setOnAction(新的EventHandler(){
@凌驾
公共无效句柄(ActionEvent事件){
System.out.println(“改变画布…”);
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=新的StackPane();
root.getChildren().addAll(c,btn);
场景=新场景(根,800800);
setTitle(“异常!”);
初级阶段。场景(场景);
primaryStage.show();
}
公共静态void main(字符串[]args){
发射(args);
}
}
我的假设是错误的。结果是我创建的PixelWriter导致了这个异常。我之前没有提到它,因为我认为它是不相关的,它的工作就是改变1像素的颜色,以指示我游戏的起点,这就是为什么只有在我保存轨迹时才会调用它。 我仍然想知道引发此异常的原因:)

这被报告为。根据bug报告,这是8.0.0中的一个回归,因此它应该可以与之前的版本以及8.0.0_20及更高版本配合使用

8.0.0和8.0.0_05的建议解决方法是调用
setPixels
,而不是
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);

有趣的发现;我从未见过那个错误。你能创建一个吗?我已经更新了我的代码:)我以前也从未见过这个异常(我见过数千个),我在谷歌上搜索了大约一个小时才决定在这里提问。我在Mac OS X 10.9、2012 Macbook Air、Java 1.8.0_20-ea-b11=>上运行了这个应用程序,没有异常。我在Windows 7上使用NetBeans,东芝Qosmio x505-885,Java 1.8.0_05我不认为这是性能问题,我的笔记本电脑没有那么旧。我将尝试更新Java,看看会发生什么…工作起来很有魅力!我尝试更新20ea,但引发了一些其他异常,如果不需要的话,我不想处理新的错误。感谢您对错误的解释和解决方法!