Issue
What is the best way to keep few text fields constantly updating in background thread? I'm logging some variables from quadrotor fly which I'm keeping in DronCoordinator class. Every time they change(100ms) I want to update their values in GUI text fields. I've tried with updateMessage() method from Task class, but in that way I can only keep updating 1 textfield. I need to add 3 or 4 more variables to keep updating. It works good but only with 1 variable to update.
public class ApplicationControler implements Initializable {
@FXML
private Canvas artHorizon;
@FXML
public TextField pitchValue;
@FXML
private TextField rollValue;
@FXML
private TextField yawValue;
@FXML
private TextField thrustValue;
@FXML
private Button start;
private Service<Void> backgroundThread;
@Override
public void initialize(URL location, ResourceBundle resources) {
}
@FXML
private void applicationStart(ActionEvent event) {
backgroundThread = new Service<Void>() {
@Override
protected Task<Void> createTask() {
return new Task<Void>() {
@Override
protected Void call() throws Exception {
//This is the place where class which uptades variables starts
updateMessage(DronCoordinator.pitch);
return null;
}
};
}
};
backgroundThread.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
@Override
public void handle(WorkerStateEvent event) {
pitchValue.textProperty().unbind();
}
});
pitchValue.textProperty().bind(backgroundThread.messageProperty());
backgroundThread.restart();
}
}
Solution
Create a model object that you can pass from your task to the updateMessage. The idea behind this is to collect the various values in one object and then update the GUI with all values instead of update each value separately. The model can look similar to this:
public class DroneModel {
private double pitch;
private double roll;
private double yaw;
private double thrust;
public double getPitch() {
return pitch;
}
public void setPitch(double pitch) {
this.pitch = pitch;
}
public double getRoll() {
return roll;
}
public void setRoll(double roll) {
this.roll = roll;
}
public double getYaw() {
return yaw;
}
public void setYaw(double yaw) {
this.yaw = yaw;
}
public double getThrust() {
return thrust;
}
public void setThrust(double thrust) {
this.thrust = thrust;
}
}
Then your update method looks like this:
public void updateMessage(DroneModel model) {
pitchValue.setText(String.valueOf(model.getPitch()));
rollValue.setText(String.valueOf(model.getRoll()));
yawValue.setText(String.valueOf(model.getYaw()));
thrustValue.setText(String.valueOf(model.getThrust()));
}
The essential part is how you call this update method, you have to use runLater, as mentioned by @RahulSingh:
Platform.runLater(() -> updateMessage(droneModel));
Answered By - hotzst
Answer Checked By - Senaida (JavaFixing Volunteer)