JavaFX TextArea appendText 在初始化中有效,但在其他地方无效
JavaFX TextArea appendText works in initialize but not elsewhere
问题很简单,但它让我抓狂。
在我的程序中我有一个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
结束并退出循环之后。
问题是您是在主线程中执行此操作。所以阶段不能更新,直到循环结束。在新线程中尝试:
@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();
}
UI 中显示的文本随布局脉冲而变化。布局脉冲在 JavaFX 应用程序线程上完成。事件处理程序,例如同一线程上的 download
方法 运行 有效地阻止它在完成之前进行任何布局或处理以及其他事件。这就是为什么你不应该用 long运行ning 任务阻塞这个线程,而是在不同的线程上执行它们。
由于对 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();
}
问题很简单,但它让我抓狂。
在我的程序中我有一个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
结束并退出循环之后。
问题是您是在主线程中执行此操作。所以阶段不能更新,直到循环结束。在新线程中尝试:
@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();
}
UI 中显示的文本随布局脉冲而变化。布局脉冲在 JavaFX 应用程序线程上完成。事件处理程序,例如同一线程上的 download
方法 运行 有效地阻止它在完成之前进行任何布局或处理以及其他事件。这就是为什么你不应该用 long运行ning 任务阻塞这个线程,而是在不同的线程上执行它们。
由于对 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();
}