我最近遇到了这个问题:
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。(这更好,因为您立即知道出了点问题。)
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了)。
ta