【发布时间】:2015-10-26 16:13:48
【问题描述】:
现在我尝试更新 Javafx 用户界面,同时自动发送 2 个或更多电子邮件。 UI 应该使用“connecting”、“sending”和“sent”来更新标签。我已经阅读了有关 Runnables、Tasks、TimeLine 的信息,但我真的不明白我应该使用哪种方法以及它是如何工作的。
在我读到关于 Platform.runLater() 的所有地方,我都使用了它,但我的 JavaFX Gui 中的动画会冻结,并且标签只会在所有电子邮件都发送后发生变化。
我很快就会用我的代码更新这篇文章,但是有人可以告诉我应该使用哪种线程以及如何轻松更新 ui 吗?
//编辑
感谢您的帮助,Branislav,但现在我收到“不在 FX 应用程序线程”-错误。以下代码不是我的“扩展应用程序”类,请看一下。
public class ControllerOCM implements Initializable{
@FXML
private ComboBox<String> comboEmpf;
@FXML
private Label lblStatus;
@FXML
private Label lblStatus1;
@Override
public void initialize(URL location, ResourceBundle resources) {
hint.setText("some hint");
}
public void sende(ActionEvent event) throws Exception {
switch (comboEmpf.getValue()) {
case "A": System.out.println("A");break;
case "B":
File fTEST = new File("C:\\B\\");
File[] fpathTEST = fTEST.listFiles();
String[] fnameTEST = fTEST.list();
for (int i=0; i<fpathTEST.length; i++) {
SendenTask sendTEST = new SendenTask(mail@address.com,
"bodycontent",
"subject",
fpathTEST[i].toString(),
fnameTEST[i],
i, //count
fpathTEST.length); //max
new Thread(sendTEST).start();
}
break;
}
}
public class SendenTask extends Task<Void> {
private String adr;
private String body;
private String subj;
private String fp;
private String fn;
private int count;
private int max;
public SendenTask(String adr, String body, String subj, String fp, String fn, int count, int max) {
this.adr = adr;
this.body = body;
this.subj = subj;
this.fp = fp;
this.fn = fn;
this.count = count;
this.max = max;
}
@Override
protected Void call() throws Exception {
lblStatus1.setText("connecting");
//doing connectionAction
lblStatus1.setText("sending");
updateMessage("sending");
//doing sendingthingys
//sending complete
lblStatus1.setText("sent");
System.out.println("done");
updateMessage("done");
return null;
}
}
}
//编辑2
现在程序正在一个接一个地发送电子邮件,但 textproperty 无法正常工作。它不刷新文本,它只是清空标签。如果我删除了 unbind-line(成功),它只会在我运行发送任务时起作用。之后,对于所有其他发送任务,它再次为空。
public class ControllerOCM implements Initializable{
@FXML
private ComboBox<String> comboEmpf;
@FXML
private Label lblStatus;
@FXML
private Label lblStatus1;
@Override
public void initialize(URL location, ResourceBundle resources) {
hint.setText("some hint");
}
public void sende(ActionEvent event) throws Exception {
switch (comboEmpf.getValue()) {
case "A": System.out.println("A");break;
case "B":
File fTEST = new File("C:\\B\\");
File[] fpathTEST = fTEST.listFiles();
String[] fnameTEST = fTEST.list();
for (int i=0; i<fpathTEST.length; i++) {
SendenTask sendTEST = new SendenTask(mail@address.com,
"bodycontent",
"subject",
fpathTEST[i].toString(),
fnameTEST[i],
i, //count
fpathTEST.length); //max
lblStatus1.textProperty().bind(sendTEST.messageProperty());
thread = new Thread(sendTEST);
thread.start();
}
break;
}
}
public class SendenTask extends Task<Void> {
private String adr;
private String body;
private String subj;
private String fp;
private String fn;
private int count;
private int max;
public SendenTask(String adr, String body, String subj, String fp, String fn, int count, int max) {
this.adr = adr;
this.body = body;
this.subj = subj;
this.fp = fp;
this.fn = fn;
this.count = count;
this.max = max;
}
@Override
protected Void call() throws Exception {
while(!sending) {
sending = true
updateMessage("connecting");
//doing connectionAction
updateMessage("sending");
//doing sendingthingys
//sending complete
updateMessage("done");
}
return null;
}
@Override
protected void succeeded() {
super.succeeded();
lblStatus1.textProperty().unbind();
sending = false;
}
}
}
//edit3 最大的问题是,我该把 lblStatus1.textProperty().bind(sendTEST.messageProperty()); 以及在哪里 lblStatus1.textProperty().unbind(); ?
【问题讨论】:
-
通读stackoverflow.com/questions/30249493/… 看看是否有帮助。
-
我用演示更新了我的问题。希望它现在能让事情变得清晰。
标签: java multithreading user-interface javafx