Binding values is a mechanic which allows to implement dependencies in views quickly. Today we will connect it with a usage of classes handling concurrent programming in JavaFX.
Lesson 13
Binding values is a mechanic which allows to implement dependencies in views quickly. Today we will connect it with a usage of classes handling concurrent programming in JavaFX.
We want to show a text in a Label which jest inserted in a TextField. We are not going to use any events nor buttons.
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane
prefHeight="160.0"
prefWidth="644.0"
xmlns="http://javafx.com/javafx/8.0.121"
xmlns:fx="http://javafx.com/fxml/1"
fx:controller="sample.Controller">
<TextField
fx:id="textField"
layoutX="14.0"
layoutY="14.0" />
<Label
fx:id="label"
layoutX="195.0"
layoutY="19.0" />
</AnchorPane>
import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
public class Controller {
@FXML
private TextField textField;
@FXML
private Label label;
public void initialize() {
label.textProperty().bind(textField.textProperty());
}
}
Execute a code, look at a usage of bind. What is binded with what? Can we swap the instruction?
Write an application which uses binding. It will allow to change the location of starting and ending point of a line only by using sliders.
Prepare a view in your application:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ProgressBar?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.text.Text?>
<AnchorPane
xmlns:fx="http://javafx.com/fxml/1"
prefHeight="196.0"
prefWidth="969.0"
xmlns="http://javafx.com/javafx/8.0.121"
fx:controller="Controller">
<Text
fx:id="name"
layoutX="27.0"
layoutY="43.0"
strokeType="OUTSIDE"
strokeWidth="0.0"
text="Progress"
wrappingWidth="210" />
<ProgressBar
fx:id="progress"
layoutX="25.0"
layoutY="126.0"
prefHeight="20.0"
prefWidth="958.0"
progress="0.0"
AnchorPane.leftAnchor="25.0"
AnchorPane.rightAnchor="25.0" />
</AnchorPane>
Task class allows to create a task which is executed once (it can be restarted). It allows JavaFX to synchronize its work.
import javafx.concurrent.Task;
import javafx.fxml.FXML;
import javafx.scene.control.ProgressBar;
import javafx.scene.text.Text;
public class Controller {
// A keyword final means that,
// variable's value cannot be changed
public static final int VALUTE_TO_COMPLETE = 1000;
@FXML
private Text name;
@FXML
private ProgressBar progress;
@FXML
public void initialize() {
// Create a task
Task progressTask = new Task() {
@Override
protected Integer call() throws Exception {
int value = 0;
while (value < VALUTE_TO_COMPLETE) {
value++;
updateMessage("Reached value: " + value);
updateProgress(value, VALUTE_TO_COMPLETE);
Thread.sleep(100);
}
return value;
}
};
// Bind values
progress.progressProperty().bind(progressTask.progressProperty());
name.textProperty().bind(progressTask.messageProperty());
// Start
Thread thread = new Thread(progressTask);
thread.setDaemon(true);
thread.start();
}
}
Execute a code, next analyze it.
Prepare a view in your application:
<Button
layoutX="712.0"
layoutY="25.0"
minHeight="77.0"
minWidth="238.0"
mnemonicParsing="false"
onAction="#stop"
prefHeight="77.0"
prefWidth="238.0"
text="Stop" />
Task class allows to check if our task riched "Cancelled" state. In that case we have to stop further calculations. Do not forget we also have to stop them if we reach the maximum value.
// We check in a loop it a task is not cancelled
// from the outside
Task<Integer> progressTask = new Task<Integer>() {
@Override
protected Integer call() throws Exception {
int value = 0;
while (!isCancelled()) {
value++;
updateMessage("Reached value: " + value);
updateProgress(value, VALUTE_TO_COMPLETE);
Thread.sleep(100);
if (value >= VALUTE_TO_COMPLETE) return value;
}
return value;
}
};
// Method connected with a button.
@FXML
public void stop() {
progressTask.cancel();
}
Analyze presented code. Copy 3 fragments of code, so you can force cancelling the task. Remember about variables visibility.
Write "Boom" application which contains:
If user solves a puzzle, timer stops (so does the progress bar).