for days now i am trying to update a Javafx userinterface while sending 2 or more E-Mails automatically. The UI should update a Label with "connecting", "sending" and "sent". I've read about Runnables, Tasks, TimeLine but i dont really understand which method i should use and how it works.
Everywhere i read about Platform.runLater(), I used it but the animation in my JavaFX Gui freezes and the Label only changes, when all E-Mails have been sent.
I will update this post with my code soon, but can someone already tell me what kind of Thread i should use and how the ui can be updated easily?
//edit
thanks for your help, Branislav but now im getting the "Not on FX application thread"-Error. The following code is not my "extends Application"-class, please take a look.
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;
}
}
}
//edit2
Now the programm is sending Emails one after another but the textproperty is not working correctly. It is not refreshing the text, it only emptys the label. If i remove the unbind-line (in succeed) it only works one time i run the send task. After that it is empty again for all other send tasks.
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 The big question is, where do i put the lblStatus1.textProperty().bind(sendTEST.messageProperty()); and where the lblStatus1.textProperty().unbind(); ?