当前位置: 首页 > 知识库问答 >
问题:

JavaFX ImageView投掷IllegalStateExc的

李敏学
2023-03-14

我在视图中有一个ImageView,并尝试用它显示一个WritableImage实例。我正在外线程中绘制它,并通过侦听ObjectProperty的更改事件将其传递给视图。

public void changed(ObservableValue<? extends Image> observable,
        Image oldValue, Image newValue) {
    this.imageView.setImage(newValue);
}

imageView应该准备好接收图像,它由我的主视图显示。但是这是一个不合法的例外

线程“Thread-4”Java . lang . illegalstateexception中的异常:不在FX应用程序线程上;当前线程=线程-4

有人能解释一下吗?

共有1个答案

陆野
2023-03-14

这个异常基本上告诉你问题是什么:你正在从一个线程而不是FX应用程序线程改变场景图的一部分的状态。这是因为侦听器方法是在更改属性的同一线程上调用的。

您有两个解决此问题的选项:一个是只使用Platform.runLater(…)。您可以在侦听器中执行此操作:

public void changed(ObservableValue<? extends Image> observable,
        Image oldValue, Image newValue) {
    Platform.runLater(new Runnable() {
        @Override
        public void run() {
            this.imageView.setImage(newValue);
        }
    });
}

或者您可以做同样的事情来设置FX应用程序线程上的属性值。

您没有显示太多代码,但也可以使用任务来计算图像。所以而不是像这样的东西:

new Thread(new Runnable() {
    @Override
    public void run() {
        WritableImage image = new WritableImage(...);
        /// draw on image....
        myImageProperty.set(image);
    }
});

你可以做这样的事情

Task<Image> imageTask = new Task<Image>() {
    @Override
    public Image call() {
        WritableImage image = new WritableImage(...);
        // draw on image....
        return image ;
    }
});

imageTask.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
    @Override
    public void handle(WorkerStateEvent event) {
        myImageProperty.set(imageTask.getValue());
    }
});

new Thread(imageTask).start();

(这在Java 8中干净多了;我发布了Java 7兼容代码,因为您在问题中使用了这种风格)。

在这里,您可以避免使用低级API(Platform.runLater()),而是使用来自Task的回调方法之一(setOnSuccessed),该方法保证在FX应用程序线程上调用。

 类似资料:
  • 有人可以解释我什么时候使用关键字 throw new 有用.而不是在方法的签名旁边使用抛出? 我知道当方法抛出Checked Exception时。Java迫使我们通过将Exception处理到try-catch块中,或者通过在签名旁边的关键字throws指定将在其他地方完成,从而直接在方法中处理它。 然而,我很难理解何时使用关键字throw new是有用的,以及为什么。它与处理未选中的异常有关吗

  • 我正在用python运行下面的代码 我每次都会遇到下面的错误-有人能帮忙吗! OpenCV错误:未指定的错误(该函数未实现。使用Windows、GTK 2.x或Carbon支持重建库。如果您在Ubuntu或Debian上,请安装libgtk2.0-dev和pkg config,然后重新运行cmake或configure脚本),位于cvShowImage、file/Users/travis/buil

  • 我有两个类(SimManager和Sim),我想为它们创建模拟对象,然后使用存根方法。 测试在上面第9行抛出这两个错误跟踪。 第一: Java语言lang.VerifyError:org/mockito/cglib/core/reflectils at org。莫基托。cglib。果心KeyFactory$发电机。在org上生成Class(KeyFactory.java:167)。莫基托。cgli

  • 我有下面的代码,它按照预期工作: 我想知道是否有一种方法,只有一个orElseThrow-Part,或做它更少的冗余?

  • 我向服务器调用一个请求网络,服务器总是响应如下所示的格式json: 对于每种请求,只有jsonObject数据包含不同的字段。新响应的示例: 因此,我决定让一个通用类调用ServerResult包含一个字段“Object”,以便将其强制转换为特定对象。 //ServerResult.class //client.java 请求完成后,我通过GSON将json转换为ServerResult对象: 然

  • 无法弄清楚这是怎么回事-试图设置一个路由,只看到cxf连接到soap web服务(我不关心实际数据,也不期望数据实际“工作”,但它不断引发一个我不理解的异常: 我想知道我是否正确配置了它。我想这可能是一个丢失的jar,但当我尝试引入其他jar时,导致了依赖冲突 我正在使用maven依赖项“camel-cxf”来加载我所有的jar配置 “原因:org.apache.cxf.bus.extension