This commit is contained in:
kab74 2020-04-29 16:52:42 +01:00
commit 05d2f829f8
24 changed files with 864 additions and 607 deletions

View file

@ -1,6 +1,10 @@
![Logo](https://cdn.discordapp.com/icons/671688550311526413/67359a4a386c62bb66eaf4641ab8de5c.png?size=128)
<div align="center">
![Logo](https://cdn.discordapp.com/icons/671688550311526413/67359a4a386c62bb66eaf4641ab8de5c.png?size=128)
# Welsh Vocabulary Tutor
</div>
> This is the group repository for Group 20 doing the CS22120 Group Project 2020.

View file

@ -4,12 +4,17 @@ module uk.ac.aber.cs22120.group20 {
requires com.fasterxml.jackson.core;
requires com.fasterxml.jackson.databind;
requires junit;
requires org.junit.jupiter.api;
opens uk.ac.aber.cs22120.group20.javafx to javafx.fxml;
opens uk.ac.aber.cs22120.group20 to javafx.fxml;
opens uk.ac.aber.cs22120.group20.json to com.fasterxml.jackson.databind;
opens uk.ac.aber.cs22120.group20.selfassessment to javafx.fxml;
exports uk.ac.aber.cs22120.group20.json to com.fasterxml.jackson.databind;
exports uk.ac.aber.cs22120.group20.javafx to javafx.graphics, javafx.fxml;
// exports uk.ac.aber.cs22120.group20.test to junit;
}

View file

@ -17,68 +17,81 @@ import uk.ac.aber.cs22120.group20.json.DictionaryEntry;
public class AddWordController {
@FXML
private TextField welsh;
@FXML
private TextField english;
@FXML
private ComboBox<String> wordType;
@FXML
private TextField welsh;
@FXML
private TextField english;
@FXML
private ComboBox<String> wordType;
public TextField getWelsh() {
return welsh;
}
public TextField getWelsh() {
return welsh;
}
public TextField getEnglish() {
return english;
}
public TextField getEnglish() {
return english;
}
@FXML
private void initialize() {
@FXML
private void initialize() {
wordType.getItems().addAll("Masculine noun", "Feminine noun", "Verb", "Other");
wordType.setValue("Type");
wordType.getItems().addAll("Masculine noun", "Feminine noun", "Verb", "Other");
wordType.setValue("Type");
}
}
@FXML
protected void addButtonClick(ActionEvent actionEvent) {
boolean entryFound = false;
// one or more blank fields
if (english.getText() == null || welsh.getText() == null || wordType.getValue().equals("Type")) {
Alert error = new Alert(Alert.AlertType.ERROR);
error.setTitle("Error");
error.setHeaderText("Entry Not Saved");
error.setContentText("One or more fields are blank");
@FXML
protected void addButtonClick(ActionEvent actionEvent) {
String trueWordType;
if (wordType.getValue() == "Masculine noun") {
trueWordType = "nm";
} else if (wordType.getValue() == "Feminine noun") {
trueWordType = "nf";
} else if (wordType.getValue() == "Verb") {
trueWordType = "verb";
} else {
trueWordType = "other";
}
boolean entryFound = false;
// one or more blank fields
if (english.getText() == null || welsh.getText() == null || wordType.getValue().equals("Type")) {
Alert error = new Alert(Alert.AlertType.ERROR);
error.setTitle("Error");
error.setHeaderText("Entry Not Saved");
error.setContentText("One or more fields are blank");
error.showAndWait();
} else {
for (DictionaryEntry entry : Application.dictionary) {
entryFound = false;
DictionaryEntry newEntry = new DictionaryEntry(english.getText(), welsh.getText(), wordType.getValue());
if (entry.equals(newEntry)) {
Alert alert = new Alert(Alert.AlertType.ERROR);
alert.setTitle("Error");
alert.setHeaderText("Entry Not Saved");
alert.setContentText("This entry already exists");
error.showAndWait();
} else {
for (DictionaryEntry entry : Application.dictionary) {
entryFound = false;
DictionaryEntry newEntry = new DictionaryEntry(english.getText(), welsh.getText(), trueWordType);
if (entry.equals(newEntry)) {
Alert alert = new Alert(Alert.AlertType.ERROR);
alert.setTitle("Error");
alert.setHeaderText("Entry Not Saved");
alert.setContentText("This entry already exists");
alert.showAndWait();
entryFound = true;
break;
} else {
continue;
}
alert.showAndWait();
entryFound = true;
break;
} else {
continue;
}
if (!entryFound) {
Alert alert = new Alert(Alert.AlertType.INFORMATION);
alert.setTitle("Success");
alert.setHeaderText("Entry Saved");
alert.setContentText("Entry Added - English: " + english.getText() + " Welsh: " + welsh.getText() + " Type: " + wordType.getValue());
}
if (!entryFound) {
Alert alert = new Alert(Alert.AlertType.INFORMATION);
alert.setTitle("Success");
alert.setHeaderText("Entry Saved");
alert.setContentText("Entry Added - English: " + english.getText() + " Welsh: " + welsh.getText() + " Type: " + wordType.getValue());
alert.showAndWait();
DictionaryEntry dictionaryEntry = new DictionaryEntry(english.getText(), welsh.getText(), wordType.getValue());
Application.dictionary.contains(dictionaryEntry);
Application.dictionary.add(dictionaryEntry);
alert.showAndWait();
DictionaryEntry dictionaryEntry = new DictionaryEntry(english.getText(), welsh.getText(), trueWordType);
dictionaryEntry.setPracticeWord(true);
Application.dictionary.contains(dictionaryEntry);
Application.dictionary.add(dictionaryEntry);
// output of what was saved for testing
// System.out.print(english.getText());
@ -86,16 +99,17 @@ public class AddWordController {
// System.out.println(wordType.getValue());
// Resets values to blank for next word to be entered
english.clear();
welsh.clear();
wordType.setValue("Type");
english.clear();
welsh.clear();
wordType.setValue("Type");
trueWordType = null;
}
}
}
}
}
}
// @Override
// public boolean equals(Object obj) {
@ -104,42 +118,42 @@ public class AddWordController {
// }
@FXML
private void switchToPrimary() throws IOException {
Application.setRoot("Primary");
}
@FXML
private void switchToPrimary() throws IOException {
Application.setRoot("Primary");
}
// add character methods for characters ch, dd, ff, ng, ll, ph, rh, th
public void addCharch(ActionEvent actionEvent) {
welsh.appendText("ch");
}
// add character methods for characters ch, dd, ff, ng, ll, ph, rh, th
public void addCharch(ActionEvent actionEvent) {
welsh.appendText("ch");
}
public void addChardd(ActionEvent actionEvent) {
welsh.appendText("dd");
}
public void addChardd(ActionEvent actionEvent) {
welsh.appendText("dd");
}
public void addCharff(ActionEvent actionEvent) {
welsh.appendText("ff");
}
public void addCharff(ActionEvent actionEvent) {
welsh.appendText("ff");
}
public void addCharng(ActionEvent actionEvent) {
welsh.appendText("ng");
}
public void addCharng(ActionEvent actionEvent) {
welsh.appendText("ng");
}
public void addCharll(ActionEvent actionEvent) {
welsh.appendText("ll");
}
public void addCharll(ActionEvent actionEvent) {
welsh.appendText("ll");
}
public void addCharph(ActionEvent actionEvent) {
welsh.appendText("ph");
}
public void addCharph(ActionEvent actionEvent) {
welsh.appendText("ph");
}
public void addCharrh(ActionEvent actionEvent) {
welsh.appendText("rh");
}
public void addCharrh(ActionEvent actionEvent) {
welsh.appendText("rh");
}
public void addCharth(ActionEvent actionEvent) {
welsh.appendText("th");
}
public void addCharth(ActionEvent actionEvent) {
welsh.appendText("th");
}
}

View file

@ -93,7 +93,7 @@ public class Application extends javafx.application.Application {
* @see ScreenSwitch.SceneEnum
*/
static void setRoot(String fxml) throws IOException {
ScreenSwitch.setLegacyScene(fxml);
ScreenSwitch.swap(ScreenSwitch.SceneEnum.dictionaryScene);
}
// /**

View file

@ -44,183 +44,189 @@ import java.util.ResourceBundle;
* @see DictionaryEntry
* @see Application
*/
public class DictionaryController implements Initializable {
public static Stage primaryStage = null;
//public class DictionaryController implements Initializable {
public class DictionaryController {
public static Stage primaryStage = null;
@FXML
private ImageView alphaSort;
@FXML
private TextField searchBox;
@FXML
private TableView<DictionaryEntry> table;
@FXML
private TableColumn<DictionaryEntry, String> english = new TableColumn<>();
@FXML
private TableColumn<DictionaryEntry, String> welsh = new TableColumn<>();
@FXML
private ImageView alphaSort;
@FXML
private TextField searchBox;
@FXML
private TableView<DictionaryEntry> table;
@FXML
private TableColumn<DictionaryEntry, String> english = new TableColumn<>();
@FXML
private TableColumn<DictionaryEntry, String> welsh = new TableColumn<>();
public ObservableList<DictionaryEntry> list = FXCollections.observableArrayList();
public ObservableList<DictionaryEntry> list = FXCollections.observableArrayList();
@FXML
private void switchLangSort() {
if (table.getSortOrder().contains(english)) {
if (welsh.getSortType().equals(TableColumn.SortType.ASCENDING)) {
alphaSort.setImage(new Image("file:src/main/resources/assets/icons/black_icons/50px/sort-alpha-up-50.png"));
}
else if (welsh.getSortType().equals(TableColumn.SortType.DESCENDING)) {
alphaSort.setImage(new Image("file:src/main/resources/assets/icons/black_icons/50px/sort-alpha-up-reversed-50.png"));
}
table.getSortOrder().clear();
table.getSortOrder().add(welsh);
}
else if (table.getSortOrder().contains(welsh)) {
if (english.getSortType().equals(TableColumn.SortType.ASCENDING)) {
alphaSort.setImage(new Image("file:src/main/resources/assets/icons/black_icons/50px/sort-alpha-up-50.png"));
}
else if (english.getSortType().equals(TableColumn.SortType.DESCENDING)) {
alphaSort.setImage(new Image("file:src/main/resources/assets/icons/black_icons/50px/sort-alpha-up-reversed-50.png"));
}
table.getSortOrder().clear();
table.getSortOrder().add(english);
}
table.sort();
}
/**
*
*/
@FXML
private void switchLangSort() {
if (table.getSortOrder().contains(english)) {
if (welsh.getSortType().equals(TableColumn.SortType.ASCENDING)) {
alphaSort.setImage(new Image("file:src/main/resources/assets/icons/black_icons/50px/sort-alpha-up-50.png"));
}
else if (welsh.getSortType().equals(TableColumn.SortType.DESCENDING)) {
alphaSort.setImage(new Image("file:src/main/resources/assets/icons/black_icons/50px/sort-alpha-up-reversed-50.png"));
}
table.getSortOrder().clear();
table.getSortOrder().add(welsh);
}
else if (table.getSortOrder().contains(welsh)) {
if (english.getSortType().equals(TableColumn.SortType.ASCENDING)) {
alphaSort.setImage(new Image("file:src/main/resources/assets/icons/black_icons/50px/sort-alpha-up-50.png"));
}
else if (english.getSortType().equals(TableColumn.SortType.DESCENDING)) {
alphaSort.setImage(new Image("file:src/main/resources/assets/icons/black_icons/50px/sort-alpha-up-reversed-50.png"));
}
table.getSortOrder().clear();
table.getSortOrder().add(english);
}
table.sort();
}
@FXML
private void switchAlphaSort() {
if (table.getSortOrder().contains(english)) {
if (english.getSortType().equals(TableColumn.SortType.ASCENDING)) {
english.setSortType(TableColumn.SortType.DESCENDING);
alphaSort.setImage(new Image("file:src/main/resources/assets/icons/black_icons/50px/sort-alpha-up-reversed-50.png"));
} else {
english.setSortType(TableColumn.SortType.ASCENDING);
alphaSort.setImage(new Image("file:src/main/resources/assets/icons/black_icons/50px/sort-alpha-up-50.png"));
}
} else if (table.getSortOrder().contains(welsh)) {
if (welsh.getSortType().equals(TableColumn.SortType.ASCENDING)) {
welsh.setSortType(TableColumn.SortType.DESCENDING);
alphaSort.setImage(new Image("file:src/main/resources/assets/icons/black_icons/50px/sort-alpha-up-reversed-50.png"));
} else {
welsh.setSortType(TableColumn.SortType.ASCENDING);
alphaSort.setImage(new Image("file:src/main/resources/assets/icons/black_icons/50px/sort-alpha-up-50.png"));
}
}
}
/**
*
*/
@FXML
private void switchAlphaSort() {
if (table.getSortOrder().contains(english)) {
if (english.getSortType().equals(TableColumn.SortType.ASCENDING)) {
english.setSortType(TableColumn.SortType.DESCENDING);
alphaSort.setImage(new Image("file:src/main/resources/assets/icons/black_icons/50px/sort-alpha-up-reversed-50.png"));
} else {
english.setSortType(TableColumn.SortType.ASCENDING);
alphaSort.setImage(new Image("file:src/main/resources/assets/icons/black_icons/50px/sort-alpha-up-50.png"));
}
} else if (table.getSortOrder().contains(welsh)) {
if (welsh.getSortType().equals(TableColumn.SortType.ASCENDING)) {
welsh.setSortType(TableColumn.SortType.DESCENDING);
alphaSort.setImage(new Image("file:src/main/resources/assets/icons/black_icons/50px/sort-alpha-up-reversed-50.png"));
} else {
welsh.setSortType(TableColumn.SortType.ASCENDING);
alphaSort.setImage(new Image("file:src/main/resources/assets/icons/black_icons/50px/sort-alpha-up-50.png"));
}
}
}
/**
* Switches to the primary scene.
*
* @throws IOException
*/
@FXML
private void switchToPracticeList() throws IOException {
Application.setRoot("practicelist");
}
/**
* Switches to the primary scene.
*
* @throws IOException
*/
@FXML
private void switchToPracticeList() throws IOException {
ScreenSwitch.swap(ScreenSwitch.SceneEnum.practiceListScene);
}
/**
* Initializes the table of dictionary entries.
* <p>
* An observable list of DictionaryEntries is loaded from the Application class into a local instance of ObservableList.
* It also sets up Lambda expressions related to live searching functionality and the display of DictionaryEntries.
*
* @param url
* @param resourceBundle
* @see Application
* @see DictionaryEntry
*/
@Override
public void initialize(URL url, ResourceBundle resourceBundle) {
list.addAll(Application.dictionary);
/**
* Initializes the table of dictionary entries.
* <p>
* An observable list of DictionaryEntries is loaded from the Application class into a local instance of ObservableList.
* It also sets up Lambda expressions related to live searching functionality and the display of DictionaryEntries.
*
// * @param url
// * @param resourceBundle
* @see Application
* @see DictionaryEntry
*/
public void initialize() {
list.addAll(Application.dictionary);
table.setRowFactory(tv -> {
TableRow<DictionaryEntry> row = new TableRow<DictionaryEntry>() {
@Override
protected void updateItem(DictionaryEntry dictionaryEntry, boolean b) {
super.updateItem(dictionaryEntry, b);
if (!isEmpty()) {
if (dictionaryEntry.isPracticeWord()) {
setStyle("-fx-background-color: gray;");
} else {
setStyle(" ");
}
}
}
};
row.setOnMouseClicked(mouseEvent -> {
if (mouseEvent.getClickCount() == 1 && (!row.isEmpty())) {
if (row.getItem().isPracticeWord()) {
Application.dictionary.get(list.indexOf(row.getItem())).setPracticeWord(false);
ArrayList<DictionaryEntry> toRemove = new ArrayList<DictionaryEntry>();
for (DictionaryEntry entry : Application.practiseList) {
if (entry.equals(row.getItem())) {
toRemove.add(entry);
}
}
Application.practiseList.removeAll(toRemove);
table.setRowFactory(tv -> {
TableRow<DictionaryEntry> row = new TableRow<DictionaryEntry>() {
@Override
protected void updateItem(DictionaryEntry dictionaryEntry, boolean b) {
super.updateItem(dictionaryEntry, b);
if (!isEmpty()) {
if (dictionaryEntry.isPracticeWord()) {
setStyle("-fx-background-color: gray;");
} else {
setStyle(" ");
}
}
}
};
row.setOnMouseClicked(mouseEvent -> {
if (mouseEvent.getClickCount() == 1 && (!row.isEmpty())) {
if (row.getItem().isPracticeWord()) {
Application.dictionary.get(list.indexOf(row.getItem())).setPracticeWord(false);
ArrayList<DictionaryEntry> toRemove = new ArrayList<DictionaryEntry>();
for (DictionaryEntry entry : Application.practiseList) {
if (entry.equals(row.getItem())) {
toRemove.add(entry);
}
}
Application.practiseList.removeAll(toRemove);
// row.getItem().setPracticeWord(false);
} else if (!row.getItem().isPracticeWord()) {
Application.dictionary.get(list.indexOf(row.getItem())).setPracticeWord(true);
Application.practiseList.add(row.getItem());
} else if (!row.getItem().isPracticeWord()) {
Application.dictionary.get(list.indexOf(row.getItem())).setPracticeWord(true);
Application.practiseList.add(row.getItem());
// row.getItem().setPracticeWord(true);
}
table.getSelectionModel().clearSelection();
}
});
return row;
}
);
welsh.setCellValueFactory(dictionaryEntryStringCellDataFeatures -> {
if (dictionaryEntryStringCellDataFeatures.getValue().getWordType().equals("nm")) {
return new SimpleStringProperty(dictionaryEntryStringCellDataFeatures.getValue().getWelsh() + " {nm}");
} else if (dictionaryEntryStringCellDataFeatures.getValue().getWordType().equals("nf")) {
return new SimpleStringProperty(dictionaryEntryStringCellDataFeatures.getValue().getWelsh() + " {nf}");
}
table.getSelectionModel().clearSelection();
}
});
return row;
}
);
welsh.setCellValueFactory(dictionaryEntryStringCellDataFeatures -> {
if (dictionaryEntryStringCellDataFeatures.getValue().getWordType().equals("nm")) {
return new SimpleStringProperty(dictionaryEntryStringCellDataFeatures.getValue().getWelsh() + " {nm}");
} else if (dictionaryEntryStringCellDataFeatures.getValue().getWordType().equals("nf")) {
return new SimpleStringProperty(dictionaryEntryStringCellDataFeatures.getValue().getWelsh() + " {nf}");
} else {
return new SimpleStringProperty(dictionaryEntryStringCellDataFeatures.getValue().getWelsh());
}
});
english.setCellValueFactory(dictionaryEntryStringCellDataFeatures -> {
if (dictionaryEntryStringCellDataFeatures.getValue().getWordType().equals("verb")) {
return new SimpleStringProperty("to " + dictionaryEntryStringCellDataFeatures.getValue().getEnglish());
} else {
return new SimpleStringProperty(dictionaryEntryStringCellDataFeatures.getValue().getEnglish());
}
});
FilteredList<DictionaryEntry> filteredList = new FilteredList<>(list, p -> true); // Wrap list in a FilteredList
searchBox.textProperty().addListener((observable, oldSearchTerm, newSearchTerm) -> {
filteredList.setPredicate(dictionaryEntry -> { // returns true on a filter match, false if no match
boolean result = false;
table.refresh(); // This fixes the table highlighting issue
if (newSearchTerm == null || newSearchTerm.isEmpty()) { // If filter text is empty, display all dictionary entries
result = true;
} else {
return new SimpleStringProperty(dictionaryEntryStringCellDataFeatures.getValue().getWelsh());
}
});
english.setCellValueFactory(dictionaryEntryStringCellDataFeatures -> {
if (dictionaryEntryStringCellDataFeatures.getValue().getWordType().equals("verb")) {
return new SimpleStringProperty("to " + dictionaryEntryStringCellDataFeatures.getValue().getEnglish());
} else {
return new SimpleStringProperty(dictionaryEntryStringCellDataFeatures.getValue().getEnglish());
}
});
FilteredList<DictionaryEntry> filteredList = new FilteredList<>(list, p -> true); // Wrap list in a FilteredList
searchBox.textProperty().addListener((observable, oldSearchTerm, newSearchTerm) -> {
filteredList.setPredicate(dictionaryEntry -> { // returns true on a filter match, false if no match
boolean result = false;
table.refresh(); // This fixes the table highlighting issue
if (newSearchTerm == null || newSearchTerm.isEmpty()) { // If filter text is empty, display all dictionary entries
result = true;
} else {
// need all same case for compare.
final String lowerCaseSearchFilter = newSearchTerm.toLowerCase();
if (dictionaryEntry.getWelsh().toLowerCase().contains(lowerCaseSearchFilter)) {
result = true; // Filter matches Welsh
} else if (dictionaryEntry.getEnglish().toLowerCase().contains(lowerCaseSearchFilter)) {
result = true; // Filter matches English
// need all same case for compare.
final String lowerCaseSearchFilter = newSearchTerm.toLowerCase();
if (dictionaryEntry.getWelsh().toLowerCase().contains(lowerCaseSearchFilter)) {
result = true; // Filter matches Welsh
} else if (dictionaryEntry.getEnglish().toLowerCase().contains(lowerCaseSearchFilter)) {
result = true; // Filter matches English
// } else if (dictionaryEntry.getWordType().toLowerCase().contains(lowerCaseSearchFilter)) {
// result = true; // Filter matches Word Type
} else if (dictionaryEntry.getWordType().equals("verb") && ("to " + dictionaryEntry.getEnglish()).toLowerCase().contains(lowerCaseSearchFilter)) {
result = true; // Filter matches ['to' + a word] or [a word] if word is a verb
}
}
return result;
});
});
} else if (dictionaryEntry.getWordType().equals("verb") && ("to " + dictionaryEntry.getEnglish()).toLowerCase().contains(lowerCaseSearchFilter)) {
result = true; // Filter matches ['to' + a word] or [a word] if word is a verb
}
}
return result;
});
});
SortedList<DictionaryEntry> sortedList = new SortedList<>(filteredList); //Wrap the filtered list in a SortedList
sortedList.comparatorProperty().bind(table.comparatorProperty()); //Bind the sorted list comparator to the table comparator
SortedList<DictionaryEntry> sortedList = new SortedList<>(filteredList); //Wrap the filtered list in a SortedList
sortedList.comparatorProperty().bind(table.comparatorProperty()); //Bind the sorted list comparator to the table comparator
// welsh.setCellValueFactory(new PropertyValueFactory<DictionaryEntry, String>("welsh"));
// english.setCellValueFactory(new PropertyValueFactory<DictionaryEntry, String>("english"));
table.setItems(sortedList);
table.getSortOrder().add(english);
}
table.setItems(sortedList);
table.getSortOrder().add(english);
}
}

View file

@ -9,11 +9,33 @@ import javafx.scene.shape.Rectangle;
import javafx.scene.text.Text;
import javafx.scene.transform.Rotate;
import javafx.util.Duration;
import uk.ac.aber.cs22120.group20.javafx.Application;
import uk.ac.aber.cs22120.group20.json.DictionaryEntry;
import uk.ac.aber.cs22120.group20.selfassessment.AssessmentGenerator;
import java.io.IOException;
/**
* A class that servers as the controller for the programs Flashcard JavaFX scene, handling all of its events and attributes. This scene is defined as "flashcard.fxml".
*
* @author Brad Corbett [brc9]
* @author Henry Dugmore [hjd3]
* @author Kain Bryan-Jones [kab74]
* @author Luke Wybar [law39]
* @author Marcin Jakob [maj83]
* @author Oscar Pocock [osp1]
* @author Tom Perry [top19]
* @author Waylen Watts [ncw]
* @version 0.1 Initial development.
* @see Application
* @see DictionaryEntry
* @see SharedCodeController
*/
public class FlashcardController {
// /////////////////// //
// Instance Variables. //
// /////////////////// //
int index = 0;
Node card;
@ -31,6 +53,14 @@ public class FlashcardController {
@FXML
private ImageView right_arrow;
// //////// //
// Methods. //
// //////// //
/**
* Method that initializes 'flashcard.fxml' by setting up the icons and text. This method is called automatically whenever the flashcard scene starts.
*
*/
@FXML
private void initialize() {
testWord.setText(Application.practiseList.getFirst().getWelsh());
@ -39,22 +69,28 @@ public class FlashcardController {
updateCounter();
card = flashcard;
Image left = new Image("file:src/main/resources/assets/icons/black_icons/50px/left-50.png");
Image right = new Image("file:src/main/resources/assets/icons/black_icons/50px/right-50.png");
left_arrow.setImage(left);
right_arrow.setImage(right);
left_arrow.setImage(new Image(getClass().getResourceAsStream("/assets/icons/black_icons/50px/left-50.png")));
right_arrow.setImage(new Image(getClass().getResourceAsStream("/assets/icons/black_icons/50px/right-50.png")));
}
/**
* Event that rotates the scenes flashcard using RotateTransition whenever the user clicks the flashcard.
* @see RotateTransition
*/
@FXML
private void handleFlashcardClick() {
RotateTransition rotator = RotateCard(card);
rotator.play();
rotator.play(); // Play the rotate transition.
}
/**
* Event that switches to the previous flashcard whenever the user clicks the 'leftArrow' icon.
* @see Application
* @see DictionaryEntry
*/
@FXML
private void handlePreviousCard() {
// If statement to check the start of the practiceList hasn't been reached before moving to the previous card.
if (index > 0) {
index--;
}
@ -63,8 +99,14 @@ public class FlashcardController {
wordType.setText("Welsh");
}
/**
* Event that switches to the next flashcard whenever the user clicks the 'right-arrow' icon.
* @see Application
* @see DictionaryEntry
*/
@FXML
private void handleNextCard() {
// If statement to check the end of the practiceList hasn't been reached before moving to the next card.
if (index < Application.practiseList.size()-1) {
index++;
}
@ -74,28 +116,42 @@ public class FlashcardController {
wordType.setText("Welsh");
}
/**
* Method that updates the onscreen counter of the current flashcard.
* @see Application
* @see DictionaryEntry
*/
private void updateCounter() {
counter.setText((index + 1) + "/" + Application.practiseList.size());
}
/**
* Method that creates a RotateTransition animation for flipping the flashcard 180 degrees.
* @param card FXML rectangle element that will be flipped.
* @return RotateTransition that will flip the rectangle 180 degrees.
* @see Application
* @see DictionaryEntry
* @see RotateTransition
*/
private RotateTransition RotateCard(Node card) {
RotateTransition rotate = new RotateTransition(Duration.millis(1000), card);
// Make the text on the card go invisible whilst the cardFlip is happening.
testWord.setVisible(false);
wordType.setVisible(false);
// Set the axis and angle of the rotation.
rotate.setAxis(Rotate.Y_AXIS);
rotate.setFromAngle(0);
rotate.setToAngle(180);
rotate.setInterpolator(Interpolator.LINEAR);
rotate.setCycleCount(1);
rotate.setOnFinished(event -> {
rotate.setOnFinished(event -> { // Once the transition is completed, update the text on the flashcard.
testWord.setText("Welsh word: \t" + Application.practiseList.get(index).getWelsh());
if (wordType.getText().equals("Welsh")) {
if (wordType.getText().equals("Welsh")) { // If the word currently on the flashcard is welsh, display the english translation.
testWord.setText(Application.practiseList.get(index).getEnglish());
wordType.setText("English");
} else {
} else { // Else display the welsh translation.
testWord.setText(Application.practiseList.get(index).getWelsh());
wordType.setText("Welsh");
}
@ -108,7 +164,7 @@ public class FlashcardController {
@FXML
private void switchToAddWord() throws IOException {
Application.setRoot("addword");
AssessmentGenerator.generateAssessment(Application.practiseList);
}
}

View file

@ -41,7 +41,7 @@ import java.util.ResourceBundle;
* @see DictionaryEntry
* @see Application
*/
public class PracticeListController implements Initializable {
public class PracticeListController {
public static Stage primaryStage = null;
@FXML
@ -63,13 +63,12 @@ public class PracticeListController implements Initializable {
* An observable list of DictionaryEntries is loaded from the Application class into a local instance of ObservableList.
* It also sets up Lambda expressions related to live searching functionality and the display of DictionaryEntries.
*
* @param url
* @param resourceBundle
// * @param url
// * @param resourceBundle
* @see Application
* @see DictionaryEntry
*/
@Override
public void initialize(URL url, ResourceBundle resourceBundle) {
public void initialize() {
// list.addAll(Application.dictionary);
list.addAll(Application.practiseList);
// for (DictionaryEntry entry : Application.dictionary) {
@ -228,7 +227,7 @@ public class PracticeListController implements Initializable {
*/
@FXML
private void switchToFlashCard() throws IOException {
Application.setRoot("flashcard");
ScreenSwitch.swap(ScreenSwitch.SceneEnum.flashcardScene);
}
}

View file

@ -88,8 +88,9 @@ public class ScreenSwitch extends SharedCodeController {
}catch (IOException e){ // If an error occurs, print out error message on STDIO and crash gracefully
System.err.print("Loading the FXML file ");
System.err.print(newScene.getFXML());
System.err.println("Failed!");
System.err.println(" Failed!");
System.err.println(e.toString());
e.printStackTrace(System.err);
System.exit(-1);
}
return root;
@ -113,6 +114,7 @@ public class ScreenSwitch extends SharedCodeController {
flashcardScene("flashcard.fxml"),
practiceListScene("practicelist.fxml"),
matchMeaningScene("matchthemeaning.fxml"),
sixMeaningScene("sixmeanings.fxml"),
translationScene("translation.fxml"),
;

View file

@ -1,5 +1,12 @@
package uk.ac.aber.cs22120.group20.javafx;
import javafx.fxml.FXML;
import javafx.scene.control.Alert;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Text;
/**
* Abstract class that contains all the shared FXML elements between the
* different controller classes including the sliding menu and the test score counter, to reduce code
@ -9,4 +16,122 @@ package uk.ac.aber.cs22120.group20.javafx;
* @See
*/
abstract public class SharedCodeController {
static int sideBarWidth = 50;
@FXML
Rectangle sideBar;
@FXML
Text dictionaryText;
@FXML
Text practiceListTest;
@FXML
Text flashcardsText;
@FXML
Text studyText;
@FXML
Text addDefinitionText;
@FXML
Text currentPageText;
@FXML
ImageView expandMenuIcon;
@FXML
ImageView dictionaryIcon;
@FXML
ImageView practiceListIcon;
@FXML
ImageView flashcardIcon;
@FXML
ImageView studyIcon;
@FXML
ImageView searchIcon;
@FXML
ImageView addDefinitionIcon;
@FXML
ImageView currentPageIcon;
public void setup() {
initializeIcons();
sideBar.setWidth(sideBarWidth);
if (sideBarWidth != 50)
initializeMenuText();
}
private void initializeIcons() {
expandMenuIcon.setImage(new Image("file:src/main/resources/assets/icons/white_icons/50px/menu-50.png"));
dictionaryIcon.setImage(new Image("file:src/main/resources/assets/icons/white_icons/50px/read-50.png"));
practiceListIcon.setImage(new Image("file:src/main/resources/assets/icons/white_icons/50px/rating-50.png"));
flashcardIcon.setImage(new Image("file:src/main/resources/assets/icons/white_icons/50px/flashcard-50.png"));
studyIcon.setImage(new Image("file:src/main/resources/assets/icons/white_icons/50px/pass-fail-50.png"));
addDefinitionIcon.setImage(new Image("file:src/main/resources/assets/icons/white_icons/50px/add-50.png"));
}
private void initializeMenuText() {
dictionaryText.setText("Dictionary");
practiceListTest.setText("Practice List");
flashcardsText.setText("Flashcards");
studyText.setText("Study");
addDefinitionText.setText("Add");
}
private void disableMenuText() {
dictionaryText.setText("");
practiceListTest.setText("");
flashcardsText.setText("");
studyText.setText("");
addDefinitionText.setText("");
}
@FXML
private void expandMenuClick() {
if(sideBar.getWidth() == 50) {
sideBar.setWidth(sideBarWidth = 230);
initializeMenuText();
} else {
sideBar.setWidth(sideBarWidth = 50);
disableMenuText();
}
}
@FXML
private void dictionaryIconClick() {
ScreenSwitch.swap(ScreenSwitch.SceneEnum.dictionaryScene);
}
@FXML
private void practiceListIconClick() {
ScreenSwitch.swap(ScreenSwitch.SceneEnum.practiceListScene);
}
@FXML
private void flashcardIconClick() {
if(Application.practiseList.size() == 0) {
Alert alert = new Alert(Alert.AlertType.ERROR);
alert.setTitle("Error");
alert.setHeaderText("Unable to use Flashcard");
alert.setContentText("The practice list is currently empty, please add some practice words to use the Flashcard feature.");
alert.showAndWait();
} else{
ScreenSwitch.swap(ScreenSwitch.SceneEnum.flashcardScene);
}
}
@FXML
private void studyIconClick() {
ScreenSwitch.swap(ScreenSwitch.SceneEnum.translationScene);
}
@FXML
private void addWordIconClick(){
ScreenSwitch.swap(ScreenSwitch.SceneEnum.addWordScene);
}
}

View file

@ -84,7 +84,9 @@ public class DictionaryEntry {
this.practiceWord = practiceWord;
}
public boolean equals(DictionaryEntry entry) {
return entry.getEnglish().equals(this.getEnglish()) && entry.getWelsh().equals(this.getWelsh()) && entry.getWordType().equals(this.getWordType());
@Override
public boolean equals(Object entry) {
DictionaryEntry otherEntry = (DictionaryEntry) entry;
return otherEntry.getEnglish().equals(this.getEnglish()) && otherEntry.getWelsh().equals(this.getWelsh()) && otherEntry.getWordType().equals(this.getWordType());
}
}

View file

@ -1,53 +1,69 @@
package uk.ac.aber.cs22120.group20.selfassessment;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonBar;
import javafx.scene.control.ButtonType;
import uk.ac.aber.cs22120.group20.javafx.Application;
import uk.ac.aber.cs22120.group20.javafx.ScreenSwitch;
import uk.ac.aber.cs22120.group20.json.DictionaryEntry;
import java.util.LinkedList;
import java.util.Random;
import java.util.*;
/**
* Class that contains methods to create a randomised list of questions that will
* contain a random distribution of question types.
*
* @Author
* @Version
* @See
*/
public class AssessmentGenerator {
static boolean isEnglish;
static boolean isEnglish;
static LinkedList<Question> listOfAssessment = new LinkedList<>();
static int currentAssessment = 0;
/**
* Method that will generate a randomized list of questions consisting of random distribution of questions
* types, using the dictionarys practice words as the parameter.
*
* @param practiseList
* @return
*/
public static LinkedList<Question> generateAssessment(LinkedList<DictionaryEntry> practiseList) {
LinkedList<Question> listOfAssessment = new LinkedList<>();
Random rand = new Random();
/**
* Method that will generate a randomized list of questions consisting of random distribution of questions
* types, using the dictionarys practice words as the parameter.
* @param wordList
* @return
*/
public LinkedList<Question> generateAssessment(LinkedList<DictionaryEntry> wordList){
LinkedList<Question> listOfAssessment = new LinkedList<>();
LinkedList<DictionaryEntry> practiseList = Application.practiseList;
Random rand = new Random();
//int wordToTranslatePlace;
if (practiseList.size()<10){
Alert alert = new Alert(Alert.AlertType.ERROR);
alert.setTitle("Error");
alert.setHeaderText("Not enough words in practice list");
alert.setResizable(false);
alert.setContentText("Please add more words to your practice list on the dictionary page before trying to test yourself!");
Optional<ButtonType> result = alert.showAndWait();
ScreenSwitch.swap(ScreenSwitch.SceneEnum.dictionaryScene);
}else {
for (int numberToGenerate = 0; numberToGenerate < 10; numberToGenerate++) {
Question generatedAssessment = null;
int quizType = rand.nextInt(3);
switch (quizType) {
case (0): //0 Means translation test.
//wordToTranslatePlace = rand.nextInt(Application.practiseList.size());
//wordToTranslate = Application.practiseList.get(wordToTranslatePlace);
int wordToTranslatePlace;
generatedAssessment = generateTranslationTest(practiseList);
break;
case (1): //1 Means six meanings test.
//wordToTranslatePlace = rand.nextInt(Application.practiseList.size());
//wordToTranslate = Application.practiseList.get(wordToTranslatePlace);
for (int numberToGenerate = 0; numberToGenerate < 10; numberToGenerate++) {
Question generatedAssessment = null;
int quizType = rand.nextInt(3);
switch (quizType) {
case (0): //0 Means translation test.
//wordToTranslatePlace = rand.nextInt(Application.practiseList.size());
//wordToTranslate = Application.practiseList.get(wordToTranslatePlace);
generatedAssessment = generateWordEnter(practiseList);
break;
case (1): //1 Means six meanings test.
//wordToTranslatePlace = rand.nextInt(Application.practiseList.size());
//wordToTranslate = Application.practiseList.get(wordToTranslatePlace);
generatedAssessment = generateSixMeanings(practiseList);
case (2): //2 Means match meanings test.
generatedAssessment = generateSixMeanings(practiseList);
break;
case (2): //2 Means match meanings test.
// LinkedList<DictionaryEntry> wordsToTranslate = new LinkedList<>();
// for (int i = 0; i < 3; i++) {
// wordToTranslatePlace = rand.nextInt(Application.practiseList.size());
@ -55,80 +71,131 @@ public class AssessmentGenerator {
// wordsToTranslate.toArray();
// }
generatedAssessment = generateWordMatch(practiseList);
}
listOfAssessment.add(generatedAssessment);
}
}
generatedAssessment = generateMatchMeaning(practiseList);
break;
}
listOfAssessment.add(generatedAssessment);
}
AssessmentGenerator.listOfAssessment = listOfAssessment;
goToNextQuestion();
}
return listOfAssessment;
}
/**
* Method
* that will generate a list of questions that are the type Match The Meanings, using the dictionary's
* practice words as the parameter.
* @return
*/
public Question generateWordMatch(LinkedList<DictionaryEntry> a){
return null;
/**
* Method
* that will generate a list of questions that are the type Match The Meanings, using the dictionary's
* practice words as the parameter.
*
* @return
*/
public static Question generateMatchMeaning(LinkedList<DictionaryEntry> practiceList) {
Random rand = new Random();
LinkedList<DictionaryEntry> answerList = new LinkedList<>();
}
int successfulAnswersSelected = 0;
while (successfulAnswersSelected < 4) {
DictionaryEntry selectedAnswer;
selectedAnswer = practiceList.get(rand.nextInt(practiceList.size()));
if (answerList.contains(selectedAnswer)) {
continue;
}
answerList.add(selectedAnswer);
successfulAnswersSelected++;
}
/**
* Method
* that will generate a list of questions that are the type 6 Meanings, using the dictionary's practice
* words as the parameter.
* @return
*/
public static Question generateSixMeanings(LinkedList<DictionaryEntry> practiseList){
Question generatedQuestion = new MatchTheMeaningQuestion(answerList.toArray(DictionaryEntry[]::new));
return generatedQuestion;
}
//CHANGE DICTIONARY TO PRACTISE LIST
/**
* Method
* that will generate a list of questions that are the type 6 Meanings, using the dictionary's practice
* words as the parameter.
*
* @return
*/
public static Question generateSixMeanings(LinkedList<DictionaryEntry> practiseList) {
Question returnValue;
ArrayList<DictionaryEntry> listOfAnswers = new ArrayList<>();
Random rand = new Random();
DictionaryEntry wordToTranslate = practiseList.get(rand.nextInt(practiseList.size()));
SixMeaningsQuestion generatedQuestion = new SixMeaningsQuestion(wordToTranslate, Application.dictionary);
return generatedQuestion;
}
Random rand = new Random();
/**
* Method that
* will generate a list of questions that are the type Translation, using the dictionary's practice words as
* the parameter.
*
* @return
*/
public static Question generateTranslationTest(LinkedList<DictionaryEntry> practiceList) {
Random rand = new Random();
DictionaryEntry selectedCorrectAnswer;
selectedCorrectAnswer = practiceList.get(rand.nextInt(practiceList.size()));
Question generatedQuestion = new TranslationQuestion(selectedCorrectAnswer);
return generatedQuestion;
}
boolean isDuplicate = false;
do{
int rand_q=rand.nextInt(Application.dictionary.size()-1);
DictionaryEntry pickedQuestion = Application.dictionary.get(rand_q);
//If size of list is greater than 1 check for duplicates...
if(MatchTheMeaningQuestion.setOfQuestions.size()>=1){
for (DictionaryEntry setOfQuestion : MatchTheMeaningQuestion.setOfQuestions) {
//If it is duplicate change isDuplicate to true and break
if (setOfQuestion.equals(pickedQuestion)) {
isDuplicate = true;
break;
}
public static void goToNextQuestion() {
if (currentAssessment < 10) {
Question currentQuestion = listOfAssessment.get(currentAssessment);
if (currentQuestion instanceof MatchTheMeaningQuestion) {
MatchTheMeaningController.answer = ((MatchTheMeaningQuestion) currentQuestion).getCorrectAnswer();
ScreenSwitch.swap(ScreenSwitch.SceneEnum.matchMeaningScene);
} else if (currentQuestion instanceof SixMeaningsQuestion) {
SixMeaningsController.allQuestions = ((SixMeaningsQuestion) currentQuestion).getCorrectAnswer();
ScreenSwitch.swap(ScreenSwitch.SceneEnum.sixMeaningScene);
} else if (currentQuestion instanceof TranslationQuestion) {
TranslationController.answer = ((TranslationQuestion) currentQuestion).getCorrectAnswer();
ScreenSwitch.swap(ScreenSwitch.SceneEnum.translationScene);
} else {
System.err.print("The question has not been recognised");
System.err.println(currentQuestion);
}
//If duplicate wasn't found add entry to the list
if(!isDuplicate){
MatchTheMeaningQuestion.setOfQuestions.add(pickedQuestion);
currentAssessment++;
} else {
StringBuilder sb = new StringBuilder();
sb.append("You scored: ")
.append(Question.correctAnswers).append("/")
.append(Question.correctAnswers + Question.wrongAnswers)
.append("\n Would you like to test yourself again?");
ButtonType yesBtn = new ButtonType("Yes");
ButtonType noBtn = new ButtonType("No");
Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
alert.setTitle("You finished the tests");
alert.setHeaderText("You finished the tests\n Well Done!");
alert.setResizable(false);
alert.setContentText(sb.toString());
alert.getButtonTypes().clear();
alert.getButtonTypes().addAll(yesBtn, noBtn);
Optional<ButtonType> result = alert.showAndWait();
if (result.isEmpty() || result.get() == noBtn) {
currentAssessment=0;
Question.resetScore();
ScreenSwitch.swap(ScreenSwitch.SceneEnum.dictionaryScene);
} else {
currentAssessment = 0;
Question.resetScore();
generateAssessment(Application.practiseList);
}
}
//... otherwise, add entry to the
}else{
MatchTheMeaningQuestion.setOfQuestions.add(pickedQuestion);
}
isDuplicate =false;
}while(MatchTheMeaningQuestion.setOfQuestions.size()<5);
}
/**
* Method that
* will generate a list of questions that are the type Translation, using the dictionary's practice words as
* the parameter.
* @return
*/
public Question generateWordEnter(LinkedList<DictionaryEntry> a){
return null;
}
}
}

View file

@ -30,10 +30,10 @@ import java.util.*;
*/
public class MatchTheMeaningController extends Question implements Initializable{
public class MatchTheMeaningController implements Initializable{
private ArrayList<DictionaryEntry> setOfQuestions=new ArrayList<>();
public static ArrayList<DictionaryEntry> answer =new ArrayList<>();
private ArrayList<Integer> orderList = new ArrayList<>(Arrays.asList(0,1,2,3));
private boolean isEnglish;
@ -81,14 +81,6 @@ public class MatchTheMeaningController extends Question implements Initializable
private Label WrongAnswer;
/**
* Pick randomly dictionary entry and add it to question list where are stored questions for this test.
*/
private void getQuestions(){
setOfQuestions.addAll(AssessmentGenerator.generateWordMatch());
}
/**
* Set chosen words from dictionary on the scene.
@ -100,6 +92,8 @@ public class MatchTheMeaningController extends Question implements Initializable
private void setWords(ArrayList<DictionaryEntry> questions, ArrayList<Integer> orderList){
isEnglish = AssessmentGenerator.isEnglish;
if(isEnglish){
LeftWord1.setText(questions.get(0).getEnglish());
LeftWord2.setText(questions.get(1).getEnglish());
@ -109,9 +103,9 @@ public class MatchTheMeaningController extends Question implements Initializable
Collections.shuffle(orderList);
RightWord1.setText(questions.get(orderList.get(0)).getWelsh());
RightWord1.setText(questions.get(orderList.get(1)).getWelsh());
RightWord1.setText(questions.get(orderList.get(2)).getWelsh());
RightWord1.setText(questions.get(orderList.get(3)).getWelsh());
RightWord2.setText(questions.get(orderList.get(1)).getWelsh());
RightWord3.setText(questions.get(orderList.get(2)).getWelsh());
RightWord4.setText(questions.get(orderList.get(3)).getWelsh());
}else {
LeftWord1.setText(questions.get(0).getWelsh());
@ -122,9 +116,9 @@ public class MatchTheMeaningController extends Question implements Initializable
Collections.shuffle(orderList);
RightWord1.setText(questions.get(orderList.get(0)).getEnglish());
RightWord1.setText(questions.get(orderList.get(1)).getEnglish());
RightWord1.setText(questions.get(orderList.get(2)).getEnglish());
RightWord1.setText(questions.get(orderList.get(3)).getEnglish());
RightWord2.setText(questions.get(orderList.get(1)).getEnglish());
RightWord3.setText(questions.get(orderList.get(2)).getEnglish());
RightWord4.setText(questions.get(orderList.get(3)).getEnglish());
}
}
@ -147,28 +141,21 @@ public class MatchTheMeaningController extends Question implements Initializable
listOfAnswers.add(LeftWord4.getText());
}
checkAnswer(setOfQuestions,listOfAnswers,isEnglish);
Question.checkAnswer(answer,listOfAnswers,isEnglish);
CorrectAnswer.setText(Integer.toString(correctAnswers));
WrongAnswer.setText(Integer.toString(wrongAnswers));
setOfQuestions.clear();
this.prepare();
answer.clear();
AssessmentGenerator.goToNextQuestion();
}
/**
* Method responsible for preparing questions and scene.
*/
private void prepare(){
getQuestions();
setWords(setOfQuestions,orderList);
}
@Override
public void initialize(URL url, ResourceBundle resourceBundle) {
this.prepare();
setWords(answer,orderList);
CorrectAnswer.setText(Integer.toString(Question.correctAnswers));
WrongAnswer.setText(Integer.toString(Question.wrongAnswers));
}
}

View file

@ -2,12 +2,17 @@ package uk.ac.aber.cs22120.group20.selfassessment;
import uk.ac.aber.cs22120.group20.json.DictionaryEntry;
public class MatchTheMeaningQuestion {
DictionaryEntry[] correctAnswer;
import java.util.ArrayList;
import java.util.Arrays;
public class MatchTheMeaningQuestion extends Question {
private ArrayList<DictionaryEntry> correctAnswer = new ArrayList<>();
public MatchTheMeaningQuestion(DictionaryEntry[] correctAnswer){
this.correctAnswer = correctAnswer;
this.correctAnswer.addAll(Arrays.asList(correctAnswer));
}
public ArrayList<DictionaryEntry> getCorrectAnswer() {
return correctAnswer;
}
}

View file

@ -15,8 +15,8 @@ import java.util.ArrayList;
*/
public class Question {
public int correctAnswers = 0;
public int wrongAnswers =0;
public static int correctAnswers = 0;
public static int wrongAnswers =0;
/**
*
@ -24,7 +24,7 @@ public class Question {
* @param listOfAnswers
* @param isEnglish
*/
public void checkAnswer(ArrayList<DictionaryEntry> listOfCorrectQuestions, ArrayList<String>listOfAnswers, boolean isEnglish){
public static void checkAnswer(ArrayList<DictionaryEntry> listOfCorrectQuestions, ArrayList<String>listOfAnswers, boolean isEnglish){
if(isEnglish){
for(int i=0; i<listOfCorrectQuestions.size();i++){
if(listOfCorrectQuestions.get(i).getWelsh().equals(listOfAnswers.get(i))){
@ -38,6 +38,11 @@ public class Question {
}else wrongAnswers++;
}
}
}
public static void resetScore(){
correctAnswers = 0;
wrongAnswers =0;
}
}
}

View file

@ -32,14 +32,13 @@ import java.util.*;
* @see uk.ac.aber.cs22120.group20.javafx.Application
*/
public class SixMeaningsController extends TranslationController implements Initializable {
public class SixMeaningsController implements Initializable {
private Random rand = new Random();
private LinkedList<DictionaryEntry> wordSet = new LinkedList<>();
private ArrayList<DictionaryEntry> wordSet = new ArrayList<>();
public static ArrayList<DictionaryEntry> allQuestions = new ArrayList<>();
private ArrayList<Integer> orderList = new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4, 5));
private int correct = 0;
private int incorrect = 0;
private String wordCounterpart;
private boolean isEnglish = AssessmentGenerator.isEnglish;
@FXML
@ -70,132 +69,102 @@ public class SixMeaningsController extends TranslationController implements Init
private Text possibleAnswer6;
@FXML
void temp(MouseEvent event) {
void answer1(MouseEvent event) {
wordCounterpart = possibleAnswer1.getText();
checkAnswers();
}
@FXML
void answer2(MouseEvent event) {
wordCounterpart = possibleAnswer2.getText();
checkAnswers();
}
@FXML
void answer3(MouseEvent event) {
wordCounterpart = possibleAnswer3.getText();
checkAnswers();
}
@FXML
void answer4(MouseEvent event) {
wordCounterpart = possibleAnswer4.getText();
checkAnswers();
}
@FXML
void answer5(MouseEvent event) {
wordCounterpart = possibleAnswer5.getText();
checkAnswers();
}
@FXML
void answer6(MouseEvent event) {
wordCounterpart = possibleAnswer6.getText();
checkAnswers();
}
private void getWords(LinkedList<DictionaryEntry> practiceList) {
boolean isDuplicate = false;
do {
int word = rand.nextInt(practiceList.size() - 1);
DictionaryEntry chosenWord = practiceList.get(word);
if (wordSet.size() >= 1) {
private void setWords(boolean isEnglish){
for (DictionaryEntry setOfQuestion : wordSet) {
if(isEnglish){
if (setOfQuestion.equals(chosenWord)) {
isDuplicate = true;
break;
}
}
wordSet.add(allQuestions.get(0));
//WelshWord1 Is the question word and as a result is always right.
wordToTranslate.setText(wordSet.get(0).getEnglish());
//This stores the correct answer for the english word.
//If duplicate wasn't found add entry to the list
if (!isDuplicate) {
wordSet.add(chosenWord);
}
Collections.shuffle(orderList);
//... otherwise, add entry to the
} else {
wordSet.add(chosenWord);
}
possibleAnswer1.setText(allQuestions.get(orderList.get(0)).getWelsh());
possibleAnswer2.setText(allQuestions.get(orderList.get(1)).getWelsh());
possibleAnswer3.setText(allQuestions.get(orderList.get(2)).getWelsh());
possibleAnswer4.setText(allQuestions.get(orderList.get(3)).getWelsh());
possibleAnswer5.setText(allQuestions.get(orderList.get(4)).getWelsh());
possibleAnswer6.setText(allQuestions.get(orderList.get(5)).getWelsh());
}else {
isDuplicate = false;
wordSet.add(allQuestions.get(0));
//WelshWord1 Is the question word and as a result is always right.
wordToTranslate.setText(wordSet.get(0).getWelsh());
//This stores the correct answer for the english word.
} while (wordSet.size() < 6);
Collections.shuffle(orderList);
possibleAnswer1.setText(allQuestions.get(orderList.get(0)).getEnglish());
possibleAnswer2.setText(allQuestions.get(orderList.get(1)).getEnglish());
possibleAnswer3.setText(allQuestions.get(orderList.get(2)).getEnglish());
possibleAnswer4.setText(allQuestions.get(orderList.get(3)).getEnglish());
possibleAnswer5.setText(allQuestions.get(orderList.get(4)).getEnglish());
possibleAnswer6.setText(allQuestions.get(orderList.get(5)).getEnglish());
}
}
private void setWordsE(LinkedList<DictionaryEntry> questions, ArrayList<Integer> orderList) {
//WelshWord1 Is the question word and as a result is always right.
wordToTranslate.setText(questions.get(0).getWelsh());
//This stores the correct answer for the english word.
wordCounterpart = questions.get(0).getEnglish();
possibleAnswer1.setText(questions.get(orderList.get(0)).getEnglish());
possibleAnswer2.setText(questions.get(orderList.get(1)).getEnglish());
possibleAnswer3.setText(questions.get(orderList.get(2)).getEnglish());
possibleAnswer4.setText(questions.get(orderList.get(3)).getEnglish());
possibleAnswer5.setText(questions.get(orderList.get(4)).getEnglish());
possibleAnswer6.setText(questions.get(orderList.get(5)).getEnglish());
Collections.shuffle(orderList); //I know that this does not belong here it was moved here for debug purposes. It lives five lines up.
}
private void checkAnswers() {
private void setWordsW(LinkedList<DictionaryEntry> questions, ArrayList<Integer> orderList) {
//WelshWord1 Is the question word and as a result is always right.
wordToTranslate.setText(questions.get(0).getEnglish());
//This stores the correct answer for the english word.
wordCounterpart = questions.get(0).getWelsh();
possibleAnswer1.setText(questions.get(orderList.get(0)).getWelsh());
possibleAnswer2.setText(questions.get(orderList.get(1)).getWelsh());
possibleAnswer3.setText(questions.get(orderList.get(2)).getWelsh());
possibleAnswer4.setText(questions.get(orderList.get(3)).getWelsh());
possibleAnswer5.setText(questions.get(orderList.get(4)).getWelsh());
possibleAnswer6.setText(questions.get(orderList.get(5)).getWelsh());
ArrayList<String> answer = new ArrayList<>();
Collections.shuffle(orderList); //I know that this does not belong here it was moved here for debug purposes. It lives five lines up.
}
answer.add(wordCounterpart);
Question.checkAnswer(wordSet,answer,isEnglish);
public void checkAnswers() {
String option1 = possibleAnswer1.toString();
String option2 = possibleAnswer2.toString();
String option3 = possibleAnswer3.toString();
String option4 = possibleAnswer4.toString();
String option5 = possibleAnswer5.toString();
String option6 = possibleAnswer6.toString();
if (option1 == wordCounterpart) {
correct++;
} else incorrect++;
if (option2 == wordCounterpart) {
correct++;
} else incorrect++;
if (option3 == wordCounterpart) {
correct++;
} else incorrect++;
if (option4 == wordCounterpart) {
correct++;
} else incorrect++;
if (option5 == wordCounterpart) {
correct++;
} else incorrect++;
if (option6 == wordCounterpart) {
correct++;
} else incorrect++;
correctAnswer.setText(Integer.toString(correct));
wrongAnswer.setText(Integer.toString(incorrect));
wordSet.clear();
this.prepare();
}
AssessmentGenerator.goToNextQuestion();
private void prepare() {
getWords(Application.dictionary);
Random rd = new Random();
System.out.println(rd.nextBoolean());
if (rd.nextBoolean() == true) {
setWordsE(wordSet, orderList);
} else setWordsW(wordSet, orderList);
}
@Override
public void initialize(URL url, ResourceBundle resourceBundle) {
this.prepare();
setWords(isEnglish);
correctAnswer.setText(Integer.toString(Question.correctAnswers));
wrongAnswer.setText(Integer.toString(Question.wrongAnswers));
}

View file

@ -1,11 +1,40 @@
package uk.ac.aber.cs22120.group20.selfassessment;
import uk.ac.aber.cs22120.group20.javafx.Application;
import uk.ac.aber.cs22120.group20.json.DictionaryEntry;
public class SixMeaningsQuestion {
private DictionaryEntry correctAnswer;
import java.util.ArrayList;
import java.util.Dictionary;
import java.util.LinkedList;
import java.util.Random;
private SixMeaningsQuestion(DictionaryEntry correctAnswer) {
public class SixMeaningsQuestion extends Question{
private DictionaryEntry correctAnswer;
private LinkedList<DictionaryEntry> dictionary;
public SixMeaningsQuestion(DictionaryEntry correctAnswer, LinkedList<DictionaryEntry> dictionary) {
this.correctAnswer = correctAnswer;
this.dictionary = dictionary;
}
public ArrayList<DictionaryEntry> getCorrectAnswer() {
Random rand = new Random();
ArrayList<DictionaryEntry> result = new ArrayList<>();
result.add(correctAnswer);
int successfulAnswersSelected = 0;
while(successfulAnswersSelected<5){
DictionaryEntry selectedAnswer;
selectedAnswer = dictionary.get(rand.nextInt(dictionary.size()-1));
if (result.contains(selectedAnswer)){
continue;
}
result.add(selectedAnswer);
successfulAnswersSelected++;
}
return result;
}
}

View file

@ -18,19 +18,12 @@ import uk.ac.aber.cs22120.group20.javafx.Application;
* Controller for the translationTest fxml file.
*
* @author Brad Corbett brc9
* @version 0.9
* @version 0.1
*
*/
public class TranslationController extends Question {
ArrayList<DictionaryEntry> practiceList = new ArrayList<>();
/**
* Represents the words that have already been used, and are no longer to be generated.
*/
ArrayList<Integer> numbersUsed = new ArrayList<Integer>();
int correctGuessesInt = 0;
int incorrectGuessesInt = 0;
public class TranslationController {
private ArrayList<DictionaryEntry> practiceList = new ArrayList<>();
public static DictionaryEntry answer = new DictionaryEntry();
/**
* Represents the word that will be randomly chosen from the practiceList.
@ -57,8 +50,6 @@ public class TranslationController extends Question {
Random rand = new Random();
boolean englishOrWelsh = false; // False means English to Welsh, true means Welsh to English
/**
* Loads the test for the first time, filling the practice list with words from the dictionary,
@ -70,35 +61,23 @@ public class TranslationController extends Question {
submitButton.setImage(new Image ("file:src/main/resources/assets/icons/black_icons/50px/right-50.png"));
for(DictionaryEntry entry : Application.dictionary){
if(entry.isPracticeWord()){
practiceList.add(entry);
}
}
correctGuesses.setText("Correct Guesses: " + Question.correctAnswers);
incorrectGuesses.setText("Incorrect Guesses: " + Question.wrongAnswers);
chosenWord = (rand.nextInt(practiceList.size()));
numbersUsed.add(chosenWord);
englishOrWelsh = rand.nextBoolean();
correctGuesses.setText("Correct Guesses: 0");
incorrectGuesses.setText("Incorrect Guesses: 0");
if(englishOrWelsh){
wordToTranslate.setText(practiceList.get(chosenWord).getWelsh());
if(AssessmentGenerator.isEnglish){
wordToTranslate.setText(answer.getEnglish());
}
else{
wordToTranslate.setText(practiceList.get(chosenWord).getEnglish());
wordToTranslate.setText(answer.getWelsh());
}
}
/**
* Takes the word that the user has entered as their attempt at translate, compares
* it to the correct translation, and depending on if it is correct or not, increment how many
* right or wrong answers they have so far. After checking if the user got it right,
* it will generate a new word for the user to translate, provided they have words left to translate.
* Takes the word the user inputs and compares it to the correct answer using
* the checkAnswer function in the QuestionClass.
*/
@FXML
void translateWord() {
@ -107,37 +86,12 @@ public class TranslationController extends Question {
usersInput.add(translationBox.getText());
ArrayList<DictionaryEntry> correctTranslation = new ArrayList<>();
correctTranslation.add(practiceList.get(chosenWord));
correctTranslation.add(answer);
checkAnswer(correctTranslation, usersInput, englishOrWelsh);
Question.checkAnswer(correctTranslation, usersInput, AssessmentGenerator.isEnglish);
AssessmentGenerator.goToNextQuestion();
correctGuesses.setText("Correct Guesses: " + correctAnswer);
incorrectGuesses.setText("Incorrect Guesses: " + wrongAnswer);
do{
chosenWord = (rand.nextInt(practiceList.size()));
}while((numbersUsed.contains(chosenWord)) && numbersUsed.size() < practiceList.size());
numbersUsed.add(chosenWord);
if(numbersUsed.size() > practiceList.size()){
wordToTranslate.setText("Test Complete");
submitButton.setVisible(false);
}
if(englishOrWelsh){
wordToTranslate.setText(practiceList.get(chosenWord).getWelsh());
}
else{
wordToTranslate.setText(practiceList.get(chosenWord).getEnglish());
}
}
}

View file

@ -4,10 +4,14 @@ import uk.ac.aber.cs22120.group20.json.DictionaryEntry;
import java.util.LinkedList;
public class TranslationQuestion {
DictionaryEntry correctAnswer;
public class TranslationQuestion extends Question {
private DictionaryEntry correctAnswer;
public TranslationQuestion(DictionaryEntry correctAnswer){
this.correctAnswer = correctAnswer;
}
public DictionaryEntry getCorrectAnswer() {
return correctAnswer;
}
}

View file

@ -1,29 +0,0 @@
package uk.ac.aber.cs22120.group20.test;
/**
* Class that contains methods to test that the Add Word Screen only saves words to the dictionary when
* all fields are filled and the entry does not already exist in as an entry in the dictionary.
* @Author
* @Version
* @See
*/
public class AddWordText {
/**
* Test to check if the correct error is thrown when there are one or more blank fields and that the entry
* does not save to the dictionary.
*/
@test
public void testBlankFields() {
}
/**
* Test to check if the correct error is thrown when the entry attempting to be added already exists within
* the dictionary and that the entry is not saved.
*/
@test
public void testDuplicateEntry() {
}
}

View file

@ -0,0 +1,5 @@
import static org.junit.jupiter.api.Assertions.*;
class FlashcardControllerTest {
}

View file

@ -1,5 +1,19 @@
package uk.ac.aber.cs22120.group20.test;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.Assert;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import uk.ac.aber.cs22120.group20.json.DictionaryEntry;
import uk.ac.aber.cs22120.group20.json.JsonProcessing;
import java.io.File;
import java.io.FileWriter;
import java.util.Arrays;
import java.util.LinkedList;
/**
* Class that contains methods which will be used to test that the JSON package classes are
* correctly loading and saving to and from the JSON file.
@ -8,21 +22,55 @@ package uk.ac.aber.cs22120.group20.test;
* @See
*/
public class JSONTest {
LinkedList<DictionaryEntry> testList;
LinkedList<DictionaryEntry> loadedList;
File testFile;
JsonProcessing processor = new JsonProcessing();
@Before
public void setupTest() {
// Populate a test list with DictionaryEntrys that is to be used for the loading/saving tests.
testList = new LinkedList<>(Arrays.asList(new DictionaryEntry("abbey","abaty","nm"), new DictionaryEntry("about to", "ar fin", "other"),
new DictionaryEntry("above","uwchben","other"), new DictionaryEntry("abroad","dramor","other"),
new DictionaryEntry("abstract","haniaethol","other")));
// Create a JSON test file in the test package
testFile = new File("src/main/java/uk/ac/aber/cs22120/group20/test/jsontest.json");
// Save the testList to the testFile.
processor.writeOutJson("src/main/java/uk/ac/aber/cs22120/group20/test/jsontest.json", testList);
}
/**
* JUnit test to check that the JSON file has been correctly loaded.
*/
@test public void testLoad(){
@Test
public void testLoad(){
// Load the DictionaryEntry's from testFile and check if the loaded list matches the test list.
loadedList = processor.readInJson(testFile);
Assert.assertArrayEquals(testList.toArray(),loadedList.toArray());
}
/**
* JUnit test to check that any changes to the list of definitions are
* updated and saved to the JSON file accordingly.
*/
@test public void testSave(){
@Test public void testSave(){
// Add an additional word to the testList and save it to jsontest.
testList.add(new DictionaryEntry("beer", "cwrw", "nm"));
processor.writeOutJson("src/main/java/uk/ac/aber/cs22120/group20/test/jsontest.json", testList);
// Load the DictionaryEntry's back from the file and check that they match the testList.
loadedList = processor.readInJson(testFile);
Assert.assertArrayEquals(testList.toArray(), loadedList.toArray());
}
@After
public void deleteFile() {
testFile.delete();
}
}

View file

@ -23,17 +23,17 @@
<Font name="System Bold" size="25.0"/>
</font>
</Label>
<Text fx:id="possibleAnswer1" layoutX="61.0" layoutY="176.0" onMouseClicked="#temp" strokeType="OUTSIDE"
<Text fx:id="possibleAnswer1" layoutX="61.0" layoutY="176.0" onMouseClicked="#answer1" strokeType="OUTSIDE"
strokeWidth="0.0" text="English Word 1"/>
<Text fx:id="possibleAnswer2" layoutX="260.0" layoutY="175.0" onMouseClicked="#temp"
<Text fx:id="possibleAnswer2" layoutX="260.0" layoutY="175.0" onMouseClicked="#answer2"
strokeType="OUTSIDE" strokeWidth="0.0" text="English Word 2"/>
<Text fx:id="possibleAnswer3" layoutX="472.0" layoutY="175.0" onMouseClicked="#temp"
<Text fx:id="possibleAnswer3" layoutX="472.0" layoutY="175.0" onMouseClicked="#answer3"
strokeType="OUTSIDE" strokeWidth="0.0" text="English Word 3"/>
<Text fx:id="possibleAnswer4" layoutX="61.0" layoutY="297.0" onMouseClicked="#temp" strokeType="OUTSIDE"
<Text fx:id="possibleAnswer4" layoutX="61.0" layoutY="297.0" onMouseClicked="#answer4" strokeType="OUTSIDE"
strokeWidth="0.0" text="English Word 4"/>
<Text fx:id="possibleAnswer5" layoutX="260.0" layoutY="297.0" onMouseClicked="#temp"
<Text fx:id="possibleAnswer5" layoutX="260.0" layoutY="297.0" onMouseClicked="#answer5"
strokeType="OUTSIDE" strokeWidth="0.0" text="English Word 5"/>
<Text fx:id="possibleAnswer6" layoutX="472.0" layoutY="297.0" onMouseClicked="#temp"
<Text fx:id="possibleAnswer6" layoutX="472.0" layoutY="297.0" onMouseClicked="#answer6"
strokeType="OUTSIDE" strokeWidth="0.0" text="English Word 6"/>
</children>
</AnchorPane>