简单的问题,但它让我发疯。
在我的程序中,我有TextArea
,定义为:
<TextArea fx:id="output" editable="false" prefHeight="300.0" prefWidth="200.0" text="Output" GridPane.columnSpan="2" GridPane.rowIndex="4" />
@FXML private TextArea output;
...
public void initialize(URL url, ResourceBundle rb) {
output.setText("Test"); //Test appears correctly in output
...
}
@FXML
public void download() {
String outputTemplate = templateField.getText();
String url = urlField.getText();
System.out.println("Downloading from " + url);
try {
Process down = Runtime.getRuntime().exec("youtube-dl -o \"" + outputTemplate + "\" " + url);
BufferedReader reader = new BufferedReader(new InputStreamReader(down.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line); //Prints as expected
output.appendText(line + "\n"); //Has no effect
}
} catch (IOException e) {
e.printStackTrace();
}
}
关于如何让文字出现的任何想法都会很棒,我之前已经在不同的节目中做过这件事,只是出于某种原因,这次它是不好的
编辑:进一步修改后,它实际上会打印出结果,但只有在Process
结束后它才会退出循环。
答案 0 :(得分:3)
UI中显示的文本在布局脉冲上发生变化。布局脉冲在JavaFX应用程序线程上完成。事件处理程序(如download
方法)在同一个线程上运行,有效地阻止它在完成之前进行任何布局或处理以及其他事件。这就是为什么你不应该用冗长的任务来阻止这个线程,而是在不同的线程上执行它们。
由于应该从应用程序线程对UI进行更新,因此请使用Platform.runLater
附加文本:
@FXML
public void download() {
String outputTemplate = templateField.getText();
String url = urlField.getText();
Runnable r = () -> {
System.out.println("Downloading from " + url);
try {
Process down = Runtime.getRuntime().exec("youtube-dl -o \"" + outputTemplate + "\" " + url);
BufferedReader reader = new BufferedReader(new InputStreamReader(down.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line); //Prints as expected
final String printText = line + "\n";
// append the line on the application thread
Platform.runLater(() -> output.appendText(printText));
}
} catch (IOException e) {
e.printStackTrace();
}
};
// run task on different thread
Thread t = new Thread(r);
t.start();
}
答案 1 :(得分:0)
问题是你在主线程中这样做了。所以阶段无法更新,直到循环结束。在新主题中尝试:
@FXML
public void download() {
Task<Void> task = new Task<Void>() {
@Override
protected Void call() {
String outputTemplate = templateField.getText();
String url = urlField.getText();
System.out.println("Downloading from " + url);
try {
Process down = Runtime.getRuntime().exec("youtube-dl -o \"" + outputTemplate + "\" " + url);
BufferedReader reader = new BufferedReader(new InputStreamReader(down.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line); // Prints as expected
output.appendText(line + "\n"); // Has no effect
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
};
new Thread(task).start();
}