gpt4 book ai didi

java - JavaFX 自定义控制台中的线程冲突

转载 作者:行者123 更新时间:2023-11-29 10:02:53 24 4
gpt4 key购买 nike

我制作了一个 Java/JavaFX 控制台,现在我遇到一个异常:控制台报告一个内部错误。错误是:java.lang.IllegalStateException: Not on FX application thread;当前线程 = 线程 5。控制台代码:

package core.console;
import javafx.concurrent.Service;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.TextArea;
import javafx.stage.Stage;

import java.io.*;
import java.util.ResourceBundle;

public class Console implements Runnable{
private Console(ResourceBundle resourceBundle) throws IOException {
FXMLLoader loader = new FXMLLoader(this.getClass().getResource("Console.fxml"), resourceBundle);
Parent root = (Parent) loader.load();
controller = loader.getController();
Scene scene = new Scene(root);
stage = new Stage();
stage.setScene(scene);
textArea = controller.getTextArea();
show();

PipedOutputStream pout=new PipedOutputStream(this.pin);
System.setOut(new PrintStream(pout,true));

PipedOutputStream pout2=new PipedOutputStream(this.pin2);
System.setErr(new PrintStream(pout2,true));

System.setIn(new PipedInputStream(this.pout3));

reader = new Thread(this);
reader.setDaemon(true);
reader.start();

reader2 = new Thread(this);
reader2.setDaemon(true);
reader2.start();
}

public static Console getInstance(ResourceBundle resourceBundle) {
if (console == null) {
try {
console = new Console(resourceBundle);
} catch (IOException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
return console;
}

public void show() {
stage.show();
}

@Override
public synchronized void run()
{
try
{
while (Thread.currentThread()==reader)
{
try {
this.wait(100);
} catch(InterruptedException ie) {}
if (pin.available()!= 0)
{
String input=this.readLine(pin);
controller.appendText(input);
}
if (quit) return;
}

while (Thread.currentThread()==reader2)
{
try {
this.wait(100);
} catch(InterruptedException ie) {}
if (pin2.available()!= 0)
{
String input = this.readLine(pin2);
controller.appendText(input);
}
if (quit) return;
}
} catch (Exception e)
{
controller.appendText("\nConsole reports an Internal error.");
controller.appendText("The error is: "+e);
}

}

private synchronized String readLine(PipedInputStream in) throws IOException
{
String input="";
do
{
int available=in.available();
if (available==0) break;
byte b[]=new byte[available];
in.read(b);
input=input+new String(b,0,b.length);
}while( !input.endsWith("\n") && !input.endsWith("\r\n") && !quit);
return input;
}

private static Console console = null;
private ConsoleController controller;
private Stage stage;
private TextArea textArea;
private Thread reader;
private Thread reader2;

private final PipedInputStream pin=new PipedInputStream();
private final PipedInputStream pin2=new PipedInputStream();
private final PipedOutputStream pout3=new PipedOutputStream();


}

启动应用程序时,控制台显示上述异常,但一切正常。但是如果应用程序产生异常,控制台不会显示它并且所有内容都被锁定。我做错了什么?

最佳答案

JavaFX 是一个单线程工具包。您永远不应该从后台线程查询或更新 UI。所以你需要用

包装对 JFX 类的所有调用
Platform.runLater(new Runnable() {
@Override
public void run() {
// Update/Query the FX classes here
}
});

在您的上下文中,Console.run() 方法中的代码是在 JavaFX 应用程序线程之外执行的,因此它不应该通过调用 controller.appendText( )。在您的情况下,所有 controller.appendText() 调用都应包装在上面定义的 Platform.runLater 构造中。

关于java - JavaFX 自定义控制台中的线程冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18387626/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com