Dziś połączymy dowiązania do klas obsługujących współbieżność w ramach JavaFX.
Lekcja 13
Dziś połączymy dowiązania do klas obsługujących współbieżność w ramach JavaFX.
Przygotuj widok w swojej aplikacji:
<?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="Postęp"
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>
Klasa Task pozwala nam na stworzenie takiego zadania, które będzie wykonane raz (nie można wznowić). Takie opakowanie sprawia, że JavaFX może synchronizować swoją pracę.
import javafx.concurrent.Task;
import javafx.fxml.FXML;
import javafx.scene.control.ProgressBar;
import javafx.scene.text.Text;
public class Controller {
// Słowo kluczowe final sprawia,
// że nie można zmienić wartości zmiennej.
public static final int VALUTE_TO_COMPLETE = 1000;
@FXML
private Text name;
@FXML
private ProgressBar progress;
@FXML
public void initialize() {
// Tworzymy zadanie
Task progressTask = new Task() {
@Override
protected Integer call() throws Exception {
int value = 0;
while (value < VALUTE_TO_COMPLETE) {
value++;
updateMessage("Osiągnięta wartość: " + value);
updateProgress(value, VALUTE_TO_COMPLETE);
Thread.sleep(100);
}
return value;
}
};
// Dowiązujemy wartości
progress.progressProperty().bind(progressTask.progressProperty());
name.textProperty().bind(progressTask.messageProperty());
// Uruchamiamy
Thread thread = new Thread(progressTask);
thread.setDaemon(true);
thread.start();
}
}
Uruchom kod, a następnie przenanalizuj.
Przygotuj widok w swojej aplikacji:
<Button
layoutX="712.0"
layoutY="25.0"
minHeight="77.0"
minWidth="238.0"
mnemonicParsing="false"
onAction="#stop"
prefHeight="77.0"
prefWidth="238.0"
text="Zatrzymaj" />
Klasa Task pozwala na sprawdzenie, czy nasze zadanie nie osiągnęło stanu "Zakończone" (Cancelled). W takim wypadku, musimy zakończyć dalsze obliczenia. Nie możemy jednak zapomnieć, że musimy skończyć, gdy tylko osiągnięmy wartość maksymalną.
// Sprawdzamy w pętli, czy nasze zadanie nie zostało
// z zewnątrz przerwane
Task<Integer> progressTask = new Task<Integer>() {
@Override
protected Integer call() throws Exception {
int value = 0;
while (!isCancelled()) {
value++;
updateMessage("Osiągnięta wartość: " + value);
updateProgress(value, VALUTE_TO_COMPLETE);
Thread.sleep(100);
if (value >= VALUTE_TO_COMPLETE) return value;
}
return value;
}
};
// Dodajemy metodę, która po zatrzyma nam task.
@FXML
public void stop() {
progressTask.cancel();
}
Przeanalizuj przedstawiony kod. Skopiuj 3 fragmenty kodu tak, aby dało radę wymusić zakończenie zadania. Pamiętaj o widoczności zmiennych.
Napisz aplikację "Boom", która składa się z:
Jeśli użytkownik rozwiąże problem, to odliczanie zatrzymuje się.
Przykład: aplikacja losuje liczbę z dowolnego zakresu. Użytkownik ma za zadanie ją zgadnąć. Jeśli użytkownik spróbuje podać wartość i mu się nie uda, to aplikacja pokaże mu komunikat "za mało" albo "za dużo".