diff --git a/app/src/main/java/ch/zhaw/projekt2/turnierverwaltung/Factory.java b/app/src/main/java/ch/zhaw/projekt2/turnierverwaltung/Factory.java index dec1687..dbf6ae5 100644 --- a/app/src/main/java/ch/zhaw/projekt2/turnierverwaltung/Factory.java +++ b/app/src/main/java/ch/zhaw/projekt2/turnierverwaltung/Factory.java @@ -10,21 +10,23 @@ import javafx.scene.paint.Color; import javafx.scene.text.Font; import java.io.IOException; +import java.util.logging.Logger; +/** + * + */ public class Factory { private TournamentDecorator tournamentDecorator; private FileIO fileIO; + private static final Logger logger = Logger.getLogger(FileIO.class.getCanonicalName()); + public Factory(FileIO fileIO, TournamentDecorator tournamentDecorator) { this.fileIO = fileIO; this.tournamentDecorator = tournamentDecorator; } - public TournamentDecorator getTournamentDecorator() { - return tournamentDecorator; - } - public void setTournament(Tournament tournament) { this.tournamentDecorator.setTournament(tournament); } @@ -34,8 +36,8 @@ public class Factory { try { return loader.load(); } catch (IOException e) { + logger.warning("Fatal error program can not continue after this: " + e ); e.printStackTrace(); - //TODO handle and logging } return null; } @@ -85,8 +87,8 @@ public class Factory { controller.setup(tournamentDecorator, fileIO, factoryDecorator, box, gameDecorator); return controller; } catch (IOException e) { + logger.warning("Fatal error program can not continue after this: " + e ); e.printStackTrace(); - //TODO LOGGER } return null; } @@ -118,6 +120,11 @@ public class Factory { } + /** + * + * @param pane + * @param error + */ public void resetFooter(BorderPane pane,boolean error) { VBox bottom = (VBox) pane.getBottom(); VBox vBox; @@ -130,6 +137,9 @@ public class Factory { vBox.setBorder(null); } + /** + * Enum for keeping the different fxml form views + */ public enum View { tournamentList("tournamentList/tournamentList.fxml"), participantFormular("participantAddFormular/participantFormular.fxml"), diff --git a/app/src/main/java/ch/zhaw/projekt2/turnierverwaltung/FactoryDecorator.java b/app/src/main/java/ch/zhaw/projekt2/turnierverwaltung/FactoryDecorator.java index 5ab8da7..df9d18a 100644 --- a/app/src/main/java/ch/zhaw/projekt2/turnierverwaltung/FactoryDecorator.java +++ b/app/src/main/java/ch/zhaw/projekt2/turnierverwaltung/FactoryDecorator.java @@ -12,63 +12,128 @@ import javafx.scene.shape.Line; import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.logging.Logger; -public class FactoryDecorator implements IsObservable{ +/** + * Factory Decorator Class giving additional functionality to the factory and holding the listeners in itself. + */ +public class FactoryDecorator implements IsObservable { private Factory factory; private FileIO fileIO; private Pane pane; - private List listener = new ArrayList<>(); + private final List listener = new ArrayList<>(); - public FactoryDecorator(FileIO fileIO, Factory factory, Pane pane){ + private static final Logger logger = Logger.getLogger(FileIO.class.getCanonicalName()); + + /** + * Setup of Factory Decorator with needed classes + * + * @param fileIO for Reading and Saving Files + * @param factory factory which this class adds additional functionality to + * @param pane standard pane + */ + public FactoryDecorator(FileIO fileIO, Factory factory, Pane pane) { + logger.fine("Setting up the Factory decorator"); setFactory(factory); setFileIO(fileIO); setPane(pane); } + /** + * Setting the File IO Class for its functionality + * + * @param fileIO for reading and saving to and from a file + */ public void setFileIO(FileIO fileIO) { + logger.finer("Setting the FileIO to the FactoryDecorator"); this.fileIO = fileIO; } + /** + * Setting the main class + * + * @param factory needed for the main functionality + */ public void setFactory(Factory factory) { + logger.finer("Setting the factory to the FactoryDecorator"); this.factory = factory; } + /** + * Setting of the given pane to the factory decorator + * + * @param pane that will be set + */ public void setPane(Pane pane) { + logger.finer("Setting the pane to the FactoryDecorator"); this.pane = pane; } + /** + * Method adds a new Listener to the listener list + * + * @param observer that is being added to the Listener List + */ @Override public void addListener(IsObserver observer) { + logger.fine("Adding Listener: " + observer); listener.add(observer); } + /** + * Removes a Listener from the Listener List + * + * @param observer the Listener to be removed + */ @Override public void removeListener(IsObserver observer) { + logger.fine("Removing Listener: " + observer); listener.remove(observer); } - public void openTournament(FileIO.TournamentFile tournamentFile){ + /** + * Opens a tournament File in connection with the File IO Class, shows error Message if error occurs while opening + * it. + * + * @param tournamentFile the File to be opened + */ + public void openTournament(FileIO.TournamentFile tournamentFile) { + logger.finer("Trying to open tournament file:" + tournamentFile); try { factory.setTournament(fileIO.loadTournament(tournamentFile)); openScheduleView(); clearMessage(false); + logger.fine("Opened tournament file successfully"); } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); + logger.warning("Failed to open tournament file Error: " + e); printMessageToFooter("Fehler beim lesen der Datei.", true); - } //TODO handle and logging + } } + /** + * Initializes the display of the Tournament list view + */ public void openTournamentList() { + logger.fine("Showing TournamentList view"); factory.showTournamentList((BorderPane) pane, this); informListener(); } - public void openParticipantFormular() { + /** + * Initializes the view of the participant form + */ + public void openParticipantForm() { + logger.fine("Showing participant form view"); factory.showParticipantFormular((BorderPane) pane, this); informListener(); } - public void openPlacesFormular() { + /** + * Initializes the view of the places form + */ + public void openPlacesForm() { + logger.fine("Showing places form view"); factory.showPlacesFormular((BorderPane) pane, this); informListener(); } @@ -81,7 +146,7 @@ public class FactoryDecorator implements IsObservable{ public void loadGameList(HBox hBoxCenter, TournamentDecorator tournamentDecorator, boolean treeView) { hBoxCenter.getChildren().clear(); - if(tournamentDecorator.getTournament() == null){ + if (tournamentDecorator.getTournament() == null) { return; } @@ -93,7 +158,7 @@ public class FactoryDecorator implements IsObservable{ for (int i = 0; i < gameList.size(); i++) { List newGameDecoratorsList = new ArrayList<>(); VBox vBox = new VBox(); - if(treeView){ + if (treeView) { vBox.setAlignment(Pos.CENTER); vBox.setSpacing(gameBoxHeight * spacingFactor); } else { @@ -103,12 +168,12 @@ public class FactoryDecorator implements IsObservable{ for (int j = 0; j < gameList.get(i).size(); j++) { GameDecorator gameDecorator = new GameDecorator(gameList.get(i).get(j)); newGameDecoratorsList.add(gameDecorator); - GameController gameController = openGameView(vBox,gameDecorator); - if(i>0){ - gameController.addListener(gameDecoratorsList.get(j*2)); - gameController.addListener(gameDecoratorsList.get(j*2+1)); - } else if(gameBoxHeight == 0) { - gameBoxHeight = gameController.getGameBoxHeigth(); + GameController gameController = openGameView(vBox, gameDecorator); + if (i > 0) { + gameController.addListener(gameDecoratorsList.get(j * 2)); + gameController.addListener(gameDecoratorsList.get(j * 2 + 1)); + } else if (gameBoxHeight == 0) { + gameBoxHeight = gameController.getGameBoxHeight(); } gameDecorator.addListener(new IsObserver() { @Override @@ -119,28 +184,28 @@ public class FactoryDecorator implements IsObservable{ gameController.loadContent(); } hBoxCenter.getChildren().add(vBox); - if(treeView){ - if(i+1 < gameList.size()) - hBoxCenter.getChildren().add(drawLines(vBox, gameBoxHeight, 30)); + if (treeView) { + if (i + 1 < gameList.size()) + hBoxCenter.getChildren().add(drawLines(vBox, gameBoxHeight, 30)); } gameDecoratorsList = newGameDecoratorsList; } } - public VBox drawLines(VBox gameVBox, double gameBoxHeight, double lineLength){ + public VBox drawLines(VBox gameVBox, double gameBoxHeight, double lineLength) { VBox completeLineVBox = new VBox(); completeLineVBox.setAlignment(Pos.CENTER_LEFT); double lineSpacing = gameVBox.getSpacing() + gameBoxHeight - 1; completeLineVBox.setSpacing(lineSpacing); - for(int i = 0; i < gameVBox.getChildren().size(); i+=2){ + for (int i = 0; i < gameVBox.getChildren().size(); i += 2) { HBox lineBox = new HBox(); lineBox.setAlignment(Pos.CENTER); //add Lines from left Game to center VBox vBox = new VBox(); vBox.setSpacing(lineSpacing); - vBox.getChildren().add(new Line(0,0,lineLength,0)); - vBox.getChildren().add(new Line(0,0,lineLength,0)); + vBox.getChildren().add(new Line(0, 0, lineLength, 0)); + vBox.getChildren().add(new Line(0, 0, lineLength, 0)); lineBox.getChildren().add(vBox); @@ -157,20 +222,43 @@ public class FactoryDecorator implements IsObservable{ return completeLineVBox; } + /** + * Method Initializes the Game View, in order to do that a vbox is needed and the gameDecorator + * @param vBox used for display + * @param gameDecorator + * @return + */ public GameController openGameView(VBox vBox, GameDecorator gameDecorator) { - return factory.loadGameView(vBox ,gameDecorator, this); + + return factory.loadGameView(vBox, gameDecorator, this); } + /** + * Method that initializes a new Message to be written on the footer, if it's an error boolean can be set. + * + * @param msg The message to be written + * @param error true if an error false if not + */ public void printMessageToFooter(String msg, boolean error) { - factory.printMessageToFooter((BorderPane) pane,msg,error); + logger.fine("Initializes to write message: " + msg + " on the footer"); + factory.printMessageToFooter((BorderPane) pane, msg, error); } - public void clearMessage(boolean error){ + /** + * Method used to clear Messages shown on the footer + * @param error true if an error false if not + */ + public void clearMessage(boolean error) { + logger.fine("Initializing to clear messages from the footer"); factory.resetFooter((BorderPane) pane, error); } + /** + * Method that informs all listeners of an update. + */ public void informListener() { - for(IsObserver observer : listener) { + + for (IsObserver observer : listener) { observer.update(); } } diff --git a/app/src/main/java/ch/zhaw/projekt2/turnierverwaltung/TournamentDecorator.java b/app/src/main/java/ch/zhaw/projekt2/turnierverwaltung/TournamentDecorator.java index 2e53ec6..a050058 100644 --- a/app/src/main/java/ch/zhaw/projekt2/turnierverwaltung/TournamentDecorator.java +++ b/app/src/main/java/ch/zhaw/projekt2/turnierverwaltung/TournamentDecorator.java @@ -181,6 +181,7 @@ public class TournamentDecorator implements IsObservable{ executorService.awaitTermination(2000, TimeUnit.MILLISECONDS); } + private class saveTask implements Runnable { @Override diff --git a/app/src/main/java/ch/zhaw/projekt2/turnierverwaltung/main/gameScheduleView/AlertNewSchedule.java b/app/src/main/java/ch/zhaw/projekt2/turnierverwaltung/main/gameScheduleView/AlertNewSchedule.java index 17a823d..3de3702 100644 --- a/app/src/main/java/ch/zhaw/projekt2/turnierverwaltung/main/gameScheduleView/AlertNewSchedule.java +++ b/app/src/main/java/ch/zhaw/projekt2/turnierverwaltung/main/gameScheduleView/AlertNewSchedule.java @@ -1,22 +1,40 @@ package ch.zhaw.projekt2.turnierverwaltung.main.gameScheduleView; +import ch.zhaw.projekt2.turnierverwaltung.FileIO; import javafx.scene.control.Alert; import javafx.scene.control.ButtonBar; import javafx.scene.control.ButtonType; +import java.util.logging.Logger; + + +/** + * Class that is used to display the popup window to confirm a sensitive action of the user. + */ public class AlertNewSchedule extends Alert { - private ButtonType yesButton = new ButtonType("Ja", ButtonBar.ButtonData.YES); - private ButtonType noButton = new ButtonType("Nein", ButtonBar.ButtonData.NO); + private final ButtonType yesButton = new ButtonType("Ja", ButtonBar.ButtonData.YES); + private final ButtonType noButton = new ButtonType("Nein", ButtonBar.ButtonData.NO); private boolean result; + private static final Logger logger = Logger.getLogger(FileIO.class.getCanonicalName()); + + /** + * Popup to ask the user if he is sure that he wants to reshuffle the game board. + */ public AlertNewSchedule() { super(AlertType.WARNING); + logger.fine("Displaying Popup to ask user if he wants to reshuffle the game board"); setTitle("Neu erstellen"); setHeaderText("Spielplan neu erstellen?"); setContentText("Sind Sie sicher, dass Sie den Spielplan neu erstellen moechten?\nAlle Spielfortschritte gehen daraufhin verloren!"); - getButtonTypes().setAll(yesButton,noButton); + getButtonTypes().setAll(yesButton, noButton); } + /** + * Result gathered from previous question popup window + * + * @return boolean true if yes button is pressed and false if no is pressed + */ public boolean showAndGetResult() { showAndWait().ifPresent(input -> { result = input == yesButton; diff --git a/app/src/main/java/ch/zhaw/projekt2/turnierverwaltung/main/gameScheduleView/GameController.java b/app/src/main/java/ch/zhaw/projekt2/turnierverwaltung/main/gameScheduleView/GameController.java index 07f4de1..81c8900 100644 --- a/app/src/main/java/ch/zhaw/projekt2/turnierverwaltung/main/gameScheduleView/GameController.java +++ b/app/src/main/java/ch/zhaw/projekt2/turnierverwaltung/main/gameScheduleView/GameController.java @@ -10,6 +10,9 @@ import javafx.scene.control.TextField; import javafx.scene.layout.Pane; import javafx.scene.layout.VBox; +/** + * Class GameController in Charge of the Controller Element of the Schedule view. + */ public class GameController extends FXController{ private GameDecorator gameDecorator; @@ -33,7 +36,7 @@ public class GameController extends FXController{ private TextField pointsTeamTwo; @FXML - void saveGameResult(Event event) { + void saveGameResult() { gameDecorator.saveGameResult(pointsTeamOne.getText(), pointsTeamTwo.getText()); } @@ -42,7 +45,7 @@ public class GameController extends FXController{ gameDecorator.saveGamePlace(newPlace); } - public double getGameBoxHeigth(){ + public double getGameBoxHeight(){ return mainVBox.getPrefHeight(); } diff --git a/app/src/main/java/ch/zhaw/projekt2/turnierverwaltung/main/gameScheduleView/GameScheduleController.java b/app/src/main/java/ch/zhaw/projekt2/turnierverwaltung/main/gameScheduleView/GameScheduleController.java index f6e15a1..b634e13 100644 --- a/app/src/main/java/ch/zhaw/projekt2/turnierverwaltung/main/gameScheduleView/GameScheduleController.java +++ b/app/src/main/java/ch/zhaw/projekt2/turnierverwaltung/main/gameScheduleView/GameScheduleController.java @@ -41,12 +41,12 @@ public class GameScheduleController extends FXController { @FXML void openPlacesFormular(ActionEvent event) { - getFactoryDecorator().openPlacesFormular(); + getFactoryDecorator().openPlacesForm(); } @FXML void openParticipantFormular(ActionEvent event) { - getFactoryDecorator().openParticipantFormular(); + getFactoryDecorator().openParticipantForm(); } @FXML diff --git a/app/src/test/java/ch/zhaw/projekt2/turnierverwaltung/FileIOTest.java b/app/src/test/java/ch/zhaw/projekt2/turnierverwaltung/FileIOTest.java index 09eeef6..0ef5ab5 100644 --- a/app/src/test/java/ch/zhaw/projekt2/turnierverwaltung/FileIOTest.java +++ b/app/src/test/java/ch/zhaw/projekt2/turnierverwaltung/FileIOTest.java @@ -1,6 +1,6 @@ package ch.zhaw.projekt2.turnierverwaltung; -import org.junit.jupiter.api.Assertions; + import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -12,10 +12,13 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.Comparator; import java.util.List; -import java.util.logging.Logger; + import static org.junit.jupiter.api.Assertions.*; +/** + * FileIO Test Class + */ class FileIOTest { String RESOURCES_DIR = "./src/test/resources/ch/zhaw/projekt2/turnierverwaltung/"; @@ -23,6 +26,11 @@ class FileIOTest { String saveDir; FileIO io; + /** + * Method checks if a new directory is set up correctly and can be accessed. + * + * @throws IOException Exceptions should not be thrown + */ @Test void FileIONewDir() throws IOException { mainDir = RESOURCES_DIR + "FileIONew"; @@ -50,14 +58,23 @@ class FileIOTest { assertFalse(saveDirFile.exists()); } + /** + * Method tests the read behavior and if a file is read correctly + */ @Nested class Read{ + /** + * Sets up a directory + */ @BeforeEach void init() { mainDir = RESOURCES_DIR + "FileIORead"; io = new FileIO(mainDir); } + /** + * Test if the list is displayed correctly when getting it via getList + */ @Test void getList() { List tournaments = io.getList(); @@ -65,6 +82,9 @@ class FileIOTest { assertEquals("test1.txt", tournaments.get(1).getName()); } + /** + * Test behaviour when the list is empty + */ @Test void getListEmpty() { mainDir = RESOURCES_DIR + "FileIOEmpty"; @@ -72,6 +92,12 @@ class FileIOTest { assertEquals(0, io.getList().size()); } + /** + * Tests behavior when loading a tournament that exists. + * + * @throws IOException Exceptions should not be thrown + * @throws ClassNotFoundException Exceptions should not be thrown + */ @Test void loadTournament() throws IOException, ClassNotFoundException { mainDir = RESOURCES_DIR + "FileIORead"; @@ -80,6 +106,9 @@ class FileIOTest { assertEquals("test1", tournament.getName()); } + /** + * Test behavior when trying to load non-existent tournament + */ @Test void loadTournamentNotExisting(){ File file = new File("Not-existing-File"); @@ -88,11 +117,17 @@ class FileIOTest { assertFalse(file.exists()); } + /** + * Tests behavior when trying to load an empty tournament. + */ @Test void loadTournamentEmpty(){ assertThrows(IOException.class, () -> io.loadTournament(new File(mainDir + "/saves/empty.txt"))); } + /** + * Tests behavior when the tournamentfile input is null + */ @Test void loadTournamentFileNull(){ assertThrows(IllegalArgumentException.class, () -> io.loadTournament(null)); @@ -107,6 +142,13 @@ class FileIOTest { io = new FileIO(mainDir); } + /** + * Saves the Saving mechanism and deletion + * + * @throws IOException Exceptions should not be thrown + * @throws InvalidNameException Exceptions should not be thrown + * @throws Tournament.InvalidTypeException Exceptions should not be thrown + */ @Test void saveTournament() throws IOException, InvalidNameException, Tournament.InvalidTypeException { Tournament tournament = null; @@ -118,6 +160,9 @@ class FileIOTest { assertFalse(file.exists()); } + /** + * Tests behavior when a tournament is being saved that is only null + */ @Test void saveTournamentNull(){ assertThrows(IllegalArgumentException.class, () -> io.saveTournament(null)); @@ -132,6 +177,10 @@ class FileIOTest { io = new FileIO(mainDir); } + /** + * Test if tournament that does exist can be deleted + * @throws IOException Exceptions should not be thrown + */ @Test void deleteTournament() throws IOException { File file = new File(mainDir + "/saves/test1.txt"); @@ -141,6 +190,11 @@ class FileIOTest { assertFalse(file.exists()); } + /** + * Testing if tournament that does not exist can be deleted + * + * @throws IOException Exception should not be thrown only checking for FileNotFoundException + */ @Test void deleteTournamentNotExisting() throws IOException { File file = new File("Not-existing-File"); @@ -149,6 +203,9 @@ class FileIOTest { assertFalse(file.exists()); } + /** + * Tests if a tournament that is null can be deleted + */ @Test void deleteTournamentNull(){ assertThrows(IllegalArgumentException.class, () -> io.deleteTournament(null));