当前位置: 首页 > 面试题库 >

JavaFX可以在jdk7上正常运行,但不能在jdk8上正常运行:在FX应用程序线程上无效

微生运浩
2023-03-14
问题内容

我最近遇到了这个问题:

java.util.NoSuchElementException线程“
Thread-4”中的异常java.lang.IllegalStateException:不在FX应用程序线程上;仅在FX应用程序线程上有效。currentThread
=线程4

该代码适用于jdk7,但不适用于jdk8,该代码如下所示:

public class myThread extends Thread {
    TextArea ta;
    String foo;
    connect(String foo, TextArea ta){
        this.ta = ta;
        this.foo = foo;
    }
    @Override
    public void run{
        Scanner scanner = new Scanner(foo);
        scanner.next();
        ta.appendText(scanner.next());
    }
}

然后我从以下代码中调用此线程:

    public class myApp extends Application {

        @Override
        public void start(Stage stage) {
            TextArea ta = new TextArea();
            TextField tf = new TextField
            Pane root = new Pane();
            root.getChildren().addAll(ta,tf);
            Scene scene = new Scene(root);
            stage.setScene(scene);
            stage.show();

            tf.setOnAction((javafx.event.ActionEvent event) -> {
                String foo = tf.getText();
                tf.clear();
                new myThread(foo,ta).start();
            });
        }

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

我要做的就是从其他具有功能的线程中更改控件的值/属性,就像在我的示例中一样,它扫描下一个字符串,然后将其附加到TextArea。

为什么它可以在jdk7上运行但不能在jdk8上运行?请 说明…

我已经进行了一些研究,并提出了解决JavaFX任务和服务的解决方案,但是我没有得到它们,网上也没有很好的例子。

请帮助…谢谢…


问题答案:

您的代码实际上在JDK7上也被破坏了。从后台线程(即不是从FX Application
Thread)更改UI控件的状态是非法的。与几乎所有UI工具包一样,JavaFX使用单线程模型,并且不提供UI元素的同步。因此,如果您从FX
Application Thread之外的其他线程更改或查看UI控件的状态,则您的代码容易发生未指定且不可预测的行为。

在JavaFX 2.2和更早版本(与JDK 7一起提供)中,很少有运行时检查来检查代码是否在正确的线程上执行。因此,您不会在JDK
7中遇到运行时异常,但是如上所述,您的代码有错误,并且结果不确定。在JavaFX
8中,对API进行了改进,以便(在大多数情况下)违反此规则将引发IllegalStateException。(这更好,因为您立即知道出了点问题。)

解决方法是更新FX Application Thread上的UI控件:

final TextArea ta = new TextArea() ;

// ...

Platform.runLater(new Runnable() {
    @Override
    public void run() {
        ta.appendText(scanner.next());
    }
});

如果现在仅使用Java 8,则可以使用lambda表达式替换匿名内部类:

Platform.runLater(() -> ta.appendText(scanner.next()));

ta尽管仍然有限制,但不再需要声明为final了)。



 类似资料:
  • 我的应用程序在emulator上运行得很好,但当我导出后在我的智能手机(galaxy s3)上运行它时,它会在这个活动中崩溃,因为有HTTP连接!问题出在哪里?代码还是导出?当我点击连接按钮时,它崩溃了。

  • 我正在为我的Android应用程序使用Firebase身份验证和数据库。所有的一切都可以在一个仿真器上运行(Nexus 5X API 26、Nexus 6 API 26、Galaxy Nexus API 24)。当我在我的个人Galaxy S6 Edge API 24上启动应用程序时,我的Firebase相关项目都没有工作。 没有崩溃错误。 很抱歉写了这么长的日志,我似乎弄不明白问题所在。请让我知

  • 问题内容: 我正在尝试使用Windows上的SOnarQube MsBuild在Jenkins的.NET Core 2.0解决方案上启动Sonarqube。 当我从Jenkins工作区执行以下脚本时,它工作正常: 但是,当我从詹金斯执行相同的命令时,我得到了以下消息: SonarQube MSBuild集成失败:SonarQube无法收集有关您的项目的必需信息。可能的原因: 该项目尚未构建-必须在

  • 它可以在仿真器和真实设备(android版本4)上工作,但不能在真实设备(android版本7.0)上工作 相关代码: logcat: 05-23 10:31:39.464 173 42-17342/laftel.net.laftel E/AndroidRuntime:致命异常:主进程:laftel.net.laftel,pid:17342 java.lang.nullPointerExcepti

  • 我是爱奥尼亚的新手,如果我的问题很愚蠢,请原谅我。在开发过程中,我使用浏览器来显示和测试我的应用程序,一切都正常工作,没有任何问题,但是当我在android设备上的Ionic DevApp上测试我的应用程序时,应用程序无法与后端通信(REST API)。每次我发送请求(如登录请求)时,系统都会响应。 console.log显示错误信息: 我的申请: 前端:离子角 后端(RESTAPI):JavaS

  • 问题内容: 我有以下代码: 在模拟器中工作正常。但是当我在手机上尝试时,它崩溃了。这是控制台: 这行: NSNumberFormatter()。numberFromString(display.text!)! 返回nil,这导致应用程序崩溃,导致无法打开可选包装。我真的不知道怎么了 我正在关注iTunes U中的一些教程。 任何帮助,将不胜感激。 问题答案: 尝试: 因为默认情况下使用设备区域设置