diff --git a/core/src/main/java/ch/gtache/fro/practice/impl/PracticeRunnerImpl.java b/core/src/main/java/ch/gtache/fro/practice/impl/PracticeRunnerImpl.java index 94a9811..952be5e 100644 --- a/core/src/main/java/ch/gtache/fro/practice/impl/PracticeRunnerImpl.java +++ b/core/src/main/java/ch/gtache/fro/practice/impl/PracticeRunnerImpl.java @@ -41,7 +41,7 @@ public class PracticeRunnerImpl implements PracticeRunner { if (run.currentQuestionIndex() < run.parameters().questionsNumber()) { final var question = questionGenerator.generate(run.parameters()); final var currentQuestion = run.currentQuestion(); - if (currentQuestion.bird() == answer) { + if (currentQuestion.bird().equals(answer)) { final var newCorrectQuestions = new ArrayList<>(run.correctQuestions()); newCorrectQuestions.add(currentQuestion); return new PracticeRunImpl(run.parameters(), run.currentQuestionIndex() + 1, question, newCorrectQuestions, run.failedQuestions()); diff --git a/gui/api/src/main/java/ch/gtache/fro/practice/gui/PracticeResultModel.java b/gui/api/src/main/java/ch/gtache/fro/practice/gui/PracticeResultModel.java index 1c56f6b..2cf586e 100644 --- a/gui/api/src/main/java/ch/gtache/fro/practice/gui/PracticeResultModel.java +++ b/gui/api/src/main/java/ch/gtache/fro/practice/gui/PracticeResultModel.java @@ -1,8 +1,11 @@ package ch.gtache.fro.practice.gui; import ch.gtache.fro.gui.Model; +import ch.gtache.fro.practice.PracticeQuestion; import ch.gtache.fro.practice.PracticeResult; +import java.util.List; + /** * Model for the practice result view */ @@ -37,16 +40,16 @@ public interface PracticeResultModel extends Model { String failureLabel(); /** - * The text for the label of successful guesses + * The list of successful questions * - * @return The text + * @return The list of questions */ - String successListLabel(); + List successList(); /** - * The text for the label of failed guesses + * The list of failed questions * - * @return The text + * @return The list of questions */ - String failureListLabel(); + List failureList(); } diff --git a/gui/fx/src/main/java/ch/gtache/fro/practice/gui/fx/FXPracticeResultController.java b/gui/fx/src/main/java/ch/gtache/fro/practice/gui/fx/FXPracticeResultController.java index 7bb2f66..4ba8699 100644 --- a/gui/fx/src/main/java/ch/gtache/fro/practice/gui/fx/FXPracticeResultController.java +++ b/gui/fx/src/main/java/ch/gtache/fro/practice/gui/fx/FXPracticeResultController.java @@ -1,13 +1,18 @@ package ch.gtache.fro.practice.gui.fx; +import ch.gtache.fro.BirdTranslator; +import ch.gtache.fro.practice.PracticeQuestion; import ch.gtache.fro.practice.gui.PracticeResultController; import jakarta.inject.Inject; import jakarta.inject.Singleton; import javafx.fxml.FXML; import javafx.scene.control.Button; import javafx.scene.control.Label; +import javafx.scene.control.ListCell; +import javafx.scene.control.ListView; +import javafx.util.Callback; -import java.util.Objects; +import static java.util.Objects.requireNonNull; /** * FX implementation of {@link PracticeResultController} @@ -16,28 +21,33 @@ import java.util.Objects; public final class FXPracticeResultController implements PracticeResultController { private final FXPracticeResultModel model; + private final BirdTranslator translator; @FXML private Label successNumberLabel; @FXML private Label failureNumberLabel; @FXML - private Label successListLabel; + private ListView successList; @FXML - private Label failureListLabel; + private ListView failureList; @FXML private Button confirmButton; @Inject - FXPracticeResultController(final FXPracticeResultModel model) { - this.model = Objects.requireNonNull(model); + FXPracticeResultController(final FXPracticeResultModel model, + final BirdTranslator translator) { + this.model = requireNonNull(model); + this.translator = requireNonNull(translator); } @FXML private void initialize() { successNumberLabel.textProperty().bind(model.successLabelProperty()); failureNumberLabel.textProperty().bind(model.failureLabelProperty()); - successListLabel.textProperty().bind(model.successListLabelProperty()); - failureListLabel.textProperty().bind(model.failureListLabelProperty()); + successList.setItems(model.successList()); + failureList.setItems(model.failureList()); + successList.setCellFactory(new QuestionListCellFactory()); + failureList.setCellFactory(new QuestionListCellFactory()); } @FXML @@ -54,4 +64,23 @@ public final class FXPracticeResultController implements PracticeResultControlle public FXPracticeResultModel model() { return model; } + + private class QuestionListCellFactory implements Callback, ListCell> { + @Override + public ListCell call(final ListView param) { + return new PracticeQuestionListCell(); + } + + private class PracticeQuestionListCell extends ListCell { + @Override + protected void updateItem(final PracticeQuestion item, final boolean empty) { + super.updateItem(item, empty); + if (empty || item == null) { + setText(null); + } else { + setText(translator.translateAsync(item.bird()).join()); + } + } + } + } } diff --git a/gui/fx/src/main/java/ch/gtache/fro/practice/gui/fx/FXPracticeResultModel.java b/gui/fx/src/main/java/ch/gtache/fro/practice/gui/fx/FXPracticeResultModel.java index e19527b..0b9dd72 100644 --- a/gui/fx/src/main/java/ch/gtache/fro/practice/gui/fx/FXPracticeResultModel.java +++ b/gui/fx/src/main/java/ch/gtache/fro/practice/gui/fx/FXPracticeResultModel.java @@ -1,6 +1,6 @@ package ch.gtache.fro.practice.gui.fx; -import ch.gtache.fro.BirdTranslator; +import ch.gtache.fro.practice.PracticeQuestion; import ch.gtache.fro.practice.PracticeResult; import ch.gtache.fro.practice.gui.PracticeResultModel; import jakarta.inject.Inject; @@ -9,8 +9,8 @@ import javafx.beans.property.ObjectProperty; import javafx.beans.property.ReadOnlyStringProperty; import javafx.beans.property.ReadOnlyStringWrapper; import javafx.beans.property.SimpleObjectProperty; - -import java.util.stream.Collectors; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; /** * FX implementation of {@link PracticeResultModel} @@ -21,20 +21,27 @@ public final class FXPracticeResultModel implements PracticeResultModel { private final ObjectProperty practiceResult; private final ReadOnlyStringWrapper successLabel; private final ReadOnlyStringWrapper failureLabel; - private final ReadOnlyStringWrapper successListLabel; - private final ReadOnlyStringWrapper failureListLabel; + private final ObservableList successList; + private final ObservableList failureList; @Inject - FXPracticeResultModel(final BirdTranslator translator) { + FXPracticeResultModel() { this.practiceResult = new SimpleObjectProperty<>(); this.successLabel = new ReadOnlyStringWrapper(); this.failureLabel = new ReadOnlyStringWrapper(); - this.successListLabel = new ReadOnlyStringWrapper(); - this.failureListLabel = new ReadOnlyStringWrapper(); + this.successList = FXCollections.observableArrayList(); + this.failureList = FXCollections.observableArrayList(); successLabel.bind(resultProperty().map(r -> r.correctQuestionsCount() + "/" + r.totalQuestions())); failureLabel.bind(resultProperty().map(r -> r.failedQuestionsCount() + "/" + r.totalQuestions())); - successListLabel.bind(resultProperty().map(r -> r.correctQuestions().stream().map(pq -> translator.translateAsync(pq.bird()).join()).collect(Collectors.joining(", ")))); - failureListLabel.bind(resultProperty().map(r -> r.failedQuestions().stream().map(pq -> translator.translateAsync(pq.bird()).join()).collect(Collectors.joining(", ")))); + practiceResult.addListener((_, _, newValue) -> { + if (newValue == null) { + successList.clear(); + failureList.clear(); + } else { + successList.setAll(newValue.correctQuestions()); + failureList.setAll(newValue.failedQuestions()); + } + }); } @Override @@ -70,20 +77,12 @@ public final class FXPracticeResultModel implements PracticeResultModel { } @Override - public String successListLabel() { - return successListLabel.get(); - } - - ReadOnlyStringProperty successListLabelProperty() { - return successListLabel.getReadOnlyProperty(); + public ObservableList successList() { + return successList; } @Override - public String failureListLabel() { - return failureListLabel.get(); - } - - ReadOnlyStringProperty failureListLabelProperty() { - return failureListLabel.getReadOnlyProperty(); + public ObservableList failureList() { + return failureList; } } diff --git a/gui/fx/src/main/resources/ch/gtache/fro/practice/gui/fx/practiceResultView.fxml b/gui/fx/src/main/resources/ch/gtache/fro/practice/gui/fx/practiceResultView.fxml index 7b396f1..1b668f7 100644 --- a/gui/fx/src/main/resources/ch/gtache/fro/practice/gui/fx/practiceResultView.fxml +++ b/gui/fx/src/main/resources/ch/gtache/fro/practice/gui/fx/practiceResultView.fxml @@ -3,6 +3,7 @@ + @@ -23,8 +24,8 @@