From dab55bf8f2abc545debf8c968f235636611edc40 Mon Sep 17 00:00:00 2001 From: Vetle <vetletb@stud.ntnu.no> Date: Thu, 16 May 2024 13:15:15 +0200 Subject: [PATCH 1/3] Remade custom exceptions to reflex what went wrong, not where --- .../exceptions/ChaosCanvasException.java | 32 ------------------ .../ChaosGameDescriptionException.java | 32 ------------------ .../ChaosGameDescriptionFactoryException.java | 32 ------------------ .../exceptions/ChaosGameException.java | 32 ------------------ .../ChaosGameFileHandlerException.java | 32 ------------------ .../exceptions/CouldNotWriteException.java | 32 ++++++++++++++++++ .../exceptions/EmptyListException.java | 32 ++++++++++++++++++ .../InvalidPositiveIntException.java | 32 ++++++++++++++++++ .../exceptions/InvalidSignException.java | 33 +++++++++++++++++++ .../exceptions/InvalidTypeException.java | 32 ++++++++++++++++++ .../InvalidVectorRangeException.java | 33 +++++++++++++++++++ .../idatt2003/exceptions/IsNullException.java | 32 ++++++++++++++++++ .../exceptions/ObservingException.java | 32 ++++++++++++++++++ .../exceptions/WrongLengthException.java | 32 ++++++++++++++++++ 14 files changed, 290 insertions(+), 160 deletions(-) delete mode 100644 src/main/java/edu/ntnu/idatt2003/exceptions/ChaosCanvasException.java delete mode 100644 src/main/java/edu/ntnu/idatt2003/exceptions/ChaosGameDescriptionException.java delete mode 100644 src/main/java/edu/ntnu/idatt2003/exceptions/ChaosGameDescriptionFactoryException.java delete mode 100644 src/main/java/edu/ntnu/idatt2003/exceptions/ChaosGameException.java delete mode 100644 src/main/java/edu/ntnu/idatt2003/exceptions/ChaosGameFileHandlerException.java create mode 100644 src/main/java/edu/ntnu/idatt2003/exceptions/CouldNotWriteException.java create mode 100644 src/main/java/edu/ntnu/idatt2003/exceptions/EmptyListException.java create mode 100644 src/main/java/edu/ntnu/idatt2003/exceptions/InvalidPositiveIntException.java create mode 100644 src/main/java/edu/ntnu/idatt2003/exceptions/InvalidSignException.java create mode 100644 src/main/java/edu/ntnu/idatt2003/exceptions/InvalidTypeException.java create mode 100644 src/main/java/edu/ntnu/idatt2003/exceptions/InvalidVectorRangeException.java create mode 100644 src/main/java/edu/ntnu/idatt2003/exceptions/IsNullException.java create mode 100644 src/main/java/edu/ntnu/idatt2003/exceptions/ObservingException.java create mode 100644 src/main/java/edu/ntnu/idatt2003/exceptions/WrongLengthException.java diff --git a/src/main/java/edu/ntnu/idatt2003/exceptions/ChaosCanvasException.java b/src/main/java/edu/ntnu/idatt2003/exceptions/ChaosCanvasException.java deleted file mode 100644 index 4e0cde2..0000000 --- a/src/main/java/edu/ntnu/idatt2003/exceptions/ChaosCanvasException.java +++ /dev/null @@ -1,32 +0,0 @@ -package edu.ntnu.idatt2003.exceptions; - -/** - * Exception class for ChaosCanvas. - */ -public class ChaosCanvasException extends Exception { - /** - * Constructs a new ChaosCanvasException with the default message. - */ - public ChaosCanvasException() { - super("Chaos canvas exception occurred."); - } - - /** - * Constructs a new ChaosCanvasException with the specified message and cause. - * - * @param message the message - * @param cause the cause - */ - public ChaosCanvasException(String message, Throwable cause) { - super(message, cause); - } - - /** - * Constructs a new ChaosCanvasException with the specified message. - * - * @param message the message - */ - public ChaosCanvasException(String message) { - super(message); - } -} diff --git a/src/main/java/edu/ntnu/idatt2003/exceptions/ChaosGameDescriptionException.java b/src/main/java/edu/ntnu/idatt2003/exceptions/ChaosGameDescriptionException.java deleted file mode 100644 index 679b88d..0000000 --- a/src/main/java/edu/ntnu/idatt2003/exceptions/ChaosGameDescriptionException.java +++ /dev/null @@ -1,32 +0,0 @@ -package edu.ntnu.idatt2003.exceptions; - -/** - * Exception class for ChaosGameDescription. - */ -public class ChaosGameDescriptionException extends Exception { - /** - * Constructs a new ChaosGameDescriptionException with the default message. - */ - public ChaosGameDescriptionException() { - super("An error occurred in the ChaosGameDescription class."); - } - - /** - * Constructs a new ChaosGameDescriptionException with the specified message. - * - * @param message the message - */ - public ChaosGameDescriptionException(String message) { - super(message); - } - - /** - * Constructs a new ChaosGameDescriptionException with the specified message and cause. - * - * @param message the message - * @param cause the cause - */ - public ChaosGameDescriptionException(String message, Throwable cause) { - super(message, cause); - } -} diff --git a/src/main/java/edu/ntnu/idatt2003/exceptions/ChaosGameDescriptionFactoryException.java b/src/main/java/edu/ntnu/idatt2003/exceptions/ChaosGameDescriptionFactoryException.java deleted file mode 100644 index 9d9acce..0000000 --- a/src/main/java/edu/ntnu/idatt2003/exceptions/ChaosGameDescriptionFactoryException.java +++ /dev/null @@ -1,32 +0,0 @@ -package edu.ntnu.idatt2003.exceptions; - -/** - * Exception class for ChaosGameDescriptionFactory. - */ -public class ChaosGameDescriptionFactoryException extends Exception { - /** - * Constructs a new ChaosGameDescriptionFactoryException with the default message. - */ - public ChaosGameDescriptionFactoryException() { - super("An error occurred while creating a ChaosGameDescription object."); - } - - /** - * Constructs a new ChaosGameDescriptionFactoryException with the specified message and cause. - * - * @param message the message - * @param cause the cause - */ - public ChaosGameDescriptionFactoryException(String message, Throwable cause) { - super(message, cause); - } - - /** - * Constructs a new ChaosGameDescriptionFactoryException with the specified message. - * - * @param message the message - */ - public ChaosGameDescriptionFactoryException(String message) { - super(message); - } -} diff --git a/src/main/java/edu/ntnu/idatt2003/exceptions/ChaosGameException.java b/src/main/java/edu/ntnu/idatt2003/exceptions/ChaosGameException.java deleted file mode 100644 index e31a7ea..0000000 --- a/src/main/java/edu/ntnu/idatt2003/exceptions/ChaosGameException.java +++ /dev/null @@ -1,32 +0,0 @@ -package edu.ntnu.idatt2003.exceptions; - -/** - * Exception class for ChaosGame. - */ -public class ChaosGameException extends Exception { - /** - * Constructs a new ChaosGameException with the default message. - */ - public ChaosGameException() { - super("Chaos game exception occurred."); - } - - /** - * Constructs a new ChaosGameException with the specified message and cause. - * - * @param message the message - * @param cause the cause - */ - public ChaosGameException(String message, Throwable cause) { - super(message, cause); - } - - /** - * Constructs a new ChaosGameException with the specified message. - * - * @param message the message - */ - public ChaosGameException(String message) { - super(message); - } -} diff --git a/src/main/java/edu/ntnu/idatt2003/exceptions/ChaosGameFileHandlerException.java b/src/main/java/edu/ntnu/idatt2003/exceptions/ChaosGameFileHandlerException.java deleted file mode 100644 index 1f6c62e..0000000 --- a/src/main/java/edu/ntnu/idatt2003/exceptions/ChaosGameFileHandlerException.java +++ /dev/null @@ -1,32 +0,0 @@ -package edu.ntnu.idatt2003.exceptions; - -/** - * Exception class for ChaosGameFileHandler. - */ -public class ChaosGameFileHandlerException extends Exception { - /** - * Constructs a new ChaosGameFileHandlerException with the default message. - */ - public ChaosGameFileHandlerException() { - super("An error occurred while handling the file"); - } - - /** - * Constructs a new ChaosGameFileHandlerException with the specified message and cause. - * - * @param message the message - * @param cause the cause - */ - public ChaosGameFileHandlerException(String message, Throwable cause) { - super(message, cause); - } - - /** - * Constructs a new ChaosGameFileHandlerException with the specified message. - * - * @param message the message - */ - public ChaosGameFileHandlerException(String message) { - super(message); - } -} diff --git a/src/main/java/edu/ntnu/idatt2003/exceptions/CouldNotWriteException.java b/src/main/java/edu/ntnu/idatt2003/exceptions/CouldNotWriteException.java new file mode 100644 index 0000000..6617c12 --- /dev/null +++ b/src/main/java/edu/ntnu/idatt2003/exceptions/CouldNotWriteException.java @@ -0,0 +1,32 @@ +package edu.ntnu.idatt2003.exceptions; + +/** + * Exception class for when a file could not be written to. + */ +public class CouldNotWriteException extends Exception { + /** + * Constructs a new CouldNotWriteException with the default message. + */ + public CouldNotWriteException() { + super("Could not write exception occurred."); + } + + /** + * Constructs a new CouldNotWriteException with the specified message and cause. + * + * @param message the message + * @param cause the cause + */ + public CouldNotWriteException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Constructs a new CouldNotWriteException with the specified message. + * + * @param message the message + */ + public CouldNotWriteException(String message) { + super(message); + } +} diff --git a/src/main/java/edu/ntnu/idatt2003/exceptions/EmptyListException.java b/src/main/java/edu/ntnu/idatt2003/exceptions/EmptyListException.java new file mode 100644 index 0000000..9e3e27b --- /dev/null +++ b/src/main/java/edu/ntnu/idatt2003/exceptions/EmptyListException.java @@ -0,0 +1,32 @@ +package edu.ntnu.idatt2003.exceptions; + +/** + * Exception class for empty lists. + */ +public class EmptyListException extends Exception { + /** + * Constructs a new EmptyListException with the default message. + */ + public EmptyListException() { + super("Empty list exception occurred."); + } + + /** + * Constructs a new EmptyListException with the specified message and cause. + * + * @param message the message + * @param cause the cause + */ + public EmptyListException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Constructs a new EmptyListException with the specified message. + * + * @param message the message + */ + public EmptyListException(String message) { + super(message); + } +} diff --git a/src/main/java/edu/ntnu/idatt2003/exceptions/InvalidPositiveIntException.java b/src/main/java/edu/ntnu/idatt2003/exceptions/InvalidPositiveIntException.java new file mode 100644 index 0000000..ecd5d1b --- /dev/null +++ b/src/main/java/edu/ntnu/idatt2003/exceptions/InvalidPositiveIntException.java @@ -0,0 +1,32 @@ +package edu.ntnu.idatt2003.exceptions; + +/** + * Exception class for invalid positive integers. + */ +public class InvalidPositiveIntException extends Exception { + /** + * Constructs a new InvalidPositiveIntException with the default message. + */ + public InvalidPositiveIntException() { + super("Invalid positive integer exception occurred."); + } + + /** + * Constructs a new InvalidPositiveIntException with the specified message and cause. + * + * @param message the message + * @param cause the cause + */ + public InvalidPositiveIntException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Constructs a new InvalidPositiveIntException with the specified message. + * + * @param message the message + */ + public InvalidPositiveIntException(String message) { + super(message); + } +} \ No newline at end of file diff --git a/src/main/java/edu/ntnu/idatt2003/exceptions/InvalidSignException.java b/src/main/java/edu/ntnu/idatt2003/exceptions/InvalidSignException.java new file mode 100644 index 0000000..8f1e11f --- /dev/null +++ b/src/main/java/edu/ntnu/idatt2003/exceptions/InvalidSignException.java @@ -0,0 +1,33 @@ +package edu.ntnu.idatt2003.exceptions; + +/** + * Exception class for invalid signs. + */ +public class InvalidSignException extends Exception { + + /** + * Constructs a new InvalidSignException with the default message. + */ + public InvalidSignException() { + super("Invalid sign exception occurred."); + } + + /** + * Constructs a new InvalidSignException with the specified message and cause. + * + * @param message the message + * @param cause the cause + */ + public InvalidSignException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Constructs a new InvalidSignException with the specified message. + * + * @param message the message + */ + public InvalidSignException(String message) { + super(message); + } +} diff --git a/src/main/java/edu/ntnu/idatt2003/exceptions/InvalidTypeException.java b/src/main/java/edu/ntnu/idatt2003/exceptions/InvalidTypeException.java new file mode 100644 index 0000000..37d2f80 --- /dev/null +++ b/src/main/java/edu/ntnu/idatt2003/exceptions/InvalidTypeException.java @@ -0,0 +1,32 @@ +package edu.ntnu.idatt2003.exceptions; + +/** + * Exception class for invalid types. + */ +public class InvalidTypeException extends Exception { + /** + * Constructs a new InvalidTypeException with the default message. + */ + public InvalidTypeException() { + super("Invalid type exception occurred."); + } + + /** + * Constructs a new InvalidTypeException with the specified message and cause. + * + * @param message the message + * @param cause the cause + */ + public InvalidTypeException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Constructs a new InvalidTypeException with the specified message. + * + * @param message the message + */ + public InvalidTypeException(String message) { + super(message); + } +} diff --git a/src/main/java/edu/ntnu/idatt2003/exceptions/InvalidVectorRangeException.java b/src/main/java/edu/ntnu/idatt2003/exceptions/InvalidVectorRangeException.java new file mode 100644 index 0000000..38d5b2f --- /dev/null +++ b/src/main/java/edu/ntnu/idatt2003/exceptions/InvalidVectorRangeException.java @@ -0,0 +1,33 @@ +package edu.ntnu.idatt2003.exceptions; + +/** + * Exception class for invalid vector ranges. + */ +public class InvalidVectorRangeException extends Exception { + + /** + * Constructs a new InvalidVectorRangeException with the default message. + */ + public InvalidVectorRangeException() { + super("Invalid vector range exception occurred."); + } + + /** + * Constructs a new InvalidVectorRangeException with the specified message and cause. + * + * @param message the message + * @param cause the cause + */ + public InvalidVectorRangeException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Constructs a new InvalidVectorRangeException with the specified message. + * + * @param message the message + */ + public InvalidVectorRangeException(String message) { + super(message); + } +} diff --git a/src/main/java/edu/ntnu/idatt2003/exceptions/IsNullException.java b/src/main/java/edu/ntnu/idatt2003/exceptions/IsNullException.java new file mode 100644 index 0000000..3e4483c --- /dev/null +++ b/src/main/java/edu/ntnu/idatt2003/exceptions/IsNullException.java @@ -0,0 +1,32 @@ +package edu.ntnu.idatt2003.exceptions; + +/** + * Exception class for objects that are null. + */ +public class IsNullException extends Exception { + /** + * Constructs a new NullException with the default message. + */ + public IsNullException() { + super("Null exception occurred."); + } + + /** + * Constructs a new NullException with the specified message and cause. + * + * @param message the message + * @param cause the cause + */ + public IsNullException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Constructs a new NullException with the specified message. + * + * @param message the message + */ + public IsNullException(String message) { + super(message); + } +} diff --git a/src/main/java/edu/ntnu/idatt2003/exceptions/ObservingException.java b/src/main/java/edu/ntnu/idatt2003/exceptions/ObservingException.java new file mode 100644 index 0000000..5139a67 --- /dev/null +++ b/src/main/java/edu/ntnu/idatt2003/exceptions/ObservingException.java @@ -0,0 +1,32 @@ +package edu.ntnu.idatt2003.exceptions; + +/** + * Exception class for exceptions caused by observing. + */ +public class ObservingException extends Exception { + /** + * Constructs a new ObservingException with the default message. + */ + public ObservingException() { + super("Observing exception occurred."); + } + + /** + * Constructs a new ObservingException with the specified message and cause. + * + * @param message the message + * @param cause the cause + */ + public ObservingException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Constructs a new ObservingException with the specified message. + * + * @param message the message + */ + public ObservingException(String message) { + super(message); + } +} diff --git a/src/main/java/edu/ntnu/idatt2003/exceptions/WrongLengthException.java b/src/main/java/edu/ntnu/idatt2003/exceptions/WrongLengthException.java new file mode 100644 index 0000000..5d3cd25 --- /dev/null +++ b/src/main/java/edu/ntnu/idatt2003/exceptions/WrongLengthException.java @@ -0,0 +1,32 @@ +package edu.ntnu.idatt2003.exceptions; + +/** + * Exception class for wrong length. + */ +public class WrongLengthException extends Exception { + /** + * Constructs a new WrongLengthException with the default message. + */ + public WrongLengthException() { + super("Wrong length exception occurred."); + } + + /** + * Constructs a new WrongLengthException with the specified message and cause. + * + * @param message the message + * @param cause the cause + */ + public WrongLengthException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Constructs a new WrongLengthException with the specified message. + * + * @param message the message + */ + public WrongLengthException(String message) { + super(message); + } +} -- GitLab From 28b1aa2bda75b1cc68f39ced980052750fd8ffab Mon Sep 17 00:00:00 2001 From: Vetle <vetletb@stud.ntnu.no> Date: Thu, 16 May 2024 13:15:58 +0200 Subject: [PATCH 2/3] Implemented new exceptions --- .../exceptions/WrongFileFormatException.java | 4 +- .../idatt2003/model/game/ChaosCanvas.java | 55 +++++---- .../ntnu/idatt2003/model/game/ChaosGame.java | 60 +++++----- .../model/game/ChaosGameDescription.java | 36 +++--- .../game/ChaosGameDescriptionFactory.java | 71 ++++++----- .../model/io/ChaosGameFileHandler.java | 112 +++++++++++------- .../math/transformation/JuliaTransform.java | 7 +- .../ntnu/idatt2003/util/InputValidation.java | 71 +++++++++-- .../idatt2003/model/game/ChaosCanvasTest.java | 27 +++-- .../game/ChaosGameDescriptionFactoryTest.java | 19 ++- .../model/game/ChaosGameDescriptionTest.java | 36 +++--- .../idatt2003/model/game/ChaosGameTest.java | 52 ++++---- .../model/io/ChaosGameFileHandlerTest.java | 24 ++-- .../transformation/JuliaTransformTest.java | 21 ++-- 14 files changed, 362 insertions(+), 233 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/exceptions/WrongFileFormatException.java b/src/main/java/edu/ntnu/idatt2003/exceptions/WrongFileFormatException.java index d558923..d934051 100644 --- a/src/main/java/edu/ntnu/idatt2003/exceptions/WrongFileFormatException.java +++ b/src/main/java/edu/ntnu/idatt2003/exceptions/WrongFileFormatException.java @@ -1,9 +1,9 @@ package edu.ntnu.idatt2003.exceptions; /** - * Exception class for ChaosGameFileHandler. + * Exception class for wrongly formatted files. */ -public class WrongFileFormatException extends ChaosGameFileHandlerException { +public class WrongFileFormatException extends Exception { /** * Constructs a new WrongFileFormatException with the default message. */ diff --git a/src/main/java/edu/ntnu/idatt2003/model/game/ChaosCanvas.java b/src/main/java/edu/ntnu/idatt2003/model/game/ChaosCanvas.java index 73c0ac5..0be394a 100644 --- a/src/main/java/edu/ntnu/idatt2003/model/game/ChaosCanvas.java +++ b/src/main/java/edu/ntnu/idatt2003/model/game/ChaosCanvas.java @@ -1,6 +1,8 @@ package edu.ntnu.idatt2003.model.game; -import edu.ntnu.idatt2003.exceptions.ChaosCanvasException; +import edu.ntnu.idatt2003.exceptions.InvalidPositiveIntException; +import edu.ntnu.idatt2003.exceptions.InvalidVectorRangeException; +import edu.ntnu.idatt2003.exceptions.IsNullException; import edu.ntnu.idatt2003.model.math.mathModel.Matrix2x2; import edu.ntnu.idatt2003.model.math.mathModel.Vector2D; import edu.ntnu.idatt2003.model.math.transformation.AffineTransform2D; @@ -28,20 +30,20 @@ public class ChaosCanvas { * @param minCoords the minimum coordinates of the canvas. * @param maxCoords the maximum coordinates of the canvas. * - * @throws IllegalArgumentException if width is not positive, - * if height is not positive, - * if minCoords is null, - * if maxCoords is null + * @throws InvalidPositiveIntException if width is not positive, + * if height is not positive, + * if minCoords is null, + * if maxCoords is null + * @throws IsNullException if minCoords or maxCoords are null, + * @throws InvalidVectorRangeException if the minimum coordinates are greater than or equal to the + * maximum coordinates. */ public ChaosCanvas(int width, int height, Vector2D minCoords, Vector2D maxCoords) - throws ChaosCanvasException { - try { - InputValidation.validatePositiveInt(width, "width"); - InputValidation.validatePositiveInt(height, "height"); - setMinMaxCoords(minCoords, maxCoords); - } catch (IllegalArgumentException e) { - throw new ChaosCanvasException("An error occurred while creating the ChaosCanvas class", e); - } + throws InvalidPositiveIntException, IsNullException, InvalidVectorRangeException { + InputValidation.validatePositiveInt(width, "width"); + InputValidation.validatePositiveInt(height, "height"); + + setMinMaxCoords(minCoords, maxCoords); this.width = width; this.height = height; this.canvas = new int[width][height]; @@ -69,8 +71,9 @@ public class ChaosCanvas { * Sets the minimum coordinates of the canvas. * * @param minCoords the minimum coordinates of the canvas. + * @throws IsNullException if minCoords is null */ - private void setMinCoords(Vector2D minCoords) { + private void setMinCoords(Vector2D minCoords) throws IsNullException { InputValidation.validateNotNull(minCoords, "minCoords"); this.minCoords = minCoords; } @@ -79,8 +82,9 @@ public class ChaosCanvas { * Sets the maximum coordinates of the canvas. * * @param maxCoords the maximum coordinates of the canvas. + * @throws IsNullException if maxCoords is null */ - private void setMaxCoords(Vector2D maxCoords) { + private void setMaxCoords(Vector2D maxCoords) throws IsNullException { InputValidation.validateNotNull(maxCoords, "maxCoords"); this.maxCoords = maxCoords; } @@ -91,18 +95,17 @@ public class ChaosCanvas { * @param minCoords the minimum coordinates of the canvas. * @param maxCoords the maximum coordinates of the canvas. * - * @throws IllegalArgumentException if minCoords is null, - * if maxCoords is null + * @throws IsNullException if minCoords is null, + * if maxCoords is null */ - public void setMinMaxCoords(Vector2D minCoords, Vector2D maxCoords) throws ChaosCanvasException { - try { - setMinCoords(minCoords); - setMaxCoords(maxCoords); - setTransformCoordsToIndices(); - } catch (IllegalArgumentException e) { - throw new ChaosCanvasException( - "An error occurred while setting the min and max coordinates", e); - } + public void setMinMaxCoords(Vector2D minCoords, Vector2D maxCoords) + throws IsNullException, InvalidVectorRangeException { + setMinCoords(minCoords); + setMaxCoords(maxCoords); + + InputValidation.validateVectorRange(minCoords, maxCoords); + + setTransformCoordsToIndices(); } /** diff --git a/src/main/java/edu/ntnu/idatt2003/model/game/ChaosGame.java b/src/main/java/edu/ntnu/idatt2003/model/game/ChaosGame.java index c101d84..07ae75f 100644 --- a/src/main/java/edu/ntnu/idatt2003/model/game/ChaosGame.java +++ b/src/main/java/edu/ntnu/idatt2003/model/game/ChaosGame.java @@ -1,7 +1,8 @@ package edu.ntnu.idatt2003.model.game; -import edu.ntnu.idatt2003.exceptions.ChaosCanvasException; -import edu.ntnu.idatt2003.exceptions.ChaosGameException; +import edu.ntnu.idatt2003.exceptions.InvalidPositiveIntException; +import edu.ntnu.idatt2003.exceptions.InvalidVectorRangeException; +import edu.ntnu.idatt2003.exceptions.IsNullException; import edu.ntnu.idatt2003.model.math.mathModel.Vector2D; import edu.ntnu.idatt2003.model.math.transformation.Transform2D; import edu.ntnu.idatt2003.util.InputValidation; @@ -23,18 +24,18 @@ public class ChaosGame extends Subject { * @param description the description of the chaos game. * @param width the width of the canvas. * @param height the height of the canvas. + * @throws IsNullException if the description is null. + * @throws InvalidPositiveIntException if the width or height are not positive. + * @throws InvalidVectorRangeException if the minimum coordinates are greater than or equal to the + * maximum coordinates. */ public ChaosGame(ChaosGameDescription description, int width, int height) - throws ChaosGameException { - try { - InputValidation.validateNotNull(description, "description"); - this.canvas = new ChaosCanvas( - width, height, description.getMinCoords(), description.getMaxCoords()); - } catch (IllegalArgumentException e) { - throw new ChaosGameException("The description of the chaos game cannot be null.", e); - } catch (ChaosCanvasException e) { - throw new ChaosGameException("An error occurred while creating the ChaosCanvas class.", e); - } + throws IsNullException, InvalidPositiveIntException, + InvalidVectorRangeException { + InputValidation.validateNotNull(description, "description"); + + this.canvas = new ChaosCanvas( + width, height, description.getMinCoords(), description.getMaxCoords()); this.description = description; this.currentPoint = new Vector2D(0, 0); this.random = new Random(); @@ -60,17 +61,17 @@ public class ChaosGame extends Subject { /** * Sets the description of the chaos game. + * + * @param description the description of the chaos game. + * @throws IsNullException if the description is null. + * @throws InvalidVectorRangeException if the minimum coordinates are greater than or equal to the + * maximum coordinates. */ - private void setDescription(ChaosGameDescription description) throws ChaosGameException { - try { - InputValidation.validateNotNull(description, "description"); - canvas.setMinMaxCoords(description.getMinCoords(), description.getMaxCoords()); - } catch (IllegalArgumentException e) { - throw new ChaosGameException("The description of the chaos game cannot be null.", e); - } catch (ChaosCanvasException e) { - throw new ChaosGameException( - "An error occurred while setting the description of the chaos game.", e); - } + private void setDescription(ChaosGameDescription description) + throws IsNullException, InvalidVectorRangeException { + InputValidation.validateNotNull(description, "description"); + + canvas.setMinMaxCoords(description.getMinCoords(), description.getMaxCoords()); this.description = description; notifyObservers("setDescription"); } @@ -88,8 +89,11 @@ public class ChaosGame extends Subject { * Resets the canvas and sets new description for the chaos game. * * @param description the description to reset the chaos game with. + * @throws IsNullException if the description is null. + * @throws InvalidVectorRangeException if the minimum coordinates are greater than or equal to the */ - public void resetGameWithDescription(ChaosGameDescription description) throws ChaosGameException { + public void resetGameWithDescription(ChaosGameDescription description) + throws IsNullException, InvalidVectorRangeException { setDescription(description); resetGame(); } @@ -98,13 +102,11 @@ public class ChaosGame extends Subject { * Runs the chaos game for the given number of steps. * * @param steps the number of steps to run the chaos game for. + * @throws InvalidPositiveIntException if the number of steps is not positive. */ - public void runSteps(int steps) throws ChaosGameException { - try { - InputValidation.validatePositiveInt(steps, "steps"); - } catch (IllegalArgumentException e) { - throw new ChaosGameException("The number of steps must be positive.", e); - } + public void runSteps(int steps) throws InvalidPositiveIntException { + InputValidation.validatePositiveInt(steps, "steps"); + List<Transform2D> transforms = description.getTransforms(); for (int i = 0; i < steps; i++) { Transform2D currentTransformation = transforms.get(random.nextInt(transforms.size())); diff --git a/src/main/java/edu/ntnu/idatt2003/model/game/ChaosGameDescription.java b/src/main/java/edu/ntnu/idatt2003/model/game/ChaosGameDescription.java index 8488aa7..fa61df3 100644 --- a/src/main/java/edu/ntnu/idatt2003/model/game/ChaosGameDescription.java +++ b/src/main/java/edu/ntnu/idatt2003/model/game/ChaosGameDescription.java @@ -1,6 +1,8 @@ package edu.ntnu.idatt2003.model.game; -import edu.ntnu.idatt2003.exceptions.ChaosGameDescriptionException; +import edu.ntnu.idatt2003.exceptions.EmptyListException; +import edu.ntnu.idatt2003.exceptions.InvalidVectorRangeException; +import edu.ntnu.idatt2003.exceptions.IsNullException; import edu.ntnu.idatt2003.model.math.mathModel.Vector2D; import edu.ntnu.idatt2003.model.math.transformation.Transform2D; import edu.ntnu.idatt2003.util.InputValidation; @@ -21,23 +23,19 @@ public class ChaosGameDescription { * @param minCoords the minimum coordinates. * @param maxCoords the maximum coordinates. * - * @throws ChaosGameDescriptionException if the list of transforms is null, - * if the list of transforms is empty, - * if minCoords is null, - * if maxCoords is null, - * if minCoords is greater than or equal to maxCoords + * @throws IsNullException if any of the parameters are null. + * @throws EmptyListException if the list of transforms is empty. + * @throws InvalidVectorRangeException if the minimum coordinates are greater than or equal to the + * maximum coordinates. */ public ChaosGameDescription(List<Transform2D> transforms, Vector2D minCoords, Vector2D maxCoords) - throws ChaosGameDescriptionException { - try { - InputValidation.validateNotNull(transforms, "transforms"); - InputValidation.validateListNotEmpty(transforms, "transforms"); - InputValidation.validateNotNull(minCoords, "minCoords"); - InputValidation.validateNotNull(maxCoords, "maxCoords"); - validateCoordinates(minCoords, maxCoords); - } catch (IllegalArgumentException e) { - throw new ChaosGameDescriptionException("Invalid ChaosGameDescription", e); - } + throws IsNullException, EmptyListException, InvalidVectorRangeException { + InputValidation.validateNotNull(transforms, "transforms"); + InputValidation.validateListNotEmpty(transforms, "transforms"); + InputValidation.validateNotNull(minCoords, "minCoords"); + InputValidation.validateNotNull(maxCoords, "maxCoords"); + InputValidation.validateVectorRange(minCoords, maxCoords); + this.transforms = transforms; this.minCoords = minCoords; this.maxCoords = maxCoords; @@ -76,12 +74,12 @@ public class ChaosGameDescription { * @param minCoords the minimum coordinates. * @param maxCoords the maximum coordinates. * - * @throws ChaosGameDescriptionException if minCoords is greater than or equal to maxCoords + * @throws InvalidVectorRangeException if minCoords is greater than or equal to maxCoords */ private void validateCoordinates(Vector2D minCoords, Vector2D maxCoords) - throws ChaosGameDescriptionException { + throws InvalidVectorRangeException { if (minCoords.getX0() >= maxCoords.getX0() || minCoords.getX1() >= maxCoords.getX1()) { - throw new ChaosGameDescriptionException("minCoords must be less than maxCoords"); + throw new InvalidVectorRangeException("minCoords must be less than maxCoords"); } } diff --git a/src/main/java/edu/ntnu/idatt2003/model/game/ChaosGameDescriptionFactory.java b/src/main/java/edu/ntnu/idatt2003/model/game/ChaosGameDescriptionFactory.java index 04ad1d0..f060b1a 100644 --- a/src/main/java/edu/ntnu/idatt2003/model/game/ChaosGameDescriptionFactory.java +++ b/src/main/java/edu/ntnu/idatt2003/model/game/ChaosGameDescriptionFactory.java @@ -1,7 +1,10 @@ package edu.ntnu.idatt2003.model.game; -import edu.ntnu.idatt2003.exceptions.ChaosGameDescriptionException; -import edu.ntnu.idatt2003.exceptions.ChaosGameDescriptionFactoryException; +import edu.ntnu.idatt2003.exceptions.EmptyListException; +import edu.ntnu.idatt2003.exceptions.InvalidSignException; +import edu.ntnu.idatt2003.exceptions.InvalidTypeException; +import edu.ntnu.idatt2003.exceptions.InvalidVectorRangeException; +import edu.ntnu.idatt2003.exceptions.IsNullException; import edu.ntnu.idatt2003.model.math.mathModel.Complex; import edu.ntnu.idatt2003.model.math.mathModel.Matrix2x2; import edu.ntnu.idatt2003.model.math.mathModel.Vector2D; @@ -21,14 +24,21 @@ public class ChaosGameDescriptionFactory { * * @param type the type of chaos game to create. * @return a ChaosGameDescription object. - * @throws ChaosGameDescriptionFactoryException if the type is invalid. + * @throws InvalidTypeException if the transformation type is invalid. + * @throws EmptyListException if the list of transforms is empty. + * @throws InvalidVectorRangeException if the minimum coordinates are greater than or equal to the + * maximum coordinates. + * @throws IsNullException if any of the parameters are null. + * @throws InvalidSignException if the sign of the vector is invalid. */ - public static ChaosGameDescription get(String type) throws ChaosGameDescriptionFactoryException { + public static ChaosGameDescription get(String type) + throws EmptyListException, InvalidVectorRangeException, + InvalidSignException, IsNullException, InvalidTypeException { return switch (type) { case "Sierpinski" -> createSierpinskiTriangle(); case "Barnsley" -> createBarnsleyFern(); case "Julia Set" -> createJuliaSet(); - default -> throw new ChaosGameDescriptionFactoryException("Invalid chaos game type"); + default -> throw new InvalidTypeException("Invalid description type"); }; } @@ -36,31 +46,37 @@ public class ChaosGameDescriptionFactory { * Helper method for creating a chaos game description of the Julia set. * * @return a list of the available chaos game types. - * @throws ChaosGameDescriptionFactoryException if an error occurs while creating the chaos game + * @throws EmptyListException if the list of transforms is empty. + * @throws InvalidVectorRangeException if the minimum coordinates are greater than or equal to the + * maximum coordinates. + * @throws IsNullException if any of the parameters are null. + * @throws InvalidSignException if the sign of the vector is invalid. */ - private static ChaosGameDescription createJuliaSet() throws ChaosGameDescriptionFactoryException { + private static ChaosGameDescription createJuliaSet() + throws EmptyListException, InvalidVectorRangeException, InvalidSignException, + IsNullException { List<Transform2D> transforms = List.of( new JuliaTransform(new Complex(0, 0.8), 1), new JuliaTransform(new Complex(0, 0.8), -1) ); Vector2D minCoords = new Vector2D(-1.4, -1.4); Vector2D maxCoords = new Vector2D(1.4, 1.4); - try { - return new ChaosGameDescription(transforms, minCoords, maxCoords); - } catch (ChaosGameDescriptionException e) { - throw new ChaosGameDescriptionFactoryException( - "An error occurred while creating a ChaosGameDescription object in factory.", e); - } + + return new ChaosGameDescription(transforms, minCoords, maxCoords); } /** * Helper method for creating a chaos game description of the Barnsley fern. * * @return a list of the available chaos game types. - * @throws ChaosGameDescriptionFactoryException if an error occurs while creating the chaos game + * @throws IsNullException if any of the parameters are null. + * @throws EmptyListException if the list of transforms is empty. + * @throws InvalidVectorRangeException if the minimum coordinates are greater than or equal to the + * maximum coordinates. */ private static ChaosGameDescription createBarnsleyFern() - throws ChaosGameDescriptionFactoryException { + throws IsNullException, EmptyListException, + InvalidVectorRangeException { List<Transform2D> transforms = List.of( new AffineTransform2D(new Matrix2x2(0, 0, 0, 0.16), new Vector2D(0, 0)), new AffineTransform2D(new Matrix2x2(0.85, 0.04, -0.04, 0.85), new Vector2D(0, 1.6)), @@ -69,22 +85,22 @@ public class ChaosGameDescriptionFactory { ); Vector2D minCoords = new Vector2D(-2.65, 0); Vector2D maxCoords = new Vector2D(2.65, 10); - try { - return new ChaosGameDescription(transforms, minCoords, maxCoords); - } catch (ChaosGameDescriptionException e) { - throw new ChaosGameDescriptionFactoryException( - "An error occurred while creating a ChaosGameDescription object in factory.", e); - } + + return new ChaosGameDescription(transforms, minCoords, maxCoords); } /** * Helper method for creating a chaos game description of the Sierpinski triangle. * * @return a list of the available chaos game types. - * @throws ChaosGameDescriptionFactoryException if an error occurs while creating the chaos game + * @throws IsNullException if any of the parameters are null. + * @throws EmptyListException if the list of transforms is empty. + * @throws InvalidVectorRangeException if the minimum coordinates are greater than or equal to the + * maximum coordinates. */ private static ChaosGameDescription createSierpinskiTriangle() - throws ChaosGameDescriptionFactoryException { + throws IsNullException, EmptyListException, + InvalidVectorRangeException { List<Transform2D> transforms = List.of( new AffineTransform2D(new Matrix2x2(0.5, 0, 0, 0.5), new Vector2D(0, 0)), new AffineTransform2D(new Matrix2x2(0.5, 0, 0, 0.5), new Vector2D(0.5, 0)), @@ -92,11 +108,8 @@ public class ChaosGameDescriptionFactory { ); Vector2D minCoords = new Vector2D(0, 0); Vector2D maxCoords = new Vector2D(1, 1); - try { - return new ChaosGameDescription(transforms, minCoords, maxCoords); - } catch (ChaosGameDescriptionException e) { - throw new ChaosGameDescriptionFactoryException( - "An error occurred while creating a ChaosGameDescription object in factory.", e); - } + + return new ChaosGameDescription(transforms, minCoords, maxCoords); + } } diff --git a/src/main/java/edu/ntnu/idatt2003/model/io/ChaosGameFileHandler.java b/src/main/java/edu/ntnu/idatt2003/model/io/ChaosGameFileHandler.java index 5f64769..6490c29 100644 --- a/src/main/java/edu/ntnu/idatt2003/model/io/ChaosGameFileHandler.java +++ b/src/main/java/edu/ntnu/idatt2003/model/io/ChaosGameFileHandler.java @@ -1,8 +1,12 @@ package edu.ntnu.idatt2003.model.io; -import edu.ntnu.idatt2003.exceptions.ChaosGameDescriptionException; -import edu.ntnu.idatt2003.exceptions.ChaosGameFileHandlerException; +import edu.ntnu.idatt2003.exceptions.CouldNotWriteException; +import edu.ntnu.idatt2003.exceptions.EmptyListException; +import edu.ntnu.idatt2003.exceptions.InvalidSignException; +import edu.ntnu.idatt2003.exceptions.InvalidVectorRangeException; +import edu.ntnu.idatt2003.exceptions.IsNullException; import edu.ntnu.idatt2003.exceptions.WrongFileFormatException; +import edu.ntnu.idatt2003.exceptions.WrongLengthException; import edu.ntnu.idatt2003.model.game.ChaosGameDescription; import edu.ntnu.idatt2003.model.math.mathModel.Complex; import edu.ntnu.idatt2003.model.math.mathModel.Matrix2x2; @@ -34,24 +38,31 @@ public class ChaosGameFileHandler { * * @param file the file to be read. * @return the ChaosGameDescription read from the file. - * @throws ChaosGameFileHandlerException if the file is not found. - * @throws ChaosGameDescriptionException if the ChaosGameDescription could not be created. + * @throws FileNotFoundException if the file is not found. + * @throws WrongFileFormatException if the ChaosGameDescription could not be created. + * @throws IsNullException if an object is null. + * @throws EmptyListException if a list is empty. + * @throws InvalidVectorRangeException if the vector range is invalid. + * @throws InvalidSignException if the sign is invalid. */ public ChaosGameDescription readFromFile(File file) - throws ChaosGameFileHandlerException { + throws WrongFileFormatException, IsNullException, EmptyListException, + InvalidVectorRangeException, InvalidSignException, FileNotFoundException { List<List<String>> lines = divideFileToLines(file); - if (lines.size() <= 3) { - throw new WrongFileFormatException(); + + try { + InputValidation.validateListLessOrEqualThan(lines, 3, "lines"); + } catch (WrongLengthException e) { + throw new WrongFileFormatException("The file should have at least three lines", e); } + List<String> type = lines.getFirst(); try { InputValidation.validateNotNull(type, "type"); - } catch (IllegalArgumentException e) { + InputValidation.validateListLength(type, 1, "type"); + } catch (IsNullException | WrongLengthException e) { throw new WrongFileFormatException("The file should have one transformation type", e); } - if (type.size() != 1) { - throw new WrongFileFormatException("The file should have one transformation type"); - } if (!type.getFirst().equals("Affine2D") && !type.getFirst().equals("Julia")) { throw new WrongFileFormatException("The file has an unsupported transformation type"); } @@ -61,12 +72,11 @@ public class ChaosGameFileHandler { try { InputValidation.validateNotNull(minCoords, "minCoords"); InputValidation.validateNotNull(maxCoords, "maxCoords"); - } catch (IllegalArgumentException e) { + InputValidation.validateListLength(minCoords, 2, "minCoords"); + InputValidation.validateListLength(maxCoords, 2, "maxCoords"); + } catch (IllegalArgumentException | WrongLengthException e) { throw new WrongFileFormatException("The file should have two min/max coordinates each", e); } - if (minCoords.size() != 2 || maxCoords.size() != 2) { - throw new WrongFileFormatException("The file should have two min/max coordinates each"); - } double minX; double minY; @@ -79,10 +89,7 @@ public class ChaosGameFileHandler { maxY = Double.parseDouble(maxCoords.get(1)); } catch (NumberFormatException e) { throw new WrongFileFormatException("The min/max coordinates in the file are not numbers", e); - } catch (IndexOutOfBoundsException e) { - throw new WrongFileFormatException("The file is missing min/max coordinates", e); } - if (minX >= maxX || minY >= maxY) { throw new WrongFileFormatException( "The min coordinates should be less than the max coordinates"); @@ -91,12 +98,9 @@ public class ChaosGameFileHandler { List<Transform2D> transforms = (type.getFirst().equals("Affine2D")) ? packageToAffineList(lines) : packageToJuliaList(lines); - try { - return new ChaosGameDescription(transforms, new Vector2D(minX, minY), - new Vector2D(maxX, maxY)); - } catch (ChaosGameDescriptionException e) { - throw new ChaosGameFileHandlerException("Could not create ChaosGameDescription", e); - } + + return new ChaosGameDescription(transforms, new Vector2D(minX, minY), + new Vector2D(maxX, maxY)); } /** @@ -104,10 +108,10 @@ public class ChaosGameFileHandler { * * @param file the file to divide. * @return a list of lines in the file. - * @throws ChaosGameFileHandlerException if the file is not found. + * @throws FileNotFoundException if the file is not found. */ private List<List<String>> divideFileToLines(File file) - throws ChaosGameFileHandlerException { + throws FileNotFoundException { List<List<String>> lines = new ArrayList<>(); try (Scanner scanner = new Scanner(file)) { scanner.useDelimiter("#.*|\n"); @@ -126,7 +130,7 @@ public class ChaosGameFileHandler { i++; } } catch (FileNotFoundException e) { - throw new ChaosGameFileHandlerException("File not found", e); + throw new FileNotFoundException("File not found"); } return lines; } @@ -141,9 +145,11 @@ public class ChaosGameFileHandler { private List<Transform2D> packageToAffineList(List<List<String>> lines) throws WrongFileFormatException { for (int i = 3; i < lines.size(); i++) { - if (lines.get(i).size() != 6) { + try { + InputValidation.validateListLength(lines.get(i), 6, "transformation"); + } catch (WrongLengthException e) { throw new WrongFileFormatException( - "The file should have six values for each transformation"); + "The file should have six values for each transformation", e); } for (String value : lines.get(i)) { try { @@ -178,22 +184,28 @@ public class ChaosGameFileHandler { * @param lines the lines of the file. * @return a list of JuliaTransform. * @throws WrongFileFormatException if the file is not formatted correctly. + * @throws InvalidSignException if the sign is invalid. */ private List<Transform2D> packageToJuliaList(List<List<String>> lines) - throws WrongFileFormatException { + throws WrongFileFormatException, InvalidSignException { - if (lines.size() != 4) { - throw new WrongFileFormatException("The file should have one Julia transformation"); + try { + InputValidation.validateListLength(lines, 4, "Julia transformation"); + } catch (WrongLengthException e) { + throw new WrongFileFormatException("The file should have one Julia transformation", e); } + List<String> julia = lines.get(3); try { InputValidation.validateNotNull(julia, "Julia transformation"); - } catch (IllegalArgumentException e) { + } catch (IsNullException e) { throw new WrongFileFormatException("The file should have one Julia transformation", e); } - if (julia.size() != 2) { - throw new WrongFileFormatException("The Julia transformation should have two values"); + try { + InputValidation.validateListLength(julia, 2, "Julia transformation"); + } catch (WrongLengthException e) { + throw new WrongFileFormatException("The Julia transformation should have two values", e); } double real; @@ -219,10 +231,10 @@ public class ChaosGameFileHandler { * * @param chaosGameDescription the ChaosGameDescription to write. * @param path the path to the file. - * @throws ChaosGameFileHandlerException if the file could not be written to. + * @throws CouldNotWriteException if the file could not be written to. */ public void writeToFile(ChaosGameDescription chaosGameDescription, File path) - throws ChaosGameFileHandlerException { + throws CouldNotWriteException { try (BufferedWriter writer = new BufferedWriter(new FileWriter(path))) { String type = chaosGameDescription.getTransforms().getFirst() instanceof AffineTransform2D ? "Affine2D" : "Julia"; @@ -246,7 +258,7 @@ public class ChaosGameFileHandler { writeJuliaToFile(writer, juliaTransform); } } catch (IOException e) { - throw new ChaosGameFileHandlerException("Could not write to file", e); + throw new CouldNotWriteException("Could not write to file", e); } } @@ -255,10 +267,10 @@ public class ChaosGameFileHandler { * * @param writer the writer to write to. * @param affineTransform the AffineTransform2D to write. - * @throws IOException if the AffineTransform2D could not be written to the file. + * @throws CouldNotWriteException if the AffineTransform2D could not be written to the file. */ private void writeAffineToFile(BufferedWriter writer, AffineTransform2D affineTransform) - throws IOException { + throws CouldNotWriteException { Matrix2x2 matrix = affineTransform.getMatrix(); double a00 = matrix.getA00(); double a01 = matrix.getA01(); @@ -269,7 +281,11 @@ public class ChaosGameFileHandler { double x0 = vector.getX0(); double x1 = vector.getX1(); - writer.write(a00 + ", " + a01 + ", " + a10 + ", " + a11 + ", " + x0 + ", " + x1 + "\n"); + try { + writer.write(a00 + ", " + a01 + ", " + a10 + ", " + a11 + ", " + x0 + ", " + x1 + "\n"); + } catch (IOException e) { + throw new CouldNotWriteException("Could not write to file", e); + } } /** @@ -277,24 +293,28 @@ public class ChaosGameFileHandler { * * @param writer the writer to write to. * @param juliaTransform the JuliaTransform to write. - * @throws IOException if the JuliaTransform could not be written to the file. + * @throws CouldNotWriteException if the JuliaTransform could not be written to the file. */ private void writeJuliaToFile(BufferedWriter writer, JuliaTransform juliaTransform) - throws IOException { + throws CouldNotWriteException { Complex complex = juliaTransform.getPoint(); double real = complex.getX0(); double imaginary = complex.getX1(); + try { writer.write(real + ", " + imaginary + "\n"); + } catch (IOException e) { + throw new CouldNotWriteException("Could not write to file", e); + } } /** * Lists all files in the resources directory. * * @return a list of all files in the resources directory. - * @throws ChaosGameFileHandlerException if the files could not be listed. + * @throws IOException if the files could not be listed. */ - public List<String> listFiles() throws ChaosGameFileHandlerException { + public List<String> listFiles() throws IOException { List<String> fileList = new ArrayList<>(); try { Path resourceDirectory = Paths.get("src/main/resources"); @@ -304,7 +324,7 @@ public class ChaosGameFileHandler { .forEach(path -> fileList.add(path.toString())); } } catch (IOException e) { - throw new ChaosGameFileHandlerException("Could not list files", e); + throw new IOException("Could not list files"); } return fileList; } diff --git a/src/main/java/edu/ntnu/idatt2003/model/math/transformation/JuliaTransform.java b/src/main/java/edu/ntnu/idatt2003/model/math/transformation/JuliaTransform.java index 4f29c6c..529de0f 100644 --- a/src/main/java/edu/ntnu/idatt2003/model/math/transformation/JuliaTransform.java +++ b/src/main/java/edu/ntnu/idatt2003/model/math/transformation/JuliaTransform.java @@ -1,5 +1,6 @@ package edu.ntnu.idatt2003.model.math.transformation; +import edu.ntnu.idatt2003.exceptions.InvalidSignException; import edu.ntnu.idatt2003.model.math.mathModel.Complex; import edu.ntnu.idatt2003.model.math.mathModel.Vector2D; @@ -17,12 +18,12 @@ public class JuliaTransform implements Transform2D { * @param point the point to transform around. * @param sign the sign of the transformation. * - * @throws IllegalArgumentException if sign is not 1 or -1. + * @throws InvalidSignException if sign is not 1 or -1. */ - public JuliaTransform(Complex point, int sign) { + public JuliaTransform(Complex point, int sign) throws InvalidSignException { this.point = point; if (sign != 1 && sign != -1) { - throw new IllegalArgumentException("Sign must be 1 or -1"); + throw new InvalidSignException("Sign must be 1 or -1"); } this.sign = sign; } diff --git a/src/main/java/edu/ntnu/idatt2003/util/InputValidation.java b/src/main/java/edu/ntnu/idatt2003/util/InputValidation.java index 0505244..433b20e 100644 --- a/src/main/java/edu/ntnu/idatt2003/util/InputValidation.java +++ b/src/main/java/edu/ntnu/idatt2003/util/InputValidation.java @@ -1,5 +1,11 @@ package edu.ntnu.idatt2003.util; +import edu.ntnu.idatt2003.exceptions.EmptyListException; +import edu.ntnu.idatt2003.exceptions.InvalidPositiveIntException; +import edu.ntnu.idatt2003.exceptions.InvalidVectorRangeException; +import edu.ntnu.idatt2003.exceptions.IsNullException; +import edu.ntnu.idatt2003.exceptions.WrongLengthException; +import edu.ntnu.idatt2003.model.math.mathModel.Vector2D; import java.util.List; /** @@ -13,12 +19,12 @@ public class InputValidation { * * @param object to be validated * @param parameterName the name of the object - * @throws IllegalArgumentException if the object is null + * @throws IsNullException if the object is null */ public static void validateNotNull(Object object, String parameterName) - throws IllegalArgumentException { + throws IsNullException { if (object == null) { - throw new IllegalArgumentException("Object: " + parameterName + " cannot be null"); + throw new IsNullException("Object: " + parameterName + " cannot be null"); } } @@ -27,12 +33,12 @@ public class InputValidation { * * @param number to be validated * @param parameterName the name of the int - * @throws IllegalArgumentException if the int is not positive + * @throws InvalidPositiveIntException if the int is not positive */ public static void validatePositiveInt(int number, String parameterName) - throws IllegalArgumentException { + throws InvalidPositiveIntException { if (number <= 0) { - throw new IllegalArgumentException("Number: " + parameterName + " must be positive"); + throw new InvalidPositiveIntException("Number: " + parameterName + " must be positive"); } } @@ -41,12 +47,59 @@ public class InputValidation { * * @param list to be validated * @param parameterName the name of the list - * @throws IllegalArgumentException if the list is empty + * @throws EmptyListException if the list is empty */ public static <T> void validateListNotEmpty(List<T> list, String parameterName) - throws IllegalArgumentException { + throws EmptyListException { if (list.isEmpty()) { - throw new IllegalArgumentException("List: " + parameterName + " must not be empty"); + throw new EmptyListException("List: " + parameterName + " must not be empty"); + } + } + + /** + * Validates that a list is less or equal to a given size. + * + * @param list to be validated + * @param size the maximum size of the list + * @param parameterName the name of the list + * @throws WrongLengthException if the list is bigger than the given size + */ + public static void validateListLessOrEqualThan(List<?> list, int size, String parameterName) + throws WrongLengthException { + if (list.size() <= size) { + throw new WrongLengthException("List: " + parameterName + + " must have at least " + size + " elements"); + } + } + + /** + * Validates that a list is exactly a given size. + * + * @param list to be validated + * @param size the size of the list + * @param parameterName the name of the list + * @throws WrongLengthException if the list is not the given size + */ + public static void validateListLength(List<?> list, int size, String parameterName) + throws WrongLengthException { + if (list.size() != size) { + throw new WrongLengthException("List: " + parameterName + + " must have exactly " + size + " elements"); + } + } + + /** + * Validates that the minimum coordinates are less than the maximum coordinates. + * + * @param minCoords the minimum coordinates + * @param maxCoords the maximum coordinates + * @throws InvalidVectorRangeException if the minimum coordinates are greater than or equal to the + * maximum coordinates + */ + public static void validateVectorRange(Vector2D minCoords, Vector2D maxCoords) + throws InvalidVectorRangeException { + if (minCoords.getX0() >= maxCoords.getX0() || minCoords.getX1() >= maxCoords.getX1()) { + throw new InvalidVectorRangeException("Minimum coordinates must be less than maximum coordinates"); } } } diff --git a/src/test/java/edu/ntnu/idatt2003/model/game/ChaosCanvasTest.java b/src/test/java/edu/ntnu/idatt2003/model/game/ChaosCanvasTest.java index a38ec50..e6ab5eb 100644 --- a/src/test/java/edu/ntnu/idatt2003/model/game/ChaosCanvasTest.java +++ b/src/test/java/edu/ntnu/idatt2003/model/game/ChaosCanvasTest.java @@ -2,7 +2,9 @@ package edu.ntnu.idatt2003.model.game; import static org.junit.jupiter.api.Assertions.*; -import edu.ntnu.idatt2003.exceptions.ChaosCanvasException; +import edu.ntnu.idatt2003.exceptions.InvalidPositiveIntException; +import edu.ntnu.idatt2003.exceptions.InvalidVectorRangeException; +import edu.ntnu.idatt2003.exceptions.IsNullException; import edu.ntnu.idatt2003.model.math.mathModel.Vector2D; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; @@ -20,7 +22,8 @@ class ChaosCanvasTest { ChaosCanvas canvas; @BeforeEach - public void setUp() throws ChaosCanvasException { + public void setUp() throws InvalidPositiveIntException, IsNullException, + InvalidVectorRangeException { canvas = new ChaosCanvas(100, 100, new Vector2D(0, 0), new Vector2D(200, 200)); } @@ -102,14 +105,18 @@ class ChaosCanvasTest { public class PositiveTestsForEquals { @Test @DisplayName("Equals returns true when two canvases are equal") - void equalsReturnsTrueWhenTwoCanvasesAreEqual() throws ChaosCanvasException { + void equalsReturnsTrueWhenTwoCanvasesAreEqual() + throws InvalidPositiveIntException, IsNullException, + InvalidVectorRangeException { ChaosCanvas canvas2 = new ChaosCanvas(100, 100, new Vector2D(0, 0), new Vector2D(200, 200)); assertEquals(canvas, canvas2); } @Test @DisplayName("Equals returns false when two canvases are not equal") - void equalsReturnsFalseWhenTwoCanvasesAreNotEqual() throws ChaosCanvasException { + void equalsReturnsFalseWhenTwoCanvasesAreNotEqual() + throws InvalidPositiveIntException, IsNullException, + InvalidVectorRangeException { ChaosCanvas canvas2 = new ChaosCanvas(120, 120, new Vector2D(1, 1), new Vector2D(100, 100)); assertNotEquals(canvas, canvas2); } @@ -134,10 +141,12 @@ class ChaosCanvasTest { @Test @DisplayName("Negative tests for setMinMaxCoords") - public void setMinMaxCoordsThrowsExceptionOnNull() throws ChaosCanvasException { + public void setMinMaxCoordsThrowsExceptionOnNull() + throws InvalidPositiveIntException, IsNullException, + InvalidVectorRangeException { ChaosCanvas canvas = new ChaosCanvas(100, 100, new Vector2D(0, 0), new Vector2D(200, 200)); - assertThrows(ChaosCanvasException.class, () -> canvas.setMinMaxCoords(null, new Vector2D(200, 200))); - assertThrows(ChaosCanvasException.class, () -> canvas.setMinMaxCoords(new Vector2D(0, 0), null)); + assertThrows(IsNullException.class, () -> canvas.setMinMaxCoords(null, new Vector2D(200, 200))); + assertThrows(IsNullException.class, () -> canvas.setMinMaxCoords(new Vector2D(0, 0), null)); } @Nested @@ -147,13 +156,13 @@ class ChaosCanvasTest { @Test @DisplayName("Constructor throws exception on negative width") public void constructorThrowsExceptionOnNegativeWidth() { - assertThrows(ChaosCanvasException.class, () -> new ChaosCanvas(-100, 100, new Vector2D(0, 0), new Vector2D(200, 200))); + assertThrows(InvalidPositiveIntException.class, () -> new ChaosCanvas(-100, 100, new Vector2D(0, 0), new Vector2D(200, 200))); } @Test @DisplayName("Constructor throws exception on negative height") public void constructorThrowsExceptionOnNegativeHeight() { - assertThrows(ChaosCanvasException.class, () -> new ChaosCanvas(100, -100, new Vector2D(0, 0), new Vector2D(200, 200))); + assertThrows(InvalidPositiveIntException.class, () -> new ChaosCanvas(100, -100, new Vector2D(0, 0), new Vector2D(200, 200))); } } } diff --git a/src/test/java/edu/ntnu/idatt2003/model/game/ChaosGameDescriptionFactoryTest.java b/src/test/java/edu/ntnu/idatt2003/model/game/ChaosGameDescriptionFactoryTest.java index cfb14bc..281b3f5 100644 --- a/src/test/java/edu/ntnu/idatt2003/model/game/ChaosGameDescriptionFactoryTest.java +++ b/src/test/java/edu/ntnu/idatt2003/model/game/ChaosGameDescriptionFactoryTest.java @@ -2,7 +2,11 @@ package edu.ntnu.idatt2003.model.game; import static org.junit.jupiter.api.Assertions.*; -import edu.ntnu.idatt2003.exceptions.ChaosGameDescriptionFactoryException; +import edu.ntnu.idatt2003.exceptions.EmptyListException; +import edu.ntnu.idatt2003.exceptions.InvalidSignException; +import edu.ntnu.idatt2003.exceptions.InvalidTypeException; +import edu.ntnu.idatt2003.exceptions.InvalidVectorRangeException; +import edu.ntnu.idatt2003.exceptions.IsNullException; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -18,7 +22,8 @@ class ChaosGameDescriptionFactoryTest { @Test @DisplayName("get Sierpinski returns a ChaosGameDescription object") public void getSierpinskiReturnsCorrectDescription() - throws ChaosGameDescriptionFactoryException { + throws InvalidSignException, IsNullException, + EmptyListException, InvalidVectorRangeException, InvalidTypeException { ChaosGameDescription chaosGameDescription = ChaosGameDescriptionFactory.get("Sierpinski"); assertNotNull(chaosGameDescription); } @@ -26,7 +31,8 @@ class ChaosGameDescriptionFactoryTest { @Test @DisplayName("get Barnsley returns a ChaosGameDescription object") public void getBarnsleyReturnsCorrectDescription() - throws ChaosGameDescriptionFactoryException { + throws InvalidSignException, IsNullException, + EmptyListException, InvalidVectorRangeException, InvalidTypeException { ChaosGameDescription chaosGameDescription = ChaosGameDescriptionFactory.get("Barnsley"); assertNotNull(chaosGameDescription); } @@ -34,7 +40,8 @@ class ChaosGameDescriptionFactoryTest { @Test @DisplayName("get Julia Set returns a ChaosGameDescription object") public void getJuliaSetReturnsCorrectDescription() - throws ChaosGameDescriptionFactoryException { + throws InvalidSignException, IsNullException, + EmptyListException, InvalidVectorRangeException, InvalidTypeException { ChaosGameDescription chaosGameDescription = ChaosGameDescriptionFactory.get("Julia Set"); assertNotNull(chaosGameDescription); } @@ -44,9 +51,9 @@ class ChaosGameDescriptionFactoryTest { @DisplayName("Negative tests") class MethodsThrowsException { @Test - @DisplayName("get with invalid type throws ChaosGameDescriptionFactoryException") + @DisplayName("get with invalid type throws InvalidTypeException") public void getWithInvalidTypeThrowsException() { - assertThrows(ChaosGameDescriptionFactoryException.class, () -> ChaosGameDescriptionFactory.get("Invalid")); + assertThrows(InvalidTypeException.class, () -> ChaosGameDescriptionFactory.get("Invalid")); } } } \ No newline at end of file diff --git a/src/test/java/edu/ntnu/idatt2003/model/game/ChaosGameDescriptionTest.java b/src/test/java/edu/ntnu/idatt2003/model/game/ChaosGameDescriptionTest.java index 55f5782..1ead946 100644 --- a/src/test/java/edu/ntnu/idatt2003/model/game/ChaosGameDescriptionTest.java +++ b/src/test/java/edu/ntnu/idatt2003/model/game/ChaosGameDescriptionTest.java @@ -1,6 +1,9 @@ package edu.ntnu.idatt2003.model.game; -import edu.ntnu.idatt2003.exceptions.ChaosGameDescriptionException; +import edu.ntnu.idatt2003.exceptions.EmptyListException; +import edu.ntnu.idatt2003.exceptions.InvalidSignException; +import edu.ntnu.idatt2003.exceptions.InvalidVectorRangeException; +import edu.ntnu.idatt2003.exceptions.IsNullException; import edu.ntnu.idatt2003.model.math.mathModel.Complex; import edu.ntnu.idatt2003.model.math.mathModel.Vector2D; import edu.ntnu.idatt2003.model.math.transformation.JuliaTransform; @@ -26,7 +29,8 @@ class ChaosGameDescriptionTest { Vector2D maxCoords; @BeforeEach - public void setUp() throws ChaosGameDescriptionException { + public void setUp() throws InvalidSignException, IsNullException, EmptyListException, + InvalidVectorRangeException { transforms = List.of( new JuliaTransform(new Complex(-0.74543, 0.11301), 1), new JuliaTransform(new Complex(-0.74543, 0.11301), -1) @@ -59,14 +63,18 @@ class ChaosGameDescriptionTest { public class PositiveTestsForEquals { @Test @DisplayName("Equals returns true when two descriptions are equal") - void equalsReturnsTrueWhenTwoDescriptionsAreEqual() throws ChaosGameDescriptionException { + void equalsReturnsTrueWhenTwoDescriptionsAreEqual() + throws IsNullException, EmptyListException, + InvalidVectorRangeException { ChaosGameDescription description2 = new ChaosGameDescription(transforms, minCoords, maxCoords); assertEquals(description, description2); } @Test @DisplayName("Equals returns false when two descriptions are not equal") - void equalsReturnsFalseWhenTwoDescriptionsAreNotEqual() throws ChaosGameDescriptionException { + void equalsReturnsFalseWhenTwoDescriptionsAreNotEqual() + throws InvalidSignException, IsNullException, EmptyListException, + InvalidVectorRangeException { List<Transform2D> transforms2 = List.of( new JuliaTransform(new Complex(-0.7, 0.301), 1), new JuliaTransform(new Complex(-0.7, 0.301), -1) @@ -95,37 +103,37 @@ class ChaosGameDescriptionTest { @DisplayName("Negative tests") class MethodsThrowsExceptions { @Test - @DisplayName("Test constructor throws ChaosGameDescriptionException if transforms is null") + @DisplayName("Test constructor throws IsNullException if transforms is null") public void testConstructorTransformsIsNull() { - assertThrows(ChaosGameDescriptionException.class, () -> new ChaosGameDescription( + assertThrows(IsNullException.class, () -> new ChaosGameDescription( null, new Vector2D(0, 0), new Vector2D(1, 1))); } @Test - @DisplayName("Test constructor throws ChaosGameDescriptionException if transforms is empty") + @DisplayName("Test constructor throws EmptyListException if transforms is empty") public void testConstructorTransformsIsEmpty() { - assertThrows(ChaosGameDescriptionException.class, () -> new ChaosGameDescription( + assertThrows(EmptyListException.class, () -> new ChaosGameDescription( List.of(), new Vector2D(0, 0), new Vector2D(1, 1))); } @Test - @DisplayName("Test constructor throws ChaosGameDescriptionException if minCoords is null") + @DisplayName("Test constructor throws IsNullException if minCoords is null") public void testConstructorIfMinCoordsIsNull() { - assertThrows(ChaosGameDescriptionException.class, () -> new ChaosGameDescription( + assertThrows(IsNullException.class, () -> new ChaosGameDescription( List.of(new JuliaTransform(new Complex(0, 0), 1)), null, new Vector2D(1, 1))); } @Test - @DisplayName("Test constructor throws ChaosGameDescriptionException if maxCoords is null") + @DisplayName("Test constructor throws IsNullException if maxCoords is null") public void testConstructorMaxCoordsIsNull() { - assertThrows(ChaosGameDescriptionException.class, () -> new ChaosGameDescription( + assertThrows(IsNullException.class, () -> new ChaosGameDescription( List.of(new JuliaTransform(new Complex(0, 0), 1)), new Vector2D(0, 0), null)); } @Test - @DisplayName("Test constructor throws ChaosGameDescriptionException if minCoords is greater than maxCoords") + @DisplayName("Test constructor throws InvalidVectorRangeException if minCoords is greater than maxCoords") public void testConstructorMinCoordsIsGreaterThanMaxCoords() { - assertThrows(ChaosGameDescriptionException.class, () -> new ChaosGameDescription( + assertThrows(InvalidVectorRangeException.class, () -> new ChaosGameDescription( List.of(new JuliaTransform(new Complex(0, 0), 1)), new Vector2D(1, 1), new Vector2D(0, 0))); } } diff --git a/src/test/java/edu/ntnu/idatt2003/model/game/ChaosGameTest.java b/src/test/java/edu/ntnu/idatt2003/model/game/ChaosGameTest.java index c82810b..b802ef1 100644 --- a/src/test/java/edu/ntnu/idatt2003/model/game/ChaosGameTest.java +++ b/src/test/java/edu/ntnu/idatt2003/model/game/ChaosGameTest.java @@ -2,13 +2,12 @@ package edu.ntnu.idatt2003.model.game; import static org.junit.jupiter.api.Assertions.*; -import edu.ntnu.idatt2003.exceptions.ChaosCanvasException; -import edu.ntnu.idatt2003.exceptions.ChaosGameDescriptionException; -import edu.ntnu.idatt2003.exceptions.ChaosGameDescriptionFactoryException; -import edu.ntnu.idatt2003.exceptions.ChaosGameException; -import edu.ntnu.idatt2003.model.math.transformation.AffineTransform2D; -import edu.ntnu.idatt2003.model.math.transformation.Transform2D; -import java.util.List; +import edu.ntnu.idatt2003.exceptions.EmptyListException; +import edu.ntnu.idatt2003.exceptions.InvalidPositiveIntException; +import edu.ntnu.idatt2003.exceptions.InvalidSignException; +import edu.ntnu.idatt2003.exceptions.InvalidTypeException; +import edu.ntnu.idatt2003.exceptions.InvalidVectorRangeException; +import edu.ntnu.idatt2003.exceptions.IsNullException; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; @@ -26,8 +25,9 @@ class ChaosGameTest { @Test @DisplayName("Constructor creates a ChaosGame object") void constructorDoesNotThrowExceptionOnValidParameters() - throws ChaosGameDescriptionFactoryException, ChaosGameDescriptionException, - ChaosGameException, ChaosCanvasException { + throws InvalidSignException, IsNullException, + EmptyListException, InvalidVectorRangeException, InvalidTypeException, + InvalidPositiveIntException { ChaosGameDescription description = ChaosGameDescriptionFactory.get("Sierpinski"); ChaosGame chaosGame = new ChaosGame(description, 100, 100); assertNotNull(chaosGame); @@ -39,8 +39,9 @@ class ChaosGameTest { ChaosGame chaosGame; @BeforeEach - void setUp() throws ChaosGameDescriptionFactoryException, ChaosGameDescriptionException, - ChaosGameException, ChaosCanvasException { + void setUp() throws InvalidSignException, IsNullException, + EmptyListException, InvalidVectorRangeException, InvalidTypeException, + InvalidPositiveIntException { ChaosGameDescription description = ChaosGameDescriptionFactory.get("Sierpinski"); chaosGame = new ChaosGame(description, 100, 100); } @@ -54,7 +55,8 @@ class ChaosGameTest { @Test @DisplayName("resetGameWithNewDescription does not throw exception on valid parameters") void resetGameWithNewDescriptionDoesNotThrowException() - throws ChaosGameDescriptionFactoryException { + throws InvalidSignException, IsNullException, + EmptyListException, InvalidVectorRangeException, InvalidTypeException { ChaosGameDescription description = ChaosGameDescriptionFactory.get("Julia Set"); assertDoesNotThrow(() -> chaosGame.resetGameWithDescription(description)); } @@ -72,28 +74,30 @@ class ChaosGameTest { class MethodsThrowsExceptionOnInvalidParameters { @Test - @DisplayName("Constructor throws ChaosGameException on null description") - void constructorThrowsChaosGameExceptionOnNullDescription() { - assertThrows(ChaosGameException.class, () -> new ChaosGame(null, 100, 100)); + @DisplayName("Constructor throws IsNullException on null description") + void constructorThrowsIsNullExceptionOnNullDescription() { + assertThrows(IsNullException.class, () -> new ChaosGame(null, 100, 100)); } @Test - @DisplayName("resetGameWithNewDescription throws ChaosGameException on null description") - void resetGameWithNewDescriptionThrowsChaosGameExceptionOnNullDescription() - throws ChaosGameDescriptionFactoryException, ChaosGameException { + @DisplayName("resetGameWithNewDescription throws IsNullException on null description") + void resetGameWithNewDescriptionThrowsIsNullExceptionOnNullDescription() + throws InvalidSignException, + IsNullException, EmptyListException, InvalidVectorRangeException, InvalidTypeException, + InvalidPositiveIntException { ChaosGameDescription description = ChaosGameDescriptionFactory.get("Sierpinski"); ChaosGame chaosGame = new ChaosGame(description, 100, 100); - assertThrows(ChaosGameException.class, () -> chaosGame.resetGameWithDescription(null)); + assertThrows(IsNullException.class, () -> chaosGame.resetGameWithDescription(null)); } @Test - @DisplayName("runSteps throws ChaosGameException on negative steps") - void runStepsThrowsChaosGameExceptionOnNegativeSteps() - throws ChaosGameDescriptionFactoryException, - ChaosGameException { + @DisplayName("runSteps throws InvalidPositiveIntException on negative steps") + void runStepsThrowsInvalidPositiveIntExceptionOnNegativeSteps() + throws InvalidSignException, IsNullException, EmptyListException, + InvalidVectorRangeException, InvalidTypeException, InvalidPositiveIntException { ChaosGameDescription description = ChaosGameDescriptionFactory.get("Sierpinski"); ChaosGame chaosGame = new ChaosGame(description, 100, 100); - assertThrows(ChaosGameException.class, () -> chaosGame.runSteps(0)); + assertThrows(InvalidPositiveIntException.class, () -> chaosGame.runSteps(0)); } } } \ No newline at end of file diff --git a/src/test/java/edu/ntnu/idatt2003/model/io/ChaosGameFileHandlerTest.java b/src/test/java/edu/ntnu/idatt2003/model/io/ChaosGameFileHandlerTest.java index 2ab3432..a14c083 100644 --- a/src/test/java/edu/ntnu/idatt2003/model/io/ChaosGameFileHandlerTest.java +++ b/src/test/java/edu/ntnu/idatt2003/model/io/ChaosGameFileHandlerTest.java @@ -2,8 +2,11 @@ package edu.ntnu.idatt2003.model.io; import static org.junit.jupiter.api.Assertions.*; -import edu.ntnu.idatt2003.exceptions.ChaosGameDescriptionException; -import edu.ntnu.idatt2003.exceptions.ChaosGameFileHandlerException; +import edu.ntnu.idatt2003.exceptions.CouldNotWriteException; +import edu.ntnu.idatt2003.exceptions.EmptyListException; +import edu.ntnu.idatt2003.exceptions.InvalidSignException; +import edu.ntnu.idatt2003.exceptions.InvalidVectorRangeException; +import edu.ntnu.idatt2003.exceptions.IsNullException; import edu.ntnu.idatt2003.exceptions.WrongFileFormatException; import edu.ntnu.idatt2003.model.game.ChaosGameDescription; import edu.ntnu.idatt2003.model.math.mathModel.Complex; @@ -12,6 +15,7 @@ import edu.ntnu.idatt2003.model.math.mathModel.Vector2D; import edu.ntnu.idatt2003.model.math.transformation.AffineTransform2D; import edu.ntnu.idatt2003.model.math.transformation.JuliaTransform; import java.io.File; +import java.io.FileNotFoundException; import java.util.List; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; @@ -37,7 +41,8 @@ class ChaosGameFileHandlerTest { ChaosGameDescription affine2DPositive; @BeforeEach - void setUp() throws ChaosGameDescriptionException { + void setUp() throws IsNullException, EmptyListException, + InvalidVectorRangeException, InvalidSignException { Vector2D vector1 = new Vector2D(0, 0); Vector2D vector2 = new Vector2D(0, 1.6); Vector2D vector3 = new Vector2D(0, 1.6); @@ -63,7 +68,9 @@ class ChaosGameFileHandlerTest { @Test @DisplayName("Test if readFromFile reads affine transformations correctly") void testIfReadChaosGameFileReadsAffineTransformationsCorrectly() - throws ChaosGameFileHandlerException, ChaosGameDescriptionException { + throws InvalidSignException, + WrongFileFormatException, IsNullException, FileNotFoundException, EmptyListException, + InvalidVectorRangeException { File file = new File("src/test/resources/Affine2DReadPositive.txt"); ChaosGameDescription chaosGameDescription = chaosGameFileHandler.readFromFile(file); @@ -73,7 +80,8 @@ class ChaosGameFileHandlerTest { @Test @DisplayName("Test if readFromFile reads julia transformations correctly") void testIfReadChaosGameFileReadsJuliaTransformationsCorrectly() - throws ChaosGameFileHandlerException, ChaosGameDescriptionException { + throws InvalidSignException, WrongFileFormatException, IsNullException, + FileNotFoundException, EmptyListException, InvalidVectorRangeException { File file = new File("src/test/resources/JuliaReadPositive.txt"); ChaosGameDescription chaosGameDescription = chaosGameFileHandler.readFromFile(file); @@ -83,7 +91,8 @@ class ChaosGameFileHandlerTest { @Test @DisplayName("Test if writeToFile writes affine transformations correctly") void testIfWriteChaosGameFileWritesAffineTransformationsCorrectly() - throws ChaosGameFileHandlerException, ChaosGameDescriptionException { + throws CouldNotWriteException, InvalidSignException, WrongFileFormatException, + IsNullException, FileNotFoundException, EmptyListException, InvalidVectorRangeException { File file = new File("src/test/resources/Affine2DWritePositive.txt"); chaosGameFileHandler.writeToFile(affine2DPositive, file); ChaosGameDescription chaosGameDescription = chaosGameFileHandler.readFromFile(file); @@ -95,7 +104,8 @@ class ChaosGameFileHandlerTest { @Test @DisplayName("Test if writeToFile writes julia transformations correctly") void testIfWriteChaosGameFileWritesJuliaTransformationsCorrectly() - throws ChaosGameFileHandlerException, ChaosGameDescriptionException { + throws CouldNotWriteException, InvalidSignException, WrongFileFormatException, IsNullException, + FileNotFoundException, EmptyListException, InvalidVectorRangeException { File file = new File("src/test/resources/JuliaWritePositive.txt"); chaosGameFileHandler.writeToFile(juliaPositive, file); ChaosGameDescription chaosGameDescription = chaosGameFileHandler.readFromFile(file); diff --git a/src/test/java/edu/ntnu/idatt2003/model/math/transformation/JuliaTransformTest.java b/src/test/java/edu/ntnu/idatt2003/model/math/transformation/JuliaTransformTest.java index 9f40040..22e6f64 100644 --- a/src/test/java/edu/ntnu/idatt2003/model/math/transformation/JuliaTransformTest.java +++ b/src/test/java/edu/ntnu/idatt2003/model/math/transformation/JuliaTransformTest.java @@ -2,6 +2,7 @@ package edu.ntnu.idatt2003.model.math.transformation; import static org.junit.jupiter.api.Assertions.*; +import edu.ntnu.idatt2003.exceptions.InvalidSignException; import edu.ntnu.idatt2003.model.math.mathModel.Complex; import edu.ntnu.idatt2003.model.math.mathModel.Vector2D; import org.junit.jupiter.api.DisplayName; @@ -20,7 +21,7 @@ class JuliaTransformTest { @Test @DisplayName("Transform returns correct values, test 1") - void transformReturnsCorrectValues1() { + void transformReturnsCorrectValues1() throws InvalidSignException { JuliaTransform juliaTransform = new JuliaTransform(new Complex(3, 2), 1); Vector2D vector = new Vector2D(4, 1); Vector2D vector2 = juliaTransform.transform(vector); @@ -30,7 +31,7 @@ class JuliaTransformTest { @Test @DisplayName("Transform returns correct values, test 2") - void transformReturnsCorrectValues2() { + void transformReturnsCorrectValues2() throws InvalidSignException { JuliaTransform juliaTransform = new JuliaTransform(new Complex(-2, 3), 1); Vector2D vector = new Vector2D(0, 3); Vector2D vector2 = juliaTransform.transform(vector); @@ -40,7 +41,7 @@ class JuliaTransformTest { @Test @DisplayName("Transform returns correct values, test 3") - void transformReturnsCorrectValues3() { + void transformReturnsCorrectValues3() throws InvalidSignException { JuliaTransform juliaTransform = new JuliaTransform(new Complex(4, 5), 1); Vector2D vector = new Vector2D(2, 1); Vector2D vector2 = juliaTransform.transform(vector); @@ -54,7 +55,7 @@ class JuliaTransformTest { public class PositiveTestsForEquals { @Test @DisplayName("Equals returns true when two julia are equal") - void equalsReturnsTrueWhenTwoJuliaAreEqual() { + void equalsReturnsTrueWhenTwoJuliaAreEqual() throws InvalidSignException { Complex complex = new Complex(3, 2); JuliaTransform julia1 = new JuliaTransform(complex, 1); JuliaTransform julia2 = new JuliaTransform(complex, 1); @@ -63,7 +64,7 @@ class JuliaTransformTest { @Test @DisplayName("Equals returns false when two julia are not equal") - void equalsReturnsFalseWhenTwoJuliaAreNotEqual() { + void equalsReturnsFalseWhenTwoJuliaAreNotEqual() throws InvalidSignException { Complex complex1 = new Complex(3, 2); Complex complex2 = new Complex(4, 1); JuliaTransform julia1 = new JuliaTransform(complex1, 1); @@ -73,7 +74,7 @@ class JuliaTransformTest { @Test @DisplayName("Equals returns false when comparing a vector to null") - void equalsReturnsFalseWhenComparingAVectorToNull() { + void equalsReturnsFalseWhenComparingAVectorToNull() throws InvalidSignException { Complex complex = new Complex(3, 2); JuliaTransform julia = new JuliaTransform(complex, 1); assertNotEquals(julia, null); @@ -81,7 +82,7 @@ class JuliaTransformTest { @Test @DisplayName("Equals returns false when comparing a vector to a different object") - void equalsReturnsFalseWhenComparingAVectorToADifferentObject() { + void equalsReturnsFalseWhenComparingAVectorToADifferentObject() throws InvalidSignException { Complex complex = new Complex(3, 2); JuliaTransform julia = new JuliaTransform(complex, 1); assertNotEquals(julia, new Object()); @@ -94,9 +95,9 @@ class JuliaTransformTest { public class MethodsThrowsExceptions { @Test - @DisplayName("Constructor throws IllegalArgumentException if sign is not 1 or -1") - void constructorThrowsIllegalArgumentException() { - assertThrows(IllegalArgumentException.class, () -> new JuliaTransform(new Complex(3, 2), 0)); + @DisplayName("Constructor throws InvalidSignException if sign is not 1 or -1") + void constructorThrowsInvalidSignException() { + assertThrows(InvalidSignException.class, () -> new JuliaTransform(new Complex(3, 2), 0)); } } } \ No newline at end of file -- GitLab From d3a5f26cf431e02f64d431b9da0851479443713d Mon Sep 17 00:00:00 2001 From: Vetle <vetletb@stud.ntnu.no> Date: Thu, 16 May 2024 13:16:19 +0200 Subject: [PATCH 3/3] Added exception handling --- .../controller/ChaosGameController.java | 105 +++++++++++++----- .../idatt2003/view/CommandLineInterface.java | 60 ++++++---- .../idatt2003/view/components/TopBar.java | 28 ++--- 3 files changed, 127 insertions(+), 66 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/controller/ChaosGameController.java b/src/main/java/edu/ntnu/idatt2003/controller/ChaosGameController.java index a67f353..4c7a04a 100644 --- a/src/main/java/edu/ntnu/idatt2003/controller/ChaosGameController.java +++ b/src/main/java/edu/ntnu/idatt2003/controller/ChaosGameController.java @@ -1,8 +1,14 @@ package edu.ntnu.idatt2003.controller; -import edu.ntnu.idatt2003.exceptions.ChaosGameDescriptionFactoryException; -import edu.ntnu.idatt2003.exceptions.ChaosGameException; -import edu.ntnu.idatt2003.exceptions.ChaosGameFileHandlerException; +import edu.ntnu.idatt2003.exceptions.CouldNotWriteException; +import edu.ntnu.idatt2003.exceptions.EmptyListException; +import edu.ntnu.idatt2003.exceptions.InvalidPositiveIntException; +import edu.ntnu.idatt2003.exceptions.InvalidSignException; +import edu.ntnu.idatt2003.exceptions.InvalidTypeException; +import edu.ntnu.idatt2003.exceptions.InvalidVectorRangeException; +import edu.ntnu.idatt2003.exceptions.IsNullException; +import edu.ntnu.idatt2003.exceptions.ObservingException; +import edu.ntnu.idatt2003.exceptions.WrongFileFormatException; import edu.ntnu.idatt2003.model.game.ChaosGame; import edu.ntnu.idatt2003.model.game.ChaosGameDescription; import edu.ntnu.idatt2003.model.game.ChaosGameDescriptionFactory; @@ -12,6 +18,7 @@ import edu.ntnu.idatt2003.util.ExceptionLogger; import edu.ntnu.idatt2003.view.PopupHandler; import edu.ntnu.idatt2003.view.components.ViewCanvas; import java.io.File; +import java.io.FileNotFoundException; import javafx.animation.KeyFrame; import javafx.animation.Timeline; import javafx.util.Duration; @@ -20,15 +27,25 @@ import javafx.util.Duration; * The controller class for the chaos game. */ public class ChaosGameController implements Observer { + //Constants for the chaos game. public static final int CHAOS_GAME_WIDTH = 680; public static final int CHAOS_GAME_HEIGHT = 680; public static final String START_DESCRIPTION = "Julia Set"; + //Constants for the animation + public static int RUN_SECONDS = 3; + public static int FPS = 60; + public static double K = 0.05; + + //Constant for unexpected exceptions not caused by the user + public static final String UNEXPECTED_EXCEPTION = + "Something went wrong. Please try again or restart."; + private ChaosGame chaosGame = null; private Timeline timeline; private final ViewCanvas viewCanvas; private final PopupHandler popupHandler; - private ExceptionLogger exceptionLogger; + private final ExceptionLogger exceptionLogger; /** * Constructor for the ChaosGameController class. @@ -36,15 +53,18 @@ public class ChaosGameController implements Observer { * @param viewCanvas the view canvas to draw on. */ public ChaosGameController(ViewCanvas viewCanvas, PopupHandler popupHandler) { + exceptionLogger = new ExceptionLogger("ChaosGameController"); this.viewCanvas = viewCanvas; this.popupHandler = popupHandler; try { - chaosGame = new ChaosGame(ChaosGameDescriptionFactory.get(START_DESCRIPTION), CHAOS_GAME_WIDTH, CHAOS_GAME_HEIGHT); + chaosGame = new ChaosGame(ChaosGameDescriptionFactory.get( + START_DESCRIPTION), CHAOS_GAME_WIDTH, CHAOS_GAME_HEIGHT); chaosGame.attach(this); - } catch (ChaosGameException | ChaosGameDescriptionFactoryException ex) { - popupHandler.showErrorPopup(ex.getMessage()); + } catch (EmptyListException | InvalidVectorRangeException | InvalidSignException + | IsNullException | InvalidTypeException | InvalidPositiveIntException e) { + exceptionLogger.logSevere(e); + popupHandler.showErrorPopup(UNEXPECTED_EXCEPTION); } - exceptionLogger = new ExceptionLogger("ChaosGameController"); } /** @@ -58,8 +78,10 @@ public class ChaosGameController implements Observer { chaosGame.resetGameWithDescription(newDescription); stopTimeline(); popupHandler.showSuccessPopup(description + " loaded successfully"); - } catch (ChaosGameDescriptionFactoryException | ChaosGameException ex) { - popupHandler.showErrorPopup(ex.getMessage()); + } catch (IsNullException | InvalidVectorRangeException | EmptyListException + | InvalidSignException | InvalidTypeException e) { + exceptionLogger.logSevere(e); + popupHandler.showErrorPopup(UNEXPECTED_EXCEPTION); } } @@ -89,8 +111,16 @@ public class ChaosGameController implements Observer { ChaosGameDescription newDescription = fileHandler.readFromFile(file); chaosGame.resetGameWithDescription(newDescription); popupHandler.showSuccessPopup("File loaded successfully"); - } catch (ChaosGameFileHandlerException | ChaosGameException ex) { - popupHandler.showErrorPopup(ex.getMessage()); + } catch (IsNullException | InvalidVectorRangeException + | EmptyListException | InvalidSignException e) { + exceptionLogger.logSevere(e); + popupHandler.showErrorPopup(e.getMessage()); + } catch (FileNotFoundException e) { + exceptionLogger.logWarning(e); + popupHandler.showErrorPopup("File not found"); + } catch (WrongFileFormatException e) { + exceptionLogger.logWarning(e); + popupHandler.showErrorPopup(e.getMessage()); } } @@ -100,8 +130,9 @@ public class ChaosGameController implements Observer { public void runSteps(int steps) { try { chaosGame.runSteps(steps); - } catch (ChaosGameException ex) { - popupHandler.showErrorPopup(ex.getMessage()); + } catch (InvalidPositiveIntException e) { + exceptionLogger.logWarning(e); + popupHandler.showErrorPopup(e.getMessage()); } } @@ -155,39 +186,43 @@ public class ChaosGameController implements Observer { */ public void animateIterations(int iterations) { if (iterations <= 0) { - popupHandler.showErrorPopup("Iterations must be a positive number"); + try { + throw new InvalidPositiveIntException("Iterations must be a positive number"); + } catch (InvalidPositiveIntException e) { + exceptionLogger.logWarning(e); + popupHandler.showErrorPopup(e.getMessage()); + } return; } - int runSeconds = 3; - int fps = 60; final int [] x = {0}; - double k = 0.05; final int [] totalSteps = {0}; timeline = new Timeline(); - KeyFrame keyFrame = new KeyFrame(Duration.millis(1000.0 / fps), e -> { - int steps = (int) (iterations * k / Math.exp(fps * runSeconds * k) * Math.exp(k * x[0])); + KeyFrame keyFrame = new KeyFrame(Duration.millis(1000.0 / FPS), e -> { + int steps = (int) (iterations * K / Math.exp(FPS * RUN_SECONDS * K) * Math.exp(K * x[0])); try { if (steps != 0) { chaosGame.runSteps(steps); } - } catch (ChaosGameException ex) { - popupHandler.showErrorPopup(ex.getMessage()); + } catch (InvalidPositiveIntException ex) { + exceptionLogger.logSevere(ex); + popupHandler.showErrorPopup(UNEXPECTED_EXCEPTION); timeline.stop(); } x[0]++; totalSteps[0] += steps; }); timeline.getKeyFrames().add(keyFrame); - timeline.setCycleCount(fps * runSeconds); + timeline.setCycleCount(FPS * RUN_SECONDS); timeline.setOnFinished(e -> { try { if (iterations - totalSteps[0] != 0) { chaosGame.runSteps(iterations - totalSteps[0]); } - } catch (ChaosGameException ex) { - popupHandler.showErrorPopup(ex.getMessage()); + } catch (InvalidPositiveIntException ex) { + exceptionLogger.logSevere(ex); + popupHandler.showErrorPopup(UNEXPECTED_EXCEPTION); } }); timeline.play(); @@ -227,8 +262,9 @@ public class ChaosGameController implements Observer { try { fileHandler.writeToFile(chaosGame.getDescriptions(), file); popupHandler.showSuccessPopup("File written successfully"); - } catch (ChaosGameFileHandlerException ex) { - popupHandler.showErrorPopup(ex.getMessage()); + } catch (CouldNotWriteException e) { + exceptionLogger.logSevere(e); + popupHandler.showErrorPopup(UNEXPECTED_EXCEPTION); } } @@ -236,6 +272,13 @@ public class ChaosGameController implements Observer { return popupHandler; } + /** + * logs a warning exception. + */ + public void logWarning(Exception e) { + exceptionLogger.logWarning(e); + } + /** * When the chaosGame is updated, this method is called. */ @@ -245,6 +288,14 @@ public class ChaosGameController implements Observer { case "clearGame" -> viewCanvas.reset(); case "putPixel" -> drawCurrentPixel(); case "setDescription" -> System.out.println("description"); + default -> { + try { + throw new ObservingException(updated + " is not being observed."); + } catch (ObservingException e) { + exceptionLogger.logSevere(e); + popupHandler.showErrorPopup(UNEXPECTED_EXCEPTION); + } + } } } } diff --git a/src/main/java/edu/ntnu/idatt2003/view/CommandLineInterface.java b/src/main/java/edu/ntnu/idatt2003/view/CommandLineInterface.java index c0fb3fa..3289642 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/CommandLineInterface.java +++ b/src/main/java/edu/ntnu/idatt2003/view/CommandLineInterface.java @@ -1,14 +1,19 @@ package edu.ntnu.idatt2003.view; -import edu.ntnu.idatt2003.exceptions.ChaosCanvasException; -import edu.ntnu.idatt2003.exceptions.ChaosGameDescriptionException; -import edu.ntnu.idatt2003.exceptions.ChaosGameException; -import edu.ntnu.idatt2003.exceptions.ChaosGameFileHandlerException; +import edu.ntnu.idatt2003.exceptions.CouldNotWriteException; +import edu.ntnu.idatt2003.exceptions.EmptyListException; +import edu.ntnu.idatt2003.exceptions.InvalidPositiveIntException; +import edu.ntnu.idatt2003.exceptions.InvalidSignException; +import edu.ntnu.idatt2003.exceptions.InvalidVectorRangeException; +import edu.ntnu.idatt2003.exceptions.IsNullException; import edu.ntnu.idatt2003.exceptions.WrongFileFormatException; import edu.ntnu.idatt2003.model.game.ChaosGame; import edu.ntnu.idatt2003.model.game.ChaosGameDescription; import edu.ntnu.idatt2003.model.io.ChaosGameFileHandler; import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.List; import java.util.Scanner; /** @@ -31,11 +36,8 @@ public class CommandLineInterface { /** * Starts the command line interface. - * - * @throws ChaosGameFileHandlerException if an error occurs while reading or writing to a file. - * @throws ChaosGameException if an error occurs while running the chaos game. */ - public void start() throws ChaosGameFileHandlerException, ChaosGameException { + public void start() { boolean exit = false; while (!exit) { System.out.println("Welcome to the Chaos Game!"); @@ -59,14 +61,18 @@ public class CommandLineInterface { /** * Chooses a file to construct a ChaosGameDescription from. - * - * @throws ChaosGameFileHandlerException if an error occurs while getting the list of files - * or reading from a file. */ - private void chooseFile() throws ChaosGameFileHandlerException { + private void chooseFile() { System.out.println("Choose a file:"); int i = 1; - for (String path : chaosGameFileHandler.listFiles()) { + List<String> files; + try { + files = chaosGameFileHandler.listFiles(); + } catch (IOException e) { + System.out.println("An error occurred. Please try again."); + return; + } + for (String path : files) { String name = path.replace("src/main/resources/", "").replace(".txt", ""); System.out.println(i + ". " + name); i++; @@ -74,7 +80,7 @@ public class CommandLineInterface { int choice = scanner.nextInt(); scanner.nextLine(); boolean found = false; - for (String path : chaosGameFileHandler.listFiles()) { + for (String path : files) { choice--; if (choice == 0) { found = true; @@ -84,8 +90,11 @@ public class CommandLineInterface { System.out.println("File read successfully!"); } catch (WrongFileFormatException e) { System.out.println("Wrong file format. Please try again."); - } catch (ChaosGameFileHandlerException e) { + } catch (FileNotFoundException e) { System.out.println("File not found. Please try again."); + } catch (IsNullException | EmptyListException + | InvalidVectorRangeException | InvalidSignException e) { + System.out.println("An error occurred. Please try again."); } break; } @@ -109,21 +118,30 @@ public class CommandLineInterface { File file = new File(path); chaosGameFileHandler.writeToFile(description, file); System.out.println("File written successfully!"); - } catch (ChaosGameFileHandlerException e) { + } catch (CouldNotWriteException e) { System.out.println("An error occurred. Please try again."); } } /** * Runs the chaos game and prints the result. - * - * @throws ChaosGameException if an error occurs while running the chaos game. */ - private void runChaosGame() throws ChaosGameException { - ChaosGame chaosGame = new ChaosGame(description, width, height); + private void runChaosGame() { + ChaosGame chaosGame; + try { + chaosGame = new ChaosGame(description, width, height); + } catch (IsNullException | InvalidPositiveIntException | InvalidVectorRangeException e) { + System.out.println("An error occurred. Please try again."); + return; + } System.out.println("Choose number of steps:"); int steps = scanner.nextInt(); - chaosGame.runSteps(steps); + try { + chaosGame.runSteps(steps); + } catch (InvalidPositiveIntException e) { + System.out.println("Steps must be a positive number."); + return; + } StringBuilder sb = new StringBuilder(); for (int i = 0; i < height; i++) { diff --git a/src/main/java/edu/ntnu/idatt2003/view/components/TopBar.java b/src/main/java/edu/ntnu/idatt2003/view/components/TopBar.java index 333f738..db93e12 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/components/TopBar.java +++ b/src/main/java/edu/ntnu/idatt2003/view/components/TopBar.java @@ -1,12 +1,10 @@ package edu.ntnu.idatt2003.view.components; import edu.ntnu.idatt2003.controller.ChaosGameController; -import java.io.File; - import edu.ntnu.idatt2003.view.components.Input.InputBar; import edu.ntnu.idatt2003.view.components.buttons.PrimaryButton; import edu.ntnu.idatt2003.view.components.buttons.SecondaryButton; -import edu.ntnu.idatt2003.view.components.popups.EditPopup; +import java.io.File; import javafx.geometry.Pos; import javafx.scene.control.Button; import javafx.scene.control.TextField; @@ -22,7 +20,6 @@ import javafx.stage.Window; public class TopBar extends StackPane { private final ChaosGameController controller; private int iterations; - private EditPopup editPopup; private Window ownerWindow; /** @@ -46,19 +43,13 @@ public class TopBar extends StackPane { Button juliaButton = new SecondaryButton("Julia Set"); - juliaButton.setOnAction(e -> { - this.controller.resetChaosGameWithDescription("Julia Set"); - }); + juliaButton.setOnAction(e -> this.controller.resetChaosGameWithDescription("Julia Set")); Button sierpinskiButton = new SecondaryButton("Sierpinski"); - sierpinskiButton.setOnAction(e -> { - this.controller.resetChaosGameWithDescription("Sierpinski"); - }); + sierpinskiButton.setOnAction(e -> this.controller.resetChaosGameWithDescription("Sierpinski")); Button barnsleyButton = new SecondaryButton("Barnsley"); - barnsleyButton.setOnAction(e -> { - this.controller.resetChaosGameWithDescription("Barnsley"); - }); + barnsleyButton.setOnAction(e -> this.controller.resetChaosGameWithDescription("Barnsley")); Button readFileButton = new SecondaryButton("Read File"); readFileButton.setOnAction(e -> { @@ -72,7 +63,8 @@ public class TopBar extends StackPane { Button writeFileButton = new PrimaryButton("Write File"); writeFileButton.setOnAction(e -> { FileChooser fileChooser = new FileChooser(); - FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter("TXT files (*.txt)", "*.txt"); + FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter( + "TXT files (*.txt)", "*.txt"); fileChooser.getExtensionFilters().add(extFilter); File file = fileChooser.showSaveDialog(ownerWindow); if (file != null) { @@ -81,9 +73,7 @@ public class TopBar extends StackPane { }); Button editButton = new PrimaryButton("Edit"); - editButton.setOnAction(e -> { - this.controller.getPopupHandler().showEditPopup(); - }); + editButton.setOnAction(e -> this.controller.getPopupHandler().showEditPopup()); TextField iterationsField = new InputBar(); iterationsField.setPromptText("Iterations"); @@ -95,6 +85,7 @@ public class TopBar extends StackPane { try { iterations = Integer.parseInt(iterationsField.getText()); } catch (NumberFormatException ex) { + controller.logWarning(ex); this.controller.getPopupHandler().showErrorPopup("Iterations must be a number"); return; } @@ -106,7 +97,8 @@ public class TopBar extends StackPane { HBox rightButtonBox = new HBox(); leftButtonBox.getChildren().addAll(writeFileButton, editButton); - middleButtonBox.getChildren().addAll(juliaButton, sierpinskiButton, barnsleyButton, readFileButton); + middleButtonBox.getChildren().addAll( + juliaButton, sierpinskiButton, barnsleyButton, readFileButton); rightButtonBox.getChildren().addAll(iterationsField, runButton); leftButtonBox.setSpacing(8); -- GitLab