From f01782119c56db0a28857da156cf9ae8bb5272cb Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Fri, 22 Mar 2024 12:17:02 +0100 Subject: [PATCH 001/168] test1 dev --- src/main/java/edu/ntnu/idatt2003/Main.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/edu/ntnu/idatt2003/Main.java b/src/main/java/edu/ntnu/idatt2003/Main.java index 0b2aac3..2c2ef3c 100644 --- a/src/main/java/edu/ntnu/idatt2003/Main.java +++ b/src/main/java/edu/ntnu/idatt2003/Main.java @@ -13,6 +13,7 @@ public class Main { //TIP Press <shortcut actionId="Debug"/> to start debugging your code. We have set one <icon src="AllIcons.Debugger.Db_set_breakpoint"/> breakpoint // for you, but you can always add more by pressing <shortcut actionId="ToggleLineBreakpoint"/>. System.out.println("i = " + i); + System.out.println("testtt"); } } } \ No newline at end of file -- GitLab From 35177f2aa88af3416328f0e94bd36a7dc5b86eed Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Fri, 22 Mar 2024 12:22:58 +0100 Subject: [PATCH 002/168] test2 dev --- src/main/java/edu/ntnu/idatt2003/Main.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/edu/ntnu/idatt2003/Main.java b/src/main/java/edu/ntnu/idatt2003/Main.java index 2c2ef3c..f7e3fc7 100644 --- a/src/main/java/edu/ntnu/idatt2003/Main.java +++ b/src/main/java/edu/ntnu/idatt2003/Main.java @@ -14,6 +14,7 @@ public class Main { // for you, but you can always add more by pressing <shortcut actionId="ToggleLineBreakpoint"/>. System.out.println("i = " + i); System.out.println("testtt"); + System.out.println("test") } } } \ No newline at end of file -- GitLab From 2703b5882f77e356d472c922126d453a8c0d1c65 Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Fri, 22 Mar 2024 12:57:49 +0100 Subject: [PATCH 003/168] made ChaosGameDescription --- .../idatt2003/model/ChaosGameDescription.java | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 src/main/java/edu/ntnu/idatt2003/model/ChaosGameDescription.java diff --git a/src/main/java/edu/ntnu/idatt2003/model/ChaosGameDescription.java b/src/main/java/edu/ntnu/idatt2003/model/ChaosGameDescription.java new file mode 100644 index 0000000..ae7415d --- /dev/null +++ b/src/main/java/edu/ntnu/idatt2003/model/ChaosGameDescription.java @@ -0,0 +1,28 @@ +package edu.ntnu.idatt2003.model; + +import javax.xml.crypto.dsig.Transform; +import java.util.List; + +public class ChaosGameDescription { + private Vector2D minCoords; + private Vector2D maxCoords; + private List<Transform2D> transforms; + + public ChaosGameDescription( List<Transform2D> transforms, Vector2D minCoords, Vector2D maxCoords) { + this.minCoords = minCoords; + this.maxCoords = maxCoords; + this.transforms = transforms; + } + + public List<Transform2D> getTransforms() { + return transforms; + } + + public Vector2D getMinCoords() { + return minCoords; + } + + public Vector2D getMaxCoords() { + return maxCoords; + } +} -- GitLab From ac67ad469249e5586fe0bcbc7e9b21916e25c83e Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Fri, 22 Mar 2024 13:00:30 +0100 Subject: [PATCH 004/168] fixed main --- src/main/java/edu/ntnu/idatt2003/Main.java | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/Main.java b/src/main/java/edu/ntnu/idatt2003/Main.java index f7e3fc7..aa4781c 100644 --- a/src/main/java/edu/ntnu/idatt2003/Main.java +++ b/src/main/java/edu/ntnu/idatt2003/Main.java @@ -1,20 +1,6 @@ package edu.ntnu.idatt2003; - -//TIP To <b>Run</b> code, press <shortcut actionId="Run"/> or -// click the <icon src="AllIcons.Actions.Execute"/> icon in the gutter. public class Main { public static void main(String[] args) { - //TIP Press <shortcut actionId="ShowIntentionActions"/> with your caret at the highlighted text - // to see how IntelliJ IDEA suggests fixing it. - System.out.printf("Hello and welcome!!!!!\n"); - - for (int i = 1; i <= 5; i++) { - //TIP Press <shortcut actionId="Debug"/> to start debugging your code. We have set one <icon src="AllIcons.Debugger.Db_set_breakpoint"/> breakpoint - // for you, but you can always add more by pressing <shortcut actionId="ToggleLineBreakpoint"/>. - System.out.println("i = " + i); - System.out.println("testtt"); - System.out.println("test") - } } -} \ No newline at end of file +} -- GitLab From 4d3a598e22e168d984b3ccbc4cd5e21836f4ab01 Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Fri, 22 Mar 2024 14:14:13 +0100 Subject: [PATCH 005/168] ChaosCanvas made --- .../edu/ntnu/idatt2003/model/ChaosCanvas.java | 94 +++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 src/main/java/edu/ntnu/idatt2003/model/ChaosCanvas.java diff --git a/src/main/java/edu/ntnu/idatt2003/model/ChaosCanvas.java b/src/main/java/edu/ntnu/idatt2003/model/ChaosCanvas.java new file mode 100644 index 0000000..bffaefe --- /dev/null +++ b/src/main/java/edu/ntnu/idatt2003/model/ChaosCanvas.java @@ -0,0 +1,94 @@ +package edu.ntnu.idatt2003.model; + +/** + * This class represents a canvas for drawing chaos game fractals. + * It has methods for putting and getting pixels, and for clearing the canvas. + */ +public class ChaosCanvas { + private int[][] canvas; + private int width; + private int height; + private Vector2D minCoords; + private Vector2D maxCoords; + private AffineTransform2D transformCoordsToIndices; + + /** + * Constructs a ChaosCanvas with the given width, height, minCoords and maxCoords. + * @param width the width of the canvas + * @param height the height of the canvas + * @param minCoords the minimum coordinates of the canvas + * @param maxCoords the maximum coordinates of the canvas + * + */ +public ChaosCanvas(int width, int height, Vector2D minCoords, Vector2D maxCoords) { + this.width = width; + this.height = height; + this.minCoords = minCoords; + this.maxCoords = maxCoords; + canvas = new int[height][width]; + initializeTransform(); + } + + /** + * Initializes the transformation from coordinates to indices. + */ + private void initializeTransform() { + double scaleX = (width - 1) / (maxCoords.getX0() - minCoords.getX0()); + double scaleY = (height - 1) / (maxCoords.getX1() - minCoords.getX1()); + Matrix2x2 matrix2x2 = new Matrix2x2( 0, scaleX, scaleY, 0); + double bX = (height - 1)*maxCoords.getX1() / (maxCoords.getX1() - minCoords.getX1()); + double bY = (width - 1)*minCoords.getX0() / (minCoords.getX0() - maxCoords.getX0()); + Vector2D vector2D = new Vector2D(bX, bY); + transformCoordsToIndices = new AffineTransform2D(matrix2x2, vector2D); + } + + /** + * Returns the pixel at the given point. + * @param point the point to get the pixel from + * @return the pixel at the given point + */ + public int getPixel(Vector2D point) { + Vector2D transformedPoint = transformCoordsToIndices.transform(point); + int i = (int) transformedPoint.getX0(); + int j = (int) transformedPoint.getX1(); + + if (i >= 0 && i < height && j >= 0 && j < width) { + return canvas[i][j]; + } else { + return -1; + } + } + + /** + * Puts a pixel at the given point. + * @param point the point to put the pixel at + */ + public void putPixel(Vector2D point) { + Vector2D transformedPoint = transformCoordsToIndices.transform(point); + int i = (int) transformedPoint.getX0(); + int j = (int) transformedPoint.getX1(); + + if (i >= 0 && i < height && j >= 0 && j < width) { + canvas[i][j] = 1; + } + } + + /** + * Returns the canvas array. + * @return the canvas array + */ + public int[][] getCanvasArray() { + return canvas; + } + + /** + * Clears the canvas. + */ + public void clear() { + for (int i = 0; i < height; i++) { + for (int j = 0; j < width; j++) { + canvas[i][j] = 0; + } + } + } +} -- GitLab From 61f7410e9262c4f0f5443f7c2f32b0a819fc1cf4 Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Fri, 22 Mar 2024 14:55:40 +0100 Subject: [PATCH 006/168] made ChaosGame --- .../edu/ntnu/idatt2003/model/ChaosGame.java | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 src/main/java/edu/ntnu/idatt2003/model/ChaosGame.java diff --git a/src/main/java/edu/ntnu/idatt2003/model/ChaosGame.java b/src/main/java/edu/ntnu/idatt2003/model/ChaosGame.java new file mode 100644 index 0000000..5024c4e --- /dev/null +++ b/src/main/java/edu/ntnu/idatt2003/model/ChaosGame.java @@ -0,0 +1,30 @@ +package edu.ntnu.idatt2003.model; + +import java.util.Random; + +public class ChaosGame { + private ChaosCanvas canvas; + private ChaosGameDescription description; + private Vector2D currentPoint; + private Random random; + + public ChaosGame(ChaosGameDescription description, int width, int height) { + this.description = description; + this.canvas = new ChaosCanvas(width, height, description.getMinCoords(), description.getMaxCoords()); + this.currentPoint = new Vector2D(0, 0); + this.random = new Random(); + } + + public ChaosCanvas getCanvas() { + return canvas; + } + + public void runSteps(int steps) { + for (int i = 0; i < steps; i++) { + int randomIndex = random.nextInt(description.getTransforms().size()); + Transform2D transform = description.getTransforms().get(randomIndex); + currentPoint = transform.transform(currentPoint); + canvas.putPixel(currentPoint); // currentPoint is of type Vector2D + } + } +} -- GitLab From 57f2a9946a81b983279ecb17caf0fd51655a4773 Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Tue, 2 Apr 2024 12:10:15 +0200 Subject: [PATCH 007/168] Layout for GUI made --- src/main/java/edu/ntnu/idatt2003/Main.java | 4 ++++ src/main/java/edu/ntnu/idatt2003/view/App.java | 14 ++++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 src/main/java/edu/ntnu/idatt2003/view/App.java diff --git a/src/main/java/edu/ntnu/idatt2003/Main.java b/src/main/java/edu/ntnu/idatt2003/Main.java index aa4781c..025ef66 100644 --- a/src/main/java/edu/ntnu/idatt2003/Main.java +++ b/src/main/java/edu/ntnu/idatt2003/Main.java @@ -1,6 +1,10 @@ package edu.ntnu.idatt2003; +import edu.ntnu.idatt2003.view.App; +import javafx.application.Application; + public class Main { public static void main(String[] args) { + Application.launch(App.class, args); } } diff --git a/src/main/java/edu/ntnu/idatt2003/view/App.java b/src/main/java/edu/ntnu/idatt2003/view/App.java new file mode 100644 index 0000000..11fe9ec --- /dev/null +++ b/src/main/java/edu/ntnu/idatt2003/view/App.java @@ -0,0 +1,14 @@ +package edu.ntnu.idatt2003.view; + +import javafx.application.Application; +import javafx.stage.Stage; + +public class App extends Application { + public static void main (String[] args) { + launch(args); + } + @Override + public void start(Stage primaryStage) throws Exception { + + } +} -- GitLab From f3d467248b06cf034486c6d52bdc0aa18ebf8020 Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Thu, 18 Apr 2024 10:58:20 +0200 Subject: [PATCH 008/168] Made getMatrix and getVector --- .../java/edu/ntnu/idatt2003/model/AffineTransform2D.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/java/edu/ntnu/idatt2003/model/AffineTransform2D.java b/src/main/java/edu/ntnu/idatt2003/model/AffineTransform2D.java index d7d7562..5f16c49 100644 --- a/src/main/java/edu/ntnu/idatt2003/model/AffineTransform2D.java +++ b/src/main/java/edu/ntnu/idatt2003/model/AffineTransform2D.java @@ -29,4 +29,12 @@ public class AffineTransform2D implements Transform2D { public Vector2D transform(Vector2D point) { return matrix.multiply(point).add(vector); } + + public Matrix2x2 getMatrix() { + return matrix; + } + + public Vector2D getVector() { + return vector; + } } -- GitLab From a665b73509cda87af0cba57e698c309d949e4cda Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Thu, 18 Apr 2024 11:00:11 +0200 Subject: [PATCH 009/168] Started on ChaosGameCLI, made printMenu, loadDescriptionFromFile and saveDescriptionFromFile --- .../java/edu/ntnu/idatt2003/ChaosGameCLI.java | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 src/main/java/edu/ntnu/idatt2003/ChaosGameCLI.java diff --git a/src/main/java/edu/ntnu/idatt2003/ChaosGameCLI.java b/src/main/java/edu/ntnu/idatt2003/ChaosGameCLI.java new file mode 100644 index 0000000..4d96b7b --- /dev/null +++ b/src/main/java/edu/ntnu/idatt2003/ChaosGameCLI.java @@ -0,0 +1,87 @@ +package edu.ntnu.idatt2003; + +import edu.ntnu.idatt2003.model.ChaosGameDescription; +import edu.ntnu.idatt2003.model.ChaosGameFileHandler; + +import java.io.IOException; +import java.util.Scanner; + +public class ChaosGameCLI { + + private ChaosGameDescription chaosGameFileHandler; + + public static void main(String[] args) { + ChaosGameCLI cli = new ChaosGameCLI(); + cli.run(); + } + + public void run() { + Scanner scanner = new Scanner(System.in); + boolean running = true; + while (running) { + printMenu(); + int choice = scanner.nextInt(); + switch (choice) { + case 1: + loadDescriptionFromFile(); + break; + case 2: + saveDescriptionToFile(); + break; + case 3: + System.out.println("Run iterations"); + break; + case 4: + System.out.println("Print ASCII fractal to console"); + break; + case 5: + running = false; + break; + default: + System.out.println("Invalid choice"); + } + } + } + + private void printMenu() { + System.out.println("Menu:"); + System.out.println("1. Load description from file"); + System.out.println("2. Save description to file"); + System.out.println("3. Run iterations"); + System.out.println("4. Print ASCII fractal to console"); + System.out.println("5. Exit"); + System.out.print("Enter your choice: "); + } + + private void loadDescriptionFromFile() { + System.out.println("Enter the file path: "); + Scanner scanner = new Scanner(System.in); + String filePath = scanner.nextLine(); + try { + chaosGameFileHandler = ChaosGameFileHandler.readFromFile(filePath); + System.out.println("Description loaded successfully"); + } catch (IOException e) { + System.out.println("Failed to load description from file"); + } + } + + private void saveDescriptionToFile() { + if (chaosGameFileHandler == null) { + System.out.println("No description to save"); + return; + } + System.out.println("Enter the file path: "); + Scanner scanner = new Scanner(System.in); + String filePath = scanner.nextLine(); + try { + ChaosGameFileHandler.writeToFile(chaosGameFileHandler, filePath); + System.out.println("Description saved successfully"); + } catch (IOException e) { + System.out.println("Failed to save description to file"); + } + } + + private void runIterations() { + + } +} \ No newline at end of file -- GitLab From ef6f0431d3a19b4625c0ec185a6782b62560945b Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Thu, 18 Apr 2024 11:01:04 +0200 Subject: [PATCH 010/168] Made ChaosGameFileHandler --- .../idatt2003/model/ChaosGameFileHandler.java | 116 ++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 src/main/java/edu/ntnu/idatt2003/model/ChaosGameFileHandler.java diff --git a/src/main/java/edu/ntnu/idatt2003/model/ChaosGameFileHandler.java b/src/main/java/edu/ntnu/idatt2003/model/ChaosGameFileHandler.java new file mode 100644 index 0000000..8404170 --- /dev/null +++ b/src/main/java/edu/ntnu/idatt2003/model/ChaosGameFileHandler.java @@ -0,0 +1,116 @@ +package edu.ntnu.idatt2003.model; + +import java.io.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Scanner; + +public class ChaosGameFileHandler { + + // Read a fractal description from a file + public static ChaosGameDescription readFromFile(String filePath) throws IOException { + File file = new File(filePath); + try (Scanner scanner = new Scanner(file)) { + scanner.useDelimiter("\n"); // Split by new lines + + // Read and ignore transformation type (assumed always Affine2D here) + String transformType = scanner.nextLine().trim(); + transformType = transformType.split("#")[0].trim(); // Ignore comments after # + + // Reading coordinates + String line = scanner.nextLine().trim(); + line = line.split("#")[0].trim(); // Ignore comments after # + Vector2D minCoords = parseCoords(line); + + line = scanner.nextLine().trim(); + line = line.split("#")[0].trim(); // Ignore comments after # + Vector2D maxCoords = parseCoords(line); + + // Reading transformations + List<Transform2D> transforms = new ArrayList<>(); + while (scanner.hasNextLine()) { + line = scanner.nextLine().trim(); + if (line.startsWith("#") || line.isEmpty()) continue; // Ignore comments and empty lines + line = line.split("#")[0].trim(); // Ignore comments after # + transforms.add(parseAffineTransform(line)); + } + + return new ChaosGameDescription(transforms, minCoords, maxCoords); + } + } + + // Write a fractal description to a file + public static void writeToFile(ChaosGameDescription description, String filePath) throws IOException { + try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath))) { + String transformType = null; + + if (description.getTransforms().getFirst() instanceof JuliaTransform) { + transformType = "JuliaTransform"; + } else if (description.getTransforms().getFirst() instanceof AffineTransform2D) { + transformType = "Affine2D"; + } + // Write the type of transformation + writer.write(transformType + "\n"); + + // Write the coordinates + Vector2D minCoords = description.getMinCoords(); + writer.write(minCoords.getX0() + ", " + minCoords.getX1() + "\n"); + Vector2D maxCoords = description.getMaxCoords(); + writer.write(maxCoords.getX0() + ", " + maxCoords.getX1() + "\n"); + + if (transformType.equals("JuliaTransform")) { + for (Transform2D transform : description.getTransforms()) { + writer.write(juliaTransformToString((JuliaTransform) transform) + "\n"); + } + } + + if (transformType.equals("Affine2D")) { + for (Transform2D transform : description.getTransforms()) { + writer.write(affineTransformToString((AffineTransform2D) transform) + "\n"); + } + } + } + } + + // Utility method to parse coordinates + private static Vector2D parseCoords(String line) { + String[] parts = line.split(","); + return new Vector2D(Double.parseDouble(parts[0].trim()), Double.parseDouble(parts[1].trim())); + } + + // Parse an AffineTransform2D from a string + private static AffineTransform2D parseAffineTransform(String line) { + String[] parts = line.split(","); + Matrix2x2 matrix = new Matrix2x2( + Double.parseDouble(parts[0].trim()), + Double.parseDouble(parts[1].trim()), + Double.parseDouble(parts[2].trim()), + Double.parseDouble(parts[3].trim()) + ); + Vector2D vector = new Vector2D( + Double.parseDouble(parts[4].trim()), + Double.parseDouble(parts[5].trim()) + ); + return new AffineTransform2D(matrix, vector); + } + + // Convert an AffineTransform2D to a string for file output + private static String affineTransformToString(AffineTransform2D transform) { + Matrix2x2 matrix = transform.getMatrix(); + Vector2D vector = transform.getVector(); + return String.format("%.6f, %.6f, %.6f, %.6f, %.6f, %.6f", + Math.round(matrix.getA00() * 1000000.0) / 1000000.0, + Math.round(matrix.getA01() * 1000000.0) / 1000000.0, + Math.round(matrix.getA10() * 1000000.0) / 1000000.0, + Math.round(matrix.getA11() * 1000000.0) / 1000000.0, + Math.round(vector.getX0() * 1000000.0) / 1000000.0, + Math.round(vector.getX1() * 1000000.0) / 1000000.0); + } + + private static String juliaTransformToString(JuliaTransform transform) { + double real = transform.getPoint().getX0(); + double imaginary = transform.getPoint().getX1(); + return String.format("%f, %f", real, imaginary); + } +} + -- GitLab From 25c908a96f1306896a2f02d65eaba46b334feeb9 Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Thu, 18 Apr 2024 11:01:17 +0200 Subject: [PATCH 011/168] Made getPoint method --- src/main/java/edu/ntnu/idatt2003/model/JuliaTransform.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/edu/ntnu/idatt2003/model/JuliaTransform.java b/src/main/java/edu/ntnu/idatt2003/model/JuliaTransform.java index cd2d628..3d192ae 100644 --- a/src/main/java/edu/ntnu/idatt2003/model/JuliaTransform.java +++ b/src/main/java/edu/ntnu/idatt2003/model/JuliaTransform.java @@ -35,4 +35,8 @@ public class JuliaTransform implements Transform2D { complexResult = complexResult.sqrt(); return new Vector2D(complexResult.getX0()*sign, complexResult.getX1()*sign); } + + public Complex getPoint() { + return point; + } } -- GitLab From a5ef4559f8f72cc19e702b7a9ad8608bbe1f110d Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Thu, 18 Apr 2024 11:03:01 +0200 Subject: [PATCH 012/168] Made getters for each number in the matrix --- src/main/java/edu/ntnu/idatt2003/Main.java | 10 -------- .../edu/ntnu/idatt2003/model/Matrix2x2.java | 24 +++++++++++++++---- 2 files changed, 20 insertions(+), 14 deletions(-) delete mode 100644 src/main/java/edu/ntnu/idatt2003/Main.java diff --git a/src/main/java/edu/ntnu/idatt2003/Main.java b/src/main/java/edu/ntnu/idatt2003/Main.java deleted file mode 100644 index 025ef66..0000000 --- a/src/main/java/edu/ntnu/idatt2003/Main.java +++ /dev/null @@ -1,10 +0,0 @@ -package edu.ntnu.idatt2003; - -import edu.ntnu.idatt2003.view.App; -import javafx.application.Application; - -public class Main { - public static void main(String[] args) { - Application.launch(App.class, args); - } -} diff --git a/src/main/java/edu/ntnu/idatt2003/model/Matrix2x2.java b/src/main/java/edu/ntnu/idatt2003/model/Matrix2x2.java index 56de80f..d9c21ec 100644 --- a/src/main/java/edu/ntnu/idatt2003/model/Matrix2x2.java +++ b/src/main/java/edu/ntnu/idatt2003/model/Matrix2x2.java @@ -1,10 +1,10 @@ package edu.ntnu.idatt2003.model; public class Matrix2x2 { - private double a00; - private double a01; - private double a10; - private double a11; + private final double a00; + private final double a01; + private final double a10; + private final double a11; public Matrix2x2(double a00, double a01, double a10, double a11) { this.a00 = a00; @@ -16,5 +16,21 @@ public class Matrix2x2 { public Vector2D multiply(Vector2D vector) { return new Vector2D(a00 * vector.getX0() + a01 * vector.getX1(), a10 * vector.getX0() + a11 * vector.getX1()); } + + public double getA00() { + return a00; + } + + public double getA01() { + return a01; + } + + public double getA10() { + return a10; + } + + public double getA11() { + return a11; + } } -- GitLab From fc18d45cb182eb0541aac7823259aca55dfeffc8 Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Thu, 18 Apr 2024 11:24:02 +0200 Subject: [PATCH 013/168] Fixed issue in initializeTransform --- .../edu/ntnu/idatt2003/model/ChaosCanvas.java | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/model/ChaosCanvas.java b/src/main/java/edu/ntnu/idatt2003/model/ChaosCanvas.java index bffaefe..f64a21a 100644 --- a/src/main/java/edu/ntnu/idatt2003/model/ChaosCanvas.java +++ b/src/main/java/edu/ntnu/idatt2003/model/ChaosCanvas.java @@ -5,11 +5,11 @@ package edu.ntnu.idatt2003.model; * It has methods for putting and getting pixels, and for clearing the canvas. */ public class ChaosCanvas { - private int[][] canvas; - private int width; - private int height; - private Vector2D minCoords; - private Vector2D maxCoords; + private final int[][] canvas; + private final int width; + private final int height; + private final Vector2D minCoords; + private final Vector2D maxCoords; private AffineTransform2D transformCoordsToIndices; /** @@ -33,11 +33,14 @@ public ChaosCanvas(int width, int height, Vector2D minCoords, Vector2D maxCoords * Initializes the transformation from coordinates to indices. */ private void initializeTransform() { - double scaleX = (width - 1) / (maxCoords.getX0() - minCoords.getX0()); - double scaleY = (height - 1) / (maxCoords.getX1() - minCoords.getX1()); - Matrix2x2 matrix2x2 = new Matrix2x2( 0, scaleX, scaleY, 0); + double a01 = (height - 1) / (maxCoords.getX0() - minCoords.getX0()); + double a10 = (width - 1) / (maxCoords.getX1() - minCoords.getX1()); + + Matrix2x2 matrix2x2 = new Matrix2x2( 0, a01, a10, 0); + double bX = (height - 1)*maxCoords.getX1() / (maxCoords.getX1() - minCoords.getX1()); double bY = (width - 1)*minCoords.getX0() / (minCoords.getX0() - maxCoords.getX0()); + Vector2D vector2D = new Vector2D(bX, bY); transformCoordsToIndices = new AffineTransform2D(matrix2x2, vector2D); } -- GitLab From c0e8143ca62c5bba86d158afca50d85a8ef69982 Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Tue, 23 Apr 2024 18:27:04 +0200 Subject: [PATCH 014/168] Affine2dSave added --- src/main/java/edu/ntnu/idatt2003/Affine2dSave.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 src/main/java/edu/ntnu/idatt2003/Affine2dSave.txt diff --git a/src/main/java/edu/ntnu/idatt2003/Affine2dSave.txt b/src/main/java/edu/ntnu/idatt2003/Affine2dSave.txt new file mode 100644 index 0000000..8f2ef23 --- /dev/null +++ b/src/main/java/edu/ntnu/idatt2003/Affine2dSave.txt @@ -0,0 +1 @@ +0,50, 0,00, 0,00, 0,50, 0,00, 0,000,50, 0,00, 0,00, 0,50, 0,25, 0,500,50, 0,00, 0,00, 0,50, 0,50, 0,00 \ No newline at end of file -- GitLab From c440e3edafd55a728b1281c6b53a4bba6088c3b4 Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Tue, 23 Apr 2024 18:28:14 +0200 Subject: [PATCH 015/168] Classes refactored --- .../java/edu/ntnu/idatt2003/ChaosGameCLI.java | 63 +++++-- .../idatt2003/model/AffineTransform2D.java | 12 ++ .../edu/ntnu/idatt2003/model/ChaosCanvas.java | 18 +- .../edu/ntnu/idatt2003/model/ChaosGame.java | 8 + .../idatt2003/model/ChaosGameDescription.java | 1 + .../idatt2003/model/ChaosGameFileHandler.java | 164 +++++++++--------- .../edu/ntnu/idatt2003/model/Matrix2x2.java | 4 +- 7 files changed, 171 insertions(+), 99 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/ChaosGameCLI.java b/src/main/java/edu/ntnu/idatt2003/ChaosGameCLI.java index 4d96b7b..59a70fe 100644 --- a/src/main/java/edu/ntnu/idatt2003/ChaosGameCLI.java +++ b/src/main/java/edu/ntnu/idatt2003/ChaosGameCLI.java @@ -1,14 +1,15 @@ package edu.ntnu.idatt2003; -import edu.ntnu.idatt2003.model.ChaosGameDescription; -import edu.ntnu.idatt2003.model.ChaosGameFileHandler; +import edu.ntnu.idatt2003.model.*; import java.io.IOException; +import java.util.ArrayList; +import java.util.List; import java.util.Scanner; public class ChaosGameCLI { - - private ChaosGameDescription chaosGameFileHandler; + private static Scanner scanner = new Scanner(System.in); + private static ChaosGame chaosGame; public static void main(String[] args) { ChaosGameCLI cli = new ChaosGameCLI(); @@ -29,10 +30,10 @@ public class ChaosGameCLI { saveDescriptionToFile(); break; case 3: - System.out.println("Run iterations"); + runIterations(); break; case 4: - System.out.println("Print ASCII fractal to console"); + printAsciiFractal(); break; case 5: running = false; @@ -55,10 +56,11 @@ public class ChaosGameCLI { private void loadDescriptionFromFile() { System.out.println("Enter the file path: "); - Scanner scanner = new Scanner(System.in); String filePath = scanner.nextLine(); try { - chaosGameFileHandler = ChaosGameFileHandler.readFromFile(filePath); + ChaosGameFileHandler handler = new ChaosGameFileHandler(filePath); + ChaosGameDescription description= handler.readFile(); + chaosGame = new ChaosGame(description, 100, 100); System.out.println("Description loaded successfully"); } catch (IOException e) { System.out.println("Failed to load description from file"); @@ -66,15 +68,28 @@ public class ChaosGameCLI { } private void saveDescriptionToFile() { - if (chaosGameFileHandler == null) { + if (chaosGame == null || chaosGame.getDescription() == null) { System.out.println("No description to save"); return; } System.out.println("Enter the file path: "); - Scanner scanner = new Scanner(System.in); String filePath = scanner.nextLine(); + List<Transform2D> transforms = chaosGame.getDescription().getTransforms(); + + List<AffineTransform2D> affineTransforms = new ArrayList<>(); + for (Transform2D transform : transforms) { + if (transform instanceof AffineTransform2D) { + affineTransforms.add((AffineTransform2D) transform); + } + } + + if (affineTransforms.isEmpty()) { + System.out.println("No affine transforms to save"); + return; + } try { - ChaosGameFileHandler.writeToFile(chaosGameFileHandler, filePath); + ChaosGameFileHandler handler = new ChaosGameFileHandler(filePath); + handler.writeToFile(filePath, affineTransforms); System.out.println("Description saved successfully"); } catch (IOException e) { System.out.println("Failed to save description to file"); @@ -82,6 +97,32 @@ public class ChaosGameCLI { } private void runIterations() { + if (chaosGame == null) { + System.out.println("No description loaded"); + return; + } + + System.out.println("Enter the number of iterations: "); + int iterations = scanner.nextInt(); + scanner.nextLine(); + + try { + chaosGame.runSteps(iterations); + System.out.println("Succsessfully ran " + iterations + " iterations"); + } catch (Exception e) { + System.out.println("Failed to run iterations: " + e.getMessage()); + } + } + private void printAsciiFractal() { + if (chaosGame == null || chaosGame.getCanvas() == null) { + System.out.println("No fractal to print"); + return; + } + try { + System.out.println(chaosGame.getCanvas().toAscii()); + } catch (Exception e) { + System.out.println("Failed to print fractal: " + e.getMessage()); + } } } \ No newline at end of file diff --git a/src/main/java/edu/ntnu/idatt2003/model/AffineTransform2D.java b/src/main/java/edu/ntnu/idatt2003/model/AffineTransform2D.java index 5f16c49..e7c6e90 100644 --- a/src/main/java/edu/ntnu/idatt2003/model/AffineTransform2D.java +++ b/src/main/java/edu/ntnu/idatt2003/model/AffineTransform2D.java @@ -37,4 +37,16 @@ public class AffineTransform2D implements Transform2D { public Vector2D getVector() { return vector; } + + public String toFormattedString() { + double a00 = matrix.getA00(); + double a01 = matrix.getA01(); + double a10 = matrix.getA10(); + double a11 = matrix.getA11(); + + double b0 = vector.getX0(); + double b1 = vector.getX1(); + + return String.format("%.2f, %.2f, %.2f, %.2f, %.2f, %.2f", a00, a01, a10, a11, b0, b1); + } } diff --git a/src/main/java/edu/ntnu/idatt2003/model/ChaosCanvas.java b/src/main/java/edu/ntnu/idatt2003/model/ChaosCanvas.java index f64a21a..6f901d1 100644 --- a/src/main/java/edu/ntnu/idatt2003/model/ChaosCanvas.java +++ b/src/main/java/edu/ntnu/idatt2003/model/ChaosCanvas.java @@ -33,8 +33,11 @@ public ChaosCanvas(int width, int height, Vector2D minCoords, Vector2D maxCoords * Initializes the transformation from coordinates to indices. */ private void initializeTransform() { - double a01 = (height - 1) / (maxCoords.getX0() - minCoords.getX0()); - double a10 = (width - 1) / (maxCoords.getX1() - minCoords.getX1()); + double a01 = (height - 1) / (minCoords.getX1() - maxCoords.getX1()); + double a10 = (width - 1) / (maxCoords.getX0() - minCoords.getX0()); + + //double bX = -(minCoords.getX1() * a01); + //double bY = -(minCoords.getX0() * a10); Matrix2x2 matrix2x2 = new Matrix2x2( 0, a01, a10, 0); @@ -94,4 +97,15 @@ public ChaosCanvas(int width, int height, Vector2D minCoords, Vector2D maxCoords } } } + + public String toAscii() { + StringBuilder sb = new StringBuilder(); + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + sb.append(getCanvasArray()[y][x] > 0 ? "X" : " "); + } + sb.append("\n"); + } + return sb.toString(); + } } diff --git a/src/main/java/edu/ntnu/idatt2003/model/ChaosGame.java b/src/main/java/edu/ntnu/idatt2003/model/ChaosGame.java index 5024c4e..38fcff8 100644 --- a/src/main/java/edu/ntnu/idatt2003/model/ChaosGame.java +++ b/src/main/java/edu/ntnu/idatt2003/model/ChaosGame.java @@ -20,6 +20,10 @@ public class ChaosGame { } public void runSteps(int steps) { + if (description.getTransforms().isEmpty() || description.getTransforms() == null) { + System.out.println("No transforms in description "); + return; + } for (int i = 0; i < steps; i++) { int randomIndex = random.nextInt(description.getTransforms().size()); Transform2D transform = description.getTransforms().get(randomIndex); @@ -27,4 +31,8 @@ public class ChaosGame { canvas.putPixel(currentPoint); // currentPoint is of type Vector2D } } + + public ChaosGameDescription getDescription() { + return this.description; + } } diff --git a/src/main/java/edu/ntnu/idatt2003/model/ChaosGameDescription.java b/src/main/java/edu/ntnu/idatt2003/model/ChaosGameDescription.java index ae7415d..d8f70e4 100644 --- a/src/main/java/edu/ntnu/idatt2003/model/ChaosGameDescription.java +++ b/src/main/java/edu/ntnu/idatt2003/model/ChaosGameDescription.java @@ -25,4 +25,5 @@ public class ChaosGameDescription { public Vector2D getMaxCoords() { return maxCoords; } + } diff --git a/src/main/java/edu/ntnu/idatt2003/model/ChaosGameFileHandler.java b/src/main/java/edu/ntnu/idatt2003/model/ChaosGameFileHandler.java index 8404170..b59b0d1 100644 --- a/src/main/java/edu/ntnu/idatt2003/model/ChaosGameFileHandler.java +++ b/src/main/java/edu/ntnu/idatt2003/model/ChaosGameFileHandler.java @@ -1,116 +1,110 @@ package edu.ntnu.idatt2003.model; import java.io.*; -import java.util.ArrayList; -import java.util.List; -import java.util.Scanner; +import java.util.*; public class ChaosGameFileHandler { + private String filePath; + + public ChaosGameFileHandler(String filePath) { + this.filePath = filePath; + } // Read a fractal description from a file - public static ChaosGameDescription readFromFile(String filePath) throws IOException { + public ChaosGameDescription readFile() throws IOException { File file = new File(filePath); - try (Scanner scanner = new Scanner(file)) { - scanner.useDelimiter("\n"); // Split by new lines + List<Transform2D> transforms = new ArrayList<>(); + Vector2D minCoords = null; + Vector2D maxCoords = null; - // Read and ignore transformation type (assumed always Affine2D here) - String transformType = scanner.nextLine().trim(); - transformType = transformType.split("#")[0].trim(); // Ignore comments after # + try (Scanner scanner = new Scanner(file)) { + while (scanner.hasNextLine()) { + String line = scanner.nextLine().trim(); + if (line.isEmpty() || line.startsWith("#") || line.contains("Type of transform")) { + continue; // Ignore comments and header information + } - // Reading coordinates - String line = scanner.nextLine().trim(); - line = line.split("#")[0].trim(); // Ignore comments after # - Vector2D minCoords = parseCoords(line); + if (line.contains("Lower left")) { + minCoords = parseVector2D(line.split("#")[0].trim()); + continue; + } - line = scanner.nextLine().trim(); - line = line.split("#")[0].trim(); // Ignore comments after # - Vector2D maxCoords = parseCoords(line); + if (line.contains("Upper right")) { + maxCoords = parseVector2D(line.split("#")[0].trim()); + continue; + } - // Reading transformations - List<Transform2D> transforms = new ArrayList<>(); - while (scanner.hasNextLine()) { - line = scanner.nextLine().trim(); - if (line.startsWith("#") || line.isEmpty()) continue; // Ignore comments and empty lines - line = line.split("#")[0].trim(); // Ignore comments after # - transforms.add(parseAffineTransform(line)); + try { + Transform2D transform = parseAffineTransform(line.split("#")[0].trim()); + if (transform != null) { + transforms.add(transform); + } + } catch (IllegalArgumentException e) { + System.err.println("Error parsing transform from line: " + line); + } } + } catch (FileNotFoundException e) { + System.err.println("Unable to open file: " + filePath); + throw new IOException("File not found: " + filePath, e); + } - return new ChaosGameDescription(transforms, minCoords, maxCoords); + if (minCoords == null || maxCoords == null || transforms.isEmpty()) { + throw new IOException("Failed to properly parse the file: Missing essential data."); } - } - // Write a fractal description to a file - public static void writeToFile(ChaosGameDescription description, String filePath) throws IOException { - try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath))) { - String transformType = null; + return new ChaosGameDescription(transforms, minCoords, maxCoords); + } - if (description.getTransforms().getFirst() instanceof JuliaTransform) { - transformType = "JuliaTransform"; - } else if (description.getTransforms().getFirst() instanceof AffineTransform2D) { - transformType = "Affine2D"; - } - // Write the type of transformation - writer.write(transformType + "\n"); - - // Write the coordinates - Vector2D minCoords = description.getMinCoords(); - writer.write(minCoords.getX0() + ", " + minCoords.getX1() + "\n"); - Vector2D maxCoords = description.getMaxCoords(); - writer.write(maxCoords.getX0() + ", " + maxCoords.getX1() + "\n"); - - if (transformType.equals("JuliaTransform")) { - for (Transform2D transform : description.getTransforms()) { - writer.write(juliaTransformToString((JuliaTransform) transform) + "\n"); - } + private AffineTransform2D parseAffineTransform(String line) { + String[] parts = line.split(","); + ArrayList<Double> params = new ArrayList<>(); + for (String part : parts) { + part = part.split("#")[0].trim(); + try { + params.add(Double.parseDouble(part)); + } catch (NumberFormatException e) { + System.err.println("Skipping invalid numeric data: " + part); } + } - if (transformType.equals("Affine2D")) { - for (Transform2D transform : description.getTransforms()) { - writer.write(affineTransformToString((AffineTransform2D) transform) + "\n"); - } - } + if (params.size() < 6) { + throw new IllegalArgumentException("Not enough valid numeric data to create an AffineTransform2D: " + line); } + + return new AffineTransform2D( + new Matrix2x2(params.get(0), params.get(1), params.get(2), params.get(3)), + new Vector2D(params.get(4), params.get(5)) + ); } - // Utility method to parse coordinates - private static Vector2D parseCoords(String line) { - String[] parts = line.split(","); - return new Vector2D(Double.parseDouble(parts[0].trim()), Double.parseDouble(parts[1].trim())); + private Vector2D parseVector2D(String line) { + String[] parts = line.split("#")[0].trim().split(","); + if (parts.length < 2) return null; + + try { + double x = Double.parseDouble(parts[0].trim()); + double y = Double.parseDouble(parts[1].trim()); + return new Vector2D(x, y); + } catch (NumberFormatException e) { + System.err.println("Failed to parse vector from line: " + line + "; Error: " + e.getMessage()); + return null; + } } - // Parse an AffineTransform2D from a string - private static AffineTransform2D parseAffineTransform(String line) { + private Complex parseComplex(String line) { String[] parts = line.split(","); - Matrix2x2 matrix = new Matrix2x2( - Double.parseDouble(parts[0].trim()), - Double.parseDouble(parts[1].trim()), - Double.parseDouble(parts[2].trim()), - Double.parseDouble(parts[3].trim()) - ); - Vector2D vector = new Vector2D( - Double.parseDouble(parts[4].trim()), - Double.parseDouble(parts[5].trim()) - ); - return new AffineTransform2D(matrix, vector); + return new Complex(Double.parseDouble(parts[0].trim()), Double.parseDouble(parts[1].trim())); } - // Convert an AffineTransform2D to a string for file output - private static String affineTransformToString(AffineTransform2D transform) { - Matrix2x2 matrix = transform.getMatrix(); - Vector2D vector = transform.getVector(); - return String.format("%.6f, %.6f, %.6f, %.6f, %.6f, %.6f", - Math.round(matrix.getA00() * 1000000.0) / 1000000.0, - Math.round(matrix.getA01() * 1000000.0) / 1000000.0, - Math.round(matrix.getA10() * 1000000.0) / 1000000.0, - Math.round(matrix.getA11() * 1000000.0) / 1000000.0, - Math.round(vector.getX0() * 1000000.0) / 1000000.0, - Math.round(vector.getX1() * 1000000.0) / 1000000.0); - } - private static String juliaTransformToString(JuliaTransform transform) { - double real = transform.getPoint().getX0(); - double imaginary = transform.getPoint().getX1(); - return String.format("%f, %f", real, imaginary); + public void writeToFile(String filePath, List<AffineTransform2D> transforms) throws IOException { + try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath))) { + for (AffineTransform2D transform : transforms) { + writer.write(transform.toFormattedString()); + } + } catch (IOException e) { + System.out.println("An error occurred: " + e.getMessage()); + } } } diff --git a/src/main/java/edu/ntnu/idatt2003/model/Matrix2x2.java b/src/main/java/edu/ntnu/idatt2003/model/Matrix2x2.java index d9c21ec..8524ab3 100644 --- a/src/main/java/edu/ntnu/idatt2003/model/Matrix2x2.java +++ b/src/main/java/edu/ntnu/idatt2003/model/Matrix2x2.java @@ -14,7 +14,9 @@ public class Matrix2x2 { } public Vector2D multiply(Vector2D vector) { - return new Vector2D(a00 * vector.getX0() + a01 * vector.getX1(), a10 * vector.getX0() + a11 * vector.getX1()); + return new Vector2D( + a00 * vector.getX0() + a01 * vector.getX1(), + a10 * vector.getX0() + a11 * vector.getX1()); } public double getA00() { -- GitLab From 57bbdcda5dd79a1e7e7981b13f4cbeff71f0a2b3 Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Tue, 23 Apr 2024 18:47:45 +0200 Subject: [PATCH 016/168] Layout for Observers added --- .../ntnu/idatt2003/controller/Observer.java | 5 +++ .../ntnu/idatt2003/controller/Subject.java | 41 +++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 src/main/java/edu/ntnu/idatt2003/controller/Observer.java create mode 100644 src/main/java/edu/ntnu/idatt2003/controller/Subject.java diff --git a/src/main/java/edu/ntnu/idatt2003/controller/Observer.java b/src/main/java/edu/ntnu/idatt2003/controller/Observer.java new file mode 100644 index 0000000..961cd4c --- /dev/null +++ b/src/main/java/edu/ntnu/idatt2003/controller/Observer.java @@ -0,0 +1,5 @@ +package edu.ntnu.idatt2003.controller; + +public interface Observer { + void update(); +} diff --git a/src/main/java/edu/ntnu/idatt2003/controller/Subject.java b/src/main/java/edu/ntnu/idatt2003/controller/Subject.java new file mode 100644 index 0000000..058042c --- /dev/null +++ b/src/main/java/edu/ntnu/idatt2003/controller/Subject.java @@ -0,0 +1,41 @@ +package edu.ntnu.idatt2003.controller; + +import java.util.ArrayList; +import java.util.List; + +/** + * Abstract class representing a subject in the observer pattern. + */ +public abstract class Subject { + List<Observer> observers; + + /** + * Constructor for the subject. + */ + public Subject() { + observers = new ArrayList<>(); + } + + /** + * Attach an observer to the subject. + * @param observer The observer to attach. + */ + public void attach(Observer observer) { + observers.add(observer); + } + + /** + * Detach an observer from the subject. + * @param observer The observer to detach. + */ + public void detach(Observer observer) { + observers.remove(observer); + } + + /** + * Notify all observers of the subject. + */ + public void notifyObservers() { + observers.forEach(Observer::update); + } +} -- GitLab From 4af4b0d214a4e01faaa354b32ae9054c2d97d142 Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Tue, 23 Apr 2024 18:48:10 +0200 Subject: [PATCH 017/168] Main added --- src/main/java/edu/ntnu/idatt2003/Main.java | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 src/main/java/edu/ntnu/idatt2003/Main.java diff --git a/src/main/java/edu/ntnu/idatt2003/Main.java b/src/main/java/edu/ntnu/idatt2003/Main.java new file mode 100644 index 0000000..c0f820a --- /dev/null +++ b/src/main/java/edu/ntnu/idatt2003/Main.java @@ -0,0 +1,9 @@ +package edu.ntnu.idatt2003; + +import edu.ntnu.idatt2003.view.App; + +public class Main { + public static void main(String[] args) { + App.main(args); + } +} -- GitLab From fdf291661527321ca30a3476b93f47faebfb3957 Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Tue, 23 Apr 2024 18:48:32 +0200 Subject: [PATCH 018/168] Resource folder added --- src/main/{java/edu/ntnu/idatt2003 => resources}/Affine2dSave.txt | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/main/{java/edu/ntnu/idatt2003 => resources}/Affine2dSave.txt (100%) diff --git a/src/main/java/edu/ntnu/idatt2003/Affine2dSave.txt b/src/main/resources/Affine2dSave.txt similarity index 100% rename from src/main/java/edu/ntnu/idatt2003/Affine2dSave.txt rename to src/main/resources/Affine2dSave.txt -- GitLab From ed070da368f8b6fa5c1f2777801afac535ced314 Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Tue, 23 Apr 2024 21:13:23 +0200 Subject: [PATCH 019/168] StartScene added --- .../idatt2003/view/scenes/StartScene.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 src/main/java/edu/ntnu/idatt2003/view/scenes/StartScene.java diff --git a/src/main/java/edu/ntnu/idatt2003/view/scenes/StartScene.java b/src/main/java/edu/ntnu/idatt2003/view/scenes/StartScene.java new file mode 100644 index 0000000..c260dec --- /dev/null +++ b/src/main/java/edu/ntnu/idatt2003/view/scenes/StartScene.java @@ -0,0 +1,21 @@ +package edu.ntnu.idatt2003.view.scenes; + +import javafx.scene.Scene; +import javafx.scene.control.Button; +import javafx.scene.layout.StackPane; +import javafx.stage.Stage; + +public class StartScene { + public void start(Stage primaryStage) { + + Button startButton = new Button("Start Game"); + StackPane root = new StackPane(); + root.getChildren().add(startButton); + + Scene scene = new Scene(root, 1300, 500); + + primaryStage.setScene(scene); + primaryStage.setTitle("Chaos Game"); + primaryStage.show(); + } +} -- GitLab From 9245d8cbea05c72699af9a91ee6625217c27f264 Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Tue, 23 Apr 2024 21:14:15 +0200 Subject: [PATCH 020/168] Refactored --- src/main/java/edu/ntnu/idatt2003/Main.java | 5 +++-- src/main/java/edu/ntnu/idatt2003/view/App.java | 8 +++++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/Main.java b/src/main/java/edu/ntnu/idatt2003/Main.java index c0f820a..dcb0edf 100644 --- a/src/main/java/edu/ntnu/idatt2003/Main.java +++ b/src/main/java/edu/ntnu/idatt2003/Main.java @@ -1,9 +1,10 @@ package edu.ntnu.idatt2003; import edu.ntnu.idatt2003.view.App; +import javafx.application.Application; -public class Main { +public class Main extends App { public static void main(String[] args) { - App.main(args); + Application.launch(App.class, args); } } diff --git a/src/main/java/edu/ntnu/idatt2003/view/App.java b/src/main/java/edu/ntnu/idatt2003/view/App.java index 11fe9ec..94060a9 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/App.java +++ b/src/main/java/edu/ntnu/idatt2003/view/App.java @@ -1,14 +1,16 @@ package edu.ntnu.idatt2003.view; +import edu.ntnu.idatt2003.view.scenes.StartScene; import javafx.application.Application; import javafx.stage.Stage; public class App extends Application { - public static void main (String[] args) { + public static void main(String[] args) { launch(args); } @Override - public void start(Stage primaryStage) throws Exception { - + public void start (Stage primaryStage) { + StartScene startScene = new StartScene(); + startScene.start(primaryStage); } } -- GitLab From c8fd2876775cee6c4ff4619e5fa2d0e5326f7427 Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Mon, 13 May 2024 12:34:48 +0200 Subject: [PATCH 021/168] Made ChaosGameDescriptionFactory --- .../model/ChaosGameDescriptionFactory.java | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 src/main/java/edu/ntnu/idatt2003/model/ChaosGameDescriptionFactory.java diff --git a/src/main/java/edu/ntnu/idatt2003/model/ChaosGameDescriptionFactory.java b/src/main/java/edu/ntnu/idatt2003/model/ChaosGameDescriptionFactory.java new file mode 100644 index 0000000..d8c5a6f --- /dev/null +++ b/src/main/java/edu/ntnu/idatt2003/model/ChaosGameDescriptionFactory.java @@ -0,0 +1,56 @@ +package edu.ntnu.idatt2003.model; + +import java.util.Arrays; + +/** + * This class is a factory for creating different standard fractals as ChaosGameDescriptions. + */ +public class ChaosGameDescriptionFactory { + /** + * Creates a ChaosGameDescription for the Sierpinski triangle. + * @return a ChaosGameDescription for the Sierpinski triangle + */ + public static ChaosGameDescription createSierpinskiTriangle() { + AffineTransform2D[] transforms = new AffineTransform2D[3]; + transforms[0] = new AffineTransform2D(new Matrix2x2(0.5, 0.0, 0.0, 0.5), new Vector2D(0.0, 0.0)); + transforms[1] = new AffineTransform2D(new Matrix2x2(0.5, 0.0, 0.0, 0.5), new Vector2D(0.5, 0.0)); + transforms[2] = new AffineTransform2D(new Matrix2x2(0.5, 0.0, 0.0, 0.5), new Vector2D(0.25, 0.5)); + + Vector2D lowerLeft = new Vector2D(0.0, 0.0); + Vector2D lowerRight = new Vector2D(1.0, 1.0); + + return new ChaosGameDescription(Arrays.asList(transforms), lowerLeft, lowerRight); + } + + /** + * Creates a ChaosGameDescription for the Barnsley fern. + * @return a ChaosGameDescription for the Barnsley fern + */ + public static ChaosGameDescription createBarnsleyFern() { + AffineTransform2D[] transforms = new AffineTransform2D[4]; + transforms[0] = new AffineTransform2D(new Matrix2x2(0.0, 0.0, 0.0, 0.16), new Vector2D(0.0, 0.0)); + transforms[1] = new AffineTransform2D(new Matrix2x2(0.85, 0.04, -0.04, 0.85), new Vector2D(0.0, 1.6)); + transforms[2] = new AffineTransform2D(new Matrix2x2(0.2, -0.26, 0.23, 0.22), new Vector2D(0.0, 1.6)); + transforms[3] = new AffineTransform2D(new Matrix2x2(-0.15, 0.28, 0.26, 0.24), new Vector2D(0.0, 0.44)); + + Vector2D lowerLeft = new Vector2D(-2.1820, 0.0); + Vector2D upperRight = new Vector2D(2.6558, 9.9983); + + return new ChaosGameDescription(Arrays.asList(transforms), lowerLeft, upperRight); + } + + /** + * Creates a ChaosGameDescription for the Julia set with the given complex number. + * @param c the complex number + * @param sign the sign of the imaginary part of the complex number + * @return a ChaosGameDescription for the Julia set + */ + public static ChaosGameDescription createJuliaSet(Complex c, int sign) { + JuliaTransform[] transforms = new JuliaTransform[1]; + transforms[0] = new JuliaTransform(c, sign); + Vector2D lowerLeft = new Vector2D(-2.0, -2.0); + Vector2D upperRight = new Vector2D(2.0, 2.0); + + return new ChaosGameDescription(Arrays.asList(transforms), lowerLeft, upperRight); + } +} -- GitLab From 15944f2e63551e032401c1c9fbb99c5291fe2683 Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Mon, 13 May 2024 12:35:14 +0200 Subject: [PATCH 022/168] Text file of Affine2D fractal --- src/main/resources/Affine2d.txt | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 src/main/resources/Affine2d.txt diff --git a/src/main/resources/Affine2d.txt b/src/main/resources/Affine2d.txt new file mode 100644 index 0000000..8219677 --- /dev/null +++ b/src/main/resources/Affine2d.txt @@ -0,0 +1,6 @@ +Affine2D # Type of transform +0, 0 # Lower left +1, 1 # Upper right +.5, 0, 0, .5, 0, 0 # 1st transform +.5, 0, 0, .5, .25, .5 # 2nd transform +.5, 0, 0, .5, .5, 0 # 3rd transform -- GitLab From 9aac91e321af6312e0b77bca2fb7d14351d525e7 Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Mon, 13 May 2024 12:41:17 +0200 Subject: [PATCH 023/168] added getTransformType and Locale.English in string.format --- .../java/edu/ntnu/idatt2003/model/AffineTransform2D.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/java/edu/ntnu/idatt2003/model/AffineTransform2D.java b/src/main/java/edu/ntnu/idatt2003/model/AffineTransform2D.java index e7c6e90..9009d94 100644 --- a/src/main/java/edu/ntnu/idatt2003/model/AffineTransform2D.java +++ b/src/main/java/edu/ntnu/idatt2003/model/AffineTransform2D.java @@ -1,5 +1,7 @@ package edu.ntnu.idatt2003.model; +import java.util.Locale; + /** * This class represents a 2D affine transformation of the form x -> Ax + b. * 'A' is a 2x2 matrix and 'b' is a 2D vector. @@ -47,6 +49,10 @@ public class AffineTransform2D implements Transform2D { double b0 = vector.getX0(); double b1 = vector.getX1(); - return String.format("%.2f, %.2f, %.2f, %.2f, %.2f, %.2f", a00, a01, a10, a11, b0, b1); + return String.format(Locale.ENGLISH,"%.2f, %.2f, %.2f, %.2f, %.2f, %.2f", a00, a01, a10, a11, b0, b1); + } + + public String getTransformType() { + return "Affine2D"; } } -- GitLab From c5953c4d4f871d62388bd183fd4f1e31b81fcc2c Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Mon, 13 May 2024 12:42:17 +0200 Subject: [PATCH 024/168] improved writeToFile --- .../idatt2003/model/ChaosGameDescription.java | 1 - .../idatt2003/model/ChaosGameFileHandler.java | 21 ++++++++++++++++--- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/model/ChaosGameDescription.java b/src/main/java/edu/ntnu/idatt2003/model/ChaosGameDescription.java index d8f70e4..a03a513 100644 --- a/src/main/java/edu/ntnu/idatt2003/model/ChaosGameDescription.java +++ b/src/main/java/edu/ntnu/idatt2003/model/ChaosGameDescription.java @@ -1,6 +1,5 @@ package edu.ntnu.idatt2003.model; -import javax.xml.crypto.dsig.Transform; import java.util.List; public class ChaosGameDescription { diff --git a/src/main/java/edu/ntnu/idatt2003/model/ChaosGameFileHandler.java b/src/main/java/edu/ntnu/idatt2003/model/ChaosGameFileHandler.java index b59b0d1..824337f 100644 --- a/src/main/java/edu/ntnu/idatt2003/model/ChaosGameFileHandler.java +++ b/src/main/java/edu/ntnu/idatt2003/model/ChaosGameFileHandler.java @@ -97,10 +97,25 @@ public class ChaosGameFileHandler { } - public void writeToFile(String filePath, List<AffineTransform2D> transforms) throws IOException { + public void writeToFile(String filePath, ChaosGameDescription description) throws IOException { try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath))) { - for (AffineTransform2D transform : transforms) { - writer.write(transform.toFormattedString()); + writer.write(description.getTransforms().getFirst().getTransformType() + " # Type of transform"); + writer.newLine(); + Vector2D minCoords = description.getMinCoords(); + Vector2D maxCoords = description.getMaxCoords(); + List<Transform2D> transforms = description.getTransforms(); + + writer.write(minCoords.getX0() + ", " + minCoords.getX1() + " # Lower left"); + writer.newLine(); + + writer.write(maxCoords.getX0() + ", " + maxCoords.getX1() + " # Upper right"); + writer.newLine(); + + int transformIndex = 1; + for (Transform2D transform : transforms) { + writer.write(transform.toFormattedString() + " # Transform nr." + transformIndex); + writer.newLine(); + transformIndex++; } } catch (IOException e) { System.out.println("An error occurred: " + e.getMessage()); -- GitLab From 7165de57474ca7fbc708ba7c75f6a113f0973108 Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Mon, 13 May 2024 12:42:51 +0200 Subject: [PATCH 025/168] refactor --- src/main/java/edu/ntnu/idatt2003/ChaosGameCLI.java | 2 +- .../java/edu/ntnu/idatt2003/model/JuliaTransform.java | 11 +++++++++++ .../java/edu/ntnu/idatt2003/model/Transform2D.java | 4 ++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/main/java/edu/ntnu/idatt2003/ChaosGameCLI.java b/src/main/java/edu/ntnu/idatt2003/ChaosGameCLI.java index 59a70fe..d943fef 100644 --- a/src/main/java/edu/ntnu/idatt2003/ChaosGameCLI.java +++ b/src/main/java/edu/ntnu/idatt2003/ChaosGameCLI.java @@ -89,7 +89,7 @@ public class ChaosGameCLI { } try { ChaosGameFileHandler handler = new ChaosGameFileHandler(filePath); - handler.writeToFile(filePath, affineTransforms); + handler.writeToFile(filePath, chaosGame.getDescription()); System.out.println("Description saved successfully"); } catch (IOException e) { System.out.println("Failed to save description to file"); diff --git a/src/main/java/edu/ntnu/idatt2003/model/JuliaTransform.java b/src/main/java/edu/ntnu/idatt2003/model/JuliaTransform.java index 3d192ae..d576c93 100644 --- a/src/main/java/edu/ntnu/idatt2003/model/JuliaTransform.java +++ b/src/main/java/edu/ntnu/idatt2003/model/JuliaTransform.java @@ -36,6 +36,17 @@ public class JuliaTransform implements Transform2D { return new Vector2D(complexResult.getX0()*sign, complexResult.getX1()*sign); } + @Override + public String getTransformType() { + return "Julia"; + } + + @Override + public String toFormattedString() { + //return String.format("c = %.2f + %.2fi, sign = %d", point.getReal(), point.getImaginary(), sign); + return ""; + } + public Complex getPoint() { return point; } diff --git a/src/main/java/edu/ntnu/idatt2003/model/Transform2D.java b/src/main/java/edu/ntnu/idatt2003/model/Transform2D.java index 2dea958..42bec3f 100644 --- a/src/main/java/edu/ntnu/idatt2003/model/Transform2D.java +++ b/src/main/java/edu/ntnu/idatt2003/model/Transform2D.java @@ -11,4 +11,8 @@ public interface Transform2D { * @return the transformed vector */ Vector2D transform(Vector2D point); + String getTransformType(); + + String toFormattedString(); } + -- GitLab From 57a67b57ae90198826bc4da33c1c8c52d25f4e2b Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Mon, 13 May 2024 12:55:16 +0200 Subject: [PATCH 026/168] Refactored ChaosGameDescriptionFactory --- .../ntnu/idatt2003/model/ChaosGameDescriptionFactory.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/model/ChaosGameDescriptionFactory.java b/src/main/java/edu/ntnu/idatt2003/model/ChaosGameDescriptionFactory.java index d8c5a6f..8b58cc1 100644 --- a/src/main/java/edu/ntnu/idatt2003/model/ChaosGameDescriptionFactory.java +++ b/src/main/java/edu/ntnu/idatt2003/model/ChaosGameDescriptionFactory.java @@ -33,8 +33,8 @@ public class ChaosGameDescriptionFactory { transforms[2] = new AffineTransform2D(new Matrix2x2(0.2, -0.26, 0.23, 0.22), new Vector2D(0.0, 1.6)); transforms[3] = new AffineTransform2D(new Matrix2x2(-0.15, 0.28, 0.26, 0.24), new Vector2D(0.0, 0.44)); - Vector2D lowerLeft = new Vector2D(-2.1820, 0.0); - Vector2D upperRight = new Vector2D(2.6558, 9.9983); + Vector2D lowerLeft = new Vector2D(-2.5, 0.0); + Vector2D upperRight = new Vector2D(2.5, 10.0); return new ChaosGameDescription(Arrays.asList(transforms), lowerLeft, upperRight); } @@ -48,8 +48,8 @@ public class ChaosGameDescriptionFactory { public static ChaosGameDescription createJuliaSet(Complex c, int sign) { JuliaTransform[] transforms = new JuliaTransform[1]; transforms[0] = new JuliaTransform(c, sign); - Vector2D lowerLeft = new Vector2D(-2.0, -2.0); - Vector2D upperRight = new Vector2D(2.0, 2.0); + Vector2D lowerLeft = new Vector2D(-1.6, -1.0); + Vector2D upperRight = new Vector2D(1.6, 1.0); return new ChaosGameDescription(Arrays.asList(transforms), lowerLeft, upperRight); } -- GitLab From 04cc9025fb428d5e418a0850243dfacd04e9cfc3 Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Mon, 13 May 2024 17:29:41 +0200 Subject: [PATCH 027/168] Vector2dTest made --- src/test/heihei.java | 0 .../ntnu/idatt2003/model/Vector2dTest.java | 56 +++++++++++++++++++ 2 files changed, 56 insertions(+) delete mode 100644 src/test/heihei.java create mode 100644 src/test/java/edu/ntnu/idatt2003/model/Vector2dTest.java diff --git a/src/test/heihei.java b/src/test/heihei.java deleted file mode 100644 index e69de29..0000000 diff --git a/src/test/java/edu/ntnu/idatt2003/model/Vector2dTest.java b/src/test/java/edu/ntnu/idatt2003/model/Vector2dTest.java new file mode 100644 index 0000000..8f11210 --- /dev/null +++ b/src/test/java/edu/ntnu/idatt2003/model/Vector2dTest.java @@ -0,0 +1,56 @@ +package edu.ntnu.idatt2003.model; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; + +public class Vector2dTest { +private Vector2D vector1; +private Vector2D vector2; + +@BeforeEach +void setUp() { + vector1 = new Vector2D(1, 2); + vector2 = new Vector2D(3, 4); +} +@Nested +@DisplayName("Positive tests for the Vector2d class.") + class PositiveVector2dTests { + + @Test + void testAdd() { + Vector2D result = vector1.add(vector2); + assertEquals(4, result.getX0()); + assertEquals(6, result.getX1()); + } + + @Test + void testSubtract() { + Vector2D result = vector1.subtract(vector2); + assertEquals(-2, result.getX0()); + assertEquals(-2, result.getX1()); + } + @Nested + @DisplayName("Negative tests for the Vector2d class.") + class NegativeVector2dTests { + @Test + void testAdd() { + Vector2D result = vector1.add(vector2); + assertNotEquals(0, result.getX0()); + assertNotEquals(0, result.getX1()); + } + + @Test + void testSubtract() { + Vector2D result = vector1.subtract(vector2); + assertNotEquals(0, result.getX0()); + assertNotEquals(0, result.getX1()); + } + } +} +} + -- GitLab From 0786a462e9aff5248060097b0b532b74425fcbc6 Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Mon, 13 May 2024 17:42:52 +0200 Subject: [PATCH 028/168] Vector2dTest refactored --- .../edu/ntnu/idatt2003/model/Vector2dTest.java | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/src/test/java/edu/ntnu/idatt2003/model/Vector2dTest.java b/src/test/java/edu/ntnu/idatt2003/model/Vector2dTest.java index 8f11210..d039a18 100644 --- a/src/test/java/edu/ntnu/idatt2003/model/Vector2dTest.java +++ b/src/test/java/edu/ntnu/idatt2003/model/Vector2dTest.java @@ -37,19 +37,7 @@ void setUp() { @Nested @DisplayName("Negative tests for the Vector2d class.") class NegativeVector2dTests { - @Test - void testAdd() { - Vector2D result = vector1.add(vector2); - assertNotEquals(0, result.getX0()); - assertNotEquals(0, result.getX1()); - } - - @Test - void testSubtract() { - Vector2D result = vector1.subtract(vector2); - assertNotEquals(0, result.getX0()); - assertNotEquals(0, result.getX1()); - } + } } } -- GitLab From 14ca3673ec45c857836e00adaad70fe63e6ebfd5 Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Mon, 13 May 2024 17:43:11 +0200 Subject: [PATCH 029/168] Matrix2x2Test made --- .../ntnu/idatt2003/model/Matrix2x2Test.java | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 src/test/java/edu/ntnu/idatt2003/model/Matrix2x2Test.java diff --git a/src/test/java/edu/ntnu/idatt2003/model/Matrix2x2Test.java b/src/test/java/edu/ntnu/idatt2003/model/Matrix2x2Test.java new file mode 100644 index 0000000..25b3b07 --- /dev/null +++ b/src/test/java/edu/ntnu/idatt2003/model/Matrix2x2Test.java @@ -0,0 +1,56 @@ +package edu.ntnu.idatt2003.model; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; + +public class Matrix2x2Test { + private Matrix2x2 matrix; + private Vector2D vector; + + @BeforeEach + void setUp() { + matrix = new Matrix2x2(1, 2, 3, 4); + vector = new Vector2D(1, 2); + } + + @Nested + @DisplayName("Positive tests for the Matrix2x2 class.") + class PositiveMatrix2x2Test { + @Test + void testMultiply() { + Vector2D result = matrix.multiply(vector); + assertEquals(5, result.getX0()); + assertEquals(11, result.getX1()); + } + + @Test + void testGetA00() { + assertEquals(1, matrix.getA00()); + } + + @Test + void testGetA01() { + assertEquals(2, matrix.getA01()); + } + + @Test + void testGetA10() { + assertEquals(3, matrix.getA10()); + } + + @Test + void testGetA11() { + assertEquals(4, matrix.getA11()); + } + } + @Nested + @DisplayName("Negative tests for the Matrix2x2 class.") + class NegativeMatrix2x2Test { + + } +} -- GitLab From 122b8ad707fb833d824bdf6617ddd5422fb9c837 Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Mon, 13 May 2024 18:34:21 +0200 Subject: [PATCH 030/168] Matrix2x2Test made --- .../model/AffineTransform2dTest.java | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 src/test/java/edu/ntnu/idatt2003/model/AffineTransform2dTest.java diff --git a/src/test/java/edu/ntnu/idatt2003/model/AffineTransform2dTest.java b/src/test/java/edu/ntnu/idatt2003/model/AffineTransform2dTest.java new file mode 100644 index 0000000..8972392 --- /dev/null +++ b/src/test/java/edu/ntnu/idatt2003/model/AffineTransform2dTest.java @@ -0,0 +1,65 @@ +package edu.ntnu.idatt2003.model; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class AffineTransform2dTest { + private Matrix2x2 matrix; + private Vector2D vector; + private Vector2D point; + + @BeforeEach + public void setUp() { + matrix = new Matrix2x2(1, 2, 3, 4); + vector = new Vector2D(1.0, 2.0); + point = new Vector2D(1.0, 2.0); + } + + @Nested + @DisplayName("Positive tests for the AffineTransform2d class.") + class PositiveAffineTransform2dTest { + @Test + void testTransform() { + AffineTransform2D transform = new AffineTransform2D(matrix, point); + Vector2D result = transform.transform(vector); + + assertEquals(6, result.getX0()); + assertEquals(13, result.getX1()); + } + + @Test + void testGetMatrix() { + AffineTransform2D transform = new AffineTransform2D(matrix, point); + assertEquals(matrix, transform.getMatrix()); + } + + @Test + void testGetVector() { + AffineTransform2D transform = new AffineTransform2D(matrix, point); + assertEquals(point, transform.getVector()); + } + + @Test + void testToFormattedString() { + AffineTransform2D transform = new AffineTransform2D(matrix, point); + String result = transform.toFormattedString(); + assertEquals("1.00, 2.00, 3.00, 4.00, 1.00, 2.00", result); + } + + @Test + void getTransformType() { + AffineTransform2D transform = new AffineTransform2D(matrix, point); + assertEquals("Affine2D", transform.getTransformType()); + } + + @Nested + @DisplayName("Negative tests for the AffineTransform2d class.") + class NegativeAffineTransform2dTest { + + } + } +} -- GitLab From c5e0a8dc56ff342ef1380f4802d108d6e92f4353 Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Mon, 13 May 2024 18:34:40 +0200 Subject: [PATCH 031/168] AffineTransform2dTest made* --- .../java/edu/ntnu/idatt2003/model/AffineTransform2dTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/java/edu/ntnu/idatt2003/model/AffineTransform2dTest.java b/src/test/java/edu/ntnu/idatt2003/model/AffineTransform2dTest.java index 8972392..9446024 100644 --- a/src/test/java/edu/ntnu/idatt2003/model/AffineTransform2dTest.java +++ b/src/test/java/edu/ntnu/idatt2003/model/AffineTransform2dTest.java @@ -59,7 +59,6 @@ public class AffineTransform2dTest { @Nested @DisplayName("Negative tests for the AffineTransform2d class.") class NegativeAffineTransform2dTest { - } } } -- GitLab From 3c3b65244ffe12a11ab3304e5f47e3797df04c80 Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Mon, 13 May 2024 19:01:10 +0200 Subject: [PATCH 032/168] ComplexTest made --- .../edu/ntnu/idatt2003/model/ComplexTest.java | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 src/test/java/edu/ntnu/idatt2003/model/ComplexTest.java diff --git a/src/test/java/edu/ntnu/idatt2003/model/ComplexTest.java b/src/test/java/edu/ntnu/idatt2003/model/ComplexTest.java new file mode 100644 index 0000000..320cb27 --- /dev/null +++ b/src/test/java/edu/ntnu/idatt2003/model/ComplexTest.java @@ -0,0 +1,28 @@ +package edu.ntnu.idatt2003.model; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class ComplexTest { + private Complex complex; + + @BeforeEach + public void setUp() { + complex = new Complex(1, 2); + } + + @Nested + @DisplayName("Positive tests for the Complex class.") + class PositiveComplexTest { + @Test + void testSqrt() { + Complex result = complex.sqrt(); + assertEquals(1.272, result.getX0(), 0.001); + assertEquals(0.786, result.getX1(), 0.001); + } + } +} -- GitLab From 1fec2fc6349945cda7a1af0f97ddc911ad5e7303 Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Mon, 13 May 2024 19:06:46 +0200 Subject: [PATCH 033/168] ComplexTest made --- .../edu/ntnu/idatt2003/model/ComplexTest.java | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 src/test/java/edu/ntnu/idatt2003/model/ComplexTest.java diff --git a/src/test/java/edu/ntnu/idatt2003/model/ComplexTest.java b/src/test/java/edu/ntnu/idatt2003/model/ComplexTest.java new file mode 100644 index 0000000..320cb27 --- /dev/null +++ b/src/test/java/edu/ntnu/idatt2003/model/ComplexTest.java @@ -0,0 +1,28 @@ +package edu.ntnu.idatt2003.model; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class ComplexTest { + private Complex complex; + + @BeforeEach + public void setUp() { + complex = new Complex(1, 2); + } + + @Nested + @DisplayName("Positive tests for the Complex class.") + class PositiveComplexTest { + @Test + void testSqrt() { + Complex result = complex.sqrt(); + assertEquals(1.272, result.getX0(), 0.001); + assertEquals(0.786, result.getX1(), 0.001); + } + } +} -- GitLab From 0864ce0c27f8e300d95539af83cd23a484b6cb41 Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Tue, 14 May 2024 10:55:25 +0200 Subject: [PATCH 034/168] Added ButtonController --- src/main/java/edu/ntnu/idatt2003/view/App.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/view/App.java b/src/main/java/edu/ntnu/idatt2003/view/App.java index 94060a9..db4c352 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/App.java +++ b/src/main/java/edu/ntnu/idatt2003/view/App.java @@ -1,5 +1,6 @@ package edu.ntnu.idatt2003.view; +import edu.ntnu.idatt2003.controller.ButtonController; import edu.ntnu.idatt2003.view.scenes.StartScene; import javafx.application.Application; import javafx.stage.Stage; @@ -8,9 +9,14 @@ public class App extends Application { public static void main(String[] args) { launch(args); } + @Override - public void start (Stage primaryStage) { + public void start(Stage primaryStage) { StartScene startScene = new StartScene(); - startScene.start(primaryStage); + startScene.setUpStage(primaryStage); + + // Initialize the controller and set up handlers + ButtonController buttonController = new ButtonController(startScene); + buttonController.initialize(); } } -- GitLab From 966ded0e30f5783e4395527eff446591ee25524c Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Tue, 14 May 2024 10:55:37 +0200 Subject: [PATCH 035/168] Made ButtonController --- .../controller/ButtonController.java | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 src/main/java/edu/ntnu/idatt2003/controller/ButtonController.java diff --git a/src/main/java/edu/ntnu/idatt2003/controller/ButtonController.java b/src/main/java/edu/ntnu/idatt2003/controller/ButtonController.java new file mode 100644 index 0000000..cebf233 --- /dev/null +++ b/src/main/java/edu/ntnu/idatt2003/controller/ButtonController.java @@ -0,0 +1,39 @@ +package edu.ntnu.idatt2003.controller; + +import edu.ntnu.idatt2003.view.scenes.StartScene; +import javafx.scene.control.Button; + +public class ButtonController { + private StartScene startScene; + + public ButtonController(StartScene startScene) { + this.startScene = startScene; + } + + public void initialize() { + setButtonHandlers(); + } + + private void setButtonHandlers() { + Button btnAdd10 = startScene.getBtnAdd10(); + btnAdd10.setOnAction(e -> { + System.out.println("Add 10"); + }); + + // Set handlers for other buttons if needed + Button btnAdd100 = startScene.getBtnAdd100(); + btnAdd100.setOnAction(e -> { + System.out.println("Add 100"); + }); + + Button btnAdd1000 = startScene.getBtnAdd1000(); + btnAdd1000.setOnAction(e -> { + System.out.println("Add 1000"); + }); + + Button btnReset = startScene.getBtnReset(); + btnReset.setOnAction(e -> { + System.out.println("Reset"); + }); + } +} -- GitLab From 0c3d89e2db9490af1ca8528d05cfd9c68926952e Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Tue, 14 May 2024 10:56:01 +0200 Subject: [PATCH 036/168] Added buttons and combox to StartScene --- .../idatt2003/view/scenes/StartScene.java | 91 +++++++++++++++++-- 1 file changed, 84 insertions(+), 7 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/view/scenes/StartScene.java b/src/main/java/edu/ntnu/idatt2003/view/scenes/StartScene.java index c260dec..939cdc6 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/scenes/StartScene.java +++ b/src/main/java/edu/ntnu/idatt2003/view/scenes/StartScene.java @@ -1,21 +1,98 @@ package edu.ntnu.idatt2003.view.scenes; +import edu.ntnu.idatt2003.model.ChaosCanvas; +import edu.ntnu.idatt2003.model.Vector2D; +import javafx.collections.FXCollections; +import javafx.geometry.Insets; import javafx.scene.Scene; import javafx.scene.control.Button; -import javafx.scene.layout.StackPane; +import javafx.scene.control.ComboBox; +import javafx.scene.layout.BorderPane; +import javafx.scene.layout.HBox; +import javafx.scene.layout.Pane; import javafx.stage.Stage; public class StartScene { - public void start(Stage primaryStage) { + private Button btnAdd10; + private Button btnAdd100; + private Button btnAdd1000; + private Button btnReset; - Button startButton = new Button("Start Game"); - StackPane root = new StackPane(); - root.getChildren().add(startButton); + private ComboBox<String> comboBoxFractal; + private ComboBox<String> comboBoxColor; + private Button btnChangeStartVector; + private Scene scene; - Scene scene = new Scene(root, 1300, 500); + public StartScene() { + initializeComponents(); + } + + private void initializeComponents() { + // Creating the root pane and setting its size + BorderPane root = new BorderPane(); + + // HBox for buttons + HBox buttonBox = new HBox(50); // spacing between buttons + HBox topBox = new HBox(50); // spacing between buttons + + buttonBox.getStyleClass().add("button-box"); + topBox.getStyleClass().add("top-box"); + + // Initialize buttons + btnAdd10 = new Button("Add 10"); + btnAdd100 = new Button("Add 100"); + btnAdd1000 = new Button("Add 1000"); + btnReset = new Button("Reset"); + btnChangeStartVector = new Button("Change start vector"); + + comboBoxFractal = new ComboBox<>(); + comboBoxFractal.setItems(FXCollections.observableArrayList( + "Option 1", "Option 2", "Option 3" + )); + comboBoxFractal.setPromptText("Choose a fractal"); + + comboBoxColor = new ComboBox<>(); + comboBoxColor.setItems(FXCollections.observableArrayList( + "Blue", "Green", "Red" + )); + comboBoxColor.setPromptText("Choose a color"); + + // Add buttons to the HBox + buttonBox.getChildren().addAll(btnAdd10, btnAdd100, btnAdd1000, btnReset, btnChangeStartVector); + buttonBox.setPadding(new Insets(0, 0, 50, 50)); + + topBox.getChildren().addAll(comboBoxFractal, comboBoxColor); + topBox.setPadding(new Insets(20, 0, 0, 50)); + + // Aligning the HBox at the bottom + root.setBottom(buttonBox); + root.setTop(topBox); + // Create a scene with the root and set the CSS style + scene = new Scene(root, 800, 600); + scene.getStylesheets().add(getClass().getResource("/style.css").toExternalForm()); + } + + public void setUpStage(Stage primaryStage) { + primaryStage.setTitle("ChaosGame"); primaryStage.setScene(scene); - primaryStage.setTitle("Chaos Game"); primaryStage.show(); } + + public Button getBtnAdd10() { + return btnAdd10; + } + + // Getters for other buttons if needed + public Button getBtnAdd100() { + return btnAdd100; + } + + public Button getBtnAdd1000() { + return btnAdd1000; + } + + public Button getBtnReset() { + return btnReset; + } } -- GitLab From cb2730cbff417d9a86d561f108b21db70de2cde3 Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Tue, 14 May 2024 10:56:25 +0200 Subject: [PATCH 037/168] Styled combox and buttons --- src/main/resources/style.css | 38 ++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 src/main/resources/style.css diff --git a/src/main/resources/style.css b/src/main/resources/style.css new file mode 100644 index 0000000..e4cb20e --- /dev/null +++ b/src/main/resources/style.css @@ -0,0 +1,38 @@ +.button { + -fx-background-color: #bfbfbf; + -fx-border: none; + -fx-color: white; + -fx-text-decoration: none; + -fx-display: inline-block; + -fx-font-size: 16px; + -fx-margin: 4px 2px; + -fx-cursor: pointer; + -fx-transition-duration: 0.4s; /* Transition effect */ + -fx-text-align: center; + -fx-border-radius: 10px; +} + +.button:hover { + -fx-background-color: #96fa7d; + -fx-cursor: hand; +} + + +.combo-box { + -fx-background-color: #bfbfbf; + -fx-border: none; + -fx-color: white; + -fx-font-size: 16px; + -fx-cursor: pointer; + -fx-text-align: center; + -fx-border-radius: 10px; +} + +.combo-box .list-cell { + -fx-background-color: white; + -fx-text-fill: black; +} + +.combo-box:hover { + -fx-background-color: #96fa7d; +} -- GitLab From 23fb4432f4c1bdce95f4eb48bdfe32d881987184 Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Tue, 14 May 2024 11:23:54 +0200 Subject: [PATCH 038/168] Made getters for Height and Width --- src/main/java/edu/ntnu/idatt2003/model/ChaosCanvas.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/java/edu/ntnu/idatt2003/model/ChaosCanvas.java b/src/main/java/edu/ntnu/idatt2003/model/ChaosCanvas.java index 6f901d1..82ff3a6 100644 --- a/src/main/java/edu/ntnu/idatt2003/model/ChaosCanvas.java +++ b/src/main/java/edu/ntnu/idatt2003/model/ChaosCanvas.java @@ -29,6 +29,14 @@ public ChaosCanvas(int width, int height, Vector2D minCoords, Vector2D maxCoords initializeTransform(); } + public int getHeight() { + return height; + } + + public int getWidth() { + return width; + } + /** * Initializes the transformation from coordinates to indices. */ -- GitLab From 5ff92ed3623359350abb10bc9de795d478c3ebda Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Tue, 14 May 2024 11:25:46 +0200 Subject: [PATCH 039/168] Added the fractal frame and chaosCanvas to StartScene --- .../idatt2003/view/scenes/StartScene.java | 65 ++++++++++++++++++- 1 file changed, 63 insertions(+), 2 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/view/scenes/StartScene.java b/src/main/java/edu/ntnu/idatt2003/view/scenes/StartScene.java index 939cdc6..cd69889 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/scenes/StartScene.java +++ b/src/main/java/edu/ntnu/idatt2003/view/scenes/StartScene.java @@ -1,17 +1,22 @@ package edu.ntnu.idatt2003.view.scenes; -import edu.ntnu.idatt2003.model.ChaosCanvas; -import edu.ntnu.idatt2003.model.Vector2D; +import edu.ntnu.idatt2003.model.*; import javafx.collections.FXCollections; import javafx.geometry.Insets; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.ComboBox; +import javafx.scene.image.ImageView; +import javafx.scene.image.PixelWriter; +import javafx.scene.image.WritableImage; import javafx.scene.layout.BorderPane; import javafx.scene.layout.HBox; import javafx.scene.layout.Pane; +import javafx.scene.paint.Color; import javafx.stage.Stage; +import java.util.List; + public class StartScene { private Button btnAdd10; private Button btnAdd100; @@ -22,9 +27,14 @@ public class StartScene { private ComboBox<String> comboBoxColor; private Button btnChangeStartVector; private Scene scene; + //private ChaosCanvas chaosCanvas; + private WritableImage writableImage; + private ImageView imageView; + private ChaosCanvas chaosCanvas; public StartScene() { initializeComponents(); + drawFractal(); } private void initializeComponents() { @@ -71,6 +81,12 @@ public class StartScene { // Create a scene with the root and set the CSS style scene = new Scene(root, 800, 600); scene.getStylesheets().add(getClass().getResource("/style.css").toExternalForm()); + + // Initialize the ChaosCanvas and the WritableImage + chaosCanvas = new ChaosCanvas(600, 400, new Vector2D(0, 0), new Vector2D(600, 400)); + writableImage = new WritableImage(600, 400); + imageView = new ImageView(writableImage); + root.setCenter(imageView); } public void setUpStage(Stage primaryStage) { @@ -95,4 +111,49 @@ public class StartScene { public Button getBtnReset() { return btnReset; } + + private void drawFractal() { + // Clear the ChaosCanvas + chaosCanvas.clear(); + + 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(300, 0)), + new AffineTransform2D(new Matrix2x2(0.5, 0, 0, 0.5), new Vector2D(150, 200)) + ); + ChaosGameDescription description = new ChaosGameDescription(transforms, new Vector2D(0, 0), new Vector2D(600, 400)); + ChaosGame chaosGame = new ChaosGame(description, 600, 400); + chaosGame.runSteps(1000); + + // Draw the fractal + // This is just a placeholder. Replace this with your fractal drawing code. + chaosCanvas.putPixel(new Vector2D(1, 1)); + chaosCanvas.putPixel(new Vector2D(1, 2)); + chaosCanvas.putPixel(new Vector2D(100, 200)); + chaosCanvas.putPixel(new Vector2D(200, 200)); + chaosCanvas.putPixel(new Vector2D(200, 300)); + chaosCanvas.putPixel(new Vector2D(200, 400)); + chaosCanvas.putPixel(new Vector2D(200, 350)); + chaosCanvas.putPixel(new Vector2D(200, 330)); + chaosCanvas.putPixel(new Vector2D(200, 320)); + chaosCanvas.putPixel(new Vector2D(200, 310)); + chaosCanvas.putPixel(new Vector2D(200, 300)); + chaosCanvas.putPixel(new Vector2D(200, 290)); + chaosCanvas.putPixel(new Vector2D(200, 280)); + + // Update the WritableImage + updateImage(); + } + + private void updateImage() { + PixelWriter pixelWriter = writableImage.getPixelWriter(); + int[][] canvasArray = chaosCanvas.getCanvasArray(); + for (int y = 0; y < chaosCanvas.getHeight(); y++) { + for (int x = 0; x < chaosCanvas.getWidth(); x++) { + int pixel = canvasArray[y][x]; + Color color = pixel == 1 ? Color.BLACK : Color.WHITE; + pixelWriter.setColor(x, y, color); + } + } + } } -- GitLab From 5a2f9551d92204e91148668a3f2a5e25bb85f34f Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Tue, 14 May 2024 12:57:40 +0200 Subject: [PATCH 040/168] Sierpinski Triangle to GUI --- .../ntnu/idatt2003/view/scenes/StartScene.java | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/view/scenes/StartScene.java b/src/main/java/edu/ntnu/idatt2003/view/scenes/StartScene.java index cd69889..597eddf 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/scenes/StartScene.java +++ b/src/main/java/edu/ntnu/idatt2003/view/scenes/StartScene.java @@ -31,6 +31,7 @@ public class StartScene { private WritableImage writableImage; private ImageView imageView; private ChaosCanvas chaosCanvas; + private ChaosGame chaosGame; public StartScene() { initializeComponents(); @@ -116,7 +117,11 @@ public class StartScene { // Clear the ChaosCanvas chaosCanvas.clear(); - List<Transform2D> transforms = List.of( + this.chaosGame = new ChaosGame(ChaosGameDescriptionFactory.createSierpinskiTriangle(), 400, 400); + chaosGame.runSteps(10000); + updateImage(); + + /**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(300, 0)), new AffineTransform2D(new Matrix2x2(0.5, 0, 0, 0.5), new Vector2D(150, 200)) @@ -142,14 +147,15 @@ public class StartScene { chaosCanvas.putPixel(new Vector2D(200, 280)); // Update the WritableImage - updateImage(); + updateImage();**/ } private void updateImage() { PixelWriter pixelWriter = writableImage.getPixelWriter(); - int[][] canvasArray = chaosCanvas.getCanvasArray(); - for (int y = 0; y < chaosCanvas.getHeight(); y++) { - for (int x = 0; x < chaosCanvas.getWidth(); x++) { + this.chaosCanvas = chaosGame.getCanvas(); + int[][] canvasArray = chaosGame.getCanvas().getCanvasArray(); + for (int y = 0; y < chaosGame.getCanvas().getHeight(); y++) { + for (int x = 0; x < chaosGame.getCanvas().getWidth(); x++) { int pixel = canvasArray[y][x]; Color color = pixel == 1 ? Color.BLACK : Color.WHITE; pixelWriter.setColor(x, y, color); -- GitLab From 68a8acfb6ef2b66e89db72445e312e758db5bd5a Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Tue, 14 May 2024 15:05:32 +0200 Subject: [PATCH 041/168] addIteration and reset to buttons added --- .../edu/ntnu/idatt2003/controller/ButtonController.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/main/java/edu/ntnu/idatt2003/controller/ButtonController.java b/src/main/java/edu/ntnu/idatt2003/controller/ButtonController.java index cebf233..3459db5 100644 --- a/src/main/java/edu/ntnu/idatt2003/controller/ButtonController.java +++ b/src/main/java/edu/ntnu/idatt2003/controller/ButtonController.java @@ -1,10 +1,13 @@ package edu.ntnu.idatt2003.controller; +import edu.ntnu.idatt2003.model.ChaosGame; +import edu.ntnu.idatt2003.model.ChaosGameDescriptionFactory; import edu.ntnu.idatt2003.view.scenes.StartScene; import javafx.scene.control.Button; public class ButtonController { private StartScene startScene; + ChaosGame chaosGame = new ChaosGame(ChaosGameDescriptionFactory.createSierpinskiTriangle(), 800, 800); public ButtonController(StartScene startScene) { this.startScene = startScene; @@ -18,21 +21,25 @@ public class ButtonController { Button btnAdd10 = startScene.getBtnAdd10(); btnAdd10.setOnAction(e -> { System.out.println("Add 10"); + startScene.addIterations(10); }); - // Set handlers for other buttons if needed Button btnAdd100 = startScene.getBtnAdd100(); btnAdd100.setOnAction(e -> { System.out.println("Add 100"); + startScene.addIterations(100); }); Button btnAdd1000 = startScene.getBtnAdd1000(); btnAdd1000.setOnAction(e -> { + startScene.addIterations(1000); System.out.println("Add 1000"); }); Button btnReset = startScene.getBtnReset(); btnReset.setOnAction(e -> { + chaosGame = new ChaosGame(ChaosGameDescriptionFactory.createSierpinskiTriangle(), 400, 400); + startScene.resetIterations(); System.out.println("Reset"); }); } -- GitLab From a40e383d33042439c247ea5de3a2fdfec5782c98 Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Tue, 14 May 2024 15:08:53 +0200 Subject: [PATCH 042/168] Method for buttons implemented --- .../idatt2003/view/scenes/StartScene.java | 68 +++++++++---------- 1 file changed, 32 insertions(+), 36 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/view/scenes/StartScene.java b/src/main/java/edu/ntnu/idatt2003/view/scenes/StartScene.java index 597eddf..a7bacca 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/scenes/StartScene.java +++ b/src/main/java/edu/ntnu/idatt2003/view/scenes/StartScene.java @@ -1,11 +1,13 @@ package edu.ntnu.idatt2003.view.scenes; +import edu.ntnu.idatt2003.controller.Observer; import edu.ntnu.idatt2003.model.*; import javafx.collections.FXCollections; import javafx.geometry.Insets; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.ComboBox; +import javafx.scene.control.Label; import javafx.scene.image.ImageView; import javafx.scene.image.PixelWriter; import javafx.scene.image.WritableImage; @@ -17,7 +19,7 @@ import javafx.stage.Stage; import java.util.List; -public class StartScene { +public class StartScene implements Observer { private Button btnAdd10; private Button btnAdd100; private Button btnAdd1000; @@ -26,16 +28,18 @@ public class StartScene { private ComboBox<String> comboBoxFractal; private ComboBox<String> comboBoxColor; private Button btnChangeStartVector; + private Label iterationsLabel; private Scene scene; //private ChaosCanvas chaosCanvas; private WritableImage writableImage; private ImageView imageView; private ChaosCanvas chaosCanvas; - private ChaosGame chaosGame; + private ChaosGame chaosGame = new ChaosGame(ChaosGameDescriptionFactory.createSierpinskiTriangle(), 400, 400); + private int iterations; public StartScene() { initializeComponents(); - drawFractal(); + drawFractal(0); } private void initializeComponents() { @@ -87,7 +91,14 @@ public class StartScene { chaosCanvas = new ChaosCanvas(600, 400, new Vector2D(0, 0), new Vector2D(600, 400)); writableImage = new WritableImage(600, 400); imageView = new ImageView(writableImage); - root.setCenter(imageView); + + iterationsLabel = new Label(); + + BorderPane imagePane = new BorderPane(); + imagePane.setCenter(imageView); + imagePane.setRight(iterationsLabel); + + root.setCenter(imagePane); } public void setUpStage(Stage primaryStage) { @@ -113,41 +124,21 @@ public class StartScene { return btnReset; } - private void drawFractal() { - // Clear the ChaosCanvas - chaosCanvas.clear(); + public void addIterations(int iterations) { + this.iterations += iterations; + iterationsLabel.setText("Iterations: " + this.iterations); + drawFractal(iterations); + } + public void resetIterations() { + iterations = 0; this.chaosGame = new ChaosGame(ChaosGameDescriptionFactory.createSierpinskiTriangle(), 400, 400); - chaosGame.runSteps(10000); - updateImage(); + drawFractal(this.iterations); + } - /**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(300, 0)), - new AffineTransform2D(new Matrix2x2(0.5, 0, 0, 0.5), new Vector2D(150, 200)) - ); - ChaosGameDescription description = new ChaosGameDescription(transforms, new Vector2D(0, 0), new Vector2D(600, 400)); - ChaosGame chaosGame = new ChaosGame(description, 600, 400); - chaosGame.runSteps(1000); - - // Draw the fractal - // This is just a placeholder. Replace this with your fractal drawing code. - chaosCanvas.putPixel(new Vector2D(1, 1)); - chaosCanvas.putPixel(new Vector2D(1, 2)); - chaosCanvas.putPixel(new Vector2D(100, 200)); - chaosCanvas.putPixel(new Vector2D(200, 200)); - chaosCanvas.putPixel(new Vector2D(200, 300)); - chaosCanvas.putPixel(new Vector2D(200, 400)); - chaosCanvas.putPixel(new Vector2D(200, 350)); - chaosCanvas.putPixel(new Vector2D(200, 330)); - chaosCanvas.putPixel(new Vector2D(200, 320)); - chaosCanvas.putPixel(new Vector2D(200, 310)); - chaosCanvas.putPixel(new Vector2D(200, 300)); - chaosCanvas.putPixel(new Vector2D(200, 290)); - chaosCanvas.putPixel(new Vector2D(200, 280)); - - // Update the WritableImage - updateImage();**/ + public void drawFractal(int iterations) { + chaosGame.runSteps(iterations); + updateImage(); } private void updateImage() { @@ -162,4 +153,9 @@ public class StartScene { } } } + + @Override + public void update() { + drawFractal(iterations); + } } -- GitLab From 8f94145a165446f693490582e162b4e076bbc6ce Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Tue, 14 May 2024 15:46:40 +0200 Subject: [PATCH 043/168] Removed redundant code --- src/main/java/edu/ntnu/idatt2003/ChaosGameCLI.java | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/ChaosGameCLI.java b/src/main/java/edu/ntnu/idatt2003/ChaosGameCLI.java index d943fef..469f55a 100644 --- a/src/main/java/edu/ntnu/idatt2003/ChaosGameCLI.java +++ b/src/main/java/edu/ntnu/idatt2003/ChaosGameCLI.java @@ -74,19 +74,7 @@ public class ChaosGameCLI { } System.out.println("Enter the file path: "); String filePath = scanner.nextLine(); - List<Transform2D> transforms = chaosGame.getDescription().getTransforms(); - List<AffineTransform2D> affineTransforms = new ArrayList<>(); - for (Transform2D transform : transforms) { - if (transform instanceof AffineTransform2D) { - affineTransforms.add((AffineTransform2D) transform); - } - } - - if (affineTransforms.isEmpty()) { - System.out.println("No affine transforms to save"); - return; - } try { ChaosGameFileHandler handler = new ChaosGameFileHandler(filePath); handler.writeToFile(filePath, chaosGame.getDescription()); -- GitLab From ad3cb20e44d58d5bded882af9bd2d43602c26832 Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Tue, 14 May 2024 15:48:00 +0200 Subject: [PATCH 044/168] Added parseJulia and made it so that it is possible to read JuliaTransform from file. --- .../idatt2003/model/ChaosGameFileHandler.java | 23 ++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/model/ChaosGameFileHandler.java b/src/main/java/edu/ntnu/idatt2003/model/ChaosGameFileHandler.java index 824337f..6ac917e 100644 --- a/src/main/java/edu/ntnu/idatt2003/model/ChaosGameFileHandler.java +++ b/src/main/java/edu/ntnu/idatt2003/model/ChaosGameFileHandler.java @@ -16,11 +16,13 @@ public class ChaosGameFileHandler { List<Transform2D> transforms = new ArrayList<>(); Vector2D minCoords = null; Vector2D maxCoords = null; + String type = null; try (Scanner scanner = new Scanner(file)) { while (scanner.hasNextLine()) { String line = scanner.nextLine().trim(); if (line.isEmpty() || line.startsWith("#") || line.contains("Type of transform")) { + type = line.split("#")[0].trim(); continue; // Ignore comments and header information } @@ -35,10 +37,15 @@ public class ChaosGameFileHandler { } try { - Transform2D transform = parseAffineTransform(line.split("#")[0].trim()); - if (transform != null) { - transforms.add(transform); + Transform2D transform = null; + assert type != null; + if (type.equals("Julia")) { + transform = parseJulia(line.split("#")[0].trim()); + } else { + transform = parseAffineTransform(line.split("#")[0].trim()); } + transforms.add(transform); + } catch (IllegalArgumentException e) { System.err.println("Error parsing transform from line: " + line); } @@ -91,9 +98,11 @@ public class ChaosGameFileHandler { } } - private Complex parseComplex(String line) { + private JuliaTransform parseJulia(String line) { String[] parts = line.split(","); - return new Complex(Double.parseDouble(parts[0].trim()), Double.parseDouble(parts[1].trim())); + return new JuliaTransform( + new Complex(Double.parseDouble(parts[0].trim()), Double.parseDouble(parts[1].trim())), + 1); } @@ -111,11 +120,9 @@ public class ChaosGameFileHandler { writer.write(maxCoords.getX0() + ", " + maxCoords.getX1() + " # Upper right"); writer.newLine(); - int transformIndex = 1; for (Transform2D transform : transforms) { - writer.write(transform.toFormattedString() + " # Transform nr." + transformIndex); + writer.write(transform.toFormattedString() ); writer.newLine(); - transformIndex++; } } catch (IOException e) { System.out.println("An error occurred: " + e.getMessage()); -- GitLab From bcc362fd6d6879cade25109c2d7349fde6044f7a Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Tue, 14 May 2024 15:48:15 +0200 Subject: [PATCH 045/168] Added getReal and getImaginary --- src/main/java/edu/ntnu/idatt2003/model/Complex.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/java/edu/ntnu/idatt2003/model/Complex.java b/src/main/java/edu/ntnu/idatt2003/model/Complex.java index 6e5f0d0..f1ba43d 100644 --- a/src/main/java/edu/ntnu/idatt2003/model/Complex.java +++ b/src/main/java/edu/ntnu/idatt2003/model/Complex.java @@ -11,4 +11,12 @@ public class Complex extends Vector2D { double absoluteZ = Math.sqrt(Math.pow(this.getX0(),2)+Math.pow(this.getX1(),2)); return new Complex(Math.sqrt((absoluteZ+this.getX0())/2),this.getX1()/abs(this.getX1())*Math.sqrt((absoluteZ-this.getX0())/2)); } + + public double getReal() { + return this.getX0(); + } + + public double getImaginary() { + return this.getX1(); + } } \ No newline at end of file -- GitLab From 0dc22a84ec8e258e2734cca4389d0210f3eb22cd Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Tue, 14 May 2024 15:48:35 +0200 Subject: [PATCH 046/168] Fixed toFormattedString --- src/main/java/edu/ntnu/idatt2003/model/JuliaTransform.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/model/JuliaTransform.java b/src/main/java/edu/ntnu/idatt2003/model/JuliaTransform.java index d576c93..7d08812 100644 --- a/src/main/java/edu/ntnu/idatt2003/model/JuliaTransform.java +++ b/src/main/java/edu/ntnu/idatt2003/model/JuliaTransform.java @@ -1,5 +1,7 @@ package edu.ntnu.idatt2003.model; +import java.util.Locale; + public class JuliaTransform implements Transform2D { private final Complex point; private final int sign; @@ -43,8 +45,7 @@ public class JuliaTransform implements Transform2D { @Override public String toFormattedString() { - //return String.format("c = %.2f + %.2fi, sign = %d", point.getReal(), point.getImaginary(), sign); - return ""; + return String.format(Locale.ENGLISH,"%.5f, %.5f", point.getReal(), point.getImaginary()); } public Complex getPoint() { -- GitLab From 16ce3824979f2170afc74be977e4679c1cf0a848 Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Tue, 14 May 2024 15:48:54 +0200 Subject: [PATCH 047/168] Made JuliaTransformTest class --- .../idatt2003/model/JuliaTransformTest.java | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 src/test/java/edu/ntnu/idatt2003/model/JuliaTransformTest.java diff --git a/src/test/java/edu/ntnu/idatt2003/model/JuliaTransformTest.java b/src/test/java/edu/ntnu/idatt2003/model/JuliaTransformTest.java new file mode 100644 index 0000000..c89690f --- /dev/null +++ b/src/test/java/edu/ntnu/idatt2003/model/JuliaTransformTest.java @@ -0,0 +1,66 @@ +package edu.ntnu.idatt2003.model; + +import static org.junit.Assert.*; +import org.junit.Before; +import org.junit.Test; + +public class JuliaTransformTest { + + private JuliaTransform juliaTransformPos; + private JuliaTransform juliaTransformNeg; + private Complex testPoint; + + @Before + public void setUp() { + testPoint = new Complex(0.285, 0.01); + juliaTransformPos = new JuliaTransform(testPoint, 1); + juliaTransformNeg = new JuliaTransform(testPoint, -1); + } + + @Test + public void testConstructor_ValidSign() { + assertNotNull("JuliaTransform should not be null with sign 1", juliaTransformPos); + assertNotNull("JuliaTransform should not be null with sign -1", juliaTransformNeg); + } + + @Test(expected = IllegalArgumentException.class) + public void testConstructor_InvalidSign() { + new JuliaTransform(testPoint, 0); + } + + @Test + public void testTransform_PositiveSign() { + Vector2D z = new Vector2D(0.5, 0.5); + Vector2D result = juliaTransformPos.transform(z); + Complex expected = new Complex(z.getX0() - testPoint.getReal(), z.getX1() - testPoint.getImaginary()).sqrt(); + assertEquals("The transformed X coordinate does not match", expected.getReal(), result.getX0(), 0.001); + assertEquals("The transformed Y coordinate does not match", expected.getImaginary(), result.getX1(), 0.001); + } + + @Test + public void testTransform_NegativeSign() { + Vector2D z = new Vector2D(0.5, 0.5); + Vector2D result = juliaTransformNeg.transform(z); + Complex expected = new Complex(z.getX0() - testPoint.getReal(), z.getX1() - testPoint.getImaginary()).sqrt(); + assertEquals("The transformed X coordinate does not match for negative sign", -expected.getReal(), result.getX0(), 0.001); + assertEquals("The transformed Y coordinate does not match for negative sign", -expected.getImaginary(), result.getX1(), 0.001); + } + + @Test + public void testGetTransformType() { + String result = juliaTransformNeg.getTransformType(); + assertEquals("Julia", result); + } + + @Test + public void testToFormattedString() { + String result = juliaTransformNeg.toFormattedString(); + assertEquals("0.28500, 0.01000", result); + } + + @Test + public void testGetPoint() { + Complex result = juliaTransformNeg.getPoint(); + assertEquals(testPoint, result); + } +} -- GitLab From 12dd3b8b9a7aef371c5ae98e3e55b9666a02917e Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Tue, 14 May 2024 15:49:21 +0200 Subject: [PATCH 048/168] Added dependecy --- pom.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pom.xml b/pom.xml index 6a86148..87f2985 100644 --- a/pom.xml +++ b/pom.xml @@ -58,5 +58,11 @@ <version>5.10.1</version> <scope>test</scope> </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>4.13.1</version> + <scope>test</scope> + </dependency> </dependencies> </project> \ No newline at end of file -- GitLab From a38f7bd6065d3f3e0102c901aa94d20f2287bf14 Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Tue, 14 May 2024 19:47:16 +0200 Subject: [PATCH 049/168] Empty scene --- src/main/java/edu/ntnu/idatt2003/view/scenes/JuliaScene.java | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 src/main/java/edu/ntnu/idatt2003/view/scenes/JuliaScene.java diff --git a/src/main/java/edu/ntnu/idatt2003/view/scenes/JuliaScene.java b/src/main/java/edu/ntnu/idatt2003/view/scenes/JuliaScene.java new file mode 100644 index 0000000..fd64a13 --- /dev/null +++ b/src/main/java/edu/ntnu/idatt2003/view/scenes/JuliaScene.java @@ -0,0 +1,3 @@ +package edu.ntnu.idatt2003.view.scenes; +public class JuliaScene { +} -- GitLab From 132be2c3df97d53faf3daa7847f999615ba9008a Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Tue, 14 May 2024 19:49:28 +0200 Subject: [PATCH 050/168] FractalOperations made to enhance reusability --- .../view/components/FractalOperations.java | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java diff --git a/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java b/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java new file mode 100644 index 0000000..fa29d1a --- /dev/null +++ b/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java @@ -0,0 +1,70 @@ +package edu.ntnu.idatt2003.view.components; + +import edu.ntnu.idatt2003.controller.ButtonController; +import edu.ntnu.idatt2003.model.ChaosCanvas; +import edu.ntnu.idatt2003.model.ChaosGame; +import edu.ntnu.idatt2003.model.ChaosGameDescriptionFactory; +import edu.ntnu.idatt2003.model.Complex; +import javafx.scene.Scene; +import javafx.scene.control.Label; +import javafx.scene.image.ImageView; +import javafx.scene.image.PixelWriter; +import javafx.scene.image.WritableImage; +import javafx.scene.paint.Color; + +public class FractalOperations { + private ChaosGame chaosGame; + private int iterations; + private Label iterationsLabel; + private WritableImage writableImage; + private ImageView imageView; + private String currentFractal; + + public FractalOperations(Label iterationsLabel, ImageView imageView, String initialFractal) { + this.iterationsLabel = iterationsLabel; + this.imageView = imageView; + this.currentFractal = initialFractal; + this.writableImage = new WritableImage(400, 400); + this.imageView.setImage(writableImage); + resetIterations(); + } + + public void drawFractal(int iterations) { + chaosGame.runSteps(iterations); + updateImage(); + } + + public void addIterations(int iterations) { + this.iterations += iterations; + iterationsLabel.setText("Iterations: " + this.iterations); + drawFractal(iterations); + } + + public void resetIterations() { + iterations = 0; + if ("SierpinskiTriangle".equals(currentFractal)) { + this.chaosGame = new ChaosGame(ChaosGameDescriptionFactory.createSierpinskiTriangle(), 400, 400); + } else if ("JuliaSet".equals(currentFractal)) { + Complex defaultComplex = new Complex(0, 0); + int defaultInt = 0; + this.chaosGame = new ChaosGame(ChaosGameDescriptionFactory.createJuliaSet(defaultComplex, defaultInt), 400, 400); + } + drawFractal(this.iterations); + } + + public void updateImage() { + PixelWriter pixelWriter = writableImage.getPixelWriter(); + int[][] canvasArray = chaosGame.getCanvas().getCanvasArray(); + for (int y = 0; y < chaosGame.getCanvas().getHeight(); y++) { + for (int x = 0; x < chaosGame.getCanvas().getWidth(); x++) { + int pixel = canvasArray[y][x]; + Color color = pixel == 1 ? Color.BLACK : Color.WHITE; + pixelWriter.setColor(x, y, color); + } + } + } + + public void setCurrentFractal(String fractal) { + this.currentFractal = fractal; + } +} -- GitLab From be789d31e9eeb38c3dcda6ef0bad7f2fff566a06 Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Tue, 14 May 2024 19:49:49 +0200 Subject: [PATCH 051/168] ComboBoxes class made to enhance reusability --- .../idatt2003/view/components/ComboBoxes.java | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 src/main/java/edu/ntnu/idatt2003/view/components/ComboBoxes.java diff --git a/src/main/java/edu/ntnu/idatt2003/view/components/ComboBoxes.java b/src/main/java/edu/ntnu/idatt2003/view/components/ComboBoxes.java new file mode 100644 index 0000000..22059ec --- /dev/null +++ b/src/main/java/edu/ntnu/idatt2003/view/components/ComboBoxes.java @@ -0,0 +1,35 @@ +package edu.ntnu.idatt2003.view.components; + +import javafx.collections.FXCollections; +import javafx.scene.control.ComboBox; + +public class ComboBoxes { + private ComboBox<String> comboBoxFractal; + private ComboBox<String> comboBoxColor; + + public ComboBoxes() { + initializeComboBoxes(); + } + + private void initializeComboBoxes() { + comboBoxFractal = new ComboBox<>(); + comboBoxFractal.setItems(FXCollections.observableArrayList( + "Sierpinski Triangle", "Barnsley Fern", "Julia Set" + )); + comboBoxFractal.setPromptText("Choose Fractal"); + + comboBoxColor = new ComboBox<>(); + comboBoxColor.setItems(FXCollections.observableArrayList( + "Red", "Green", "Blue" + )); + comboBoxColor.setPromptText("Choose Color"); + } + + public ComboBox<String> getComboBoxFractal() { + return comboBoxFractal; + } + + public ComboBox<String> getComboBoxColor() { + return comboBoxColor; + } +} -- GitLab From d87946fa4b349c932c880bd08d0c570a24a7d9f3 Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Tue, 14 May 2024 19:50:04 +0200 Subject: [PATCH 052/168] Buttons class made to enhance reusability --- .../idatt2003/view/components/Buttons.java | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 src/main/java/edu/ntnu/idatt2003/view/components/Buttons.java diff --git a/src/main/java/edu/ntnu/idatt2003/view/components/Buttons.java b/src/main/java/edu/ntnu/idatt2003/view/components/Buttons.java new file mode 100644 index 0000000..2dafb14 --- /dev/null +++ b/src/main/java/edu/ntnu/idatt2003/view/components/Buttons.java @@ -0,0 +1,38 @@ +package edu.ntnu.idatt2003.view.components; + + +import javafx.scene.control.Button; + +public class Buttons { + private Button btnAdd10; + private Button btnAdd100; + private Button btnAdd1000; + private Button btnReset; + + public Buttons() { + initializeButtons(); + } + + private void initializeButtons() { + btnAdd10 = new Button("Add 10"); + btnAdd100 = new Button("Add 100"); + btnAdd1000 = new Button("Add 1000"); + btnReset = new Button("Reset"); + } + + public Button getBtnAdd10() { + return btnAdd10; + } + + public Button getBtnAdd100() { + return btnAdd100; + } + + public Button getBtnAdd1000() { + return btnAdd1000; + } + + public Button getBtnReset() { + return btnReset; + } +} -- GitLab From 2b6aacde4a79a5b3f3f31eaa1e3f70b4579e96db Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Tue, 14 May 2024 19:50:28 +0200 Subject: [PATCH 053/168] Methods moved to other classes --- .../{StartScene.java => AffineScene.java} | 96 ++++++------------- 1 file changed, 29 insertions(+), 67 deletions(-) rename src/main/java/edu/ntnu/idatt2003/view/scenes/{StartScene.java => AffineScene.java} (55%) diff --git a/src/main/java/edu/ntnu/idatt2003/view/scenes/StartScene.java b/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java similarity index 55% rename from src/main/java/edu/ntnu/idatt2003/view/scenes/StartScene.java rename to src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java index a7bacca..c75127e 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/scenes/StartScene.java +++ b/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java @@ -1,7 +1,11 @@ package edu.ntnu.idatt2003.view.scenes; +import edu.ntnu.idatt2003.controller.ButtonController; import edu.ntnu.idatt2003.controller.Observer; import edu.ntnu.idatt2003.model.*; +import edu.ntnu.idatt2003.view.components.Buttons; +import edu.ntnu.idatt2003.view.components.ComboBoxes; +import edu.ntnu.idatt2003.view.components.FractalOperations; import javafx.collections.FXCollections; import javafx.geometry.Insets; import javafx.scene.Scene; @@ -13,33 +17,30 @@ import javafx.scene.image.PixelWriter; import javafx.scene.image.WritableImage; import javafx.scene.layout.BorderPane; import javafx.scene.layout.HBox; -import javafx.scene.layout.Pane; import javafx.scene.paint.Color; import javafx.stage.Stage; -import java.util.List; - -public class StartScene implements Observer { - private Button btnAdd10; - private Button btnAdd100; - private Button btnAdd1000; - private Button btnReset; - - private ComboBox<String> comboBoxFractal; - private ComboBox<String> comboBoxColor; - private Button btnChangeStartVector; +public class AffineScene implements Observer { private Label iterationsLabel; private Scene scene; - //private ChaosCanvas chaosCanvas; private WritableImage writableImage; private ImageView imageView; private ChaosCanvas chaosCanvas; + private Buttons buttons; + private ButtonController buttonController; + private ComboBoxes comboBoxes; + private FractalOperations fractalOperations; private ChaosGame chaosGame = new ChaosGame(ChaosGameDescriptionFactory.createSierpinskiTriangle(), 400, 400); private int iterations; - public StartScene() { + public AffineScene() { + buttons = new Buttons(); + comboBoxes = new ComboBoxes(); + buttonController = new ButtonController(this, buttons); initializeComponents(); - drawFractal(0); + fractalOperations = new FractalOperations(iterationsLabel, imageView, "SierpinskiTriangle"); + fractalOperations.resetIterations(); + fractalOperations.addIterations(0); } private void initializeComponents() { @@ -54,26 +55,17 @@ public class StartScene implements Observer { topBox.getStyleClass().add("top-box"); // Initialize buttons - btnAdd10 = new Button("Add 10"); - btnAdd100 = new Button("Add 100"); - btnAdd1000 = new Button("Add 1000"); - btnReset = new Button("Reset"); - btnChangeStartVector = new Button("Change start vector"); - - comboBoxFractal = new ComboBox<>(); - comboBoxFractal.setItems(FXCollections.observableArrayList( - "Option 1", "Option 2", "Option 3" - )); - comboBoxFractal.setPromptText("Choose a fractal"); - - comboBoxColor = new ComboBox<>(); - comboBoxColor.setItems(FXCollections.observableArrayList( - "Blue", "Green", "Red" - )); - comboBoxColor.setPromptText("Choose a color"); + Button btnAdd10 = buttons.getBtnAdd10(); + Button btnAdd100 = buttons.getBtnAdd100(); + Button btnAdd1000 = buttons.getBtnAdd1000(); + Button btnReset = buttons.getBtnReset(); + + // Initialize ComboBoxes + ComboBox<String>comboBoxFractal = comboBoxes.getComboBoxFractal(); + ComboBox<String>comboBoxColor = comboBoxes.getComboBoxColor(); // Add buttons to the HBox - buttonBox.getChildren().addAll(btnAdd10, btnAdd100, btnAdd1000, btnReset, btnChangeStartVector); + buttonBox.getChildren().addAll(btnAdd10, btnAdd100, btnAdd1000, btnReset); buttonBox.setPadding(new Insets(0, 0, 50, 50)); topBox.getChildren().addAll(comboBoxFractal, comboBoxColor); @@ -107,51 +99,21 @@ public class StartScene implements Observer { primaryStage.show(); } - public Button getBtnAdd10() { - return btnAdd10; - } - - // Getters for other buttons if needed - public Button getBtnAdd100() { - return btnAdd100; - } - - public Button getBtnAdd1000() { - return btnAdd1000; - } - - public Button getBtnReset() { - return btnReset; - } - public void addIterations(int iterations) { - this.iterations += iterations; - iterationsLabel.setText("Iterations: " + this.iterations); - drawFractal(iterations); + fractalOperations.addIterations(iterations); } public void resetIterations() { - iterations = 0; - this.chaosGame = new ChaosGame(ChaosGameDescriptionFactory.createSierpinskiTriangle(), 400, 400); - drawFractal(this.iterations); + fractalOperations.resetIterations(); } public void drawFractal(int iterations) { - chaosGame.runSteps(iterations); + fractalOperations.drawFractal(iterations); updateImage(); } private void updateImage() { - PixelWriter pixelWriter = writableImage.getPixelWriter(); - this.chaosCanvas = chaosGame.getCanvas(); - int[][] canvasArray = chaosGame.getCanvas().getCanvasArray(); - for (int y = 0; y < chaosGame.getCanvas().getHeight(); y++) { - for (int x = 0; x < chaosGame.getCanvas().getWidth(); x++) { - int pixel = canvasArray[y][x]; - Color color = pixel == 1 ? Color.BLACK : Color.WHITE; - pixelWriter.setColor(x, y, color); - } - } + fractalOperations.updateImage(); } @Override -- GitLab From 10a36b305d77023d47f8ce7595444cb404e4d72f Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Tue, 14 May 2024 19:53:45 +0200 Subject: [PATCH 054/168] Minor refactoring --- src/main/java/edu/ntnu/idatt2003/view/App.java | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/view/App.java b/src/main/java/edu/ntnu/idatt2003/view/App.java index db4c352..f091210 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/App.java +++ b/src/main/java/edu/ntnu/idatt2003/view/App.java @@ -1,7 +1,6 @@ package edu.ntnu.idatt2003.view; -import edu.ntnu.idatt2003.controller.ButtonController; -import edu.ntnu.idatt2003.view.scenes.StartScene; +import edu.ntnu.idatt2003.view.scenes.AffineScene; import javafx.application.Application; import javafx.stage.Stage; @@ -12,11 +11,7 @@ public class App extends Application { @Override public void start(Stage primaryStage) { - StartScene startScene = new StartScene(); - startScene.setUpStage(primaryStage); - - // Initialize the controller and set up handlers - ButtonController buttonController = new ButtonController(startScene); - buttonController.initialize(); + AffineScene affineScene = new AffineScene(); + affineScene.setUpStage(primaryStage); } } -- GitLab From 092c6e60c99d3621cfd2524cf77875f059358feb Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Tue, 14 May 2024 19:54:26 +0200 Subject: [PATCH 055/168] Refactored to cooperate with new class --- .../controller/ButtonController.java | 34 +++++++++---------- 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/controller/ButtonController.java b/src/main/java/edu/ntnu/idatt2003/controller/ButtonController.java index 3459db5..fe68d92 100644 --- a/src/main/java/edu/ntnu/idatt2003/controller/ButtonController.java +++ b/src/main/java/edu/ntnu/idatt2003/controller/ButtonController.java @@ -2,15 +2,18 @@ package edu.ntnu.idatt2003.controller; import edu.ntnu.idatt2003.model.ChaosGame; import edu.ntnu.idatt2003.model.ChaosGameDescriptionFactory; -import edu.ntnu.idatt2003.view.scenes.StartScene; +import edu.ntnu.idatt2003.view.components.Buttons; +import edu.ntnu.idatt2003.view.scenes.AffineScene; import javafx.scene.control.Button; public class ButtonController { - private StartScene startScene; - ChaosGame chaosGame = new ChaosGame(ChaosGameDescriptionFactory.createSierpinskiTriangle(), 800, 800); + private AffineScene affineScene; + private Buttons buttons; - public ButtonController(StartScene startScene) { - this.startScene = startScene; + public ButtonController(AffineScene affineScene, Buttons buttons) { + this.affineScene = affineScene; + this.buttons = buttons; + initialize(); } public void initialize() { @@ -18,28 +21,23 @@ public class ButtonController { } private void setButtonHandlers() { - Button btnAdd10 = startScene.getBtnAdd10(); - btnAdd10.setOnAction(e -> { + buttons.getBtnAdd10().setOnAction(e -> { System.out.println("Add 10"); - startScene.addIterations(10); + affineScene.addIterations(10); }); - Button btnAdd100 = startScene.getBtnAdd100(); - btnAdd100.setOnAction(e -> { + buttons.getBtnAdd100().setOnAction(e -> { System.out.println("Add 100"); - startScene.addIterations(100); + affineScene.addIterations(100); }); - Button btnAdd1000 = startScene.getBtnAdd1000(); - btnAdd1000.setOnAction(e -> { - startScene.addIterations(1000); + buttons.getBtnAdd1000().setOnAction(e -> { + affineScene.addIterations(1000); System.out.println("Add 1000"); }); - Button btnReset = startScene.getBtnReset(); - btnReset.setOnAction(e -> { - chaosGame = new ChaosGame(ChaosGameDescriptionFactory.createSierpinskiTriangle(), 400, 400); - startScene.resetIterations(); + buttons.getBtnReset().setOnAction(e -> { + affineScene.resetIterations(); System.out.println("Reset"); }); } -- GitLab From cd26729abd83b7fce37c1844b9ea744b634fbab4 Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Tue, 14 May 2024 19:55:11 +0200 Subject: [PATCH 056/168] buttonController.initialize() added in constructor --- src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java b/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java index c75127e..f2442a4 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java +++ b/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java @@ -33,10 +33,14 @@ public class AffineScene implements Observer { private ChaosGame chaosGame = new ChaosGame(ChaosGameDescriptionFactory.createSierpinskiTriangle(), 400, 400); private int iterations; + /** + * Constructor for the AffineScene class + */ public AffineScene() { buttons = new Buttons(); comboBoxes = new ComboBoxes(); buttonController = new ButtonController(this, buttons); + buttonController.initialize(); initializeComponents(); fractalOperations = new FractalOperations(iterationsLabel, imageView, "SierpinskiTriangle"); fractalOperations.resetIterations(); -- GitLab From fe70113fed4a2de36696b6a0b42e3db8b6197702 Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Tue, 14 May 2024 19:58:34 +0200 Subject: [PATCH 057/168] Removed not used fields --- .../edu/ntnu/idatt2003/view/scenes/AffineScene.java | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java b/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java index f2442a4..b68bcad 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java +++ b/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java @@ -1,26 +1,22 @@ package edu.ntnu.idatt2003.view.scenes; import edu.ntnu.idatt2003.controller.ButtonController; -import edu.ntnu.idatt2003.controller.Observer; import edu.ntnu.idatt2003.model.*; import edu.ntnu.idatt2003.view.components.Buttons; import edu.ntnu.idatt2003.view.components.ComboBoxes; import edu.ntnu.idatt2003.view.components.FractalOperations; -import javafx.collections.FXCollections; import javafx.geometry.Insets; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.ComboBox; import javafx.scene.control.Label; import javafx.scene.image.ImageView; -import javafx.scene.image.PixelWriter; import javafx.scene.image.WritableImage; import javafx.scene.layout.BorderPane; import javafx.scene.layout.HBox; -import javafx.scene.paint.Color; import javafx.stage.Stage; -public class AffineScene implements Observer { +public class AffineScene { private Label iterationsLabel; private Scene scene; private WritableImage writableImage; @@ -30,8 +26,6 @@ public class AffineScene implements Observer { private ButtonController buttonController; private ComboBoxes comboBoxes; private FractalOperations fractalOperations; - private ChaosGame chaosGame = new ChaosGame(ChaosGameDescriptionFactory.createSierpinskiTriangle(), 400, 400); - private int iterations; /** * Constructor for the AffineScene class @@ -119,9 +113,4 @@ public class AffineScene implements Observer { private void updateImage() { fractalOperations.updateImage(); } - - @Override - public void update() { - drawFractal(iterations); - } } -- GitLab From 37d751035fac75cb8db45794415220b3031072d3 Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Tue, 14 May 2024 20:14:09 +0200 Subject: [PATCH 058/168] Made ChaosCanvasTest --- .../ntnu/idatt2003/model/ChaosCanvasTest.java | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 src/test/java/edu/ntnu/idatt2003/model/ChaosCanvasTest.java diff --git a/src/test/java/edu/ntnu/idatt2003/model/ChaosCanvasTest.java b/src/test/java/edu/ntnu/idatt2003/model/ChaosCanvasTest.java new file mode 100644 index 0000000..963ad1d --- /dev/null +++ b/src/test/java/edu/ntnu/idatt2003/model/ChaosCanvasTest.java @@ -0,0 +1,61 @@ +package edu.ntnu.idatt2003.model; + +import static org.junit.Assert.*; +import org.junit.Before; +import org.junit.Test; + +public class ChaosCanvasTest { + private ChaosCanvas canvas; + + @Before + public void setUp() { + canvas = new ChaosCanvas(100, 100, new Vector2D(0, 0), new Vector2D(1, 1)); + } + + @Test + public void testInitialCanvasState() { + assertEquals(100, canvas.getWidth()); + assertEquals(100, canvas.getHeight()); + assertNotNull(canvas.getCanvasArray()); + } + + @Test + public void testPutAndGetPixel() { + Vector2D point = new Vector2D(0.5, 0.5); + canvas.putPixel(point); + assertEquals(1, canvas.getPixel(point)); + assertEquals(-1, canvas.getPixel(new Vector2D(-1, -1))); // Test out of bounds + } + + @Test + public void testClear() { + Vector2D point = new Vector2D(0.5, 0.5); + canvas.putPixel(point); + canvas.clear(); + assertEquals(0, canvas.getPixel(point)); + } + + @Test + public void testTransformationAccuracy() { + // Place a pixel at a specific point. + Vector2D point = new Vector2D(0.5, 0.5); + canvas.putPixel(point); + + // Check the placement of the pixel. + // Assuming the transform maps (0.5, 0.5) to the center of the canvas. + int expectedX = canvas.getWidth() / 2; + int expectedY = canvas.getHeight() / 2; + assertEquals(1, canvas.getPixel(new Vector2D(0.5, 0.5))); + // Ensure other locations are unaffected. + assertEquals(0, canvas.getPixel(new Vector2D(0.5, 0.49))); + assertEquals(0, canvas.getPixel(new Vector2D(0.49, 0.5))); + } + + @Test + public void testToAscii() { + Vector2D point = new Vector2D(0.5, 0.5); + canvas.putPixel(point); + String ascii = canvas.toAscii(); + assertTrue(ascii.contains("X")); + } +} -- GitLab From 57a6d4aa52d5649f8171d7f48487a0d7d6a25641 Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Wed, 15 May 2024 10:33:17 +0200 Subject: [PATCH 059/168] Made ChaosGameTest --- .../ntnu/idatt2003/model/ChaosGameTest.java | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 src/test/java/edu/ntnu/idatt2003/model/ChaosGameTest.java diff --git a/src/test/java/edu/ntnu/idatt2003/model/ChaosGameTest.java b/src/test/java/edu/ntnu/idatt2003/model/ChaosGameTest.java new file mode 100644 index 0000000..0395be9 --- /dev/null +++ b/src/test/java/edu/ntnu/idatt2003/model/ChaosGameTest.java @@ -0,0 +1,50 @@ +package edu.ntnu.idatt2003.model; + +import static org.junit.jupiter.api.Assertions.*; + +import java.util.Arrays; +import java.util.List; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class ChaosGameTest { + private ChaosGame chaosGame; + private ChaosGameDescription description; + private Vector2D minCoords; + private Vector2D maxCoords; + + @BeforeEach + void setUp() { + // Define the bounds and a simple transform for the test + minCoords = new Vector2D(-1.0, -1.0); + maxCoords = new Vector2D(1.0, 1.0); + Transform2D dummyTransform = new AffineTransform2D(new Matrix2x2(0.5, 0, 0, 0.5), new Vector2D(0.1, 0.1)); + List<Transform2D> transforms = List.of(dummyTransform); + + description = new ChaosGameDescription(transforms, minCoords, maxCoords); + chaosGame = new ChaosGame(description, 100, 100); + } + + @Test + void testInitialSetup() { + assertNotNull(chaosGame.getCanvas()); + assertEquals(100, chaosGame.getCanvas().getWidth()); + assertEquals(100, chaosGame.getCanvas().getHeight()); + assertEquals(description, chaosGame.getDescription()); + } + + @Test + void testRunSteps() { + chaosGame.runSteps(10); + // We cannot predict exact outcomes without a fixed seed or checking the random behavior, but we can ensure the canvas was used + assertTrue(Arrays.stream(chaosGame.getCanvas().getCanvasArray()).flatMapToInt(Arrays::stream).sum() > 0); + } + + @Test + void testNoTransforms() { + ChaosGame gameWithNoTransforms = new ChaosGame(new ChaosGameDescription(List.of(), minCoords, maxCoords), 100, 100); + gameWithNoTransforms.runSteps(10); + // Ensuring no changes were made to the canvas because there are no transforms + assertEquals(0, Arrays.stream(gameWithNoTransforms.getCanvas().getCanvasArray()).flatMapToInt(Arrays::stream).sum()); + } +} -- GitLab From 573df11f79283afa9d5f7812f0290e14382ec602 Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Wed, 15 May 2024 10:42:37 +0200 Subject: [PATCH 060/168] GUI compatible to use JuliaSet --- .../controller/ButtonController.java | 22 ++-- .../java/edu/ntnu/idatt2003/view/App.java | 4 + .../view/components/FractalOperations.java | 16 ++- .../idatt2003/view/scenes/AffineScene.java | 4 +- .../idatt2003/view/scenes/JuliaScene.java | 113 +++++++++++++++++- 5 files changed, 143 insertions(+), 16 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/controller/ButtonController.java b/src/main/java/edu/ntnu/idatt2003/controller/ButtonController.java index fe68d92..5ab8968 100644 --- a/src/main/java/edu/ntnu/idatt2003/controller/ButtonController.java +++ b/src/main/java/edu/ntnu/idatt2003/controller/ButtonController.java @@ -1,43 +1,43 @@ package edu.ntnu.idatt2003.controller; -import edu.ntnu.idatt2003.model.ChaosGame; -import edu.ntnu.idatt2003.model.ChaosGameDescriptionFactory; import edu.ntnu.idatt2003.view.components.Buttons; -import edu.ntnu.idatt2003.view.scenes.AffineScene; -import javafx.scene.control.Button; +import edu.ntnu.idatt2003.view.components.FractalOperations; public class ButtonController { - private AffineScene affineScene; + private FractalOperations fractalOperations; private Buttons buttons; - public ButtonController(AffineScene affineScene, Buttons buttons) { - this.affineScene = affineScene; + public ButtonController(FractalOperations fractalOperations, Buttons buttons) { + this.fractalOperations = fractalOperations; this.buttons = buttons; initialize(); } public void initialize() { + if (fractalOperations == null) { + throw new IllegalStateException("fractalOperations has not been initialized"); + } setButtonHandlers(); } private void setButtonHandlers() { buttons.getBtnAdd10().setOnAction(e -> { System.out.println("Add 10"); - affineScene.addIterations(10); + fractalOperations.addIterations(10); }); buttons.getBtnAdd100().setOnAction(e -> { System.out.println("Add 100"); - affineScene.addIterations(100); + fractalOperations.addIterations(100); }); buttons.getBtnAdd1000().setOnAction(e -> { - affineScene.addIterations(1000); + fractalOperations.addIterations(1000); System.out.println("Add 1000"); }); buttons.getBtnReset().setOnAction(e -> { - affineScene.resetIterations(); + fractalOperations.resetIterations(); System.out.println("Reset"); }); } diff --git a/src/main/java/edu/ntnu/idatt2003/view/App.java b/src/main/java/edu/ntnu/idatt2003/view/App.java index f091210..566a68e 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/App.java +++ b/src/main/java/edu/ntnu/idatt2003/view/App.java @@ -1,6 +1,7 @@ package edu.ntnu.idatt2003.view; import edu.ntnu.idatt2003.view.scenes.AffineScene; +import edu.ntnu.idatt2003.view.scenes.JuliaScene; import javafx.application.Application; import javafx.stage.Stage; @@ -13,5 +14,8 @@ public class App extends Application { public void start(Stage primaryStage) { AffineScene affineScene = new AffineScene(); affineScene.setUpStage(primaryStage); + + //JuliaScene juliaScene = new JuliaScene(); + //juliaScene.setUpStage(primaryStage); } } diff --git a/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java b/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java index fa29d1a..922481e 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java +++ b/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java @@ -45,8 +45,8 @@ public class FractalOperations { if ("SierpinskiTriangle".equals(currentFractal)) { this.chaosGame = new ChaosGame(ChaosGameDescriptionFactory.createSierpinskiTriangle(), 400, 400); } else if ("JuliaSet".equals(currentFractal)) { - Complex defaultComplex = new Complex(0, 0); - int defaultInt = 0; + Complex defaultComplex = new Complex(-0.74543, 0.11301); + int defaultInt = -1; this.chaosGame = new ChaosGame(ChaosGameDescriptionFactory.createJuliaSet(defaultComplex, defaultInt), 400, 400); } drawFractal(this.iterations); @@ -64,6 +64,18 @@ public class FractalOperations { } } + public void setFractalToSierpinskiTriangle() { + this.chaosGame = new ChaosGame(ChaosGameDescriptionFactory.createSierpinskiTriangle(), 400, 400); + drawFractal(this.iterations); + } + + public void setFractalToJuliaSet() { + Complex defaultComplex = new Complex(-0.74543, 0.11301); + int defaultInt = -1; + this.chaosGame = new ChaosGame(ChaosGameDescriptionFactory.createJuliaSet(defaultComplex, defaultInt), 400, 400); + drawFractal(this.iterations); + } + public void setCurrentFractal(String fractal) { this.currentFractal = fractal; } diff --git a/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java b/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java index b68bcad..815d6a0 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java +++ b/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java @@ -33,10 +33,10 @@ public class AffineScene { public AffineScene() { buttons = new Buttons(); comboBoxes = new ComboBoxes(); - buttonController = new ButtonController(this, buttons); - buttonController.initialize(); initializeComponents(); fractalOperations = new FractalOperations(iterationsLabel, imageView, "SierpinskiTriangle"); + buttonController = new ButtonController(fractalOperations, buttons); + buttonController.initialize(); fractalOperations.resetIterations(); fractalOperations.addIterations(0); } diff --git a/src/main/java/edu/ntnu/idatt2003/view/scenes/JuliaScene.java b/src/main/java/edu/ntnu/idatt2003/view/scenes/JuliaScene.java index fd64a13..b2dce4b 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/scenes/JuliaScene.java +++ b/src/main/java/edu/ntnu/idatt2003/view/scenes/JuliaScene.java @@ -1,3 +1,114 @@ package edu.ntnu.idatt2003.view.scenes; -public class JuliaScene { + +import edu.ntnu.idatt2003.controller.ButtonController; +import edu.ntnu.idatt2003.model.ChaosCanvas; +import edu.ntnu.idatt2003.model.Vector2D; +import edu.ntnu.idatt2003.view.components.Buttons; +import edu.ntnu.idatt2003.view.components.ComboBoxes; +import edu.ntnu.idatt2003.view.components.FractalOperations; +import javafx.geometry.Insets; +import javafx.scene.Scene; +import javafx.scene.control.Button; +import javafx.scene.control.ComboBox; +import javafx.scene.control.Label; +import javafx.scene.image.ImageView; +import javafx.scene.image.WritableImage; +import javafx.scene.layout.BorderPane; +import javafx.scene.layout.HBox; +import javafx.stage.Stage; + +public class JuliaScene{ + private Label iterationsLabel; + private Scene scene; + private WritableImage writableImage; + private ImageView imageView; + private ChaosCanvas chaosCanvas; + private Buttons buttons; + private ButtonController buttonController; + private ComboBoxes comboBoxes; + private FractalOperations fractalOperations; + + public JuliaScene() { + buttons = new Buttons(); + comboBoxes = new ComboBoxes(); + initializeComponents(); + fractalOperations = new FractalOperations(iterationsLabel, imageView, "JuliaSet"); + buttonController = new ButtonController(fractalOperations, buttons); + buttonController.initialize(); + fractalOperations.resetIterations(); + fractalOperations.addIterations(0); + } + + private void initializeComponents() { + // Creating the root pane and setting its size + BorderPane root = new BorderPane(); + + // HBox for buttons + HBox buttonBox = new HBox(50); // spacing between buttons + HBox topBox = new HBox(50); // spacing between buttons + + buttonBox.getStyleClass().add("button-box"); + topBox.getStyleClass().add("top-box"); + + // Initialize buttons + Button btnAdd10 = buttons.getBtnAdd10(); + Button btnAdd100 = buttons.getBtnAdd100(); + Button btnAdd1000 = buttons.getBtnAdd1000(); + Button btnReset = buttons.getBtnReset(); + + // Initialize ComboBoxes + ComboBox<String> comboBoxFractal = comboBoxes.getComboBoxFractal(); + ComboBox<String>comboBoxColor = comboBoxes.getComboBoxColor(); + + // Add buttons to the HBox + buttonBox.getChildren().addAll(btnAdd10, btnAdd100, btnAdd1000, btnReset); + buttonBox.setPadding(new Insets(0, 0, 50, 50)); + + topBox.getChildren().addAll(comboBoxFractal, comboBoxColor); + topBox.setPadding(new Insets(20, 0, 0, 50)); + + // Aligning the HBox at the bottom + root.setBottom(buttonBox); + root.setTop(topBox); + + // Create a scene with the root and set the CSS style + scene = new Scene(root, 800, 600); + scene.getStylesheets().add(getClass().getResource("/style.css").toExternalForm()); + + // Initialize the ChaosCanvas and the WritableImage + chaosCanvas = new ChaosCanvas(600, 400, new Vector2D(0, 0), new Vector2D(600, 400)); + writableImage = new WritableImage(600, 400); + imageView = new ImageView(writableImage); + + iterationsLabel = new Label(); + + BorderPane imagePane = new BorderPane(); + imagePane.setCenter(imageView); + imagePane.setRight(iterationsLabel); + + root.setCenter(imagePane); + } + + public void setUpStage(Stage primaryStage) { + primaryStage.setTitle("ChaosGame"); + primaryStage.setScene(scene); + primaryStage.show(); + } + + public void addIterations(int iterations) { + fractalOperations.addIterations(iterations); + } + + public void resetIterations() { + fractalOperations.resetIterations(); + } + + /**public void drawFractal(int iterations) { + fractalOperations.drawFractal(iterations); + updateImage(); + }**/ + + private void updateImage() { + fractalOperations.updateImage(); + } } -- GitLab From b0cdcca226620d16c4f3c64074c7c1cf4392e2ea Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Wed, 15 May 2024 11:43:02 +0200 Subject: [PATCH 061/168] Made ChaosGameFileHandlerTest --- .../model/ChaosGameFileHandlerTest.java | 115 ++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 src/test/java/edu/ntnu/idatt2003/model/ChaosGameFileHandlerTest.java diff --git a/src/test/java/edu/ntnu/idatt2003/model/ChaosGameFileHandlerTest.java b/src/test/java/edu/ntnu/idatt2003/model/ChaosGameFileHandlerTest.java new file mode 100644 index 0000000..0237238 --- /dev/null +++ b/src/test/java/edu/ntnu/idatt2003/model/ChaosGameFileHandlerTest.java @@ -0,0 +1,115 @@ +package edu.ntnu.idatt2003.model; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +import java.io.*; +import java.util.List; + +public class ChaosGameFileHandlerTest { + private static final String TEST_FILE_PATH = "testChaosGameDescription.txt"; + private ChaosGameFileHandler fileHandler; + + @BeforeEach + public void setup() { + fileHandler = new ChaosGameFileHandler(TEST_FILE_PATH); + } + + @AfterEach + public void tearDown() { + File file = new File(TEST_FILE_PATH); + if (file.exists()) { + file.delete(); + } + } + + @Test + public void testReadFileAffine() throws IOException { + createTestFileAffine(); + ChaosGameDescription description = fileHandler.readFile(); + assertNotNull(description); + assertEquals(.0, description.getMinCoords().getX0()); + assertEquals(.0, description.getMinCoords().getX1()); + assertEquals(1.0, description.getMaxCoords().getX0()); + assertEquals(1.0, description.getMaxCoords().getX1()); + assertFalse(description.getTransforms().isEmpty()); + assertInstanceOf(AffineTransform2D.class, description.getTransforms().getFirst()); + assertEquals("Affine2D", description.getTransforms().getFirst().getTransformType()); + } + + @Test + @DisplayName("Positive test for readFile() with Julia transform") + public void testReadFileJulia() throws IOException { + createTestFileJulia(); + ChaosGameDescription description = fileHandler.readFile(); + assertNotNull(description); + assertEquals(0.0, description.getMinCoords().getX0()); + assertEquals(0.0, description.getMinCoords().getX1()); + assertEquals(1.0, description.getMaxCoords().getX0()); + assertEquals(1.0, description.getMaxCoords().getX1()); + assertFalse(description.getTransforms().isEmpty()); + assertInstanceOf(JuliaTransform.class, description.getTransforms().getFirst()); + assertEquals("Julia", description.getTransforms().getFirst().getTransformType()); + } + + @Test + public void testWriteToFile() throws IOException { + ChaosGameDescription description = new ChaosGameDescription( + List.of(new AffineTransform2D(new Matrix2x2(1, 0, 0, 1), new Vector2D(0, 0))), + new Vector2D(-1, -1), + new Vector2D(1, 1) + ); + + String filePath = "outputTestFile.txt"; + fileHandler.writeToFile(filePath, description); + + File outputFile = new File(filePath); + assertTrue(outputFile.exists()); + + ChaosGameFileHandler readHandler = new ChaosGameFileHandler(filePath); + ChaosGameDescription readDescription = readHandler.readFile(); + assertNotNull(readDescription); + outputFile.delete(); // Clean up after test + } + + private void createTestFileAffine() { + try (PrintWriter out = new PrintWriter(new FileWriter(TEST_FILE_PATH))) { + out.println("Affine2D # Type of transform"); + out.println(".0, .0 # Lower left"); + out.println("1.0, 1.0 # Upper right"); + out.println("0.5, 0, 0, 0.5, 0, 0 # 1st transform"); + out.println("0.5, 0, 0, 0.5, 0.25, 0.5 # 2nd transform"); + out.println("0.5, 0, 0, 0.5, 0.5, 0 # 3rd transform"); + } catch (IOException e) { + fail("Failed to create test file."); + } + } + + @Test + public void testReadEmptyFile() throws IOException { + createEmptyFile(); + Exception exception = assertThrows(IOException.class, () -> fileHandler.readFile()); + assertTrue(exception.getMessage().contains("Missing essential data")); + } + + + + private void createTestFileJulia() { + try (PrintWriter out = new PrintWriter(new FileWriter(TEST_FILE_PATH))) { + out.println("Julia # Type of transform"); + out.println("0.0, 0.0 # Lower left"); + out.println("1.0, 1.0 # Upper right"); + out.println("0.5, 0.5 #"); + } catch (IOException e) { + fail("Failed to create test file."); + } + } + + private void createEmptyFile() throws IOException { + new PrintWriter(TEST_FILE_PATH).close(); + } +} -- GitLab From ddded19729fc93069c0252a945586408ac055d41 Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Wed, 15 May 2024 11:58:43 +0200 Subject: [PATCH 062/168] Made ChaosGameDescriptionFactoryTest --- .../ChaosGameDescriptionFactoryTest.java | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 src/test/java/edu/ntnu/idatt2003/model/ChaosGameDescriptionFactoryTest.java diff --git a/src/test/java/edu/ntnu/idatt2003/model/ChaosGameDescriptionFactoryTest.java b/src/test/java/edu/ntnu/idatt2003/model/ChaosGameDescriptionFactoryTest.java new file mode 100644 index 0000000..a4fc4cd --- /dev/null +++ b/src/test/java/edu/ntnu/idatt2003/model/ChaosGameDescriptionFactoryTest.java @@ -0,0 +1,32 @@ +package edu.ntnu.idatt2003.model; + +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + +public class ChaosGameDescriptionFactoryTest { + + @Test + public void testCreateSierpinskiTriangle() { + ChaosGameDescription description = ChaosGameDescriptionFactory.createSierpinskiTriangle(); + assertNotNull(description); + assertEquals(3, description.getTransforms().size()); + assertInstanceOf(AffineTransform2D.class, description.getTransforms().getFirst()); + } + + @Test + public void testCreateBarnsleyFern() { + ChaosGameDescription description = ChaosGameDescriptionFactory.createBarnsleyFern(); + assertNotNull(description); + assertEquals(4, description.getTransforms().size()); + assertInstanceOf(AffineTransform2D.class, description.getTransforms().getFirst()); + } + + @Test + public void testCreateJuliaSet() { + Complex c = new Complex(0.285, 0.01); + ChaosGameDescription description = ChaosGameDescriptionFactory.createJuliaSet(c, 1); + assertNotNull(description); + assertEquals(1, description.getTransforms().size()); + assertInstanceOf(JuliaTransform.class, description.getTransforms().getFirst()); + } +} \ No newline at end of file -- GitLab From 4ce473c16c3adb8c3a37add2836d69b8e23a4347 Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Wed, 15 May 2024 12:20:41 +0200 Subject: [PATCH 063/168] ComboBoxController made to handle ComboBoxes action --- .../controller/ComboBoxController.java | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 src/main/java/edu/ntnu/idatt2003/controller/ComboBoxController.java diff --git a/src/main/java/edu/ntnu/idatt2003/controller/ComboBoxController.java b/src/main/java/edu/ntnu/idatt2003/controller/ComboBoxController.java new file mode 100644 index 0000000..950db2d --- /dev/null +++ b/src/main/java/edu/ntnu/idatt2003/controller/ComboBoxController.java @@ -0,0 +1,32 @@ +package edu.ntnu.idatt2003.controller; + +import edu.ntnu.idatt2003.model.ChaosCanvas; +import edu.ntnu.idatt2003.view.components.ComboBoxes; +import edu.ntnu.idatt2003.view.components.FractalOperations; +import javafx.stage.Stage; + +public class ComboBoxController { + private FractalOperations fractalOperations; + private ComboBoxes comboBoxes; + + public ComboBoxController(FractalOperations fractalOperations, ComboBoxes comboBoxes) { + this.fractalOperations = fractalOperations; + this.comboBoxes = comboBoxes; + initialize(); + } + + public void initialize() { + setComboBoxHandlers(); + } + + private void setComboBoxHandlers() { + comboBoxes.getComboBoxFractal().setOnAction(e -> { + String selectedFractal = comboBoxes.getComboBoxFractal().getValue(); + if ("Sierpinski Triangle".equals(selectedFractal)) { + fractalOperations.setFractalToSierpinskiTriangle(); + } else if ("Julia Set".equals(selectedFractal)) { + fractalOperations.setFractalToJuliaSet(); + } + }); + } +} -- GitLab From 665e2931620dc74fc8d65c1a9ce7130b41c4f5c4 Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Wed, 15 May 2024 12:21:10 +0200 Subject: [PATCH 064/168] Refactored to handle ComboBoxController --- .../idatt2003/view/scenes/AffineScene.java | 25 +++++-------------- .../idatt2003/view/scenes/JuliaScene.java | 21 +++------------- 2 files changed, 10 insertions(+), 36 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java b/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java index 815d6a0..0da7471 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java +++ b/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java @@ -1,6 +1,7 @@ package edu.ntnu.idatt2003.view.scenes; import edu.ntnu.idatt2003.controller.ButtonController; +import edu.ntnu.idatt2003.controller.ComboBoxController; import edu.ntnu.idatt2003.model.*; import edu.ntnu.idatt2003.view.components.Buttons; import edu.ntnu.idatt2003.view.components.ComboBoxes; @@ -24,6 +25,7 @@ public class AffineScene { private ChaosCanvas chaosCanvas; private Buttons buttons; private ButtonController buttonController; + private ComboBoxController comboBoxController; private ComboBoxes comboBoxes; private FractalOperations fractalOperations; @@ -36,7 +38,9 @@ public class AffineScene { initializeComponents(); fractalOperations = new FractalOperations(iterationsLabel, imageView, "SierpinskiTriangle"); buttonController = new ButtonController(fractalOperations, buttons); + comboBoxController = new ComboBoxController(fractalOperations, comboBoxes); buttonController.initialize(); + comboBoxController.initialize(); fractalOperations.resetIterations(); fractalOperations.addIterations(0); } @@ -59,8 +63,8 @@ public class AffineScene { Button btnReset = buttons.getBtnReset(); // Initialize ComboBoxes - ComboBox<String>comboBoxFractal = comboBoxes.getComboBoxFractal(); - ComboBox<String>comboBoxColor = comboBoxes.getComboBoxColor(); + ComboBox<String> comboBoxFractal = comboBoxes.getComboBoxFractal(); + ComboBox<String> comboBoxColor = comboBoxes.getComboBoxColor(); // Add buttons to the HBox buttonBox.getChildren().addAll(btnAdd10, btnAdd100, btnAdd1000, btnReset); @@ -96,21 +100,4 @@ public class AffineScene { primaryStage.setScene(scene); primaryStage.show(); } - - public void addIterations(int iterations) { - fractalOperations.addIterations(iterations); - } - - public void resetIterations() { - fractalOperations.resetIterations(); - } - - public void drawFractal(int iterations) { - fractalOperations.drawFractal(iterations); - updateImage(); - } - - private void updateImage() { - fractalOperations.updateImage(); - } } diff --git a/src/main/java/edu/ntnu/idatt2003/view/scenes/JuliaScene.java b/src/main/java/edu/ntnu/idatt2003/view/scenes/JuliaScene.java index b2dce4b..d53f039 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/scenes/JuliaScene.java +++ b/src/main/java/edu/ntnu/idatt2003/view/scenes/JuliaScene.java @@ -1,6 +1,7 @@ package edu.ntnu.idatt2003.view.scenes; import edu.ntnu.idatt2003.controller.ButtonController; +import edu.ntnu.idatt2003.controller.ComboBoxController; import edu.ntnu.idatt2003.model.ChaosCanvas; import edu.ntnu.idatt2003.model.Vector2D; import edu.ntnu.idatt2003.view.components.Buttons; @@ -25,6 +26,7 @@ public class JuliaScene{ private ChaosCanvas chaosCanvas; private Buttons buttons; private ButtonController buttonController; + private ComboBoxController comboBoxController; private ComboBoxes comboBoxes; private FractalOperations fractalOperations; @@ -34,7 +36,9 @@ public class JuliaScene{ initializeComponents(); fractalOperations = new FractalOperations(iterationsLabel, imageView, "JuliaSet"); buttonController = new ButtonController(fractalOperations, buttons); + comboBoxController = new ComboBoxController(fractalOperations, comboBoxes); buttonController.initialize(); + comboBoxController.initialize(); fractalOperations.resetIterations(); fractalOperations.addIterations(0); } @@ -94,21 +98,4 @@ public class JuliaScene{ primaryStage.setScene(scene); primaryStage.show(); } - - public void addIterations(int iterations) { - fractalOperations.addIterations(iterations); - } - - public void resetIterations() { - fractalOperations.resetIterations(); - } - - /**public void drawFractal(int iterations) { - fractalOperations.drawFractal(iterations); - updateImage(); - }**/ - - private void updateImage() { - fractalOperations.updateImage(); - } } -- GitLab From 33d176b3c85279149ad14abf703a24ea17946344 Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Wed, 15 May 2024 12:21:24 +0200 Subject: [PATCH 065/168] Refactored methods to ComboBoxController --- .../java/edu/ntnu/idatt2003/view/components/ComboBoxes.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/edu/ntnu/idatt2003/view/components/ComboBoxes.java b/src/main/java/edu/ntnu/idatt2003/view/components/ComboBoxes.java index 22059ec..2cb8272 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/components/ComboBoxes.java +++ b/src/main/java/edu/ntnu/idatt2003/view/components/ComboBoxes.java @@ -12,12 +12,14 @@ public class ComboBoxes { } private void initializeComboBoxes() { + //ComboBox for choosing fractal comboBoxFractal = new ComboBox<>(); comboBoxFractal.setItems(FXCollections.observableArrayList( "Sierpinski Triangle", "Barnsley Fern", "Julia Set" )); comboBoxFractal.setPromptText("Choose Fractal"); + //ComboBox for choosing color comboBoxColor = new ComboBox<>(); comboBoxColor.setItems(FXCollections.observableArrayList( "Red", "Green", "Blue" -- GitLab From 6d20e9b87e53d30d202578717e85ecaf8cbc6332 Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Wed, 15 May 2024 12:21:55 +0200 Subject: [PATCH 066/168] Methods added and refactored for ComboBoxController --- .../idatt2003/view/components/FractalOperations.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java b/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java index 922481e..a6a8530 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java +++ b/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java @@ -52,6 +52,7 @@ public class FractalOperations { drawFractal(this.iterations); } + public void updateImage() { PixelWriter pixelWriter = writableImage.getPixelWriter(); int[][] canvasArray = chaosGame.getCanvas().getCanvasArray(); @@ -66,17 +67,15 @@ public class FractalOperations { public void setFractalToSierpinskiTriangle() { this.chaosGame = new ChaosGame(ChaosGameDescriptionFactory.createSierpinskiTriangle(), 400, 400); - drawFractal(this.iterations); + iterations = 0; + drawFractal(0); } public void setFractalToJuliaSet() { Complex defaultComplex = new Complex(-0.74543, 0.11301); int defaultInt = -1; this.chaosGame = new ChaosGame(ChaosGameDescriptionFactory.createJuliaSet(defaultComplex, defaultInt), 400, 400); - drawFractal(this.iterations); - } - - public void setCurrentFractal(String fractal) { - this.currentFractal = fractal; + iterations = 0; + drawFractal(0); } } -- GitLab From 9819a87b2fd6d7b455ac4b0f6dbf6c47af0b7cbe Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Wed, 15 May 2024 14:14:59 +0200 Subject: [PATCH 067/168] Bug fix --- .../view/components/FractalOperations.java | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java b/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java index a6a8530..c29e2df 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java +++ b/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java @@ -26,6 +26,11 @@ public class FractalOperations { this.currentFractal = initialFractal; this.writableImage = new WritableImage(400, 400); this.imageView.setImage(writableImage); + if ("SierpinskiTriangle".equals(initialFractal)) { + setFractalToSierpinskiTriangle(); + } else if ("JuliaSet".equals(initialFractal)) { + setFractalToJuliaSet(); + } resetIterations(); } @@ -41,15 +46,8 @@ public class FractalOperations { } public void resetIterations() { - iterations = 0; - if ("SierpinskiTriangle".equals(currentFractal)) { - this.chaosGame = new ChaosGame(ChaosGameDescriptionFactory.createSierpinskiTriangle(), 400, 400); - } else if ("JuliaSet".equals(currentFractal)) { - Complex defaultComplex = new Complex(-0.74543, 0.11301); - int defaultInt = -1; - this.chaosGame = new ChaosGame(ChaosGameDescriptionFactory.createJuliaSet(defaultComplex, defaultInt), 400, 400); - } - drawFractal(this.iterations); + chaosGame.getCanvas().clear(); + drawFractal(0); } -- GitLab From f9d05183afe96beed0255b4166fb5d07b19426cf Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Wed, 15 May 2024 14:44:48 +0200 Subject: [PATCH 068/168] Made to string method --- .../idatt2003/model/ChaosGameDescription.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/main/java/edu/ntnu/idatt2003/model/ChaosGameDescription.java b/src/main/java/edu/ntnu/idatt2003/model/ChaosGameDescription.java index a03a513..3bc144b 100644 --- a/src/main/java/edu/ntnu/idatt2003/model/ChaosGameDescription.java +++ b/src/main/java/edu/ntnu/idatt2003/model/ChaosGameDescription.java @@ -1,6 +1,7 @@ package edu.ntnu.idatt2003.model; import java.util.List; +import java.util.Objects; public class ChaosGameDescription { private Vector2D minCoords; @@ -25,4 +26,20 @@ public class ChaosGameDescription { return maxCoords; } + @Override + public String toString() { + StringBuilder result = new StringBuilder(transforms.getFirst().getTransformType() + " # Type of transform" + "\n" + + minCoords.getX0() + ", " + minCoords.getX1() + " # Lower left" + "\n" + + maxCoords.getX0() + ", " + maxCoords.getX1() + " # Upper right"); + + if (Objects.equals(transforms.getFirst().getTransformType(), "Julia")) { + result.append("\n").append(transforms.getFirst().toFormattedString()); + } else if (Objects.equals(transforms.getFirst().getTransformType(), "Affine2D")) { + for (Transform2D transform : transforms) { + result.append("\n").append(transform.toFormattedString()); + } + } + return result.toString(); + } } + -- GitLab From a522ab0f15b2af09d7b1878b4b6498c77942bdd0 Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Wed, 15 May 2024 14:45:13 +0200 Subject: [PATCH 069/168] Fixed createJuliaSet --- .../edu/ntnu/idatt2003/model/ChaosGameDescriptionFactory.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/edu/ntnu/idatt2003/model/ChaosGameDescriptionFactory.java b/src/main/java/edu/ntnu/idatt2003/model/ChaosGameDescriptionFactory.java index 8b58cc1..34e4cd7 100644 --- a/src/main/java/edu/ntnu/idatt2003/model/ChaosGameDescriptionFactory.java +++ b/src/main/java/edu/ntnu/idatt2003/model/ChaosGameDescriptionFactory.java @@ -46,8 +46,9 @@ public class ChaosGameDescriptionFactory { * @return a ChaosGameDescription for the Julia set */ public static ChaosGameDescription createJuliaSet(Complex c, int sign) { - JuliaTransform[] transforms = new JuliaTransform[1]; + JuliaTransform[] transforms = new JuliaTransform[2]; transforms[0] = new JuliaTransform(c, sign); + transforms[1] = new JuliaTransform(c, -sign); Vector2D lowerLeft = new Vector2D(-1.6, -1.0); Vector2D upperRight = new Vector2D(1.6, 1.0); -- GitLab From 8e63c553d6328441ecfb1afcfc6cfcdf4672bb1d Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Wed, 15 May 2024 14:46:44 +0200 Subject: [PATCH 070/168] Fixed parseJulia, and used toString on description in writeToFile --- .../idatt2003/model/ChaosGameFileHandler.java | 39 +++++++++---------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/model/ChaosGameFileHandler.java b/src/main/java/edu/ntnu/idatt2003/model/ChaosGameFileHandler.java index 6ac917e..3dd33e2 100644 --- a/src/main/java/edu/ntnu/idatt2003/model/ChaosGameFileHandler.java +++ b/src/main/java/edu/ntnu/idatt2003/model/ChaosGameFileHandler.java @@ -40,11 +40,11 @@ public class ChaosGameFileHandler { Transform2D transform = null; assert type != null; if (type.equals("Julia")) { - transform = parseJulia(line.split("#")[0].trim()); + transforms = parseJulia(line.split("#")[0].trim()); } else { transform = parseAffineTransform(line.split("#")[0].trim()); - } transforms.add(transform); + } } catch (IllegalArgumentException e) { System.err.println("Error parsing transform from line: " + line); @@ -98,32 +98,29 @@ public class ChaosGameFileHandler { } } - private JuliaTransform parseJulia(String line) { +// private JuliaTransform parseJulia(String line) { +// String[] parts = line.split(","); +// return new JuliaTransform( +// new Complex(Double.parseDouble(parts[0].trim()), Double.parseDouble(parts[1].trim())), +// 1); +// } + + private List<Transform2D> parseJulia(String line) { String[] parts = line.split(","); - return new JuliaTransform( + List<Transform2D> juliaTransforms = new ArrayList<>(); + juliaTransforms.add(new JuliaTransform( + new Complex(Double.parseDouble(parts[0].trim()), Double.parseDouble(parts[1].trim())), + 1)); + juliaTransforms.add(new JuliaTransform( new Complex(Double.parseDouble(parts[0].trim()), Double.parseDouble(parts[1].trim())), - 1); + -1)); + return juliaTransforms; } public void writeToFile(String filePath, ChaosGameDescription description) throws IOException { try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath))) { - writer.write(description.getTransforms().getFirst().getTransformType() + " # Type of transform"); - writer.newLine(); - Vector2D minCoords = description.getMinCoords(); - Vector2D maxCoords = description.getMaxCoords(); - List<Transform2D> transforms = description.getTransforms(); - - writer.write(minCoords.getX0() + ", " + minCoords.getX1() + " # Lower left"); - writer.newLine(); - - writer.write(maxCoords.getX0() + ", " + maxCoords.getX1() + " # Upper right"); - writer.newLine(); - - for (Transform2D transform : transforms) { - writer.write(transform.toFormattedString() ); - writer.newLine(); - } + writer.write(description.toString()); } catch (IOException e) { System.out.println("An error occurred: " + e.getMessage()); } -- GitLab From 545065cc3b16bba3c1cbf6394dd5c7907e68527c Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Wed, 15 May 2024 14:49:00 +0200 Subject: [PATCH 071/168] Fixed testCreateJuliaSet --- .../ntnu/idatt2003/model/ChaosGameDescriptionFactoryTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/edu/ntnu/idatt2003/model/ChaosGameDescriptionFactoryTest.java b/src/test/java/edu/ntnu/idatt2003/model/ChaosGameDescriptionFactoryTest.java index a4fc4cd..8f0b7a6 100644 --- a/src/test/java/edu/ntnu/idatt2003/model/ChaosGameDescriptionFactoryTest.java +++ b/src/test/java/edu/ntnu/idatt2003/model/ChaosGameDescriptionFactoryTest.java @@ -26,7 +26,7 @@ public class ChaosGameDescriptionFactoryTest { Complex c = new Complex(0.285, 0.01); ChaosGameDescription description = ChaosGameDescriptionFactory.createJuliaSet(c, 1); assertNotNull(description); - assertEquals(1, description.getTransforms().size()); + assertEquals(2, description.getTransforms().size()); assertInstanceOf(JuliaTransform.class, description.getTransforms().getFirst()); } } \ No newline at end of file -- GitLab From 96a79b7e0053ca742b7b6cb0be0e0a4c953ffbfe Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Wed, 15 May 2024 15:15:38 +0200 Subject: [PATCH 072/168] Style for Label added --- src/main/resources/style.css | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/main/resources/style.css b/src/main/resources/style.css index e4cb20e..85a9345 100644 --- a/src/main/resources/style.css +++ b/src/main/resources/style.css @@ -1,5 +1,7 @@ .button { -fx-background-color: #bfbfbf; + -fx-background-radius: 10px; + -fx-padding: 8px; -fx-border: none; -fx-color: white; -fx-text-decoration: none; @@ -9,7 +11,6 @@ -fx-cursor: pointer; -fx-transition-duration: 0.4s; /* Transition effect */ -fx-text-align: center; - -fx-border-radius: 10px; } .button:hover { @@ -36,3 +37,13 @@ .combo-box:hover { -fx-background-color: #96fa7d; } + +.label { + -fx-background-color: #bfbfbf; + -fx-background-radius: 10px; + -fx-font-size: 16px; + -fx-padding: 8px; + -fx-border-color: black; + -fx-border-radius: 10px; + -fx-pref-width: 160px; +} -- GitLab From c41251c119c482b58679701ce5d051dd804a2a18 Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Wed, 15 May 2024 15:16:26 +0200 Subject: [PATCH 073/168] Labels class added to enhance seperation of concerns --- .../idatt2003/view/components/Labels.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 src/main/java/edu/ntnu/idatt2003/view/components/Labels.java diff --git a/src/main/java/edu/ntnu/idatt2003/view/components/Labels.java b/src/main/java/edu/ntnu/idatt2003/view/components/Labels.java new file mode 100644 index 0000000..e07aa2b --- /dev/null +++ b/src/main/java/edu/ntnu/idatt2003/view/components/Labels.java @@ -0,0 +1,20 @@ +package edu.ntnu.idatt2003.view.components; + +import javafx.scene.control.Label; + +public class Labels { + private Label iterationLabel; + + public Labels() { + initializeLabels(); + } + + public void initializeLabels() { + iterationLabel = new Label(); + iterationLabel.setText("Iterations: 0"); + } + + public Label getIterationLabel() { + return iterationLabel; + } +} -- GitLab From 4e1948333a6c3b9795c4bf9b6979d07e2ffe1e04 Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Wed, 15 May 2024 15:19:54 +0200 Subject: [PATCH 074/168] iterationLabel refactored --- .../edu/ntnu/idatt2003/view/scenes/AffineScene.java | 13 ++++++++----- .../edu/ntnu/idatt2003/view/scenes/JuliaScene.java | 13 ++++++++----- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java b/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java index 0da7471..1427cb2 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java +++ b/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java @@ -6,6 +6,7 @@ import edu.ntnu.idatt2003.model.*; import edu.ntnu.idatt2003.view.components.Buttons; import edu.ntnu.idatt2003.view.components.ComboBoxes; import edu.ntnu.idatt2003.view.components.FractalOperations; +import edu.ntnu.idatt2003.view.components.Labels; import javafx.geometry.Insets; import javafx.scene.Scene; import javafx.scene.control.Button; @@ -25,8 +26,9 @@ public class AffineScene { private ChaosCanvas chaosCanvas; private Buttons buttons; private ButtonController buttonController; - private ComboBoxController comboBoxController; private ComboBoxes comboBoxes; + private ComboBoxController comboBoxController; + private Labels labels; private FractalOperations fractalOperations; /** @@ -35,6 +37,7 @@ public class AffineScene { public AffineScene() { buttons = new Buttons(); comboBoxes = new ComboBoxes(); + labels = new Labels(); initializeComponents(); fractalOperations = new FractalOperations(iterationsLabel, imageView, "SierpinskiTriangle"); buttonController = new ButtonController(fractalOperations, buttons); @@ -66,8 +69,11 @@ public class AffineScene { ComboBox<String> comboBoxFractal = comboBoxes.getComboBoxFractal(); ComboBox<String> comboBoxColor = comboBoxes.getComboBoxColor(); + // Initialize Labels + iterationsLabel = labels.getIterationLabel(); + // Add buttons to the HBox - buttonBox.getChildren().addAll(btnAdd10, btnAdd100, btnAdd1000, btnReset); + buttonBox.getChildren().addAll(btnAdd10, btnAdd100, btnAdd1000, btnReset, iterationsLabel); buttonBox.setPadding(new Insets(0, 0, 50, 50)); topBox.getChildren().addAll(comboBoxFractal, comboBoxColor); @@ -86,11 +92,8 @@ public class AffineScene { writableImage = new WritableImage(600, 400); imageView = new ImageView(writableImage); - iterationsLabel = new Label(); - BorderPane imagePane = new BorderPane(); imagePane.setCenter(imageView); - imagePane.setRight(iterationsLabel); root.setCenter(imagePane); } diff --git a/src/main/java/edu/ntnu/idatt2003/view/scenes/JuliaScene.java b/src/main/java/edu/ntnu/idatt2003/view/scenes/JuliaScene.java index d53f039..f674f21 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/scenes/JuliaScene.java +++ b/src/main/java/edu/ntnu/idatt2003/view/scenes/JuliaScene.java @@ -7,6 +7,7 @@ import edu.ntnu.idatt2003.model.Vector2D; import edu.ntnu.idatt2003.view.components.Buttons; import edu.ntnu.idatt2003.view.components.ComboBoxes; import edu.ntnu.idatt2003.view.components.FractalOperations; +import edu.ntnu.idatt2003.view.components.Labels; import javafx.geometry.Insets; import javafx.scene.Scene; import javafx.scene.control.Button; @@ -26,13 +27,15 @@ public class JuliaScene{ private ChaosCanvas chaosCanvas; private Buttons buttons; private ButtonController buttonController; - private ComboBoxController comboBoxController; private ComboBoxes comboBoxes; + private ComboBoxController comboBoxController; + private Labels labels; private FractalOperations fractalOperations; public JuliaScene() { buttons = new Buttons(); comboBoxes = new ComboBoxes(); + labels = new Labels(); initializeComponents(); fractalOperations = new FractalOperations(iterationsLabel, imageView, "JuliaSet"); buttonController = new ButtonController(fractalOperations, buttons); @@ -60,12 +63,15 @@ public class JuliaScene{ Button btnAdd1000 = buttons.getBtnAdd1000(); Button btnReset = buttons.getBtnReset(); + // Initialize Labels + iterationsLabel = labels.getIterationLabel(); + // Initialize ComboBoxes ComboBox<String> comboBoxFractal = comboBoxes.getComboBoxFractal(); ComboBox<String>comboBoxColor = comboBoxes.getComboBoxColor(); // Add buttons to the HBox - buttonBox.getChildren().addAll(btnAdd10, btnAdd100, btnAdd1000, btnReset); + buttonBox.getChildren().addAll(btnAdd10, btnAdd100, btnAdd1000, btnReset, iterationsLabel); buttonBox.setPadding(new Insets(0, 0, 50, 50)); topBox.getChildren().addAll(comboBoxFractal, comboBoxColor); @@ -84,11 +90,8 @@ public class JuliaScene{ writableImage = new WritableImage(600, 400); imageView = new ImageView(writableImage); - iterationsLabel = new Label(); - BorderPane imagePane = new BorderPane(); imagePane.setCenter(imageView); - imagePane.setRight(iterationsLabel); root.setCenter(imagePane); } -- GitLab From 2ce6d0554228d55f45b0c4a0ed2e3be164fa36ce Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Wed, 15 May 2024 15:20:16 +0200 Subject: [PATCH 075/168] iterationLabel resetIterations() refactored --- .../edu/ntnu/idatt2003/view/components/FractalOperations.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java b/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java index c29e2df..a446989 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java +++ b/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java @@ -46,8 +46,10 @@ public class FractalOperations { } public void resetIterations() { + this.iterations = 0; chaosGame.getCanvas().clear(); drawFractal(0); + iterationsLabel.setText("Iterations: 0"); } -- GitLab From 36bde43c5cf714fe6c164eb362e7d41f36435c29 Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Wed, 15 May 2024 15:27:37 +0200 Subject: [PATCH 076/168] made it so that AffineScene takes in an input, which makes it possible to choose between Sierpinski and Barnsley Fern --- src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java b/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java index 0da7471..8289f78 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java +++ b/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java @@ -32,11 +32,11 @@ public class AffineScene { /** * Constructor for the AffineScene class */ - public AffineScene() { + public AffineScene(String fractalType) { buttons = new Buttons(); comboBoxes = new ComboBoxes(); initializeComponents(); - fractalOperations = new FractalOperations(iterationsLabel, imageView, "SierpinskiTriangle"); + fractalOperations = new FractalOperations(iterationsLabel, imageView, fractalType); buttonController = new ButtonController(fractalOperations, buttons); comboBoxController = new ComboBoxController(fractalOperations, comboBoxes); buttonController.initialize(); -- GitLab From a895f7beb4c1dedd075d66dea498bfdfc26b90bc Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Wed, 15 May 2024 15:28:01 +0200 Subject: [PATCH 077/168] Added input in AffineScene --- src/main/java/edu/ntnu/idatt2003/view/App.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/edu/ntnu/idatt2003/view/App.java b/src/main/java/edu/ntnu/idatt2003/view/App.java index 566a68e..573640c 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/App.java +++ b/src/main/java/edu/ntnu/idatt2003/view/App.java @@ -12,7 +12,7 @@ public class App extends Application { @Override public void start(Stage primaryStage) { - AffineScene affineScene = new AffineScene(); + AffineScene affineScene = new AffineScene("BarnsleyFern"); affineScene.setUpStage(primaryStage); //JuliaScene juliaScene = new JuliaScene(); -- GitLab From eb2524c46f04bdea1154c6191f4dcd420dc5e77f Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Wed, 15 May 2024 15:28:33 +0200 Subject: [PATCH 078/168] Added Barnsley Fern to the ComboBoxController --- .../java/edu/ntnu/idatt2003/controller/ComboBoxController.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/edu/ntnu/idatt2003/controller/ComboBoxController.java b/src/main/java/edu/ntnu/idatt2003/controller/ComboBoxController.java index 950db2d..3d59aa2 100644 --- a/src/main/java/edu/ntnu/idatt2003/controller/ComboBoxController.java +++ b/src/main/java/edu/ntnu/idatt2003/controller/ComboBoxController.java @@ -26,6 +26,8 @@ public class ComboBoxController { fractalOperations.setFractalToSierpinskiTriangle(); } else if ("Julia Set".equals(selectedFractal)) { fractalOperations.setFractalToJuliaSet(); + } else if ("Barnsley Fern".equals(selectedFractal)) { + fractalOperations.setFractalToBransleysFern(); } }); } -- GitLab From bdd8b072273eddf687e58823eccbefeee310340f Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Wed, 15 May 2024 15:28:57 +0200 Subject: [PATCH 079/168] Added Barnsley Fern to FractalOperations --- .../ntnu/idatt2003/view/components/FractalOperations.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java b/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java index c29e2df..25bcd10 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java +++ b/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java @@ -30,6 +30,8 @@ public class FractalOperations { setFractalToSierpinskiTriangle(); } else if ("JuliaSet".equals(initialFractal)) { setFractalToJuliaSet(); + } else if ("BarnsleyFern".equals(initialFractal)) { + setFractalToBransleysFern(); } resetIterations(); } @@ -76,4 +78,10 @@ public class FractalOperations { iterations = 0; drawFractal(0); } + + public void setFractalToBransleysFern() { + this.chaosGame = new ChaosGame(ChaosGameDescriptionFactory.createBarnsleyFern(), 400, 400); + iterations = 0; + drawFractal(0); + } } -- GitLab From b5a086a343e1fee716d4f48c7e14c06c5f4f0ccf Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Wed, 15 May 2024 17:33:36 +0200 Subject: [PATCH 080/168] Style added --- src/main/resources/style.css | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/main/resources/style.css b/src/main/resources/style.css index 85a9345..ccf705c 100644 --- a/src/main/resources/style.css +++ b/src/main/resources/style.css @@ -38,7 +38,7 @@ -fx-background-color: #96fa7d; } -.label { +.iterationLabel { -fx-background-color: #bfbfbf; -fx-background-radius: 10px; -fx-font-size: 16px; @@ -47,3 +47,11 @@ -fx-border-radius: 10px; -fx-pref-width: 160px; } + +.addIterationInput { + -fx-background-radius: 10px; + -fx-font-size: 16px; + -fx-padding: 8px; + -fx-pref-width: 120px; + +} -- GitLab From 89a66006b6b275a147c3433af19dcea1c7349e8e Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Wed, 15 May 2024 17:33:54 +0200 Subject: [PATCH 081/168] TextField added --- .../idatt2003/view/components/TextFields.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 src/main/java/edu/ntnu/idatt2003/view/components/TextFields.java diff --git a/src/main/java/edu/ntnu/idatt2003/view/components/TextFields.java b/src/main/java/edu/ntnu/idatt2003/view/components/TextFields.java new file mode 100644 index 0000000..92a40db --- /dev/null +++ b/src/main/java/edu/ntnu/idatt2003/view/components/TextFields.java @@ -0,0 +1,20 @@ +package edu.ntnu.idatt2003.view.components; + +import javafx.scene.control.TextField; + +public class TextFields { + private TextField addIterationInput; + + public TextFields() { + initializeInputFields(); + } + + public void initializeInputFields() { + addIterationInput = new TextField(); + addIterationInput.setPromptText("Add iterations"); + } + + public TextField getAddIterationInput() { + return addIterationInput; + } +} -- GitLab From 0c27295cd6a187eac9b7333d0d712b5131aa043c Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Wed, 15 May 2024 17:34:41 +0200 Subject: [PATCH 082/168] TextFieldController added --- .../controller/TextFieldController.java | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 src/main/java/edu/ntnu/idatt2003/controller/TextFieldController.java diff --git a/src/main/java/edu/ntnu/idatt2003/controller/TextFieldController.java b/src/main/java/edu/ntnu/idatt2003/controller/TextFieldController.java new file mode 100644 index 0000000..65af6e3 --- /dev/null +++ b/src/main/java/edu/ntnu/idatt2003/controller/TextFieldController.java @@ -0,0 +1,35 @@ +package edu.ntnu.idatt2003.controller; + +import edu.ntnu.idatt2003.view.components.FractalOperations; +import edu.ntnu.idatt2003.view.components.TextFields; +import javafx.scene.control.TextField; + +public class TextFieldController { + private FractalOperations fractalOperations; + private TextField addIterationInput; + + public TextFieldController(FractalOperations fractalOperations, TextFields textFields) { + this.fractalOperations = fractalOperations; + this.addIterationInput = textFields.getAddIterationInput(); + initialize(); + } + + public void initialize() { + addIterationInput.setOnAction(e -> handleAddIterationInput()); + } + + public void handleAddIterationInput() { + String input = addIterationInput.getText(); + try { + int iterations = Integer.parseInt(input); + fractalOperations.addIterations(iterations); + } catch (NumberFormatException ex) { + System.out.println("Invalid input. Please enter a integer."); + } + addIterationInput.clear(); + } + + public TextField getAddIterationInput() { + return addIterationInput; + } +} -- GitLab From 1c28bbda44e05768b6d5d8ae6ab9676b111dcf15 Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Wed, 15 May 2024 17:37:05 +0200 Subject: [PATCH 083/168] Refactored to support TextFields and TextFieldController --- .../idatt2003/view/scenes/AffineScene.java | 26 ++++++++++++++----- .../idatt2003/view/scenes/JuliaScene.java | 4 ++- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java b/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java index 1d8ff30..9799ca1 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java +++ b/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java @@ -2,16 +2,15 @@ package edu.ntnu.idatt2003.view.scenes; import edu.ntnu.idatt2003.controller.ButtonController; import edu.ntnu.idatt2003.controller.ComboBoxController; +import edu.ntnu.idatt2003.controller.TextFieldController; import edu.ntnu.idatt2003.model.*; -import edu.ntnu.idatt2003.view.components.Buttons; -import edu.ntnu.idatt2003.view.components.ComboBoxes; -import edu.ntnu.idatt2003.view.components.FractalOperations; -import edu.ntnu.idatt2003.view.components.Labels; +import edu.ntnu.idatt2003.view.components.*; import javafx.geometry.Insets; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.ComboBox; import javafx.scene.control.Label; +import javafx.scene.control.TextField; import javafx.scene.image.ImageView; import javafx.scene.image.WritableImage; import javafx.scene.layout.BorderPane; @@ -29,6 +28,8 @@ public class AffineScene { private ComboBoxes comboBoxes; private ComboBoxController comboBoxController; private Labels labels; + private TextFields textFields; + private TextFieldController textFieldController; private FractalOperations fractalOperations; /** @@ -38,12 +39,15 @@ public class AffineScene { buttons = new Buttons(); comboBoxes = new ComboBoxes(); labels = new Labels(); + textFields = new TextFields(); initializeComponents(); fractalOperations = new FractalOperations(iterationsLabel, imageView, fractalType); - buttonController = new ButtonController(fractalOperations, buttons); + textFieldController = new TextFieldController(fractalOperations, textFields); + buttonController = new ButtonController(fractalOperations, buttons, textFieldController); comboBoxController = new ComboBoxController(fractalOperations, comboBoxes); buttonController.initialize(); comboBoxController.initialize(); + textFieldController.initialize(); fractalOperations.resetIterations(); fractalOperations.addIterations(0); } @@ -64,6 +68,7 @@ public class AffineScene { Button btnAdd100 = buttons.getBtnAdd100(); Button btnAdd1000 = buttons.getBtnAdd1000(); Button btnReset = buttons.getBtnReset(); + Button btnAddInput = buttons.getBtnAddInput(); // Initialize ComboBoxes ComboBox<String> comboBoxFractal = comboBoxes.getComboBoxFractal(); @@ -72,8 +77,17 @@ public class AffineScene { // Initialize Labels iterationsLabel = labels.getIterationLabel(); + // Initialize TextFields + TextField addIterationInput = textFields.getAddIterationInput(); + + // Set the style of the labels + iterationsLabel.getStyleClass().add("iterationLabel"); + addIterationInput.getStyleClass().add("addIterationInput"); + + HBox addInputBox = new HBox(0); + addInputBox.getChildren().addAll(addIterationInput, btnAddInput); // Add buttons to the HBox - buttonBox.getChildren().addAll(btnAdd10, btnAdd100, btnAdd1000, btnReset, iterationsLabel); + buttonBox.getChildren().addAll(btnAdd10, btnAdd100, btnAdd1000, addInputBox, btnReset, iterationsLabel); buttonBox.setPadding(new Insets(0, 0, 50, 50)); topBox.getChildren().addAll(comboBoxFractal, comboBoxColor); diff --git a/src/main/java/edu/ntnu/idatt2003/view/scenes/JuliaScene.java b/src/main/java/edu/ntnu/idatt2003/view/scenes/JuliaScene.java index f674f21..23e0748 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/scenes/JuliaScene.java +++ b/src/main/java/edu/ntnu/idatt2003/view/scenes/JuliaScene.java @@ -2,6 +2,7 @@ package edu.ntnu.idatt2003.view.scenes; import edu.ntnu.idatt2003.controller.ButtonController; import edu.ntnu.idatt2003.controller.ComboBoxController; +import edu.ntnu.idatt2003.controller.TextFieldController; import edu.ntnu.idatt2003.model.ChaosCanvas; import edu.ntnu.idatt2003.model.Vector2D; import edu.ntnu.idatt2003.view.components.Buttons; @@ -30,6 +31,7 @@ public class JuliaScene{ private ComboBoxes comboBoxes; private ComboBoxController comboBoxController; private Labels labels; + private TextFieldController textFieldController; private FractalOperations fractalOperations; public JuliaScene() { @@ -38,7 +40,7 @@ public class JuliaScene{ labels = new Labels(); initializeComponents(); fractalOperations = new FractalOperations(iterationsLabel, imageView, "JuliaSet"); - buttonController = new ButtonController(fractalOperations, buttons); + buttonController = new ButtonController(fractalOperations, buttons, textFieldController); comboBoxController = new ComboBoxController(fractalOperations, comboBoxes); buttonController.initialize(); comboBoxController.initialize(); -- GitLab From abf47e65f5edad310371537b8eb661085b6fc9e8 Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Wed, 15 May 2024 17:37:55 +0200 Subject: [PATCH 084/168] getBtnAddInput() added --- .../java/edu/ntnu/idatt2003/view/components/Buttons.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/edu/ntnu/idatt2003/view/components/Buttons.java b/src/main/java/edu/ntnu/idatt2003/view/components/Buttons.java index 2dafb14..15b55fe 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/components/Buttons.java +++ b/src/main/java/edu/ntnu/idatt2003/view/components/Buttons.java @@ -8,6 +8,7 @@ public class Buttons { private Button btnAdd100; private Button btnAdd1000; private Button btnReset; + private Button btnAddInput; public Buttons() { initializeButtons(); @@ -18,6 +19,7 @@ public class Buttons { btnAdd100 = new Button("Add 100"); btnAdd1000 = new Button("Add 1000"); btnReset = new Button("Reset"); + btnAddInput = new Button("Add"); } public Button getBtnAdd10() { @@ -35,4 +37,7 @@ public class Buttons { public Button getBtnReset() { return btnReset; } + public Button getBtnAddInput() { + return btnAddInput; + } } -- GitLab From 44b788a0512fe0b4d6518e79b7e250fbbfc65b0d Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Wed, 15 May 2024 17:39:35 +0200 Subject: [PATCH 085/168] getBtnAddInput() action added --- .../controller/ButtonController.java | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/main/java/edu/ntnu/idatt2003/controller/ButtonController.java b/src/main/java/edu/ntnu/idatt2003/controller/ButtonController.java index 5ab8968..b019bb2 100644 --- a/src/main/java/edu/ntnu/idatt2003/controller/ButtonController.java +++ b/src/main/java/edu/ntnu/idatt2003/controller/ButtonController.java @@ -2,14 +2,19 @@ package edu.ntnu.idatt2003.controller; import edu.ntnu.idatt2003.view.components.Buttons; import edu.ntnu.idatt2003.view.components.FractalOperations; +import javafx.scene.control.TextField; +import javafx.scene.input.KeyCode; +import javafx.scene.input.KeyEvent; public class ButtonController { private FractalOperations fractalOperations; private Buttons buttons; + private TextFieldController textFieldController; - public ButtonController(FractalOperations fractalOperations, Buttons buttons) { + public ButtonController(FractalOperations fractalOperations, Buttons buttons, TextFieldController textFieldController) { this.fractalOperations = fractalOperations; this.buttons = buttons; + this.textFieldController = textFieldController; initialize(); } @@ -40,5 +45,18 @@ public class ButtonController { fractalOperations.resetIterations(); System.out.println("Reset"); }); + + buttons.getBtnAddInput().setOnAction(e -> { + TextField addIterationInput = textFieldController.getAddIterationInput(); + String input = addIterationInput.getText(); + try { + int iterations = Integer.parseInt(input); + fractalOperations.addIterations(iterations); + System.out.println("Add " + iterations); + } catch (NumberFormatException ex) { + System.out.println("Invalid input. Please enter a integer."); + } + addIterationInput.clear(); + }); } } -- GitLab From 19480ce7bd3aeb7da11fc33a7b9ac1d39e1193be Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Wed, 15 May 2024 17:39:52 +0200 Subject: [PATCH 086/168] Minor refactoring --- src/main/java/edu/ntnu/idatt2003/view/components/Labels.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/edu/ntnu/idatt2003/view/components/Labels.java b/src/main/java/edu/ntnu/idatt2003/view/components/Labels.java index e07aa2b..825a3de 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/components/Labels.java +++ b/src/main/java/edu/ntnu/idatt2003/view/components/Labels.java @@ -4,6 +4,7 @@ import javafx.scene.control.Label; public class Labels { private Label iterationLabel; + private Label addIterationLabel; public Labels() { initializeLabels(); @@ -18,3 +19,4 @@ public class Labels { return iterationLabel; } } + -- GitLab From afe20e634f340d63836e557ba72ba41704d2245f Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Wed, 15 May 2024 21:57:33 +0200 Subject: [PATCH 087/168] iterationLabel width changed --- src/main/resources/style.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/style.css b/src/main/resources/style.css index ccf705c..4ae7283 100644 --- a/src/main/resources/style.css +++ b/src/main/resources/style.css @@ -45,7 +45,7 @@ -fx-padding: 8px; -fx-border-color: black; -fx-border-radius: 10px; - -fx-pref-width: 160px; + -fx-pref-width: 200px; } .addIterationInput { -- GitLab From 265cbe6323f54d9ebc2f1057e60ce489487749a7 Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Wed, 15 May 2024 21:58:15 +0200 Subject: [PATCH 088/168] Refactored to AnchorPane --- .../idatt2003/view/scenes/AffineScene.java | 50 +++++++++++++------ 1 file changed, 34 insertions(+), 16 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java b/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java index 9799ca1..324c0f9 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java +++ b/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java @@ -13,6 +13,7 @@ import javafx.scene.control.Label; import javafx.scene.control.TextField; import javafx.scene.image.ImageView; import javafx.scene.image.WritableImage; +import javafx.scene.layout.AnchorPane; import javafx.scene.layout.BorderPane; import javafx.scene.layout.HBox; import javafx.stage.Stage; @@ -53,14 +54,14 @@ public class AffineScene { } private void initializeComponents() { - // Creating the root pane and setting its size - BorderPane root = new BorderPane(); + // Creating the root AnchorPane + AnchorPane root = new AnchorPane(); // HBox for buttons - HBox buttonBox = new HBox(50); // spacing between buttons + HBox bottomBox = new HBox(50); // spacing between buttons HBox topBox = new HBox(50); // spacing between buttons - buttonBox.getStyleClass().add("button-box"); + bottomBox.getStyleClass().add("button-box"); topBox.getStyleClass().add("top-box"); // Initialize buttons @@ -86,20 +87,13 @@ public class AffineScene { HBox addInputBox = new HBox(0); addInputBox.getChildren().addAll(addIterationInput, btnAddInput); + // Add buttons to the HBox - buttonBox.getChildren().addAll(btnAdd10, btnAdd100, btnAdd1000, addInputBox, btnReset, iterationsLabel); - buttonBox.setPadding(new Insets(0, 0, 50, 50)); + bottomBox.getChildren().addAll(btnAdd10, btnAdd100, btnAdd1000, addInputBox, btnReset, iterationsLabel); + bottomBox.setPadding(new Insets(10, 10, 10, 10)); topBox.getChildren().addAll(comboBoxFractal, comboBoxColor); - topBox.setPadding(new Insets(20, 0, 0, 50)); - - // Aligning the HBox at the bottom - root.setBottom(buttonBox); - root.setTop(topBox); - - // Create a scene with the root and set the CSS style - scene = new Scene(root, 800, 600); - scene.getStylesheets().add(getClass().getResource("/style.css").toExternalForm()); + topBox.setPadding(new Insets(10, 10, 10, 10)); // Initialize the ChaosCanvas and the WritableImage chaosCanvas = new ChaosCanvas(600, 400, new Vector2D(0, 0), new Vector2D(600, 400)); @@ -109,7 +103,31 @@ public class AffineScene { BorderPane imagePane = new BorderPane(); imagePane.setCenter(imageView); - root.setCenter(imagePane); + imageView.fitHeightProperty().bind(imagePane.heightProperty()); + imageView.setPreserveRatio(true); + + // Add components to the root AnchorPane + root.getChildren().addAll(topBox, imagePane, bottomBox); + + // Anchor the topBox to the top of the pane + AnchorPane.setTopAnchor(topBox, 10.0); + AnchorPane.setLeftAnchor(topBox, 10.0); + AnchorPane.setRightAnchor(topBox, 10.0); + + // Anchor the bottomBox to the bottom of the pane + AnchorPane.setBottomAnchor(bottomBox, 10.0); + AnchorPane.setLeftAnchor(bottomBox, 10.0); + AnchorPane.setRightAnchor(bottomBox, 10.0); + + // Anchor the imagePane to the remaining space between top and bottom boxes + AnchorPane.setTopAnchor(imagePane, 70.0); + AnchorPane.setBottomAnchor(imagePane, 80.0); + AnchorPane.setLeftAnchor(imagePane, 10.0); + AnchorPane.setRightAnchor(imagePane, 10.0); + + // Create a scene with the root and set the CSS style + scene = new Scene(root, 1000, 800); + scene.getStylesheets().add(getClass().getResource("/style.css").toExternalForm()); } public void setUpStage(Stage primaryStage) { -- GitLab From 1b9147d09fb1393fb82569fd0a2fce6ba5e358ba Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Thu, 16 May 2024 11:36:05 +0200 Subject: [PATCH 089/168] Added input field for constant C --- .../idatt2003/view/scenes/JuliaScene.java | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/main/java/edu/ntnu/idatt2003/view/scenes/JuliaScene.java b/src/main/java/edu/ntnu/idatt2003/view/scenes/JuliaScene.java index f674f21..2b80b84 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/scenes/JuliaScene.java +++ b/src/main/java/edu/ntnu/idatt2003/view/scenes/JuliaScene.java @@ -3,6 +3,7 @@ package edu.ntnu.idatt2003.view.scenes; import edu.ntnu.idatt2003.controller.ButtonController; import edu.ntnu.idatt2003.controller.ComboBoxController; import edu.ntnu.idatt2003.model.ChaosCanvas; +import edu.ntnu.idatt2003.model.Complex; import edu.ntnu.idatt2003.model.Vector2D; import edu.ntnu.idatt2003.view.components.Buttons; import edu.ntnu.idatt2003.view.components.ComboBoxes; @@ -13,6 +14,7 @@ import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.ComboBox; import javafx.scene.control.Label; +import javafx.scene.control.TextField; import javafx.scene.image.ImageView; import javafx.scene.image.WritableImage; import javafx.scene.layout.BorderPane; @@ -26,6 +28,9 @@ public class JuliaScene{ private ImageView imageView; private ChaosCanvas chaosCanvas; private Buttons buttons; + private Button updateCButton; + private TextField realPartInput; + private TextField imaginaryPartInput; private ButtonController buttonController; private ComboBoxes comboBoxes; private ComboBoxController comboBoxController; @@ -94,6 +99,29 @@ public class JuliaScene{ imagePane.setCenter(imageView); root.setCenter(imagePane); + + updateCButton = new Button("Update C"); + // Initialize TextFields + realPartInput = new TextField(); + imaginaryPartInput = new TextField(); + realPartInput.setPromptText("Real part of C"); + imaginaryPartInput.setPromptText("Imaginary part of C"); + + HBox cBox = new HBox(2); + cBox.getChildren().addAll(realPartInput, imaginaryPartInput, updateCButton); + cBox.setPadding(new Insets(100, 0, 0, 0)); + root.setRight(cBox); + + updateCButton.setOnAction(event -> { + try { + double realPart = Double.parseDouble(realPartInput.getText()); + double imaginaryPart = Double.parseDouble(imaginaryPartInput.getText()); + fractalOperations.updateC(new Complex(realPart, imaginaryPart)); + } catch (NumberFormatException e) { + // Handle invalid input + System.out.println("Invalid input for real or imaginary part of C."); + } + }); } public void setUpStage(Stage primaryStage) { -- GitLab From 9c29aeb042bca8580b68bd41e4414b76a0c536b3 Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Thu, 16 May 2024 11:36:17 +0200 Subject: [PATCH 090/168] Styled text-field --- src/main/resources/style.css | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/main/resources/style.css b/src/main/resources/style.css index 85a9345..5497ef9 100644 --- a/src/main/resources/style.css +++ b/src/main/resources/style.css @@ -47,3 +47,13 @@ -fx-border-radius: 10px; -fx-pref-width: 160px; } + +.text-field { + -fx-background-color: white; + -fx-background-radius: 10px; + -fx-font-size: 16px; + -fx-padding: 8px; + -fx-border-color: black; + -fx-border-radius: 10px; + -fx-pref-width: 150px; +} -- GitLab From ccaf202e5feea039743ffda0dae7f05cebd2650d Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Thu, 16 May 2024 11:36:52 +0200 Subject: [PATCH 091/168] Update C method --- .../ntnu/idatt2003/view/components/FractalOperations.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java b/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java index d97f17d..9445024 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java +++ b/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java @@ -12,6 +12,8 @@ import javafx.scene.image.PixelWriter; import javafx.scene.image.WritableImage; import javafx.scene.paint.Color; +import static edu.ntnu.idatt2003.model.ChaosGameDescriptionFactory.createJuliaSet; + public class FractalOperations { private ChaosGame chaosGame; private int iterations; @@ -86,4 +88,8 @@ public class FractalOperations { iterations = 0; drawFractal(0); } + + public void updateC(Complex complex) { + this.chaosGame = new ChaosGame(createJuliaSet(complex, -1), 400, 400); + } } -- GitLab From f09872bc3ae0586d30fbf891825e87a359b16d47 Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Thu, 16 May 2024 12:43:26 +0200 Subject: [PATCH 092/168] Minor refactoring --- src/main/java/edu/ntnu/idatt2003/view/components/Labels.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/view/components/Labels.java b/src/main/java/edu/ntnu/idatt2003/view/components/Labels.java index 825a3de..d56ffd5 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/components/Labels.java +++ b/src/main/java/edu/ntnu/idatt2003/view/components/Labels.java @@ -4,8 +4,6 @@ import javafx.scene.control.Label; public class Labels { private Label iterationLabel; - private Label addIterationLabel; - public Labels() { initializeLabels(); } -- GitLab From 4a09cb2101c1b4bab7eeeb12debfe68644011a05 Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Thu, 16 May 2024 14:21:44 +0200 Subject: [PATCH 093/168] Changes refactored --- .../java/edu/ntnu/idatt2003/view/scenes/AffineScene.java | 6 +++++- .../java/edu/ntnu/idatt2003/view/scenes/JuliaScene.java | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java b/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java index 324c0f9..bbce221 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java +++ b/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java @@ -44,7 +44,7 @@ public class AffineScene { initializeComponents(); fractalOperations = new FractalOperations(iterationsLabel, imageView, fractalType); textFieldController = new TextFieldController(fractalOperations, textFields); - buttonController = new ButtonController(fractalOperations, buttons, textFieldController); + buttonController = new ButtonController(fractalOperations, buttons, textFieldController, scene.getWindow()); comboBoxController = new ComboBoxController(fractalOperations, comboBoxes); buttonController.initialize(); comboBoxController.initialize(); @@ -135,4 +135,8 @@ public class AffineScene { primaryStage.setScene(scene); primaryStage.show(); } + + public Stage getStage() { + return (Stage) scene.getWindow(); + } } diff --git a/src/main/java/edu/ntnu/idatt2003/view/scenes/JuliaScene.java b/src/main/java/edu/ntnu/idatt2003/view/scenes/JuliaScene.java index 23e0748..592d915 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/scenes/JuliaScene.java +++ b/src/main/java/edu/ntnu/idatt2003/view/scenes/JuliaScene.java @@ -40,7 +40,7 @@ public class JuliaScene{ labels = new Labels(); initializeComponents(); fractalOperations = new FractalOperations(iterationsLabel, imageView, "JuliaSet"); - buttonController = new ButtonController(fractalOperations, buttons, textFieldController); + buttonController = new ButtonController(fractalOperations, buttons, textFieldController, scene.getWindow()); comboBoxController = new ComboBoxController(fractalOperations, comboBoxes); buttonController.initialize(); comboBoxController.initialize(); -- GitLab From 9b04415440d7d59a103d5809159e31c9b085c3d4 Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Thu, 16 May 2024 14:44:55 +0200 Subject: [PATCH 094/168] Imports removed --- .../java/edu/ntnu/idatt2003/controller/ButtonController.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/controller/ButtonController.java b/src/main/java/edu/ntnu/idatt2003/controller/ButtonController.java index b019bb2..292c726 100644 --- a/src/main/java/edu/ntnu/idatt2003/controller/ButtonController.java +++ b/src/main/java/edu/ntnu/idatt2003/controller/ButtonController.java @@ -3,8 +3,6 @@ package edu.ntnu.idatt2003.controller; import edu.ntnu.idatt2003.view.components.Buttons; import edu.ntnu.idatt2003.view.components.FractalOperations; import javafx.scene.control.TextField; -import javafx.scene.input.KeyCode; -import javafx.scene.input.KeyEvent; public class ButtonController { private FractalOperations fractalOperations; -- GitLab From c2062f5eb2302cfe71678dccd33ae6aed2b1821f Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Thu, 16 May 2024 14:45:07 +0200 Subject: [PATCH 095/168] Imports removed --- .../edu/ntnu/idatt2003/model/ChaosGameDescriptionFactory.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/edu/ntnu/idatt2003/model/ChaosGameDescriptionFactory.java b/src/main/java/edu/ntnu/idatt2003/model/ChaosGameDescriptionFactory.java index 34e4cd7..3083eb8 100644 --- a/src/main/java/edu/ntnu/idatt2003/model/ChaosGameDescriptionFactory.java +++ b/src/main/java/edu/ntnu/idatt2003/model/ChaosGameDescriptionFactory.java @@ -1,6 +1,8 @@ package edu.ntnu.idatt2003.model; +import java.io.IOException; import java.util.Arrays; +import java.util.List; /** * This class is a factory for creating different standard fractals as ChaosGameDescriptions. -- GitLab From 9173a88e071cd113d222ea1c355f905426c388a8 Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Thu, 16 May 2024 14:46:13 +0200 Subject: [PATCH 096/168] private to public --- .../java/edu/ntnu/idatt2003/model/ChaosGameFileHandler.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/model/ChaosGameFileHandler.java b/src/main/java/edu/ntnu/idatt2003/model/ChaosGameFileHandler.java index 3dd33e2..9769991 100644 --- a/src/main/java/edu/ntnu/idatt2003/model/ChaosGameFileHandler.java +++ b/src/main/java/edu/ntnu/idatt2003/model/ChaosGameFileHandler.java @@ -62,7 +62,7 @@ public class ChaosGameFileHandler { return new ChaosGameDescription(transforms, minCoords, maxCoords); } - private AffineTransform2D parseAffineTransform(String line) { + public AffineTransform2D parseAffineTransform(String line) { String[] parts = line.split(","); ArrayList<Double> params = new ArrayList<>(); for (String part : parts) { @@ -84,7 +84,7 @@ public class ChaosGameFileHandler { ); } - private Vector2D parseVector2D(String line) { + public Vector2D parseVector2D(String line) { String[] parts = line.split("#")[0].trim().split(","); if (parts.length < 2) return null; -- GitLab From 241703935b8c2b24387f75e9a080340b5cc4d92c Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Thu, 16 May 2024 14:47:11 +0200 Subject: [PATCH 097/168] setFractalCustomAffine method --- .../view/components/FractalOperations.java | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java b/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java index d97f17d..7f73b2f 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java +++ b/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java @@ -1,10 +1,7 @@ package edu.ntnu.idatt2003.view.components; import edu.ntnu.idatt2003.controller.ButtonController; -import edu.ntnu.idatt2003.model.ChaosCanvas; -import edu.ntnu.idatt2003.model.ChaosGame; -import edu.ntnu.idatt2003.model.ChaosGameDescriptionFactory; -import edu.ntnu.idatt2003.model.Complex; +import edu.ntnu.idatt2003.model.*; import javafx.scene.Scene; import javafx.scene.control.Label; import javafx.scene.image.ImageView; @@ -12,6 +9,8 @@ import javafx.scene.image.PixelWriter; import javafx.scene.image.WritableImage; import javafx.scene.paint.Color; +import java.io.IOException; + public class FractalOperations { private ChaosGame chaosGame; private int iterations; @@ -86,4 +85,16 @@ public class FractalOperations { iterations = 0; drawFractal(0); } + + public void setFractalCustomAffine(String filePath) { + ChaosGameFileHandler fileHandler = new ChaosGameFileHandler(filePath); + try { + ChaosGameDescription description = fileHandler.readFile(); + this.chaosGame = new ChaosGame(description, 400, 400); + iterations = 0; + drawFractal(0); + } catch (IOException e) { + e.printStackTrace(); + } + } } -- GitLab From 4b596ffbc5d2178c4acd6dad06bd0b1dbbb48e6d Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Thu, 16 May 2024 14:48:32 +0200 Subject: [PATCH 098/168] new combobox alternative --- .../ntnu/idatt2003/controller/ComboBoxController.java | 10 ++++++++++ .../edu/ntnu/idatt2003/view/components/ComboBoxes.java | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/main/java/edu/ntnu/idatt2003/controller/ComboBoxController.java b/src/main/java/edu/ntnu/idatt2003/controller/ComboBoxController.java index 3d59aa2..2d13471 100644 --- a/src/main/java/edu/ntnu/idatt2003/controller/ComboBoxController.java +++ b/src/main/java/edu/ntnu/idatt2003/controller/ComboBoxController.java @@ -3,8 +3,11 @@ package edu.ntnu.idatt2003.controller; import edu.ntnu.idatt2003.model.ChaosCanvas; import edu.ntnu.idatt2003.view.components.ComboBoxes; import edu.ntnu.idatt2003.view.components.FractalOperations; +import javafx.stage.FileChooser; import javafx.stage.Stage; +import java.io.File; + public class ComboBoxController { private FractalOperations fractalOperations; private ComboBoxes comboBoxes; @@ -28,6 +31,13 @@ public class ComboBoxController { fractalOperations.setFractalToJuliaSet(); } else if ("Barnsley Fern".equals(selectedFractal)) { fractalOperations.setFractalToBransleysFern(); + } else if ("Fractal From File".equals(selectedFractal)) { + FileChooser fileChooser = new FileChooser(); + fileChooser.setTitle("Select Fractal From File"); + File file = fileChooser.showOpenDialog(new Stage()); + if (file != null) { + fractalOperations.setFractalCustomAffine(file.getPath()); + } } }); } diff --git a/src/main/java/edu/ntnu/idatt2003/view/components/ComboBoxes.java b/src/main/java/edu/ntnu/idatt2003/view/components/ComboBoxes.java index 2cb8272..d59b65e 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/components/ComboBoxes.java +++ b/src/main/java/edu/ntnu/idatt2003/view/components/ComboBoxes.java @@ -15,7 +15,7 @@ public class ComboBoxes { //ComboBox for choosing fractal comboBoxFractal = new ComboBox<>(); comboBoxFractal.setItems(FXCollections.observableArrayList( - "Sierpinski Triangle", "Barnsley Fern", "Julia Set" + "Sierpinski Triangle", "Barnsley Fern", "Julia Set", "Fractal From File" )); comboBoxFractal.setPromptText("Choose Fractal"); -- GitLab From b03fe6545ecc629d804449ced488a2613ebc10bc Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Thu, 16 May 2024 14:48:42 +0200 Subject: [PATCH 099/168] minor changes --- src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java | 2 +- src/main/java/edu/ntnu/idatt2003/view/scenes/JuliaScene.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java b/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java index bbce221..3781619 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java +++ b/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java @@ -44,7 +44,7 @@ public class AffineScene { initializeComponents(); fractalOperations = new FractalOperations(iterationsLabel, imageView, fractalType); textFieldController = new TextFieldController(fractalOperations, textFields); - buttonController = new ButtonController(fractalOperations, buttons, textFieldController, scene.getWindow()); + buttonController = new ButtonController(fractalOperations, buttons, textFieldController); comboBoxController = new ComboBoxController(fractalOperations, comboBoxes); buttonController.initialize(); comboBoxController.initialize(); diff --git a/src/main/java/edu/ntnu/idatt2003/view/scenes/JuliaScene.java b/src/main/java/edu/ntnu/idatt2003/view/scenes/JuliaScene.java index 592d915..23e0748 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/scenes/JuliaScene.java +++ b/src/main/java/edu/ntnu/idatt2003/view/scenes/JuliaScene.java @@ -40,7 +40,7 @@ public class JuliaScene{ labels = new Labels(); initializeComponents(); fractalOperations = new FractalOperations(iterationsLabel, imageView, "JuliaSet"); - buttonController = new ButtonController(fractalOperations, buttons, textFieldController, scene.getWindow()); + buttonController = new ButtonController(fractalOperations, buttons, textFieldController); comboBoxController = new ComboBoxController(fractalOperations, comboBoxes); buttonController.initialize(); comboBoxController.initialize(); -- GitLab From 1283e89b566ed14bc8bb627856d3fb5141e1e3e5 Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Thu, 16 May 2024 15:04:56 +0200 Subject: [PATCH 100/168] Minor fixes --- .../ntnu/idatt2003/view/components/FractalOperations.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java b/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java index 7f73b2f..139c9cb 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java +++ b/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java @@ -1,6 +1,6 @@ package edu.ntnu.idatt2003.view.components; -import edu.ntnu.idatt2003.controller.ButtonController; +import static edu.ntnu.idatt2003.model.ChaosGameDescriptionFactory.createJuliaSet; import edu.ntnu.idatt2003.model.*; import javafx.scene.Scene; import javafx.scene.control.Label; @@ -11,6 +11,8 @@ import javafx.scene.paint.Color; import java.io.IOException; +import static edu.ntnu.idatt2003.model.ChaosGameDescriptionFactory.createJuliaSet; + public class FractalOperations { private ChaosGame chaosGame; private int iterations; @@ -97,4 +99,8 @@ public class FractalOperations { e.printStackTrace(); } } + + public void updateC(Complex complex) { + this.chaosGame = new ChaosGame(createJuliaSet(complex, -1), 400, 400); + } } -- GitLab From 6f54dbc3ccec0cf7c138a0f5e2188300db93d031 Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Thu, 16 May 2024 19:15:17 +0200 Subject: [PATCH 101/168] Test --- .../java/edu/ntnu/idatt2003/controller/ComboBoxController.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/edu/ntnu/idatt2003/controller/ComboBoxController.java b/src/main/java/edu/ntnu/idatt2003/controller/ComboBoxController.java index 2d13471..ca81357 100644 --- a/src/main/java/edu/ntnu/idatt2003/controller/ComboBoxController.java +++ b/src/main/java/edu/ntnu/idatt2003/controller/ComboBoxController.java @@ -8,6 +8,9 @@ import javafx.stage.Stage; import java.io.File; +/** + * Controller class for the ComboBoxes in the GUI. + */ public class ComboBoxController { private FractalOperations fractalOperations; private ComboBoxes comboBoxes; -- GitLab From 2295ea40bfd91f1c393a5d4ca8d03d7028a73626 Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Thu, 16 May 2024 20:01:03 +0200 Subject: [PATCH 102/168] style for exit button added --- src/main/resources/style.css | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/main/resources/style.css b/src/main/resources/style.css index 1fdfa58..662adc6 100644 --- a/src/main/resources/style.css +++ b/src/main/resources/style.css @@ -18,6 +18,15 @@ -fx-cursor: hand; } +.exitButton:hover { + -fx-background-color: #e74c3c; + -fx-cursor: hand; +} + +.exitButton { + -fx-pref-width: 45px; +} + .combo-box { -fx-background-color: #bfbfbf; @@ -38,6 +47,8 @@ -fx-background-color: #96fa7d; } + + .iterationLabel { -fx-background-color: #bfbfbf; -fx-background-radius: 10px; @@ -65,3 +76,5 @@ -fx-border-radius: 10px; -fx-pref-width: 150px; } + + -- GitLab From c1bd27401b9293ec5caf44b7d26c147a39f68552 Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Thu, 16 May 2024 20:02:29 +0200 Subject: [PATCH 103/168] Exit button added with Alert popup --- .../idatt2003/controller/ButtonController.java | 15 +++++++++++++++ .../ntnu/idatt2003/view/components/Buttons.java | 5 +++++ .../ntnu/idatt2003/view/scenes/AffineScene.java | 8 +++++++- 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/main/java/edu/ntnu/idatt2003/controller/ButtonController.java b/src/main/java/edu/ntnu/idatt2003/controller/ButtonController.java index 292c726..a59db74 100644 --- a/src/main/java/edu/ntnu/idatt2003/controller/ButtonController.java +++ b/src/main/java/edu/ntnu/idatt2003/controller/ButtonController.java @@ -2,6 +2,9 @@ package edu.ntnu.idatt2003.controller; import edu.ntnu.idatt2003.view.components.Buttons; import edu.ntnu.idatt2003.view.components.FractalOperations; +import javafx.application.Platform; +import javafx.scene.control.Alert; +import javafx.scene.control.ButtonType; import javafx.scene.control.TextField; public class ButtonController { @@ -56,5 +59,17 @@ public class ButtonController { } addIterationInput.clear(); }); + + buttons.getBtnExitApplication().setOnAction(e -> { + Alert alert = new Alert(Alert.AlertType.CONFIRMATION); + alert.setTitle("Exit Confirmation"); + alert.setHeaderText("Are you sure you want to exit the application?"); + alert.setContentText("Press OK to exit the application, or Cancel to stay."); + + + var result = alert.showAndWait(); + if (result.isPresent() && result.get() == ButtonType.OK) + Platform.exit(); + }); } } diff --git a/src/main/java/edu/ntnu/idatt2003/view/components/Buttons.java b/src/main/java/edu/ntnu/idatt2003/view/components/Buttons.java index 15b55fe..65602d3 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/components/Buttons.java +++ b/src/main/java/edu/ntnu/idatt2003/view/components/Buttons.java @@ -9,6 +9,7 @@ public class Buttons { private Button btnAdd1000; private Button btnReset; private Button btnAddInput; + private Button btnExitApplication; public Buttons() { initializeButtons(); @@ -20,6 +21,7 @@ public class Buttons { btnAdd1000 = new Button("Add 1000"); btnReset = new Button("Reset"); btnAddInput = new Button("Add"); + btnExitApplication = new Button("Exit"); } public Button getBtnAdd10() { @@ -40,4 +42,7 @@ public class Buttons { public Button getBtnAddInput() { return btnAddInput; } + public Button getBtnExitApplication() { + return btnExitApplication; + } } diff --git a/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java b/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java index 3781619..a10165c 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java +++ b/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java @@ -70,6 +70,7 @@ public class AffineScene { Button btnAdd1000 = buttons.getBtnAdd1000(); Button btnReset = buttons.getBtnReset(); Button btnAddInput = buttons.getBtnAddInput(); + Button btnExitApplication = buttons.getBtnExitApplication(); // Initialize ComboBoxes ComboBox<String> comboBoxFractal = comboBoxes.getComboBoxFractal(); @@ -84,6 +85,7 @@ public class AffineScene { // Set the style of the labels iterationsLabel.getStyleClass().add("iterationLabel"); addIterationInput.getStyleClass().add("addIterationInput"); + btnExitApplication.getStyleClass().add("exitButton"); HBox addInputBox = new HBox(0); addInputBox.getChildren().addAll(addIterationInput, btnAddInput); @@ -107,7 +109,7 @@ public class AffineScene { imageView.setPreserveRatio(true); // Add components to the root AnchorPane - root.getChildren().addAll(topBox, imagePane, bottomBox); + root.getChildren().addAll(topBox, imagePane, bottomBox, btnExitApplication); // Anchor the topBox to the top of the pane AnchorPane.setTopAnchor(topBox, 10.0); @@ -125,6 +127,10 @@ public class AffineScene { AnchorPane.setLeftAnchor(imagePane, 10.0); AnchorPane.setRightAnchor(imagePane, 10.0); + // Anchor the btnExitApplication to the top right corner + AnchorPane.setTopAnchor(btnExitApplication, 10.0); + AnchorPane.setRightAnchor(btnExitApplication, 10.0); + // Create a scene with the root and set the CSS style scene = new Scene(root, 1000, 800); scene.getStylesheets().add(getClass().getResource("/style.css").toExternalForm()); -- GitLab From 8bbc4435e2238cbcfaa819fa97d1803747001ad0 Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Sun, 19 May 2024 10:01:10 +0200 Subject: [PATCH 104/168] Added input field for constant c, for julia set --- .../idatt2003/view/scenes/AffineScene.java | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java b/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java index a10165c..5253a91 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java +++ b/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java @@ -32,6 +32,7 @@ public class AffineScene { private TextFields textFields; private TextFieldController textFieldController; private FractalOperations fractalOperations; + private HBox cBox; // Container for the C input fields /** * Constructor for the AffineScene class @@ -51,6 +52,20 @@ public class AffineScene { textFieldController.initialize(); fractalOperations.resetIterations(); fractalOperations.addIterations(0); + + // Add listener to ComboBox to handle dynamic addition of C input fields + comboBoxes.getComboBoxFractal().getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> { + if ("Julia Set".equals(newValue)) { + addCInputBox(); + } else { + removeCInputBox(); + } + }); + + // Initial setup based on the provided fractal type + if ("Julia Set".equals(fractalType)) { + addCInputBox(); + } } private void initializeComponents() { @@ -136,6 +151,53 @@ public class AffineScene { scene.getStylesheets().add(getClass().getResource("/style.css").toExternalForm()); } + private void addCInputBox() { + if (cBox == null) { + cBox = createCInputBox(); + AnchorPane.setTopAnchor(cBox, 50.0); + AnchorPane.setRightAnchor(cBox, 10.0); + ((AnchorPane) scene.getRoot()).getChildren().add(cBox); + } + } + + private void removeCInputBox() { + if (cBox != null) { + ((AnchorPane) scene.getRoot()).getChildren().remove(cBox); + cBox = null; + } + } + + private HBox createCInputBox() { + // Initialize the update C button + Button updateCButton = new Button("Update C"); + // Initialize TextFields + TextField realPartInput = new TextField(); + TextField imaginaryPartInput = new TextField(); + + realPartInput.getStyleClass().add("cInput"); + imaginaryPartInput.getStyleClass().add("cInput"); + + realPartInput.setPromptText("Real part of C"); + imaginaryPartInput.setPromptText("Imaginary part of C"); + + HBox cBox = new HBox(2); + cBox.getChildren().addAll(realPartInput, imaginaryPartInput, updateCButton); + cBox.setPadding(new Insets(100, 0, 0, 0)); + + updateCButton.setOnAction(event -> { + try { + double realPart = Double.parseDouble(realPartInput.getText()); + double imaginaryPart = Double.parseDouble(imaginaryPartInput.getText()); + fractalOperations.updateC(new Complex(realPart, imaginaryPart)); + } catch (NumberFormatException e) { + // Handle invalid input + System.out.println("Invalid input for real or imaginary part of C."); + } + }); + + return cBox; + } + public void setUpStage(Stage primaryStage) { primaryStage.setTitle("ChaosGame"); primaryStage.setScene(scene); -- GitLab From 0140ad237e2aef54e3bbd85cc6ec1213438c4992 Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Sun, 19 May 2024 11:42:52 +0200 Subject: [PATCH 105/168] Added input field for matrix and vector for affine transformation --- .../idatt2003/view/scenes/AffineScene.java | 142 +++++++++++++++++- 1 file changed, 140 insertions(+), 2 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java b/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java index 5253a91..e1f4078 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java +++ b/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java @@ -16,8 +16,13 @@ import javafx.scene.image.WritableImage; import javafx.scene.layout.AnchorPane; import javafx.scene.layout.BorderPane; import javafx.scene.layout.HBox; +import javafx.scene.layout.VBox; import javafx.stage.Stage; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + public class AffineScene { private Label iterationsLabel; private Scene scene; @@ -33,6 +38,7 @@ public class AffineScene { private TextFieldController textFieldController; private FractalOperations fractalOperations; private HBox cBox; // Container for the C input fields + private VBox matrixVectorBox; // Container for the matrix and vector input fields /** * Constructor for the AffineScene class @@ -57,14 +63,21 @@ public class AffineScene { comboBoxes.getComboBoxFractal().getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> { if ("Julia Set".equals(newValue)) { addCInputBox(); - } else { + removeMatrixVectorInputBoxes(); + } else if ("Sierpinski Triangle".equals(newValue) || "Barnsley Fern".equals(newValue)) { + removeCInputBox(); + addMatrixVectorInputBoxes(); + } else if ("Fractal From File".equals(newValue)) { removeCInputBox(); + removeMatrixVectorInputBoxes(); } }); // Initial setup based on the provided fractal type if ("Julia Set".equals(fractalType)) { addCInputBox(); + } else if ("Sierpinski Triangle".equals(fractalType) || "Barnsley Fern".equals(fractalType)) { + addMatrixVectorInputBoxes(); } } @@ -147,7 +160,7 @@ public class AffineScene { AnchorPane.setRightAnchor(btnExitApplication, 10.0); // Create a scene with the root and set the CSS style - scene = new Scene(root, 1000, 800); + scene = new Scene(root, 1200, 800); scene.getStylesheets().add(getClass().getResource("/style.css").toExternalForm()); } @@ -198,6 +211,131 @@ public class AffineScene { return cBox; } + private HBox createMatrixVectorInputBox() { + HBox matrixVectorBox = new HBox(5); + matrixVectorBox.setPadding(new Insets(5)); + + VBox matrixBox = new VBox(5); + VBox vectorBox = new VBox(5); + + Label matrixLabel = new Label("Matrix"); + Label vectorLabel = new Label("Vector"); + + matrixBox.getChildren().add(matrixLabel); + vectorBox.getChildren().add(vectorLabel); + + TextField matrixInput1 = new TextField(); + TextField matrixInput2 = new TextField(); + TextField matrixInput3 = new TextField(); + TextField matrixInput4 = new TextField(); + TextField vectorInput1 = new TextField(); + TextField vectorInput2 = new TextField(); + + matrixInput1.getStyleClass().add("matrixInput"); + matrixInput2.getStyleClass().add("matrixInput"); + matrixInput3.getStyleClass().add("matrixInput"); + matrixInput4.getStyleClass().add("matrixInput"); + vectorInput1.getStyleClass().add("matrixInput"); + vectorInput2.getStyleClass().add("matrixInput"); + + matrixInput1.setPromptText("[0,0]"); + matrixInput2.setPromptText("[0,1]"); + matrixInput3.setPromptText("[1,0]"); + matrixInput4.setPromptText("[1,1]"); + vectorInput1.setPromptText("[0]"); + vectorInput2.setPromptText("[1]"); + + HBox upperMatrixRow = new HBox(5); + HBox lowerMatrixRow = new HBox(5); + + upperMatrixRow.getChildren().addAll(matrixInput1, matrixInput2); + lowerMatrixRow.getChildren().addAll(matrixInput3, matrixInput4); + + matrixBox.getChildren().addAll(upperMatrixRow, lowerMatrixRow); + + vectorBox.getChildren().addAll(vectorInput1, vectorInput2); + + matrixVectorBox.getChildren().addAll(matrixBox, vectorBox); + return matrixVectorBox; + } + + private void addMatrixVectorInputBoxes() { + if (matrixVectorBox == null) { + matrixVectorBox = new VBox(10); + matrixVectorBox.setPadding(new Insets(10)); + VBox inputContainer = new VBox(10); + inputContainer.setPadding(new Insets(10)); + + Button addMoreButton = new Button("Add More"); + addMoreButton.setOnAction(event -> { + HBox newInputBox = createMatrixVectorInputBox(); + inputContainer.getChildren().add(0, newInputBox); + }); + + Button updateMatrixVectorButton = new Button("Update Matrix and Vector"); + updateMatrixVectorButton.setOnAction(event -> { + // Handle updating the matrix and vector + updateAffineTransforms(inputContainer); + }); + + inputContainer.getChildren().addAll(createMatrixVectorInputBox(), createMatrixVectorInputBox(), createMatrixVectorInputBox(), addMoreButton, updateMatrixVectorButton); + AnchorPane.setTopAnchor(inputContainer, 120.0); + AnchorPane.setRightAnchor(inputContainer, 10.0); + ((AnchorPane) scene.getRoot()).getChildren().add(inputContainer); + matrixVectorBox = inputContainer; + } + } + + private void removeMatrixVectorInputBoxes() { + if (matrixVectorBox != null) { + ((AnchorPane) scene.getRoot()).getChildren().remove(matrixVectorBox); + matrixVectorBox = null; + } + } + + private void updateAffineTransforms(VBox inputContainer) { + List<AffineTransform2D> transforms = new ArrayList<>(); + for (int i = 0; i < inputContainer.getChildren().size() - 2; i++) { // exclude the last two buttons + HBox matrixVectorBox = (HBox) inputContainer.getChildren().get(i); + VBox matrixBox = (VBox) matrixVectorBox.getChildren().get(0); + VBox vectorBox = (VBox) matrixVectorBox.getChildren().get(1); + + HBox upperMatrixRow = (HBox) matrixBox.getChildren().get(1); + HBox lowerMatrixRow = (HBox) matrixBox.getChildren().get(2); + + TextField matrixInput1 = (TextField) upperMatrixRow.getChildren().get(0); + TextField matrixInput2 = (TextField) upperMatrixRow.getChildren().get(1); + TextField matrixInput3 = (TextField) lowerMatrixRow.getChildren().get(0); + TextField matrixInput4 = (TextField) lowerMatrixRow.getChildren().get(1); + + TextField vectorInput1 = (TextField) vectorBox.getChildren().get(1); // corrected index + TextField vectorInput2 = (TextField) vectorBox.getChildren().get(2); // corrected index + + try { + double m00 = Double.parseDouble(matrixInput1.getText()); + double m01 = Double.parseDouble(matrixInput2.getText()); + double m10 = Double.parseDouble(matrixInput3.getText()); + double m11 = Double.parseDouble(matrixInput4.getText()); + double v0 = Double.parseDouble(vectorInput1.getText()); + double v1 = Double.parseDouble(vectorInput2.getText()); + + AffineTransform2D transform = new AffineTransform2D(new Matrix2x2(m00, m01, m10, m11), new Vector2D(v0, v1)); + transforms.add(transform); + } catch (NumberFormatException e) { + System.out.println("Invalid input for matrix or vector values."); + // You can also add a dialog box here to notify the user + } + } + + // Here you should pass the transforms to create a ChaosGameDescription + Vector2D lowerLeft = new Vector2D(0.0, 0.0); + Vector2D upperRight = new Vector2D(1.0, 1.0); + ChaosGameDescription description = new ChaosGameDescription(Arrays.asList(transforms.toArray(new AffineTransform2D[0])), lowerLeft, upperRight); + + // Update the fractal operations with the new description + fractalOperations.updateMatrixAndVector(description); + } + public void setUpStage(Stage primaryStage) { primaryStage.setTitle("ChaosGame"); primaryStage.setScene(scene); -- GitLab From 4eb93df6bd62b77de51dfc207de8f314bc6ed161 Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Sun, 19 May 2024 11:43:10 +0200 Subject: [PATCH 106/168] added update matrix and Vector --- .../ntnu/idatt2003/view/components/FractalOperations.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java b/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java index 139c9cb..450f37b 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java +++ b/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java @@ -103,4 +103,10 @@ public class FractalOperations { public void updateC(Complex complex) { this.chaosGame = new ChaosGame(createJuliaSet(complex, -1), 400, 400); } + + public void updateMatrixAndVector(ChaosGameDescription description) { + this.chaosGame = new ChaosGame(description, 400, 400); + iterations = 0; + drawFractal(0); + } } -- GitLab From b889f52fabba019b28f21120550ea41053b2da17 Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Sun, 19 May 2024 11:43:24 +0200 Subject: [PATCH 107/168] style for matrix and vector inputs --- src/main/resources/style.css | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/resources/style.css b/src/main/resources/style.css index 662adc6..3ed89ce 100644 --- a/src/main/resources/style.css +++ b/src/main/resources/style.css @@ -77,4 +77,13 @@ -fx-pref-width: 150px; } +.matrixInput{ + -fx-background-color: white; + -fx-background-radius: 10px; + -fx-font-size: 16px; + -fx-padding: 8px; + -fx-border-color: black; + -fx-border-radius: 10px; + -fx-pref-width: 50px; +} -- GitLab From 2fbb650e6674660a31a6c498ea2935f4308b4fd1 Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Sun, 19 May 2024 14:36:14 +0200 Subject: [PATCH 108/168] Added reset to default fractal button --- .../idatt2003/view/scenes/AffineScene.java | 63 ++++++++++++++----- 1 file changed, 47 insertions(+), 16 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java b/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java index e1f4078..59ded77 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java +++ b/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java @@ -37,7 +37,7 @@ public class AffineScene { private TextFields textFields; private TextFieldController textFieldController; private FractalOperations fractalOperations; - private HBox cBox; // Container for the C input fields + private VBox cBox; // Container for the C input fields private VBox matrixVectorBox; // Container for the matrix and vector input fields /** @@ -180,9 +180,10 @@ public class AffineScene { } } - private HBox createCInputBox() { + private VBox createCInputBox() { // Initialize the update C button Button updateCButton = new Button("Update C"); + Button resetToDefaultButton = new Button("Reset to Default fractal"); // Initialize TextFields TextField realPartInput = new TextField(); TextField imaginaryPartInput = new TextField(); @@ -193,8 +194,8 @@ public class AffineScene { realPartInput.setPromptText("Real part of C"); imaginaryPartInput.setPromptText("Imaginary part of C"); - HBox cBox = new HBox(2); - cBox.getChildren().addAll(realPartInput, imaginaryPartInput, updateCButton); + VBox cBox = new VBox(2); + cBox.getChildren().addAll(realPartInput, imaginaryPartInput, updateCButton, resetToDefaultButton); cBox.setPadding(new Insets(100, 0, 0, 0)); updateCButton.setOnAction(event -> { @@ -208,10 +209,14 @@ public class AffineScene { } }); + resetToDefaultButton.setOnAction(event -> { + fractalOperations.setFractalToJuliaSet(); + }); + return cBox; } - private HBox createMatrixVectorInputBox() { + private HBox createMatrixVectorInputBox(AffineTransform2D transform) { HBox matrixVectorBox = new HBox(5); matrixVectorBox.setPadding(new Insets(5)); @@ -231,6 +236,13 @@ public class AffineScene { TextField vectorInput1 = new TextField(); TextField vectorInput2 = new TextField(); + matrixInput1.setText(String.valueOf(transform.getMatrix().getA00())); + matrixInput2.setText(String.valueOf(transform.getMatrix().getA01())); + matrixInput3.setText(String.valueOf(transform.getMatrix().getA10())); + matrixInput4.setText(String.valueOf(transform.getMatrix().getA11())); + vectorInput1.setText(String.valueOf(transform.getVector().getX0())); + vectorInput2.setText(String.valueOf(transform.getVector().getX1())); + matrixInput1.getStyleClass().add("matrixInput"); matrixInput2.getStyleClass().add("matrixInput"); matrixInput3.getStyleClass().add("matrixInput"); @@ -238,12 +250,12 @@ public class AffineScene { vectorInput1.getStyleClass().add("matrixInput"); vectorInput2.getStyleClass().add("matrixInput"); - matrixInput1.setPromptText("[0,0]"); - matrixInput2.setPromptText("[0,1]"); - matrixInput3.setPromptText("[1,0]"); - matrixInput4.setPromptText("[1,1]"); - vectorInput1.setPromptText("[0]"); - vectorInput2.setPromptText("[1]"); + matrixInput1.setPromptText("a00"); + matrixInput2.setPromptText("a01"); + matrixInput3.setPromptText("a10"); + matrixInput4.setPromptText("a11"); + vectorInput1.setPromptText("b0"); + vectorInput2.setPromptText("b1"); HBox upperMatrixRow = new HBox(5); HBox lowerMatrixRow = new HBox(5); @@ -268,7 +280,7 @@ public class AffineScene { Button addMoreButton = new Button("Add More"); addMoreButton.setOnAction(event -> { - HBox newInputBox = createMatrixVectorInputBox(); + HBox newInputBox = createMatrixVectorInputBox(new AffineTransform2D(new Matrix2x2(0,0,0,0), new Vector2D(0,0))); inputContainer.getChildren().add(0, newInputBox); }); @@ -278,7 +290,26 @@ public class AffineScene { updateAffineTransforms(inputContainer); }); - inputContainer.getChildren().addAll(createMatrixVectorInputBox(), createMatrixVectorInputBox(), createMatrixVectorInputBox(), addMoreButton, updateMatrixVectorButton); + + + Button resetToDefaultButton = new Button("Reset to Default fractal"); + resetToDefaultButton.setOnAction(event -> { + inputContainer.getChildren().clear(); + if ("Barnsley Fern".equals(comboBoxes.getComboBoxFractal().getValue())) { + fractalOperations.setFractalToBransleysFern(); + AffineTransform2D[] transforms = fractalOperations.getChaosGame().getDescription().getTransforms().toArray(new AffineTransform2D[0]); + inputContainer.getChildren().addAll(createMatrixVectorInputBox(transforms[0]), createMatrixVectorInputBox(transforms[1]), createMatrixVectorInputBox(transforms[2]), createMatrixVectorInputBox(transforms[3]), addMoreButton, updateMatrixVectorButton, resetToDefaultButton); + + } else if ("Sierpinski Triangle".equals(comboBoxes.getComboBoxFractal().getValue())) { + fractalOperations.setFractalToSierpinskiTriangle(); + AffineTransform2D[] transforms = fractalOperations.getChaosGame().getDescription().getTransforms().toArray(new AffineTransform2D[0]); + inputContainer.getChildren().addAll(createMatrixVectorInputBox(transforms[0]), createMatrixVectorInputBox(transforms[1]), createMatrixVectorInputBox(transforms[2]), addMoreButton, updateMatrixVectorButton, resetToDefaultButton); + } + }); + + AffineTransform2D zeroTransform = new AffineTransform2D(new Matrix2x2(0,0,0,0), new Vector2D(0,0)); + + inputContainer.getChildren().addAll(createMatrixVectorInputBox(zeroTransform), createMatrixVectorInputBox(zeroTransform), createMatrixVectorInputBox(zeroTransform), addMoreButton, updateMatrixVectorButton, resetToDefaultButton); AnchorPane.setTopAnchor(inputContainer, 120.0); AnchorPane.setRightAnchor(inputContainer, 10.0); ((AnchorPane) scene.getRoot()).getChildren().add(inputContainer); @@ -295,7 +326,7 @@ public class AffineScene { private void updateAffineTransforms(VBox inputContainer) { List<AffineTransform2D> transforms = new ArrayList<>(); - for (int i = 0; i < inputContainer.getChildren().size() - 2; i++) { // exclude the last two buttons + for (int i = 0; i < inputContainer.getChildren().size() - 3; i++) { // exclude the last three buttons HBox matrixVectorBox = (HBox) inputContainer.getChildren().get(i); VBox matrixBox = (VBox) matrixVectorBox.getChildren().get(0); VBox vectorBox = (VBox) matrixVectorBox.getChildren().get(1); @@ -328,8 +359,8 @@ public class AffineScene { } // Here you should pass the transforms to create a ChaosGameDescription - Vector2D lowerLeft = new Vector2D(0.0, 0.0); - Vector2D upperRight = new Vector2D(1.0, 1.0); + Vector2D lowerLeft = new Vector2D(-2.5, 0.0); + Vector2D upperRight = new Vector2D(2.5, 10.0); ChaosGameDescription description = new ChaosGameDescription(Arrays.asList(transforms.toArray(new AffineTransform2D[0])), lowerLeft, upperRight); // Update the fractal operations with the new description -- GitLab From 16f347e2c0a7a490ed4040bf6fd34d95ec1ac236 Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Sun, 19 May 2024 14:36:33 +0200 Subject: [PATCH 109/168] Added getChaosGame --- .../ntnu/idatt2003/view/components/FractalOperations.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java b/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java index 450f37b..d4b8250 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java +++ b/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java @@ -109,4 +109,12 @@ public class FractalOperations { iterations = 0; drawFractal(0); } + + public String getCurrentFractal() { + return currentFractal; + } + + public ChaosGame getChaosGame() { + return chaosGame; + } } -- GitLab From 30b026a6791452048a4670c9697eb0ab4890e855 Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Sun, 19 May 2024 14:37:13 +0200 Subject: [PATCH 110/168] Import all components --- .../java/edu/ntnu/idatt2003/controller/TextFieldController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/edu/ntnu/idatt2003/controller/TextFieldController.java b/src/main/java/edu/ntnu/idatt2003/controller/TextFieldController.java index 65af6e3..d433c7d 100644 --- a/src/main/java/edu/ntnu/idatt2003/controller/TextFieldController.java +++ b/src/main/java/edu/ntnu/idatt2003/controller/TextFieldController.java @@ -1,7 +1,7 @@ package edu.ntnu.idatt2003.controller; import edu.ntnu.idatt2003.view.components.FractalOperations; -import edu.ntnu.idatt2003.view.components.TextFields; +import edu.ntnu.idatt2003.view.components.*; import javafx.scene.control.TextField; public class TextFieldController { -- GitLab From 58653e510a8971a02b9dba118684b13af847c30d Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Sun, 19 May 2024 15:07:41 +0200 Subject: [PATCH 111/168] Made method to resetToDefault fractal inputs --- .../idatt2003/view/scenes/AffineScene.java | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java b/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java index 59ded77..9edabe8 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java +++ b/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java @@ -294,22 +294,10 @@ public class AffineScene { Button resetToDefaultButton = new Button("Reset to Default fractal"); resetToDefaultButton.setOnAction(event -> { - inputContainer.getChildren().clear(); - if ("Barnsley Fern".equals(comboBoxes.getComboBoxFractal().getValue())) { - fractalOperations.setFractalToBransleysFern(); - AffineTransform2D[] transforms = fractalOperations.getChaosGame().getDescription().getTransforms().toArray(new AffineTransform2D[0]); - inputContainer.getChildren().addAll(createMatrixVectorInputBox(transforms[0]), createMatrixVectorInputBox(transforms[1]), createMatrixVectorInputBox(transforms[2]), createMatrixVectorInputBox(transforms[3]), addMoreButton, updateMatrixVectorButton, resetToDefaultButton); - - } else if ("Sierpinski Triangle".equals(comboBoxes.getComboBoxFractal().getValue())) { - fractalOperations.setFractalToSierpinskiTriangle(); - AffineTransform2D[] transforms = fractalOperations.getChaosGame().getDescription().getTransforms().toArray(new AffineTransform2D[0]); - inputContainer.getChildren().addAll(createMatrixVectorInputBox(transforms[0]), createMatrixVectorInputBox(transforms[1]), createMatrixVectorInputBox(transforms[2]), addMoreButton, updateMatrixVectorButton, resetToDefaultButton); - } + resetToDefaultFractal(inputContainer, addMoreButton, updateMatrixVectorButton, resetToDefaultButton); }); - AffineTransform2D zeroTransform = new AffineTransform2D(new Matrix2x2(0,0,0,0), new Vector2D(0,0)); - - inputContainer.getChildren().addAll(createMatrixVectorInputBox(zeroTransform), createMatrixVectorInputBox(zeroTransform), createMatrixVectorInputBox(zeroTransform), addMoreButton, updateMatrixVectorButton, resetToDefaultButton); + resetToDefaultFractal(inputContainer, addMoreButton, updateMatrixVectorButton, resetToDefaultButton); AnchorPane.setTopAnchor(inputContainer, 120.0); AnchorPane.setRightAnchor(inputContainer, 10.0); ((AnchorPane) scene.getRoot()).getChildren().add(inputContainer); @@ -367,6 +355,19 @@ public class AffineScene { fractalOperations.updateMatrixAndVector(description); } + private void resetToDefaultFractal(VBox inputContainer, Button addMoreButton, Button updateMatrixVectorButton, Button resetToDefaultButton) { + inputContainer.getChildren().clear(); + if ("Barnsley Fern".equals(comboBoxes.getComboBoxFractal().getValue())) { + fractalOperations.setFractalToBransleysFern(); + AffineTransform2D[] transforms = fractalOperations.getChaosGame().getDescription().getTransforms().toArray(new AffineTransform2D[0]); + inputContainer.getChildren().addAll(createMatrixVectorInputBox(transforms[0]), createMatrixVectorInputBox(transforms[1]), createMatrixVectorInputBox(transforms[2]), createMatrixVectorInputBox(transforms[3]), addMoreButton, updateMatrixVectorButton, resetToDefaultButton); + } else if ("Sierpinski Triangle".equals(comboBoxes.getComboBoxFractal().getValue())) { + fractalOperations.setFractalToSierpinskiTriangle(); + AffineTransform2D[] transforms = fractalOperations.getChaosGame().getDescription().getTransforms().toArray(new AffineTransform2D[0]); + inputContainer.getChildren().addAll(createMatrixVectorInputBox(transforms[0]), createMatrixVectorInputBox(transforms[1]), createMatrixVectorInputBox(transforms[2]), addMoreButton, updateMatrixVectorButton, resetToDefaultButton); + } +} + public void setUpStage(Stage primaryStage) { primaryStage.setTitle("ChaosGame"); primaryStage.setScene(scene); -- GitLab From 9b0eff0d1fee7afee38dfc762193fb3b703e646e Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Sun, 19 May 2024 18:36:58 +0200 Subject: [PATCH 112/168] Implemented the ability to change max and min vector --- .../idatt2003/view/scenes/AffineScene.java | 77 +++++++++++++++---- 1 file changed, 61 insertions(+), 16 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java b/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java index 9edabe8..7a29f31 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java +++ b/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java @@ -25,6 +25,8 @@ import java.util.List; public class AffineScene { private Label iterationsLabel; + private Label MaxLabel; + private Label MinLabel; private Scene scene; private WritableImage writableImage; private ImageView imageView; @@ -106,9 +108,21 @@ public class AffineScene { // Initialize Labels iterationsLabel = labels.getIterationLabel(); + MaxLabel = labels.geMaxLabel(); + MinLabel = labels.getMinLabel(); // Initialize TextFields TextField addIterationInput = textFields.getAddIterationInput(); + TextField xMinInput = textFields.getxMinInput(); + TextField yMinInput = textFields.getyMinInput(); + TextField xMaxInput = textFields.getxMaxInput(); + TextField yMaxInput = textFields.getyMaxInput(); + + // Ensure style classes are added to these text fields + xMinInput.getStyleClass().add("MaxMinInput"); + yMinInput.getStyleClass().add("MaxMinInput"); + xMaxInput.getStyleClass().add("MaxMinInput"); + yMaxInput.getStyleClass().add("MaxMinInput"); // Set the style of the labels iterationsLabel.getStyleClass().add("iterationLabel"); @@ -125,6 +139,29 @@ public class AffineScene { topBox.getChildren().addAll(comboBoxFractal, comboBoxColor); topBox.setPadding(new Insets(10, 10, 10, 10)); + HBox MinBox = new HBox(5); + HBox MaxBox = new HBox(5); + MinBox.getChildren().addAll(xMinInput, yMinInput); + MaxBox.getChildren().addAll(xMaxInput, yMaxInput); + + Button updateMinMaxButton = new Button("Update Min and Max vector"); + + VBox MinMaxAll = new VBox(5); + MinMaxAll.getChildren().addAll(MaxLabel, MaxBox, MinLabel, MinBox, updateMinMaxButton); + + updateMinMaxButton.setOnAction(event -> { + try { + fractalOperations.resetIterations(); + double xMin = Double.parseDouble(xMinInput.getText()); + double yMin = Double.parseDouble(yMinInput.getText()); + double xMax = Double.parseDouble(xMaxInput.getText()); + double yMax = Double.parseDouble(yMaxInput.getText()); + updateMinAndMax(new Vector2D(xMin, yMin), new Vector2D(xMax, yMax)); + } catch (NumberFormatException e) { + System.out.println("Invalid input for min or max values."); + } + }); + // Initialize the ChaosCanvas and the WritableImage chaosCanvas = new ChaosCanvas(600, 400, new Vector2D(0, 0), new Vector2D(600, 400)); writableImage = new WritableImage(600, 400); @@ -137,7 +174,7 @@ public class AffineScene { imageView.setPreserveRatio(true); // Add components to the root AnchorPane - root.getChildren().addAll(topBox, imagePane, bottomBox, btnExitApplication); + root.getChildren().addAll(topBox, imagePane, bottomBox, btnExitApplication, MinMaxAll); // Anchor the topBox to the top of the pane AnchorPane.setTopAnchor(topBox, 10.0); @@ -159,16 +196,20 @@ public class AffineScene { AnchorPane.setTopAnchor(btnExitApplication, 10.0); AnchorPane.setRightAnchor(btnExitApplication, 10.0); + // Anchor the MinMaxBox to the top right corner + AnchorPane.setTopAnchor(MinMaxAll, 75.0); + AnchorPane.setRightAnchor(MinMaxAll, 30.0); + // Create a scene with the root and set the CSS style - scene = new Scene(root, 1200, 800); + scene = new Scene(root, 1400, 1000); scene.getStylesheets().add(getClass().getResource("/style.css").toExternalForm()); } private void addCInputBox() { if (cBox == null) { cBox = createCInputBox(); - AnchorPane.setTopAnchor(cBox, 50.0); - AnchorPane.setRightAnchor(cBox, 10.0); + AnchorPane.setTopAnchor(cBox, 150.0); + AnchorPane.setRightAnchor(cBox, 60.0); ((AnchorPane) scene.getRoot()).getChildren().add(cBox); } } @@ -181,6 +222,8 @@ public class AffineScene { } private VBox createCInputBox() { + + Label cLabel = new Label("Update constant C"); // Initialize the update C button Button updateCButton = new Button("Update C"); Button resetToDefaultButton = new Button("Reset to Default fractal"); @@ -195,7 +238,7 @@ public class AffineScene { imaginaryPartInput.setPromptText("Imaginary part of C"); VBox cBox = new VBox(2); - cBox.getChildren().addAll(realPartInput, imaginaryPartInput, updateCButton, resetToDefaultButton); + cBox.getChildren().addAll(cLabel, realPartInput, imaginaryPartInput, updateCButton, resetToDefaultButton); cBox.setPadding(new Insets(100, 0, 0, 0)); updateCButton.setOnAction(event -> { @@ -290,16 +333,14 @@ public class AffineScene { updateAffineTransforms(inputContainer); }); - - Button resetToDefaultButton = new Button("Reset to Default fractal"); resetToDefaultButton.setOnAction(event -> { resetToDefaultFractal(inputContainer, addMoreButton, updateMatrixVectorButton, resetToDefaultButton); }); resetToDefaultFractal(inputContainer, addMoreButton, updateMatrixVectorButton, resetToDefaultButton); - AnchorPane.setTopAnchor(inputContainer, 120.0); - AnchorPane.setRightAnchor(inputContainer, 10.0); + AnchorPane.setTopAnchor(inputContainer, 240.0); + AnchorPane.setRightAnchor(inputContainer, 30.0); ((AnchorPane) scene.getRoot()).getChildren().add(inputContainer); matrixVectorBox = inputContainer; } @@ -358,15 +399,19 @@ public class AffineScene { private void resetToDefaultFractal(VBox inputContainer, Button addMoreButton, Button updateMatrixVectorButton, Button resetToDefaultButton) { inputContainer.getChildren().clear(); if ("Barnsley Fern".equals(comboBoxes.getComboBoxFractal().getValue())) { - fractalOperations.setFractalToBransleysFern(); - AffineTransform2D[] transforms = fractalOperations.getChaosGame().getDescription().getTransforms().toArray(new AffineTransform2D[0]); - inputContainer.getChildren().addAll(createMatrixVectorInputBox(transforms[0]), createMatrixVectorInputBox(transforms[1]), createMatrixVectorInputBox(transforms[2]), createMatrixVectorInputBox(transforms[3]), addMoreButton, updateMatrixVectorButton, resetToDefaultButton); + fractalOperations.setFractalToBransleysFern(); + AffineTransform2D[] transforms = fractalOperations.getChaosGame().getDescription().getTransforms().toArray(new AffineTransform2D[0]); + inputContainer.getChildren().addAll(createMatrixVectorInputBox(transforms[0]), createMatrixVectorInputBox(transforms[1]), createMatrixVectorInputBox(transforms[2]), createMatrixVectorInputBox(transforms[3]), addMoreButton, updateMatrixVectorButton, resetToDefaultButton); } else if ("Sierpinski Triangle".equals(comboBoxes.getComboBoxFractal().getValue())) { - fractalOperations.setFractalToSierpinskiTriangle(); - AffineTransform2D[] transforms = fractalOperations.getChaosGame().getDescription().getTransforms().toArray(new AffineTransform2D[0]); - inputContainer.getChildren().addAll(createMatrixVectorInputBox(transforms[0]), createMatrixVectorInputBox(transforms[1]), createMatrixVectorInputBox(transforms[2]), addMoreButton, updateMatrixVectorButton, resetToDefaultButton); + fractalOperations.setFractalToSierpinskiTriangle(); + AffineTransform2D[] transforms = fractalOperations.getChaosGame().getDescription().getTransforms().toArray(new AffineTransform2D[0]); + inputContainer.getChildren().addAll(createMatrixVectorInputBox(transforms[0]), createMatrixVectorInputBox(transforms[1]), createMatrixVectorInputBox(transforms[2]), addMoreButton, updateMatrixVectorButton, resetToDefaultButton); } -} + } + + public void updateMinAndMax(Vector2D minCoords, Vector2D maxCoords) { + fractalOperations.updateMinAndMaxFractal(minCoords, maxCoords); + } public void setUpStage(Stage primaryStage) { primaryStage.setTitle("ChaosGame"); -- GitLab From b33a4f2ff45f21356f3caaa001fdde335df97073 Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Sun, 19 May 2024 18:48:50 +0200 Subject: [PATCH 113/168] added getChaosGameDescription --- src/main/java/edu/ntnu/idatt2003/model/ChaosGame.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/edu/ntnu/idatt2003/model/ChaosGame.java b/src/main/java/edu/ntnu/idatt2003/model/ChaosGame.java index 38fcff8..55de6cc 100644 --- a/src/main/java/edu/ntnu/idatt2003/model/ChaosGame.java +++ b/src/main/java/edu/ntnu/idatt2003/model/ChaosGame.java @@ -35,4 +35,8 @@ public class ChaosGame { public ChaosGameDescription getDescription() { return this.description; } + + public ChaosGameDescription getChaosGameDescription() { + return description; + } } -- GitLab From 74e61efe1becc04e5f523458a82b4eef5b5392d9 Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Sun, 19 May 2024 18:49:07 +0200 Subject: [PATCH 114/168] added updateMinAndMaxFractal --- .../view/components/FractalOperations.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java b/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java index d4b8250..62d49e5 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java +++ b/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java @@ -10,6 +10,7 @@ import javafx.scene.image.WritableImage; import javafx.scene.paint.Color; import java.io.IOException; +import java.util.Arrays; import static edu.ntnu.idatt2003.model.ChaosGameDescriptionFactory.createJuliaSet; @@ -110,6 +111,14 @@ public class FractalOperations { drawFractal(0); } + public void updateJuliaSet(Complex complex, int sign, Vector2D minCoords, Vector2D maxCoords) { + JuliaTransform[] transforms = new JuliaTransform[2]; + transforms[0] = new JuliaTransform(complex, sign); + transforms[1] = new JuliaTransform(complex, -sign); + ChaosGameDescription newChaosGame = new ChaosGameDescription(Arrays.asList(transforms), minCoords, maxCoords); + this.chaosGame = new ChaosGame(newChaosGame, 400, 400); + } + public String getCurrentFractal() { return currentFractal; } @@ -117,4 +126,9 @@ public class FractalOperations { public ChaosGame getChaosGame() { return chaosGame; } + + public void updateMinAndMaxFractal(Vector2D minCoords, Vector2D maxCoords) { + ChaosGameDescription newChaosGame = new ChaosGameDescription(chaosGame.getChaosGameDescription().getTransforms(), minCoords, maxCoords); + this.chaosGame = new ChaosGame(newChaosGame, 400, 400); + } } -- GitLab From cc3b56853f97b4c401896fa473d5a2ec5b881500 Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Sun, 19 May 2024 18:53:51 +0200 Subject: [PATCH 115/168] Added Min and max Labels --- .../ntnu/idatt2003/view/components/Labels.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/main/java/edu/ntnu/idatt2003/view/components/Labels.java b/src/main/java/edu/ntnu/idatt2003/view/components/Labels.java index d56ffd5..21628d9 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/components/Labels.java +++ b/src/main/java/edu/ntnu/idatt2003/view/components/Labels.java @@ -2,8 +2,13 @@ package edu.ntnu.idatt2003.view.components; import javafx.scene.control.Label; +import java.util.concurrent.Callable; + public class Labels { private Label iterationLabel; + private Label MaxLabel; + private Label MinLabel; + public Labels() { initializeLabels(); } @@ -11,10 +16,22 @@ public class Labels { public void initializeLabels() { iterationLabel = new Label(); iterationLabel.setText("Iterations: 0"); + MinLabel = new Label(); + MinLabel.setText("Change Min vector"); + MaxLabel = new Label(); + MaxLabel.setText("Change Max vector"); } public Label getIterationLabel() { return iterationLabel; } + + public Label getMinLabel() { + return MinLabel; + } + + public Label geMaxLabel() { + return MaxLabel; + } } -- GitLab From ccfd64acd72fdfece1a5ddadb5d08f5db1eba3c0 Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Sun, 19 May 2024 18:54:08 +0200 Subject: [PATCH 116/168] Styled input field for max and min --- src/main/resources/style.css | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/main/resources/style.css b/src/main/resources/style.css index 3ed89ce..6f8fdaf 100644 --- a/src/main/resources/style.css +++ b/src/main/resources/style.css @@ -87,3 +87,14 @@ -fx-pref-width: 50px; } +.MaxMinInput { + -fx-background-color: white; + -fx-background-radius: 10px; + -fx-font-size: 16px; + -fx-padding: 8px; + -fx-border-color: black; + -fx-border-radius: 10px; + -fx-pref-width: 70px; +} + + -- GitLab From 81afbf70d11cd355d12f7908e573df73d1a945e1 Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Sun, 19 May 2024 18:54:42 +0200 Subject: [PATCH 117/168] Added TextFields for min and max vector --- .../idatt2003/view/components/TextFields.java | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/main/java/edu/ntnu/idatt2003/view/components/TextFields.java b/src/main/java/edu/ntnu/idatt2003/view/components/TextFields.java index 92a40db..8beed1f 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/components/TextFields.java +++ b/src/main/java/edu/ntnu/idatt2003/view/components/TextFields.java @@ -4,6 +4,10 @@ import javafx.scene.control.TextField; public class TextFields { private TextField addIterationInput; + private TextField xMinInput; + private TextField yMinInput; + private TextField xMaxInput; + private TextField yMaxInput; public TextFields() { initializeInputFields(); @@ -12,9 +16,34 @@ public class TextFields { public void initializeInputFields() { addIterationInput = new TextField(); addIterationInput.setPromptText("Add iterations"); + xMinInput = new TextField(); + xMinInput.setPromptText("X min"); + yMinInput = new TextField(); + yMinInput.setPromptText("Y min"); + xMaxInput = new TextField(); + xMaxInput.setPromptText("X max"); + yMaxInput = new TextField(); + yMaxInput.setPromptText("Y max"); } public TextField getAddIterationInput() { return addIterationInput; } + + public TextField getxMinInput() { + return xMinInput; + } + + public TextField getyMinInput() { + return yMinInput; + } + + public TextField getxMaxInput() { + return xMaxInput; + } + + public TextField getyMaxInput() { + return yMaxInput; + } } + -- GitLab From 62fcb0bb33f9e5a682b47dccf4ae94b2464ea642 Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Sun, 19 May 2024 19:52:52 +0200 Subject: [PATCH 118/168] Update max and min vector for Julia and affine --- .../idatt2003/view/scenes/AffineScene.java | 30 ++++++++++++++++--- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java b/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java index 7a29f31..5de424b 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java +++ b/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java @@ -58,18 +58,26 @@ public class AffineScene { buttonController.initialize(); comboBoxController.initialize(); textFieldController.initialize(); + fractalOperations.resetIterations(); fractalOperations.addIterations(0); + comboBoxes.getComboBoxFractal().setValue(fractalType); // Add listener to ComboBox to handle dynamic addition of C input fields comboBoxes.getComboBoxFractal().getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> { if ("Julia Set".equals(newValue)) { addCInputBox(); removeMatrixVectorInputBoxes(); - } else if ("Sierpinski Triangle".equals(newValue) || "Barnsley Fern".equals(newValue)) { + } else if ("Sierpinski Triangle".equals(newValue)) { + removeMatrixVectorInputBoxes(); + removeCInputBox(); + addMatrixVectorInputBoxes(); + } else if ( "Barnsley Fern".equals(newValue)) { + removeMatrixVectorInputBoxes(); removeCInputBox(); addMatrixVectorInputBoxes(); - } else if ("Fractal From File".equals(newValue)) { + } + else if ("Fractal From File".equals(newValue)) { removeCInputBox(); removeMatrixVectorInputBoxes(); } @@ -246,6 +254,14 @@ public class AffineScene { double realPart = Double.parseDouble(realPartInput.getText()); double imaginaryPart = Double.parseDouble(imaginaryPartInput.getText()); fractalOperations.updateC(new Complex(realPart, imaginaryPart)); + double xMin = Double.parseDouble(textFields.getxMinInput().getText()); + double yMin = Double.parseDouble(textFields.getyMinInput().getText()); + double xMax = Double.parseDouble(textFields.getxMaxInput().getText()); + double yMax = Double.parseDouble(textFields.getyMaxInput().getText()); + + Vector2D lowerLeft = new Vector2D(xMin, yMin); + Vector2D upperRight = new Vector2D(xMax, yMax); + fractalOperations.updateMinAndMaxFractal(lowerLeft, upperRight); } catch (NumberFormatException e) { // Handle invalid input System.out.println("Invalid input for real or imaginary part of C."); @@ -388,8 +404,14 @@ public class AffineScene { } // Here you should pass the transforms to create a ChaosGameDescription - Vector2D lowerLeft = new Vector2D(-2.5, 0.0); - Vector2D upperRight = new Vector2D(2.5, 10.0); + double xMin = Double.parseDouble(textFields.getxMinInput().getText()); + double yMin = Double.parseDouble(textFields.getyMinInput().getText()); + double xMax = Double.parseDouble(textFields.getxMaxInput().getText()); + double yMax = Double.parseDouble(textFields.getyMaxInput().getText()); + + Vector2D lowerLeft = new Vector2D(xMin, yMin); + Vector2D upperRight = new Vector2D(xMax, yMax); + ChaosGameDescription description = new ChaosGameDescription(Arrays.asList(transforms.toArray(new AffineTransform2D[0])), lowerLeft, upperRight); // Update the fractal operations with the new description -- GitLab From a881f1401d301bc5df3df67d20312c0a9ddf0431 Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Sun, 19 May 2024 19:53:24 +0200 Subject: [PATCH 119/168] Set the value of ComboBox at the start --- .../java/edu/ntnu/idatt2003/controller/ComboBoxController.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/edu/ntnu/idatt2003/controller/ComboBoxController.java b/src/main/java/edu/ntnu/idatt2003/controller/ComboBoxController.java index ca81357..eff0851 100644 --- a/src/main/java/edu/ntnu/idatt2003/controller/ComboBoxController.java +++ b/src/main/java/edu/ntnu/idatt2003/controller/ComboBoxController.java @@ -19,6 +19,7 @@ public class ComboBoxController { this.fractalOperations = fractalOperations; this.comboBoxes = comboBoxes; initialize(); + comboBoxes.getComboBoxFractal().setValue(fractalOperations.getCurrentFractal()); } public void initialize() { -- GitLab From 1a395f3a09acd646c40770a63d261e206fe27fc9 Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Sun, 19 May 2024 20:05:17 +0200 Subject: [PATCH 120/168] Added space between initailfractal string --- src/main/java/edu/ntnu/idatt2003/view/App.java | 2 +- .../ntnu/idatt2003/view/components/FractalOperations.java | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/view/App.java b/src/main/java/edu/ntnu/idatt2003/view/App.java index 573640c..c4d880c 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/App.java +++ b/src/main/java/edu/ntnu/idatt2003/view/App.java @@ -12,7 +12,7 @@ public class App extends Application { @Override public void start(Stage primaryStage) { - AffineScene affineScene = new AffineScene("BarnsleyFern"); + AffineScene affineScene = new AffineScene("Barnsley Fern"); affineScene.setUpStage(primaryStage); //JuliaScene juliaScene = new JuliaScene(); diff --git a/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java b/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java index 62d49e5..07f004b 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java +++ b/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java @@ -28,11 +28,11 @@ public class FractalOperations { this.currentFractal = initialFractal; this.writableImage = new WritableImage(400, 400); this.imageView.setImage(writableImage); - if ("SierpinskiTriangle".equals(initialFractal)) { + if ("Sierpinski Triangle".equals(initialFractal)) { setFractalToSierpinskiTriangle(); - } else if ("JuliaSet".equals(initialFractal)) { + } else if ("Julia Set".equals(initialFractal)) { setFractalToJuliaSet(); - } else if ("BarnsleyFern".equals(initialFractal)) { + } else if ("Barnsley Fern".equals(initialFractal)) { setFractalToBransleysFern(); } resetIterations(); -- GitLab From ed4be8f8cec7400daa28de17bc62b5078f9b2a92 Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Sun, 19 May 2024 20:09:58 +0200 Subject: [PATCH 121/168] Fixed issue where input fields where overlaping --- src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java b/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java index 5de424b..1c4afc2 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java +++ b/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java @@ -216,7 +216,7 @@ public class AffineScene { private void addCInputBox() { if (cBox == null) { cBox = createCInputBox(); - AnchorPane.setTopAnchor(cBox, 150.0); + AnchorPane.setTopAnchor(cBox, 240.0); AnchorPane.setRightAnchor(cBox, 60.0); ((AnchorPane) scene.getRoot()).getChildren().add(cBox); } @@ -247,7 +247,7 @@ public class AffineScene { VBox cBox = new VBox(2); cBox.getChildren().addAll(cLabel, realPartInput, imaginaryPartInput, updateCButton, resetToDefaultButton); - cBox.setPadding(new Insets(100, 0, 0, 0)); + cBox.setPadding(new Insets(10, 0, 0, 0)); updateCButton.setOnAction(event -> { try { -- GitLab From 5bc9ca1554364a352d4224a255e2103c9c3ffe70 Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Sun, 19 May 2024 20:14:05 +0200 Subject: [PATCH 122/168] Added more padding in cBox input --- .../java/edu/ntnu/idatt2003/view/scenes/AffineScene.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java b/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java index 1c4afc2..ae63578 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java +++ b/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java @@ -216,7 +216,7 @@ public class AffineScene { private void addCInputBox() { if (cBox == null) { cBox = createCInputBox(); - AnchorPane.setTopAnchor(cBox, 240.0); + AnchorPane.setTopAnchor(cBox, 250.0); AnchorPane.setRightAnchor(cBox, 60.0); ((AnchorPane) scene.getRoot()).getChildren().add(cBox); } @@ -245,9 +245,9 @@ public class AffineScene { realPartInput.setPromptText("Real part of C"); imaginaryPartInput.setPromptText("Imaginary part of C"); - VBox cBox = new VBox(2); + VBox cBox = new VBox(5); cBox.getChildren().addAll(cLabel, realPartInput, imaginaryPartInput, updateCButton, resetToDefaultButton); - cBox.setPadding(new Insets(10, 0, 0, 0)); + cBox.setPadding(new Insets(0, 0, 0, 0)); updateCButton.setOnAction(event -> { try { -- GitLab From ff94e8ccd98288e2ea2848d9ce1a39b60c857bce Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Sun, 19 May 2024 20:20:47 +0200 Subject: [PATCH 123/168] Added try catch for parsing min and mac vector --- .../idatt2003/view/scenes/AffineScene.java | 28 +++++++++++++++---- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java b/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java index ae63578..7b97b81 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java +++ b/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java @@ -403,19 +403,35 @@ public class AffineScene { } } - // Here you should pass the transforms to create a ChaosGameDescription - double xMin = Double.parseDouble(textFields.getxMinInput().getText()); - double yMin = Double.parseDouble(textFields.getyMinInput().getText()); - double xMax = Double.parseDouble(textFields.getxMaxInput().getText()); - double yMax = Double.parseDouble(textFields.getyMaxInput().getText()); + double xMin, yMin, xMax, yMax; + + try { + xMin = Double.parseDouble(textFields.getxMinInput().getText()); + yMin = Double.parseDouble(textFields.getyMinInput().getText()); + xMax = Double.parseDouble(textFields.getxMaxInput().getText()); + yMax = Double.parseDouble(textFields.getyMaxInput().getText()); + } catch (NumberFormatException e) { + // Set to default values if parsing fails + if ("Barnsley Fern".equals(comboBoxes.getComboBoxFractal().getValue())) { + xMin = -2.5; + yMin = 0; + xMax = 2.5; + yMax = 10; + } else { + xMin = 0; + yMin = 0; + xMax = 1; + yMax = 1; + } Vector2D lowerLeft = new Vector2D(xMin, yMin); Vector2D upperRight = new Vector2D(xMax, yMax); ChaosGameDescription description = new ChaosGameDescription(Arrays.asList(transforms.toArray(new AffineTransform2D[0])), lowerLeft, upperRight); - // Update the fractal operations with the new description +// Update the fractal operations with the new description fractalOperations.updateMatrixAndVector(description); + } } private void resetToDefaultFractal(VBox inputContainer, Button addMoreButton, Button updateMatrixVectorButton, Button resetToDefaultButton) { -- GitLab From 2a964361668012cd3ee3c695aa79112cb4d1fd9b Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Mon, 20 May 2024 10:02:08 +0200 Subject: [PATCH 124/168] Merge conflict resolved --- .../controller/ButtonController.java | 75 ----------------- .../idatt2003/controller/ButtonObserver.java | 51 ++++++++++++ ...xController.java => ComboBoxObserver.java} | 41 ++++----- .../idatt2003/controller/LabelObserver.java | 83 +++++++++++++++++++ .../ntnu/idatt2003/controller/Observer.java | 2 +- .../ntnu/idatt2003/controller/Subject.java | 6 +- .../controller/TextFieldController.java | 35 -------- .../controller/TextFieldObserver.java | 35 ++++++++ .../idatt2003/view/components/Buttons.java | 43 +++++++++- .../idatt2003/view/components/ComboBoxes.java | 23 ++++- .../view/components/FractalOperations.java | 8 +- .../idatt2003/view/components/TextFields.java | 10 ++- .../idatt2003/view/scenes/AffineScene.java | 30 ++++--- .../idatt2003/view/scenes/JuliaScene.java | 21 ++--- 14 files changed, 285 insertions(+), 178 deletions(-) delete mode 100644 src/main/java/edu/ntnu/idatt2003/controller/ButtonController.java create mode 100644 src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java rename src/main/java/edu/ntnu/idatt2003/controller/{ComboBoxController.java => ComboBoxObserver.java} (51%) create mode 100644 src/main/java/edu/ntnu/idatt2003/controller/LabelObserver.java delete mode 100644 src/main/java/edu/ntnu/idatt2003/controller/TextFieldController.java create mode 100644 src/main/java/edu/ntnu/idatt2003/controller/TextFieldObserver.java diff --git a/src/main/java/edu/ntnu/idatt2003/controller/ButtonController.java b/src/main/java/edu/ntnu/idatt2003/controller/ButtonController.java deleted file mode 100644 index a59db74..0000000 --- a/src/main/java/edu/ntnu/idatt2003/controller/ButtonController.java +++ /dev/null @@ -1,75 +0,0 @@ -package edu.ntnu.idatt2003.controller; - -import edu.ntnu.idatt2003.view.components.Buttons; -import edu.ntnu.idatt2003.view.components.FractalOperations; -import javafx.application.Platform; -import javafx.scene.control.Alert; -import javafx.scene.control.ButtonType; -import javafx.scene.control.TextField; - -public class ButtonController { - private FractalOperations fractalOperations; - private Buttons buttons; - private TextFieldController textFieldController; - - public ButtonController(FractalOperations fractalOperations, Buttons buttons, TextFieldController textFieldController) { - this.fractalOperations = fractalOperations; - this.buttons = buttons; - this.textFieldController = textFieldController; - initialize(); - } - - public void initialize() { - if (fractalOperations == null) { - throw new IllegalStateException("fractalOperations has not been initialized"); - } - setButtonHandlers(); - } - - private void setButtonHandlers() { - buttons.getBtnAdd10().setOnAction(e -> { - System.out.println("Add 10"); - fractalOperations.addIterations(10); - }); - - buttons.getBtnAdd100().setOnAction(e -> { - System.out.println("Add 100"); - fractalOperations.addIterations(100); - }); - - buttons.getBtnAdd1000().setOnAction(e -> { - fractalOperations.addIterations(1000); - System.out.println("Add 1000"); - }); - - buttons.getBtnReset().setOnAction(e -> { - fractalOperations.resetIterations(); - System.out.println("Reset"); - }); - - buttons.getBtnAddInput().setOnAction(e -> { - TextField addIterationInput = textFieldController.getAddIterationInput(); - String input = addIterationInput.getText(); - try { - int iterations = Integer.parseInt(input); - fractalOperations.addIterations(iterations); - System.out.println("Add " + iterations); - } catch (NumberFormatException ex) { - System.out.println("Invalid input. Please enter a integer."); - } - addIterationInput.clear(); - }); - - buttons.getBtnExitApplication().setOnAction(e -> { - Alert alert = new Alert(Alert.AlertType.CONFIRMATION); - alert.setTitle("Exit Confirmation"); - alert.setHeaderText("Are you sure you want to exit the application?"); - alert.setContentText("Press OK to exit the application, or Cancel to stay."); - - - var result = alert.showAndWait(); - if (result.isPresent() && result.get() == ButtonType.OK) - Platform.exit(); - }); - } -} diff --git a/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java b/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java new file mode 100644 index 0000000..76b0e41 --- /dev/null +++ b/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java @@ -0,0 +1,51 @@ +package edu.ntnu.idatt2003.controller; + +import edu.ntnu.idatt2003.view.components.Buttons; +import edu.ntnu.idatt2003.view.components.FractalOperations; +import edu.ntnu.idatt2003.view.components.TextFields; +import javafx.scene.control.Label; +import javafx.scene.control.TextField; + +public class ButtonObserver implements Observer{ + private Buttons buttons; + private FractalOperations fractalOperations; + private TextFields textFields; + private Label iterationsLabel; + private int iterations = 0; + + public ButtonObserver(Buttons buttons, FractalOperations fractalOperations, TextFields textFields, Label iterationsLabel) { + this.buttons = buttons; + this.fractalOperations = fractalOperations; + this.textFields = textFields; + this.iterationsLabel = iterationsLabel; + buttons.attach(this); + } + + @Override + public void update(String button) { + switch (button) { + case "btnAdd10": + fractalOperations.addIterations(10); + break; + case "btnAdd100": + fractalOperations.addIterations(100); + break; + case "btnAdd1000": + fractalOperations.addIterations(1000); + break; + case "btnReset": + fractalOperations.resetIterations(); + break; + case "btnAddInput": + TextField addIterationInput = textFields.getAddIterationInput(); + String input = addIterationInput.getText(); + try { + int iterations = Integer.parseInt(input); + fractalOperations.addIterations(iterations); + } catch (NumberFormatException ex) { + System.out.println("Invalid input. Please enter a integer."); + } + break; + } + } +} \ No newline at end of file diff --git a/src/main/java/edu/ntnu/idatt2003/controller/ComboBoxController.java b/src/main/java/edu/ntnu/idatt2003/controller/ComboBoxObserver.java similarity index 51% rename from src/main/java/edu/ntnu/idatt2003/controller/ComboBoxController.java rename to src/main/java/edu/ntnu/idatt2003/controller/ComboBoxObserver.java index eff0851..273030c 100644 --- a/src/main/java/edu/ntnu/idatt2003/controller/ComboBoxController.java +++ b/src/main/java/edu/ntnu/idatt2003/controller/ComboBoxObserver.java @@ -1,6 +1,5 @@ package edu.ntnu.idatt2003.controller; -import edu.ntnu.idatt2003.model.ChaosCanvas; import edu.ntnu.idatt2003.view.components.ComboBoxes; import edu.ntnu.idatt2003.view.components.FractalOperations; import javafx.stage.FileChooser; @@ -8,41 +7,35 @@ import javafx.stage.Stage; import java.io.File; -/** - * Controller class for the ComboBoxes in the GUI. - */ -public class ComboBoxController { - private FractalOperations fractalOperations; + +public class ComboBoxObserver implements Observer { private ComboBoxes comboBoxes; + private FractalOperations fractalOperations; - public ComboBoxController(FractalOperations fractalOperations, ComboBoxes comboBoxes) { - this.fractalOperations = fractalOperations; + public ComboBoxObserver(ComboBoxes comboBoxes, FractalOperations fractalOperations) { this.comboBoxes = comboBoxes; - initialize(); - comboBoxes.getComboBoxFractal().setValue(fractalOperations.getCurrentFractal()); - } - - public void initialize() { - setComboBoxHandlers(); + this.fractalOperations = fractalOperations; + comboBoxes.attach(this); } - - private void setComboBoxHandlers() { - comboBoxes.getComboBoxFractal().setOnAction(e -> { - String selectedFractal = comboBoxes.getComboBoxFractal().getValue(); - if ("Sierpinski Triangle".equals(selectedFractal)) { + @Override + public void update(String option) { + switch (option) { + case "Sierpinski Triangle": fractalOperations.setFractalToSierpinskiTriangle(); - } else if ("Julia Set".equals(selectedFractal)) { + break; + case "Julia Set": fractalOperations.setFractalToJuliaSet(); - } else if ("Barnsley Fern".equals(selectedFractal)) { + break; + case "Barnsley Fern": fractalOperations.setFractalToBransleysFern(); - } else if ("Fractal From File".equals(selectedFractal)) { + break; + case "Fractal From File": FileChooser fileChooser = new FileChooser(); fileChooser.setTitle("Select Fractal From File"); File file = fileChooser.showOpenDialog(new Stage()); if (file != null) { fractalOperations.setFractalCustomAffine(file.getPath()); } - } - }); + } } } diff --git a/src/main/java/edu/ntnu/idatt2003/controller/LabelObserver.java b/src/main/java/edu/ntnu/idatt2003/controller/LabelObserver.java new file mode 100644 index 0000000..ab17fd9 --- /dev/null +++ b/src/main/java/edu/ntnu/idatt2003/controller/LabelObserver.java @@ -0,0 +1,83 @@ +package edu.ntnu.idatt2003.controller; + +import edu.ntnu.idatt2003.view.components.Buttons; +import edu.ntnu.idatt2003.view.components.ComboBoxes; +import edu.ntnu.idatt2003.view.components.TextFields; +import javafx.scene.control.Label; +import javafx.scene.control.TextField; + +public class LabelObserver implements Observer { + private Buttons buttons; + private ComboBoxes comboBoxes; + private TextFields textFields; + private Label iterationLabel; + private int iterations = 0; + + + public LabelObserver(Buttons buttons, ComboBoxes comboBoxes, TextFields textFields, Label iterationLabel) { + this.buttons = buttons; + this.comboBoxes = comboBoxes; + this.textFields = textFields; + this.iterationLabel = iterationLabel; + buttons.attach(this); + comboBoxes.attach(this); + textFields.attach(this); + + } + @Override + public void update(String label) { + switch (label) { + case "btnAdd10": + iterations += 10; + break; + case "btnAdd100": + iterations += 100; + break; + case "btnAdd1000": + iterations += 1000; + break; + case "btnReset": + iterations = 0; + break; + + case "btnAddInput": + TextField addIterationInput = textFields.getAddIterationInput(); + String input1 = addIterationInput.getText(); + if (!input1.isEmpty()) { + try { + int inputIterations = Integer.parseInt(input1); + iterations += inputIterations; + } catch (NumberFormatException ex) { + System.out.println("Invalid input. Please enter an integer."); + } + } + addIterationInput.clear(); + break; + + case "addIterationInput": + String input = textFields.getAddIterationInput().getText(); + if (!input.isEmpty()) { + try { + int inputIterations = Integer.parseInt(input); + iterations += inputIterations; + } catch (NumberFormatException ex) { + System.out.println("Invalid input. Please enter an integer."); + } + } + break; + case "Sierpinski Triangle": + iterations = 0; + break; + case "Julia Set": + iterations = 0; + break; + case "Barnsley Fern": + iterations = 0; + break; + case "Fractal From File": + iterations = 0; + break; + } + iterationLabel.setText("Iterations: " + iterations); + } +} diff --git a/src/main/java/edu/ntnu/idatt2003/controller/Observer.java b/src/main/java/edu/ntnu/idatt2003/controller/Observer.java index 961cd4c..49fbeb2 100644 --- a/src/main/java/edu/ntnu/idatt2003/controller/Observer.java +++ b/src/main/java/edu/ntnu/idatt2003/controller/Observer.java @@ -1,5 +1,5 @@ package edu.ntnu.idatt2003.controller; public interface Observer { - void update(); + void update(String string); } diff --git a/src/main/java/edu/ntnu/idatt2003/controller/Subject.java b/src/main/java/edu/ntnu/idatt2003/controller/Subject.java index 058042c..b09f653 100644 --- a/src/main/java/edu/ntnu/idatt2003/controller/Subject.java +++ b/src/main/java/edu/ntnu/idatt2003/controller/Subject.java @@ -35,7 +35,9 @@ public abstract class Subject { /** * Notify all observers of the subject. */ - public void notifyObservers() { - observers.forEach(Observer::update); + public void notifyObservers(String string) { + for (Observer observer : observers) { + observer.update(string); + } } } diff --git a/src/main/java/edu/ntnu/idatt2003/controller/TextFieldController.java b/src/main/java/edu/ntnu/idatt2003/controller/TextFieldController.java deleted file mode 100644 index d433c7d..0000000 --- a/src/main/java/edu/ntnu/idatt2003/controller/TextFieldController.java +++ /dev/null @@ -1,35 +0,0 @@ -package edu.ntnu.idatt2003.controller; - -import edu.ntnu.idatt2003.view.components.FractalOperations; -import edu.ntnu.idatt2003.view.components.*; -import javafx.scene.control.TextField; - -public class TextFieldController { - private FractalOperations fractalOperations; - private TextField addIterationInput; - - public TextFieldController(FractalOperations fractalOperations, TextFields textFields) { - this.fractalOperations = fractalOperations; - this.addIterationInput = textFields.getAddIterationInput(); - initialize(); - } - - public void initialize() { - addIterationInput.setOnAction(e -> handleAddIterationInput()); - } - - public void handleAddIterationInput() { - String input = addIterationInput.getText(); - try { - int iterations = Integer.parseInt(input); - fractalOperations.addIterations(iterations); - } catch (NumberFormatException ex) { - System.out.println("Invalid input. Please enter a integer."); - } - addIterationInput.clear(); - } - - public TextField getAddIterationInput() { - return addIterationInput; - } -} diff --git a/src/main/java/edu/ntnu/idatt2003/controller/TextFieldObserver.java b/src/main/java/edu/ntnu/idatt2003/controller/TextFieldObserver.java new file mode 100644 index 0000000..dae65d0 --- /dev/null +++ b/src/main/java/edu/ntnu/idatt2003/controller/TextFieldObserver.java @@ -0,0 +1,35 @@ +package edu.ntnu.idatt2003.controller; + +import edu.ntnu.idatt2003.view.components.FractalOperations; +import edu.ntnu.idatt2003.view.components.TextFields; + +public class TextFieldObserver implements Observer{ + private FractalOperations fractalOperations; + private TextFields textFields; + + public TextFieldObserver(FractalOperations fractalOperations, TextFields textFields) { + this.fractalOperations = fractalOperations; + this.textFields = textFields; + textFields.attach(this); + } + @Override + public void update(String textField) { + switch (textField) { + case "addIterationInput": + handleAddIterationInput(); + break; + } + } + + public void handleAddIterationInput() { + String input = textFields.addIterationInput.getText(); + try { + int iterations = Integer.parseInt(input); + fractalOperations.addIterations(iterations); + } catch (NumberFormatException ex) { + System.out.println("Invalid input. Please enter a integer."); + } + textFields.addIterationInput.clear(); + } + +} diff --git a/src/main/java/edu/ntnu/idatt2003/view/components/Buttons.java b/src/main/java/edu/ntnu/idatt2003/view/components/Buttons.java index 65602d3..17e2e79 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/components/Buttons.java +++ b/src/main/java/edu/ntnu/idatt2003/view/components/Buttons.java @@ -1,9 +1,13 @@ package edu.ntnu.idatt2003.view.components; +import edu.ntnu.idatt2003.controller.Subject; +import javafx.application.Platform; +import javafx.scene.control.Alert; import javafx.scene.control.Button; +import javafx.scene.control.ButtonType; -public class Buttons { +public class Buttons extends Subject { private Button btnAdd10; private Button btnAdd100; private Button btnAdd1000; @@ -17,11 +21,47 @@ public class Buttons { private void initializeButtons() { btnAdd10 = new Button("Add 10"); + btnAdd10.setOnAction(e -> { + System.out.println("Add 10"); + notifyObservers("btnAdd10"); + }); + btnAdd100 = new Button("Add 100"); + btnAdd100.setOnAction(e -> { + System.out.println("Add 100"); + notifyObservers("btnAdd100"); + }); + btnAdd1000 = new Button("Add 1000"); + btnAdd1000.setOnAction(e -> { + System.out.println("Add 1000"); + notifyObservers("btnAdd1000"); + }); + btnReset = new Button("Reset"); + btnReset.setOnAction(e -> { + System.out.println("Reset"); + notifyObservers("btnReset"); + }); + btnAddInput = new Button("Add"); + btnAddInput.setOnAction(e -> { + System.out.println("Iterations added"); + notifyObservers("btnAddInput"); + }); + btnExitApplication = new Button("Exit"); + btnExitApplication.setOnAction(e -> { + Alert alert = new Alert(Alert.AlertType.CONFIRMATION); + alert.setTitle("Exit Confirmation"); + alert.setHeaderText("Are you sure you want to exit the application?"); + alert.setContentText("Press OK to exit the application, or Cancel to stay."); + + + var result = alert.showAndWait(); + if (result.isPresent() && result.get() == ButtonType.OK) + Platform.exit(); + }); } public Button getBtnAdd10() { @@ -46,3 +86,4 @@ public class Buttons { return btnExitApplication; } } + diff --git a/src/main/java/edu/ntnu/idatt2003/view/components/ComboBoxes.java b/src/main/java/edu/ntnu/idatt2003/view/components/ComboBoxes.java index d59b65e..c46f3f3 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/components/ComboBoxes.java +++ b/src/main/java/edu/ntnu/idatt2003/view/components/ComboBoxes.java @@ -1,9 +1,10 @@ package edu.ntnu.idatt2003.view.components; +import edu.ntnu.idatt2003.controller.Subject; import javafx.collections.FXCollections; import javafx.scene.control.ComboBox; -public class ComboBoxes { +public class ComboBoxes extends Subject { private ComboBox<String> comboBoxFractal; private ComboBox<String> comboBoxColor; @@ -18,6 +19,26 @@ public class ComboBoxes { "Sierpinski Triangle", "Barnsley Fern", "Julia Set", "Fractal From File" )); comboBoxFractal.setPromptText("Choose Fractal"); + comboBoxFractal.setOnAction(e -> { + String selectedFractal = getComboBoxFractal().getValue(); + + if ("Sierpinski Triangle".equals(selectedFractal)) { + System.out.println("Sierpinski Triangle"); + notifyObservers("Sierpinski Triangle"); + + } else if ("Julia Set".equals(selectedFractal)) { + System.out.println("Julia Set"); + notifyObservers("Julia Set"); + + } else if ("Barnsley Fern".equals(selectedFractal)) { + System.out.println("Barnsley Fern"); + notifyObservers("Barnsley Fern"); + + } else if ("Fractal From File".equals(selectedFractal)) { + System.out.println("Fractal From File"); + notifyObservers("Fractal From File"); + } + }); //ComboBox for choosing color comboBoxColor = new ComboBox<>(); diff --git a/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java b/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java index 07f004b..a010ffd 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java +++ b/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java @@ -22,8 +22,7 @@ public class FractalOperations { private ImageView imageView; private String currentFractal; - public FractalOperations(Label iterationsLabel, ImageView imageView, String initialFractal) { - this.iterationsLabel = iterationsLabel; + public FractalOperations(ImageView imageView, String initialFractal) { this.imageView = imageView; this.currentFractal = initialFractal; this.writableImage = new WritableImage(400, 400); @@ -44,19 +43,16 @@ public class FractalOperations { } public void addIterations(int iterations) { - this.iterations += iterations; - iterationsLabel.setText("Iterations: " + this.iterations); drawFractal(iterations); } public void resetIterations() { - this.iterations = 0; chaosGame.getCanvas().clear(); drawFractal(0); - iterationsLabel.setText("Iterations: 0"); } + public void updateImage() { PixelWriter pixelWriter = writableImage.getPixelWriter(); int[][] canvasArray = chaosGame.getCanvas().getCanvasArray(); diff --git a/src/main/java/edu/ntnu/idatt2003/view/components/TextFields.java b/src/main/java/edu/ntnu/idatt2003/view/components/TextFields.java index 8beed1f..96d7f32 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/components/TextFields.java +++ b/src/main/java/edu/ntnu/idatt2003/view/components/TextFields.java @@ -1,9 +1,10 @@ package edu.ntnu.idatt2003.view.components; +import edu.ntnu.idatt2003.controller.Subject; import javafx.scene.control.TextField; -public class TextFields { - private TextField addIterationInput; +public class TextFields extends Subject { + public TextField addIterationInput; private TextField xMinInput; private TextField yMinInput; private TextField xMaxInput; @@ -16,6 +17,11 @@ public class TextFields { public void initializeInputFields() { addIterationInput = new TextField(); addIterationInput.setPromptText("Add iterations"); + addIterationInput.setOnAction(e -> { + System.out.println("Iterations added"); + notifyObservers("addIterationInput"); + }); + xMinInput = new TextField(); xMinInput.setPromptText("X min"); yMinInput = new TextField(); diff --git a/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java b/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java index 7b97b81..2229707 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java +++ b/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java @@ -1,8 +1,9 @@ package edu.ntnu.idatt2003.view.scenes; -import edu.ntnu.idatt2003.controller.ButtonController; -import edu.ntnu.idatt2003.controller.ComboBoxController; -import edu.ntnu.idatt2003.controller.TextFieldController; +import edu.ntnu.idatt2003.controller.ButtonObserver; +import edu.ntnu.idatt2003.controller.ComboBoxObserver; +import edu.ntnu.idatt2003.controller.LabelObserver; +import edu.ntnu.idatt2003.controller.TextFieldObserver; import edu.ntnu.idatt2003.model.*; import edu.ntnu.idatt2003.view.components.*; import javafx.geometry.Insets; @@ -32,15 +33,16 @@ public class AffineScene { private ImageView imageView; private ChaosCanvas chaosCanvas; private Buttons buttons; - private ButtonController buttonController; private ComboBoxes comboBoxes; - private ComboBoxController comboBoxController; private Labels labels; private TextFields textFields; - private TextFieldController textFieldController; private FractalOperations fractalOperations; private VBox cBox; // Container for the C input fields private VBox matrixVectorBox; // Container for the matrix and vector input fields + private ButtonObserver buttonObserver; + private ComboBoxObserver comboBoxObserver; + private LabelObserver labelObserver; + private TextFieldObserver textFieldObserver; /** * Constructor for the AffineScene class @@ -51,18 +53,14 @@ public class AffineScene { labels = new Labels(); textFields = new TextFields(); initializeComponents(); - fractalOperations = new FractalOperations(iterationsLabel, imageView, fractalType); - textFieldController = new TextFieldController(fractalOperations, textFields); - buttonController = new ButtonController(fractalOperations, buttons, textFieldController); - comboBoxController = new ComboBoxController(fractalOperations, comboBoxes); - buttonController.initialize(); - comboBoxController.initialize(); - textFieldController.initialize(); - + fractalOperations = new FractalOperations(imageView, fractalType); + buttonObserver = new ButtonObserver(buttons, fractalOperations, textFields, iterationsLabel); + comboBoxObserver = new ComboBoxObserver(comboBoxes, fractalOperations); + labelObserver = new LabelObserver(buttons, comboBoxes, textFields, iterationsLabel); + textFieldObserver = new TextFieldObserver(fractalOperations, textFields); fractalOperations.resetIterations(); fractalOperations.addIterations(0); - comboBoxes.getComboBoxFractal().setValue(fractalType); // Add listener to ComboBox to handle dynamic addition of C input fields comboBoxes.getComboBoxFractal().getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> { if ("Julia Set".equals(newValue)) { @@ -209,7 +207,7 @@ public class AffineScene { AnchorPane.setRightAnchor(MinMaxAll, 30.0); // Create a scene with the root and set the CSS style - scene = new Scene(root, 1400, 1000); + scene = new Scene(root, 1000, 800); scene.getStylesheets().add(getClass().getResource("/style.css").toExternalForm()); } diff --git a/src/main/java/edu/ntnu/idatt2003/view/scenes/JuliaScene.java b/src/main/java/edu/ntnu/idatt2003/view/scenes/JuliaScene.java index 733b9f8..1404238 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/scenes/JuliaScene.java +++ b/src/main/java/edu/ntnu/idatt2003/view/scenes/JuliaScene.java @@ -1,15 +1,10 @@ package edu.ntnu.idatt2003.view.scenes; -import edu.ntnu.idatt2003.controller.ButtonController; -import edu.ntnu.idatt2003.controller.ComboBoxController; -import edu.ntnu.idatt2003.controller.TextFieldController; +import edu.ntnu.idatt2003.controller.TextFieldObserver; import edu.ntnu.idatt2003.model.ChaosCanvas; import edu.ntnu.idatt2003.model.Complex; import edu.ntnu.idatt2003.model.Vector2D; -import edu.ntnu.idatt2003.view.components.Buttons; -import edu.ntnu.idatt2003.view.components.ComboBoxes; -import edu.ntnu.idatt2003.view.components.FractalOperations; -import edu.ntnu.idatt2003.view.components.Labels; +import edu.ntnu.idatt2003.view.components.*; import javafx.geometry.Insets; import javafx.scene.Scene; import javafx.scene.control.Button; @@ -32,11 +27,10 @@ public class JuliaScene{ private Button updateCButton; private TextField realPartInput; private TextField imaginaryPartInput; - private ButtonController buttonController; + private TextFields textFields; private ComboBoxes comboBoxes; - private ComboBoxController comboBoxController; private Labels labels; - private TextFieldController textFieldController; + private TextFieldObserver textFieldObserver; private FractalOperations fractalOperations; public JuliaScene() { @@ -44,11 +38,8 @@ public class JuliaScene{ comboBoxes = new ComboBoxes(); labels = new Labels(); initializeComponents(); - fractalOperations = new FractalOperations(iterationsLabel, imageView, "JuliaSet"); - buttonController = new ButtonController(fractalOperations, buttons, textFieldController); - comboBoxController = new ComboBoxController(fractalOperations, comboBoxes); - buttonController.initialize(); - comboBoxController.initialize(); + fractalOperations = new FractalOperations(imageView, "JuliaSet"); + textFields = new TextFields(); fractalOperations.resetIterations(); fractalOperations.addIterations(0); } -- GitLab From 9544279ba03be42d55b009b8d014ce509b3fb06c Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Mon, 20 May 2024 11:16:56 +0200 Subject: [PATCH 125/168] ExceptionHandler class implemented --- .../idatt2003/controller/ExceptionHandler.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 src/main/java/edu/ntnu/idatt2003/controller/ExceptionHandler.java diff --git a/src/main/java/edu/ntnu/idatt2003/controller/ExceptionHandler.java b/src/main/java/edu/ntnu/idatt2003/controller/ExceptionHandler.java new file mode 100644 index 0000000..26fdd0c --- /dev/null +++ b/src/main/java/edu/ntnu/idatt2003/controller/ExceptionHandler.java @@ -0,0 +1,14 @@ +package edu.ntnu.idatt2003.controller; + +import javafx.scene.control.Alert; + +public class ExceptionHandler { + public void showAlertIntegerInvalid(String input) { + Alert alert = new Alert(Alert.AlertType.ERROR); + alert.setTitle("Error"); + alert.setHeaderText("An error occurred"); + alert.setContentText("The input '" + input + "' is invalid. Please enter an integer number."); + alert.showAndWait(); + } + +} -- GitLab From 34e122ad2c0bfe76963519f9d8613ab99dbd95f5 Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Mon, 20 May 2024 11:17:36 +0200 Subject: [PATCH 126/168] Observer added to btnExitApplication --- .../edu/ntnu/idatt2003/view/components/Buttons.java | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/view/components/Buttons.java b/src/main/java/edu/ntnu/idatt2003/view/components/Buttons.java index 17e2e79..c9ae101 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/components/Buttons.java +++ b/src/main/java/edu/ntnu/idatt2003/view/components/Buttons.java @@ -52,15 +52,9 @@ public class Buttons extends Subject { btnExitApplication = new Button("Exit"); btnExitApplication.setOnAction(e -> { - Alert alert = new Alert(Alert.AlertType.CONFIRMATION); - alert.setTitle("Exit Confirmation"); - alert.setHeaderText("Are you sure you want to exit the application?"); - alert.setContentText("Press OK to exit the application, or Cancel to stay."); + System.out.println("Exiting Application..."); + notifyObservers("btnExitApplication"); - - var result = alert.showAndWait(); - if (result.isPresent() && result.get() == ButtonType.OK) - Platform.exit(); }); } -- GitLab From 456a409cf2f5408bcf3cf1c8155c316f50133a18 Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Mon, 20 May 2024 11:19:03 +0200 Subject: [PATCH 127/168] Observer added to btnExitApplication and ExceptionHandler added --- .../idatt2003/controller/ButtonObserver.java | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java b/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java index 76b0e41..e30f897 100644 --- a/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java +++ b/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java @@ -3,10 +3,14 @@ package edu.ntnu.idatt2003.controller; import edu.ntnu.idatt2003.view.components.Buttons; import edu.ntnu.idatt2003.view.components.FractalOperations; import edu.ntnu.idatt2003.view.components.TextFields; +import javafx.application.Platform; +import javafx.scene.control.Alert; +import javafx.scene.control.ButtonType; import javafx.scene.control.Label; import javafx.scene.control.TextField; public class ButtonObserver implements Observer{ + private ExceptionHandler exceptionHandler = new ExceptionHandler(); private Buttons buttons; private FractalOperations fractalOperations; private TextFields textFields; @@ -43,9 +47,20 @@ public class ButtonObserver implements Observer{ int iterations = Integer.parseInt(input); fractalOperations.addIterations(iterations); } catch (NumberFormatException ex) { - System.out.println("Invalid input. Please enter a integer."); + exceptionHandler.showAlertIntegerInvalid(input); } break; + case "btnExitApplication": + Alert alert = new Alert(Alert.AlertType.CONFIRMATION); + alert.setTitle("Exit Confirmation"); + alert.setHeaderText("Are you sure you want to exit the application?"); + alert.setContentText("Press OK to exit the application, or Cancel to stay."); + + + var result = alert.showAndWait(); + if (result.isPresent() && result.get() == ButtonType.OK) + Platform.exit(); + break; } } } \ No newline at end of file -- GitLab From 1057d96d48d2787ccae7b8b15f45e41d4cdbe915 Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Mon, 20 May 2024 11:19:18 +0200 Subject: [PATCH 128/168] ExceptionHandler added --- .../edu/ntnu/idatt2003/controller/TextFieldObserver.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/controller/TextFieldObserver.java b/src/main/java/edu/ntnu/idatt2003/controller/TextFieldObserver.java index dae65d0..8aa2aac 100644 --- a/src/main/java/edu/ntnu/idatt2003/controller/TextFieldObserver.java +++ b/src/main/java/edu/ntnu/idatt2003/controller/TextFieldObserver.java @@ -2,8 +2,10 @@ package edu.ntnu.idatt2003.controller; import edu.ntnu.idatt2003.view.components.FractalOperations; import edu.ntnu.idatt2003.view.components.TextFields; +import javafx.scene.control.Alert; public class TextFieldObserver implements Observer{ + private ExceptionHandler exceptionHandler = new ExceptionHandler(); private FractalOperations fractalOperations; private TextFields textFields; @@ -27,9 +29,8 @@ public class TextFieldObserver implements Observer{ int iterations = Integer.parseInt(input); fractalOperations.addIterations(iterations); } catch (NumberFormatException ex) { - System.out.println("Invalid input. Please enter a integer."); + exceptionHandler.showAlertIntegerInvalid(input); } textFields.addIterationInput.clear(); } - } -- GitLab From eee9fed0127fd03ace7ad5c3c7ca1df582d67d2c Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Mon, 20 May 2024 12:02:19 +0200 Subject: [PATCH 129/168] imports --- .../java/edu/ntnu/idatt2003/view/scenes/AffineScene.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java b/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java index 2229707..9b8ef91 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java +++ b/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java @@ -1,9 +1,7 @@ package edu.ntnu.idatt2003.view.scenes; -import edu.ntnu.idatt2003.controller.ButtonObserver; -import edu.ntnu.idatt2003.controller.ComboBoxObserver; +import edu.ntnu.idatt2003.controller.*; import edu.ntnu.idatt2003.controller.LabelObserver; -import edu.ntnu.idatt2003.controller.TextFieldObserver; import edu.ntnu.idatt2003.model.*; import edu.ntnu.idatt2003.view.components.*; import javafx.geometry.Insets; @@ -207,7 +205,7 @@ public class AffineScene { AnchorPane.setRightAnchor(MinMaxAll, 30.0); // Create a scene with the root and set the CSS style - scene = new Scene(root, 1000, 800); + scene = new Scene(root, 1400, 1000); scene.getStylesheets().add(getClass().getResource("/style.css").toExternalForm()); } -- GitLab From 05ce98402c6e4e819737ce88b1b7e1f9a6bbd03a Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Mon, 20 May 2024 12:33:51 +0200 Subject: [PATCH 130/168] addFractalFromFileBox and removeFractalFromFileBox added --- .../idatt2003/view/scenes/AffineScene.java | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java b/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java index 2229707..46d4fda 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java +++ b/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java @@ -39,6 +39,7 @@ public class AffineScene { private FractalOperations fractalOperations; private VBox cBox; // Container for the C input fields private VBox matrixVectorBox; // Container for the matrix and vector input fields + private HBox topBox; private ButtonObserver buttonObserver; private ComboBoxObserver comboBoxObserver; private LabelObserver labelObserver; @@ -66,18 +67,22 @@ public class AffineScene { if ("Julia Set".equals(newValue)) { addCInputBox(); removeMatrixVectorInputBoxes(); + removeFractalFromFileBox(); } else if ("Sierpinski Triangle".equals(newValue)) { removeMatrixVectorInputBoxes(); removeCInputBox(); addMatrixVectorInputBoxes(); + removeFractalFromFileBox(); } else if ( "Barnsley Fern".equals(newValue)) { removeMatrixVectorInputBoxes(); removeCInputBox(); addMatrixVectorInputBoxes(); + removeFractalFromFileBox(); } else if ("Fractal From File".equals(newValue)) { removeCInputBox(); removeMatrixVectorInputBoxes(); + addFractalFromFileBox(); } }); @@ -86,6 +91,8 @@ public class AffineScene { addCInputBox(); } else if ("Sierpinski Triangle".equals(fractalType) || "Barnsley Fern".equals(fractalType)) { addMatrixVectorInputBoxes(); + } else if ("Fractal From File".equals(fractalType)) { + addFractalFromFileBox(); } } @@ -95,7 +102,7 @@ public class AffineScene { // HBox for buttons HBox bottomBox = new HBox(50); // spacing between buttons - HBox topBox = new HBox(50); // spacing between buttons + topBox = new HBox(50); // spacing between buttons bottomBox.getStyleClass().add("button-box"); topBox.getStyleClass().add("top-box"); @@ -360,6 +367,20 @@ public class AffineScene { } } + private void addFractalFromFileBox() { + Button btnAddFractalFromFile = buttons.getBtnAddFractalFromFile(); + if (btnAddFractalFromFile != null && !topBox.getChildren().contains(btnAddFractalFromFile)) { + topBox.getChildren().add(btnAddFractalFromFile); + } + } + + private void removeFractalFromFileBox() { + Button btnAddFractalFromFile = buttons.getBtnAddFractalFromFile(); + if (btnAddFractalFromFile != null && topBox.getChildren().contains(btnAddFractalFromFile)) { + topBox.getChildren().remove(btnAddFractalFromFile); + } + } + private void removeMatrixVectorInputBoxes() { if (matrixVectorBox != null) { ((AnchorPane) scene.getRoot()).getChildren().remove(matrixVectorBox); -- GitLab From 63da22c37bc5cdca5218cf037ba515257e350f21 Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Mon, 20 May 2024 12:34:47 +0200 Subject: [PATCH 131/168] btnAddFractalFromFile and its observer implemented --- .../ntnu/idatt2003/controller/ButtonObserver.java | 14 +++++++++++++- .../ntnu/idatt2003/view/components/Buttons.java | 11 ++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java b/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java index e30f897..55755a6 100644 --- a/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java +++ b/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java @@ -8,6 +8,10 @@ import javafx.scene.control.Alert; import javafx.scene.control.ButtonType; import javafx.scene.control.Label; import javafx.scene.control.TextField; +import javafx.stage.FileChooser; +import javafx.stage.Stage; + +import java.io.File; public class ButtonObserver implements Observer{ private ExceptionHandler exceptionHandler = new ExceptionHandler(); @@ -56,11 +60,19 @@ public class ButtonObserver implements Observer{ alert.setHeaderText("Are you sure you want to exit the application?"); alert.setContentText("Press OK to exit the application, or Cancel to stay."); - var result = alert.showAndWait(); if (result.isPresent() && result.get() == ButtonType.OK) Platform.exit(); break; + + case "btnAddFractalFromFile": + FileChooser fileChooser = new FileChooser(); + fileChooser.setTitle("Select Fractal From File"); + File file = fileChooser.showOpenDialog(new Stage()); + if (file != null) { + fractalOperations.setFractalCustomAffine(file.getPath()); + } + break; } } } \ No newline at end of file diff --git a/src/main/java/edu/ntnu/idatt2003/view/components/Buttons.java b/src/main/java/edu/ntnu/idatt2003/view/components/Buttons.java index c9ae101..e59def2 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/components/Buttons.java +++ b/src/main/java/edu/ntnu/idatt2003/view/components/Buttons.java @@ -13,6 +13,7 @@ public class Buttons extends Subject { private Button btnAdd1000; private Button btnReset; private Button btnAddInput; + private Button btnAddFractalFromFile; private Button btnExitApplication; public Buttons() { @@ -50,11 +51,16 @@ public class Buttons extends Subject { notifyObservers("btnAddInput"); }); + btnAddFractalFromFile = new Button("Load Fractal From File"); + btnAddFractalFromFile.setOnAction(e -> { + System.out.println("Fractal From File"); + notifyObservers("btnAddFractalFromFile"); + }); + btnExitApplication = new Button("Exit"); btnExitApplication.setOnAction(e -> { System.out.println("Exiting Application..."); notifyObservers("btnExitApplication"); - }); } @@ -76,6 +82,9 @@ public class Buttons extends Subject { public Button getBtnAddInput() { return btnAddInput; } + public Button getBtnAddFractalFromFile() { + return btnAddFractalFromFile; + } public Button getBtnExitApplication() { return btnExitApplication; } -- GitLab From 36875d3111c8b8f5237c4bcaeab89d90e1b11aa8 Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Mon, 20 May 2024 12:34:54 +0200 Subject: [PATCH 132/168] Checkstyle fixes for model --- .../edu/ntnu/idatt2003/model/ChaosCanvas.java | 4 + .../edu/ntnu/idatt2003/model/ChaosGame.java | 23 +++++- .../idatt2003/model/ChaosGameDescription.java | 20 ++++- .../model/ChaosGameDescriptionFactory.java | 25 ++++-- .../idatt2003/model/ChaosGameFileHandler.java | 80 ++++++++++++++----- .../edu/ntnu/idatt2003/model/Complex.java | 25 +++++- .../ntnu/idatt2003/model/JuliaTransform.java | 7 +- .../edu/ntnu/idatt2003/model/Matrix2x2.java | 17 ++++ .../edu/ntnu/idatt2003/model/Transform2D.java | 3 + .../edu/ntnu/idatt2003/model/Vector2D.java | 7 +- 10 files changed, 171 insertions(+), 40 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/model/ChaosCanvas.java b/src/main/java/edu/ntnu/idatt2003/model/ChaosCanvas.java index 82ff3a6..2df7819 100644 --- a/src/main/java/edu/ntnu/idatt2003/model/ChaosCanvas.java +++ b/src/main/java/edu/ntnu/idatt2003/model/ChaosCanvas.java @@ -106,6 +106,10 @@ public ChaosCanvas(int width, int height, Vector2D minCoords, Vector2D maxCoords } } +/** + * Returns the canvas as an ASCII string. + * @return the canvas as an ASCII string + */ public String toAscii() { StringBuilder sb = new StringBuilder(); for (int y = 0; y < height; y++) { diff --git a/src/main/java/edu/ntnu/idatt2003/model/ChaosGame.java b/src/main/java/edu/ntnu/idatt2003/model/ChaosGame.java index 55de6cc..3a7c567 100644 --- a/src/main/java/edu/ntnu/idatt2003/model/ChaosGame.java +++ b/src/main/java/edu/ntnu/idatt2003/model/ChaosGame.java @@ -2,23 +2,44 @@ package edu.ntnu.idatt2003.model; import java.util.Random; +/** + * Represents a chaos game. + */ public class ChaosGame { private ChaosCanvas canvas; private ChaosGameDescription description; private Vector2D currentPoint; private Random random; + /** + * Constructs a ChaosGame with the given ChaosGameDescription, width and height. + * + * @param description the description of the chaos game + * @param width the width of the canvas + * @param height the height of the canvas + */ public ChaosGame(ChaosGameDescription description, int width, int height) { this.description = description; - this.canvas = new ChaosCanvas(width, height, description.getMinCoords(), description.getMaxCoords()); + this.canvas = new ChaosCanvas(width, height, description.getMinCoords(), + description.getMaxCoords()); this.currentPoint = new Vector2D(0, 0); this.random = new Random(); } + /** + * Returns the canvas of the chaos game. + * + * @return the canvas + */ public ChaosCanvas getCanvas() { return canvas; } + /** + * Runs the chaos game for the given number of steps. + * + * @param steps the number of steps to run + */ public void runSteps(int steps) { if (description.getTransforms().isEmpty() || description.getTransforms() == null) { System.out.println("No transforms in description "); diff --git a/src/main/java/edu/ntnu/idatt2003/model/ChaosGameDescription.java b/src/main/java/edu/ntnu/idatt2003/model/ChaosGameDescription.java index 3bc144b..7358475 100644 --- a/src/main/java/edu/ntnu/idatt2003/model/ChaosGameDescription.java +++ b/src/main/java/edu/ntnu/idatt2003/model/ChaosGameDescription.java @@ -3,12 +3,23 @@ package edu.ntnu.idatt2003.model; import java.util.List; import java.util.Objects; +/** + * Represents a chaos game description. + */ public class ChaosGameDescription { private Vector2D minCoords; private Vector2D maxCoords; private List<Transform2D> transforms; - public ChaosGameDescription( List<Transform2D> transforms, Vector2D minCoords, Vector2D maxCoords) { + /** + * Constructs a ChaosGameDescription with the given transforms, minCoords and maxCoords. + * + * @param transforms the transforms of the chaos game + * @param minCoords the minimum coordinates of the chaos game + * @param maxCoords the maximum coordinates of the chaos game + */ + public ChaosGameDescription(List<Transform2D> transforms, Vector2D minCoords, + Vector2D maxCoords) { this.minCoords = minCoords; this.maxCoords = maxCoords; this.transforms = transforms; @@ -28,9 +39,10 @@ public class ChaosGameDescription { @Override public String toString() { - StringBuilder result = new StringBuilder(transforms.getFirst().getTransformType() + " # Type of transform" + "\n" + - minCoords.getX0() + ", " + minCoords.getX1() + " # Lower left" + "\n" + - maxCoords.getX0() + ", " + maxCoords.getX1() + " # Upper right"); + StringBuilder result = new StringBuilder(transforms.getFirst().getTransformType() + + " # Type of transform" + "\n" + + minCoords.getX0() + ", " + minCoords.getX1() + " # Lower left" + "\n" + + maxCoords.getX0() + ", " + maxCoords.getX1() + " # Upper right"); if (Objects.equals(transforms.getFirst().getTransformType(), "Julia")) { result.append("\n").append(transforms.getFirst().toFormattedString()); diff --git a/src/main/java/edu/ntnu/idatt2003/model/ChaosGameDescriptionFactory.java b/src/main/java/edu/ntnu/idatt2003/model/ChaosGameDescriptionFactory.java index 3083eb8..cbc049d 100644 --- a/src/main/java/edu/ntnu/idatt2003/model/ChaosGameDescriptionFactory.java +++ b/src/main/java/edu/ntnu/idatt2003/model/ChaosGameDescriptionFactory.java @@ -10,13 +10,17 @@ import java.util.List; public class ChaosGameDescriptionFactory { /** * Creates a ChaosGameDescription for the Sierpinski triangle. + * * @return a ChaosGameDescription for the Sierpinski triangle */ public static ChaosGameDescription createSierpinskiTriangle() { AffineTransform2D[] transforms = new AffineTransform2D[3]; - transforms[0] = new AffineTransform2D(new Matrix2x2(0.5, 0.0, 0.0, 0.5), new Vector2D(0.0, 0.0)); - transforms[1] = new AffineTransform2D(new Matrix2x2(0.5, 0.0, 0.0, 0.5), new Vector2D(0.5, 0.0)); - transforms[2] = new AffineTransform2D(new Matrix2x2(0.5, 0.0, 0.0, 0.5), new Vector2D(0.25, 0.5)); + transforms[0] = new AffineTransform2D(new Matrix2x2(0.5, 0.0, 0.0, 0.5), + new Vector2D(0.0, 0.0)); + transforms[1] = new AffineTransform2D(new Matrix2x2(0.5, 0.0, 0.0, 0.5), + new Vector2D(0.5, 0.0)); + transforms[2] = new AffineTransform2D(new Matrix2x2(0.5, 0.0, 0.0, 0.5), + new Vector2D(0.25, 0.5)); Vector2D lowerLeft = new Vector2D(0.0, 0.0); Vector2D lowerRight = new Vector2D(1.0, 1.0); @@ -26,14 +30,19 @@ public class ChaosGameDescriptionFactory { /** * Creates a ChaosGameDescription for the Barnsley fern. + * * @return a ChaosGameDescription for the Barnsley fern */ public static ChaosGameDescription createBarnsleyFern() { AffineTransform2D[] transforms = new AffineTransform2D[4]; - transforms[0] = new AffineTransform2D(new Matrix2x2(0.0, 0.0, 0.0, 0.16), new Vector2D(0.0, 0.0)); - transforms[1] = new AffineTransform2D(new Matrix2x2(0.85, 0.04, -0.04, 0.85), new Vector2D(0.0, 1.6)); - transforms[2] = new AffineTransform2D(new Matrix2x2(0.2, -0.26, 0.23, 0.22), new Vector2D(0.0, 1.6)); - transforms[3] = new AffineTransform2D(new Matrix2x2(-0.15, 0.28, 0.26, 0.24), new Vector2D(0.0, 0.44)); + transforms[0] = new AffineTransform2D(new Matrix2x2(0.0, 0.0, 0.0, 0.16), + new Vector2D(0.0, 0.0)); + transforms[1] = new AffineTransform2D(new Matrix2x2(0.85, 0.04, -0.04, 0.85), + new Vector2D(0.0, 1.6)); + transforms[2] = new AffineTransform2D(new Matrix2x2(0.2, -0.26, 0.23, 0.22), + new Vector2D(0.0, 1.6)); + transforms[3] = new AffineTransform2D(new Matrix2x2(-0.15, 0.28, 0.26, 0.24), + new Vector2D(0.0, 0.44)); Vector2D lowerLeft = new Vector2D(-2.5, 0.0); Vector2D upperRight = new Vector2D(2.5, 10.0); @@ -43,8 +52,10 @@ public class ChaosGameDescriptionFactory { /** * Creates a ChaosGameDescription for the Julia set with the given complex number. + * * @param c the complex number * @param sign the sign of the imaginary part of the complex number + * * @return a ChaosGameDescription for the Julia set */ public static ChaosGameDescription createJuliaSet(Complex c, int sign) { diff --git a/src/main/java/edu/ntnu/idatt2003/model/ChaosGameFileHandler.java b/src/main/java/edu/ntnu/idatt2003/model/ChaosGameFileHandler.java index 9769991..bccc7ba 100644 --- a/src/main/java/edu/ntnu/idatt2003/model/ChaosGameFileHandler.java +++ b/src/main/java/edu/ntnu/idatt2003/model/ChaosGameFileHandler.java @@ -1,16 +1,36 @@ package edu.ntnu.idatt2003.model; -import java.io.*; -import java.util.*; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Scanner; + +/** + * This class is responsible for reading and writing ChaosGameDescriptions to and from files. + */ public class ChaosGameFileHandler { - private String filePath; + private final String filePath; + /** + * Constructs a ChaosGameFileHandler with the given file path. + * + * @param filePath the path to the file + */ public ChaosGameFileHandler(String filePath) { this.filePath = filePath; } - // Read a fractal description from a file + /** + * Reads a file and returns a ChaosGameDescription. + * + * @return a ChaosGameDescription + * @throws IOException if an I/O error occurs + */ public ChaosGameDescription readFile() throws IOException { File file = new File(filePath); List<Transform2D> transforms = new ArrayList<>(); @@ -62,6 +82,12 @@ public class ChaosGameFileHandler { return new ChaosGameDescription(transforms, minCoords, maxCoords); } + /** + * Parses a line of text to create an AffineTransform2D. + * + * @param line the line of text + * @return an AffineTransform2D + */ public AffineTransform2D parseAffineTransform(String line) { String[] parts = line.split(","); ArrayList<Double> params = new ArrayList<>(); @@ -75,7 +101,8 @@ public class ChaosGameFileHandler { } if (params.size() < 6) { - throw new IllegalArgumentException("Not enough valid numeric data to create an AffineTransform2D: " + line); + throw new IllegalArgumentException("Not enough valid numeric data to create an " + + "AffineTransform2D: " + line); } return new AffineTransform2D( @@ -84,40 +111,53 @@ public class ChaosGameFileHandler { ); } + /** + * Parses a line of text to create a Vector2D. + * + * @param line the line of text + * @return a Vector2D + */ public Vector2D parseVector2D(String line) { String[] parts = line.split("#")[0].trim().split(","); - if (parts.length < 2) return null; - + if (parts.length < 2) { + return null; + } try { double x = Double.parseDouble(parts[0].trim()); double y = Double.parseDouble(parts[1].trim()); return new Vector2D(x, y); } catch (NumberFormatException e) { - System.err.println("Failed to parse vector from line: " + line + "; Error: " + e.getMessage()); + System.err.println("Failed to parse vector from line: " + line + "; Error: " + + e.getMessage()); return null; } } -// private JuliaTransform parseJulia(String line) { -// String[] parts = line.split(","); -// return new JuliaTransform( -// new Complex(Double.parseDouble(parts[0].trim()), Double.parseDouble(parts[1].trim())), -// 1); -// } - + /** + * Parses a line of text to create a list of JuliaTransforms. + * + * @param line the line of text + * @return a list of JuliaTransforms + */ private List<Transform2D> parseJulia(String line) { String[] parts = line.split(","); List<Transform2D> juliaTransforms = new ArrayList<>(); juliaTransforms.add(new JuliaTransform( - new Complex(Double.parseDouble(parts[0].trim()), Double.parseDouble(parts[1].trim())), - 1)); + new Complex(Double.parseDouble(parts[0].trim()), Double.parseDouble(parts[1].trim())), + 1)); juliaTransforms.add(new JuliaTransform( - new Complex(Double.parseDouble(parts[0].trim()), Double.parseDouble(parts[1].trim())), - -1)); + new Complex(Double.parseDouble(parts[0].trim()), Double.parseDouble(parts[1].trim())), + -1)); return juliaTransforms; } - + /** + * Writes a ChaosGameDescription to a file. + * + * @param filePath the path to the file + * @param description the ChaosGameDescription to write + * @throws IOException if an I/O error occurs + */ public void writeToFile(String filePath, ChaosGameDescription description) throws IOException { try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath))) { writer.write(description.toString()); diff --git a/src/main/java/edu/ntnu/idatt2003/model/Complex.java b/src/main/java/edu/ntnu/idatt2003/model/Complex.java index f1ba43d..140d12d 100644 --- a/src/main/java/edu/ntnu/idatt2003/model/Complex.java +++ b/src/main/java/edu/ntnu/idatt2003/model/Complex.java @@ -3,13 +3,30 @@ package edu.ntnu.idatt2003.model; import static java.lang.Math.abs; +/** + * Class representing a complex number. + */ public class Complex extends Vector2D { - public Complex(double realPart, double imaginaryPart){ + + /** + * Constructs a complex number with the specified real and imaginary parts. + * + * @param realPart The real part of the complex number. + * @param imaginaryPart The imaginary part of the complex number. + */ + public Complex(double realPart, double imaginaryPart) { super(realPart, imaginaryPart); } - public Complex sqrt(){ - double absoluteZ = Math.sqrt(Math.pow(this.getX0(),2)+Math.pow(this.getX1(),2)); - return new Complex(Math.sqrt((absoluteZ+this.getX0())/2),this.getX1()/abs(this.getX1())*Math.sqrt((absoluteZ-this.getX0())/2)); + + /** + * Calculates the square root of the complex number. + * + * @return The square root of the complex number. + */ + public Complex sqrt() { + double absoluteZ = Math.sqrt(Math.pow(this.getX0(), 2) + Math.pow(this.getX1(), 2)); + return new Complex(Math.sqrt((absoluteZ + this.getX0()) / 2), this.getX1() + / abs(this.getX1()) * Math.sqrt((absoluteZ - this.getX0()) / 2)); } public double getReal() { diff --git a/src/main/java/edu/ntnu/idatt2003/model/JuliaTransform.java b/src/main/java/edu/ntnu/idatt2003/model/JuliaTransform.java index 7d08812..ca94ff8 100644 --- a/src/main/java/edu/ntnu/idatt2003/model/JuliaTransform.java +++ b/src/main/java/edu/ntnu/idatt2003/model/JuliaTransform.java @@ -2,6 +2,9 @@ package edu.ntnu.idatt2003.model; import java.util.Locale; +/** + * Class representing a Julia transformation. + */ public class JuliaTransform implements Transform2D { private final Complex point; private final int sign; @@ -35,7 +38,7 @@ public class JuliaTransform implements Transform2D { Vector2D result = (z.subtract(point)); Complex complexResult = new Complex(result.getX0(), result.getX1()); complexResult = complexResult.sqrt(); - return new Vector2D(complexResult.getX0()*sign, complexResult.getX1()*sign); + return new Vector2D(complexResult.getX0() * sign, complexResult.getX1() * sign); } @Override @@ -45,7 +48,7 @@ public class JuliaTransform implements Transform2D { @Override public String toFormattedString() { - return String.format(Locale.ENGLISH,"%.5f, %.5f", point.getReal(), point.getImaginary()); + return String.format(Locale.ENGLISH, "%.5f, %.5f", point.getReal(), point.getImaginary()); } public Complex getPoint() { diff --git a/src/main/java/edu/ntnu/idatt2003/model/Matrix2x2.java b/src/main/java/edu/ntnu/idatt2003/model/Matrix2x2.java index 8524ab3..e13dc9f 100644 --- a/src/main/java/edu/ntnu/idatt2003/model/Matrix2x2.java +++ b/src/main/java/edu/ntnu/idatt2003/model/Matrix2x2.java @@ -1,11 +1,22 @@ package edu.ntnu.idatt2003.model; +/** + * Class representing a 2x2 matrix. + */ public class Matrix2x2 { private final double a00; private final double a01; private final double a10; private final double a11; + /** + * Constructs a 2x2 matrix with the specified elements. + * + * @param a00 The element in the first row and first column. + * @param a01 The element in the first row and second column. + * @param a10 The element in the second row and first column. + * @param a11 The element in the second row and second column. + */ public Matrix2x2(double a00, double a01, double a10, double a11) { this.a00 = a00; this.a01 = a01; @@ -13,6 +24,12 @@ public class Matrix2x2 { this.a11 = a11; } + /** + * Multiplies the matrix with a vector. + * + * @param vector The vector to multiply with. + * @return The resulting vector. + */ public Vector2D multiply(Vector2D vector) { return new Vector2D( a00 * vector.getX0() + a01 * vector.getX1(), diff --git a/src/main/java/edu/ntnu/idatt2003/model/Transform2D.java b/src/main/java/edu/ntnu/idatt2003/model/Transform2D.java index 42bec3f..f4f20df 100644 --- a/src/main/java/edu/ntnu/idatt2003/model/Transform2D.java +++ b/src/main/java/edu/ntnu/idatt2003/model/Transform2D.java @@ -7,10 +7,13 @@ package edu.ntnu.idatt2003.model; public interface Transform2D { /** * Transforms the given point. + * * @param point the vector to transform * @return the transformed vector */ + Vector2D transform(Vector2D point); + String getTransformType(); String toFormattedString(); diff --git a/src/main/java/edu/ntnu/idatt2003/model/Vector2D.java b/src/main/java/edu/ntnu/idatt2003/model/Vector2D.java index e547a89..5fd6946 100644 --- a/src/main/java/edu/ntnu/idatt2003/model/Vector2D.java +++ b/src/main/java/edu/ntnu/idatt2003/model/Vector2D.java @@ -10,8 +10,9 @@ public class Vector2D { /** * Constructs a Vector2D with the given x0 and x1 components. - * @param x0 - * @param x1 + * + * @param x0 the x-component of the vector + * @param x1 the y-component of the vector */ public Vector2D(double x0, double x1) { this.x0 = x0; @@ -20,6 +21,7 @@ public class Vector2D { /** * Returns the x0 component of the vector. + * * @return x0 */ public double getX0() { @@ -28,6 +30,7 @@ public class Vector2D { /** * Returns the x1 component of the vector. + * * @return x1 */ public double getX1() { -- GitLab From 5d2c8446ed490f35875c5272fc6a59ae12717a8e Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Mon, 20 May 2024 12:36:06 +0200 Subject: [PATCH 133/168] setBlankImageView implemented --- .../ntnu/idatt2003/controller/ComboBoxObserver.java | 7 +------ .../idatt2003/view/components/FractalOperations.java | 11 +++++++++++ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/controller/ComboBoxObserver.java b/src/main/java/edu/ntnu/idatt2003/controller/ComboBoxObserver.java index 273030c..efd57f4 100644 --- a/src/main/java/edu/ntnu/idatt2003/controller/ComboBoxObserver.java +++ b/src/main/java/edu/ntnu/idatt2003/controller/ComboBoxObserver.java @@ -30,12 +30,7 @@ public class ComboBoxObserver implements Observer { fractalOperations.setFractalToBransleysFern(); break; case "Fractal From File": - FileChooser fileChooser = new FileChooser(); - fileChooser.setTitle("Select Fractal From File"); - File file = fileChooser.showOpenDialog(new Stage()); - if (file != null) { - fractalOperations.setFractalCustomAffine(file.getPath()); - } + fractalOperations.setBlankImageView(); } } } diff --git a/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java b/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java index a010ffd..7fb63a3 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java +++ b/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java @@ -97,6 +97,17 @@ public class FractalOperations { } } + public void setBlankImageView() { + AffineTransform2D[] defaultTransforms = new AffineTransform2D[0]; + Vector2D defaultLowerLeft = new Vector2D(0, 0); + Vector2D defaultUpperRight = new Vector2D(0, 0); + + ChaosGameDescription description = new ChaosGameDescription(Arrays.asList(defaultTransforms), defaultLowerLeft, defaultUpperRight); + this.chaosGame = new ChaosGame(description, 400, 400); + iterations = 0; + drawFractal(0); + } + public void updateC(Complex complex) { this.chaosGame = new ChaosGame(createJuliaSet(complex, -1), 400, 400); } -- GitLab From ba786a00d6ab660073245cf493764f2e012a40ba Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Mon, 20 May 2024 12:36:24 +0200 Subject: [PATCH 134/168] minor improvments --- src/main/java/edu/ntnu/idatt2003/model/ChaosGame.java | 6 +++--- .../java/edu/ntnu/idatt2003/model/ChaosGameDescription.java | 6 +++--- .../java/edu/ntnu/idatt2003/model/ChaosGameFileHandler.java | 2 +- src/main/java/edu/ntnu/idatt2003/model/Vector2D.java | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/model/ChaosGame.java b/src/main/java/edu/ntnu/idatt2003/model/ChaosGame.java index 3a7c567..e322cae 100644 --- a/src/main/java/edu/ntnu/idatt2003/model/ChaosGame.java +++ b/src/main/java/edu/ntnu/idatt2003/model/ChaosGame.java @@ -6,10 +6,10 @@ import java.util.Random; * Represents a chaos game. */ public class ChaosGame { - private ChaosCanvas canvas; - private ChaosGameDescription description; + private final ChaosCanvas canvas; + private final ChaosGameDescription description; private Vector2D currentPoint; - private Random random; + private final Random random; /** * Constructs a ChaosGame with the given ChaosGameDescription, width and height. diff --git a/src/main/java/edu/ntnu/idatt2003/model/ChaosGameDescription.java b/src/main/java/edu/ntnu/idatt2003/model/ChaosGameDescription.java index 7358475..41a6262 100644 --- a/src/main/java/edu/ntnu/idatt2003/model/ChaosGameDescription.java +++ b/src/main/java/edu/ntnu/idatt2003/model/ChaosGameDescription.java @@ -7,9 +7,9 @@ import java.util.Objects; * Represents a chaos game description. */ public class ChaosGameDescription { - private Vector2D minCoords; - private Vector2D maxCoords; - private List<Transform2D> transforms; + private final Vector2D minCoords; + private final Vector2D maxCoords; + private final List<Transform2D> transforms; /** * Constructs a ChaosGameDescription with the given transforms, minCoords and maxCoords. diff --git a/src/main/java/edu/ntnu/idatt2003/model/ChaosGameFileHandler.java b/src/main/java/edu/ntnu/idatt2003/model/ChaosGameFileHandler.java index bccc7ba..cce3c37 100644 --- a/src/main/java/edu/ntnu/idatt2003/model/ChaosGameFileHandler.java +++ b/src/main/java/edu/ntnu/idatt2003/model/ChaosGameFileHandler.java @@ -57,7 +57,7 @@ public class ChaosGameFileHandler { } try { - Transform2D transform = null; + Transform2D transform; assert type != null; if (type.equals("Julia")) { transforms = parseJulia(line.split("#")[0].trim()); diff --git a/src/main/java/edu/ntnu/idatt2003/model/Vector2D.java b/src/main/java/edu/ntnu/idatt2003/model/Vector2D.java index 5fd6946..4e54ae7 100644 --- a/src/main/java/edu/ntnu/idatt2003/model/Vector2D.java +++ b/src/main/java/edu/ntnu/idatt2003/model/Vector2D.java @@ -5,8 +5,8 @@ package edu.ntnu.idatt2003.model; * y-component represented by x1. */ public class Vector2D { - private double x0; - private double x1; + private final double x0; + private final double x1; /** * Constructs a Vector2D with the given x0 and x1 components. -- GitLab From 6dad8e35569e33fc4dcae2969a9431f30ea139a1 Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Mon, 20 May 2024 12:49:11 +0200 Subject: [PATCH 135/168] fixed placement --- .../ntnu/idatt2003/view/scenes/AffineScene.java | 14 +++++++------- src/main/resources/style.css | 1 + 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java b/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java index a7c2532..6cab19c 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java +++ b/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java @@ -208,11 +208,11 @@ public class AffineScene { AnchorPane.setRightAnchor(btnExitApplication, 10.0); // Anchor the MinMaxBox to the top right corner - AnchorPane.setTopAnchor(MinMaxAll, 75.0); + AnchorPane.setTopAnchor(MinMaxAll, 65.0); AnchorPane.setRightAnchor(MinMaxAll, 30.0); // Create a scene with the root and set the CSS style - scene = new Scene(root, 1400, 1000); + scene = new Scene(root, 1400, 830); scene.getStylesheets().add(getClass().getResource("/style.css").toExternalForm()); } @@ -335,10 +335,10 @@ public class AffineScene { private void addMatrixVectorInputBoxes() { if (matrixVectorBox == null) { - matrixVectorBox = new VBox(10); - matrixVectorBox.setPadding(new Insets(10)); - VBox inputContainer = new VBox(10); - inputContainer.setPadding(new Insets(10)); + matrixVectorBox = new VBox(5); + matrixVectorBox.setPadding(new Insets(5)); + VBox inputContainer = new VBox(5); + inputContainer.setPadding(new Insets(5)); Button addMoreButton = new Button("Add More"); addMoreButton.setOnAction(event -> { @@ -358,7 +358,7 @@ public class AffineScene { }); resetToDefaultFractal(inputContainer, addMoreButton, updateMatrixVectorButton, resetToDefaultButton); - AnchorPane.setTopAnchor(inputContainer, 240.0); + AnchorPane.setTopAnchor(inputContainer, 230.0); AnchorPane.setRightAnchor(inputContainer, 30.0); ((AnchorPane) scene.getRoot()).getChildren().add(inputContainer); matrixVectorBox = inputContainer; diff --git a/src/main/resources/style.css b/src/main/resources/style.css index 6f8fdaf..c18ffa7 100644 --- a/src/main/resources/style.css +++ b/src/main/resources/style.css @@ -85,6 +85,7 @@ -fx-border-color: black; -fx-border-radius: 10px; -fx-pref-width: 50px; + -fx-pref-height: 5px; } .MaxMinInput { -- GitLab From 5cacb1877673f6734dcf3a3bd663fa7ed92ff5d8 Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Mon, 20 May 2024 12:59:56 +0200 Subject: [PATCH 136/168] Removed JuliaScene --- .../java/edu/ntnu/idatt2003/view/App.java | 10 +- .../idatt2003/view/scenes/JuliaScene.java | 125 ------------------ .../scenes/{AffineScene.java => Scene.java} | 9 +- 3 files changed, 7 insertions(+), 137 deletions(-) delete mode 100644 src/main/java/edu/ntnu/idatt2003/view/scenes/JuliaScene.java rename src/main/java/edu/ntnu/idatt2003/view/scenes/{AffineScene.java => Scene.java} (99%) diff --git a/src/main/java/edu/ntnu/idatt2003/view/App.java b/src/main/java/edu/ntnu/idatt2003/view/App.java index c4d880c..c4a6c51 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/App.java +++ b/src/main/java/edu/ntnu/idatt2003/view/App.java @@ -1,7 +1,6 @@ package edu.ntnu.idatt2003.view; -import edu.ntnu.idatt2003.view.scenes.AffineScene; -import edu.ntnu.idatt2003.view.scenes.JuliaScene; +import edu.ntnu.idatt2003.view.scenes.Scene; import javafx.application.Application; import javafx.stage.Stage; @@ -12,10 +11,7 @@ public class App extends Application { @Override public void start(Stage primaryStage) { - AffineScene affineScene = new AffineScene("Barnsley Fern"); - affineScene.setUpStage(primaryStage); - - //JuliaScene juliaScene = new JuliaScene(); - //juliaScene.setUpStage(primaryStage); + Scene scene = new Scene("Sierpinski Triangle"); + scene.setUpStage(primaryStage); } } diff --git a/src/main/java/edu/ntnu/idatt2003/view/scenes/JuliaScene.java b/src/main/java/edu/ntnu/idatt2003/view/scenes/JuliaScene.java deleted file mode 100644 index 1404238..0000000 --- a/src/main/java/edu/ntnu/idatt2003/view/scenes/JuliaScene.java +++ /dev/null @@ -1,125 +0,0 @@ -package edu.ntnu.idatt2003.view.scenes; - -import edu.ntnu.idatt2003.controller.TextFieldObserver; -import edu.ntnu.idatt2003.model.ChaosCanvas; -import edu.ntnu.idatt2003.model.Complex; -import edu.ntnu.idatt2003.model.Vector2D; -import edu.ntnu.idatt2003.view.components.*; -import javafx.geometry.Insets; -import javafx.scene.Scene; -import javafx.scene.control.Button; -import javafx.scene.control.ComboBox; -import javafx.scene.control.Label; -import javafx.scene.control.TextField; -import javafx.scene.image.ImageView; -import javafx.scene.image.WritableImage; -import javafx.scene.layout.BorderPane; -import javafx.scene.layout.HBox; -import javafx.stage.Stage; - -public class JuliaScene{ - private Label iterationsLabel; - private Scene scene; - private WritableImage writableImage; - private ImageView imageView; - private ChaosCanvas chaosCanvas; - private Buttons buttons; - private Button updateCButton; - private TextField realPartInput; - private TextField imaginaryPartInput; - private TextFields textFields; - private ComboBoxes comboBoxes; - private Labels labels; - private TextFieldObserver textFieldObserver; - private FractalOperations fractalOperations; - - public JuliaScene() { - buttons = new Buttons(); - comboBoxes = new ComboBoxes(); - labels = new Labels(); - initializeComponents(); - fractalOperations = new FractalOperations(imageView, "JuliaSet"); - textFields = new TextFields(); - fractalOperations.resetIterations(); - fractalOperations.addIterations(0); - } - - private void initializeComponents() { - // Creating the root pane and setting its size - BorderPane root = new BorderPane(); - - // HBox for buttons - HBox buttonBox = new HBox(50); // spacing between buttons - HBox topBox = new HBox(50); // spacing between buttons - - buttonBox.getStyleClass().add("button-box"); - topBox.getStyleClass().add("top-box"); - - // Initialize buttons - Button btnAdd10 = buttons.getBtnAdd10(); - Button btnAdd100 = buttons.getBtnAdd100(); - Button btnAdd1000 = buttons.getBtnAdd1000(); - Button btnReset = buttons.getBtnReset(); - - // Initialize Labels - iterationsLabel = labels.getIterationLabel(); - - // Initialize ComboBoxes - ComboBox<String> comboBoxFractal = comboBoxes.getComboBoxFractal(); - ComboBox<String>comboBoxColor = comboBoxes.getComboBoxColor(); - - // Add buttons to the HBox - buttonBox.getChildren().addAll(btnAdd10, btnAdd100, btnAdd1000, btnReset, iterationsLabel); - buttonBox.setPadding(new Insets(0, 0, 50, 50)); - - topBox.getChildren().addAll(comboBoxFractal, comboBoxColor); - topBox.setPadding(new Insets(20, 0, 0, 50)); - - // Aligning the HBox at the bottom - root.setBottom(buttonBox); - root.setTop(topBox); - - // Create a scene with the root and set the CSS style - scene = new Scene(root, 800, 600); - scene.getStylesheets().add(getClass().getResource("/style.css").toExternalForm()); - - // Initialize the ChaosCanvas and the WritableImage - chaosCanvas = new ChaosCanvas(600, 400, new Vector2D(0, 0), new Vector2D(600, 400)); - writableImage = new WritableImage(600, 400); - imageView = new ImageView(writableImage); - - BorderPane imagePane = new BorderPane(); - imagePane.setCenter(imageView); - - root.setCenter(imagePane); - - updateCButton = new Button("Update C"); - // Initialize TextFields - realPartInput = new TextField(); - imaginaryPartInput = new TextField(); - realPartInput.setPromptText("Real part of C"); - imaginaryPartInput.setPromptText("Imaginary part of C"); - - HBox cBox = new HBox(2); - cBox.getChildren().addAll(realPartInput, imaginaryPartInput, updateCButton); - cBox.setPadding(new Insets(100, 0, 0, 0)); - root.setRight(cBox); - - updateCButton.setOnAction(event -> { - try { - double realPart = Double.parseDouble(realPartInput.getText()); - double imaginaryPart = Double.parseDouble(imaginaryPartInput.getText()); - fractalOperations.updateC(new Complex(realPart, imaginaryPart)); - } catch (NumberFormatException e) { - // Handle invalid input - System.out.println("Invalid input for real or imaginary part of C."); - } - }); - } - - public void setUpStage(Stage primaryStage) { - primaryStage.setTitle("ChaosGame"); - primaryStage.setScene(scene); - primaryStage.show(); - } -} diff --git a/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java b/src/main/java/edu/ntnu/idatt2003/view/scenes/Scene.java similarity index 99% rename from src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java rename to src/main/java/edu/ntnu/idatt2003/view/scenes/Scene.java index 6cab19c..527318d 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/scenes/AffineScene.java +++ b/src/main/java/edu/ntnu/idatt2003/view/scenes/Scene.java @@ -5,7 +5,6 @@ import edu.ntnu.idatt2003.controller.LabelObserver; import edu.ntnu.idatt2003.model.*; import edu.ntnu.idatt2003.view.components.*; import javafx.geometry.Insets; -import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.ComboBox; import javafx.scene.control.Label; @@ -22,11 +21,11 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; -public class AffineScene { +public class Scene { private Label iterationsLabel; private Label MaxLabel; private Label MinLabel; - private Scene scene; + private javafx.scene.Scene scene; private WritableImage writableImage; private ImageView imageView; private ChaosCanvas chaosCanvas; @@ -46,7 +45,7 @@ public class AffineScene { /** * Constructor for the AffineScene class */ - public AffineScene(String fractalType) { + public Scene(String fractalType) { buttons = new Buttons(); comboBoxes = new ComboBoxes(); labels = new Labels(); @@ -212,7 +211,7 @@ public class AffineScene { AnchorPane.setRightAnchor(MinMaxAll, 30.0); // Create a scene with the root and set the CSS style - scene = new Scene(root, 1400, 830); + scene = new javafx.scene.Scene(root, 1400, 830); scene.getStylesheets().add(getClass().getResource("/style.css").toExternalForm()); } -- GitLab From 1231f3b6f372e32b4f734d006f594275d8bbc2d2 Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Mon, 20 May 2024 14:53:51 +0200 Subject: [PATCH 137/168] Javadoc and minor improvements --- .../idatt2003/controller/ButtonObserver.java | 36 +++++++-- .../controller/ComboBoxObserver.java | 27 +++++-- .../controller/ExceptionHandler.java | 7 ++ .../idatt2003/controller/LabelObserver.java | 33 +++++++- .../ntnu/idatt2003/controller/Observer.java | 9 +++ .../ntnu/idatt2003/controller/Subject.java | 9 +-- .../controller/TextFieldObserver.java | 25 ++++++- .../idatt2003/model/AffineTransform2D.java | 8 +- .../edu/ntnu/idatt2003/model/ChaosCanvas.java | 21 +++--- .../idatt2003/view/components/Buttons.java | 12 +++ .../idatt2003/view/components/ComboBoxes.java | 9 +++ .../view/components/FractalOperations.java | 75 ++++++++++++++++--- .../idatt2003/view/components/Labels.java | 27 ++++--- .../idatt2003/view/components/TextFields.java | 41 ++++++---- 14 files changed, 268 insertions(+), 71 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java b/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java index 55755a6..603c92c 100644 --- a/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java +++ b/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java @@ -3,6 +3,7 @@ package edu.ntnu.idatt2003.controller; import edu.ntnu.idatt2003.view.components.Buttons; import edu.ntnu.idatt2003.view.components.FractalOperations; import edu.ntnu.idatt2003.view.components.TextFields; +import java.io.File; import javafx.application.Platform; import javafx.scene.control.Alert; import javafx.scene.control.ButtonType; @@ -11,17 +12,28 @@ import javafx.scene.control.TextField; import javafx.stage.FileChooser; import javafx.stage.Stage; -import java.io.File; -public class ButtonObserver implements Observer{ +/** + * This class is responsible for handling button events. + */ +public class ButtonObserver implements Observer { private ExceptionHandler exceptionHandler = new ExceptionHandler(); private Buttons buttons; private FractalOperations fractalOperations; private TextFields textFields; private Label iterationsLabel; - private int iterations = 0; - public ButtonObserver(Buttons buttons, FractalOperations fractalOperations, TextFields textFields, Label iterationsLabel) { + /** + * Constructs a ButtonObserver with the given buttons, fractalOperations, + * textFields and iterationsLabel. + * + * @param buttons the buttons + * @param fractalOperations the fractalOperations + * @param textFields the textFields + * @param iterationsLabel the iterationsLabel + */ + public ButtonObserver(Buttons buttons, FractalOperations fractalOperations, + TextFields textFields, Label iterationsLabel) { this.buttons = buttons; this.fractalOperations = fractalOperations; this.textFields = textFields; @@ -29,21 +41,30 @@ public class ButtonObserver implements Observer{ buttons.attach(this); } + /** + * Updates the button observer depending on the button pressed. + * + * @param button the button pressed + */ @Override public void update(String button) { switch (button) { case "btnAdd10": fractalOperations.addIterations(10); break; + case "btnAdd100": fractalOperations.addIterations(100); break; + case "btnAdd1000": fractalOperations.addIterations(1000); break; + case "btnReset": fractalOperations.resetIterations(); break; + case "btnAddInput": TextField addIterationInput = textFields.getAddIterationInput(); String input = addIterationInput.getText(); @@ -54,6 +75,7 @@ public class ButtonObserver implements Observer{ exceptionHandler.showAlertIntegerInvalid(input); } break; + case "btnExitApplication": Alert alert = new Alert(Alert.AlertType.CONFIRMATION); alert.setTitle("Exit Confirmation"); @@ -61,8 +83,9 @@ public class ButtonObserver implements Observer{ alert.setContentText("Press OK to exit the application, or Cancel to stay."); var result = alert.showAndWait(); - if (result.isPresent() && result.get() == ButtonType.OK) + if (result.isPresent() && result.get() == ButtonType.OK) { Platform.exit(); + } break; case "btnAddFractalFromFile": @@ -73,6 +96,9 @@ public class ButtonObserver implements Observer{ fractalOperations.setFractalCustomAffine(file.getPath()); } break; + + default: + break; } } } \ No newline at end of file diff --git a/src/main/java/edu/ntnu/idatt2003/controller/ComboBoxObserver.java b/src/main/java/edu/ntnu/idatt2003/controller/ComboBoxObserver.java index efd57f4..9ffc509 100644 --- a/src/main/java/edu/ntnu/idatt2003/controller/ComboBoxObserver.java +++ b/src/main/java/edu/ntnu/idatt2003/controller/ComboBoxObserver.java @@ -2,35 +2,52 @@ package edu.ntnu.idatt2003.controller; import edu.ntnu.idatt2003.view.components.ComboBoxes; import edu.ntnu.idatt2003.view.components.FractalOperations; -import javafx.stage.FileChooser; -import javafx.stage.Stage; - -import java.io.File; - +/** + * This class is responsible for handling combobox events. + */ public class ComboBoxObserver implements Observer { private ComboBoxes comboBoxes; private FractalOperations fractalOperations; + /** + * Constructs a ComboBoxObserver with the given comboBoxes and fractalOperations. + * + * @param comboBoxes the comboBoxes + * @param fractalOperations the fractalOperations + */ public ComboBoxObserver(ComboBoxes comboBoxes, FractalOperations fractalOperations) { this.comboBoxes = comboBoxes; this.fractalOperations = fractalOperations; comboBoxes.attach(this); } + + /** + * Updates the combobox observer when an option is pressed in a ComboBox. + * + * @param option the option pressed in the ComboBox + */ @Override public void update(String option) { switch (option) { case "Sierpinski Triangle": fractalOperations.setFractalToSierpinskiTriangle(); break; + case "Julia Set": fractalOperations.setFractalToJuliaSet(); break; + case "Barnsley Fern": fractalOperations.setFractalToBransleysFern(); break; + case "Fractal From File": fractalOperations.setBlankImageView(); + break; + + default: + break; } } } diff --git a/src/main/java/edu/ntnu/idatt2003/controller/ExceptionHandler.java b/src/main/java/edu/ntnu/idatt2003/controller/ExceptionHandler.java index 26fdd0c..cce2367 100644 --- a/src/main/java/edu/ntnu/idatt2003/controller/ExceptionHandler.java +++ b/src/main/java/edu/ntnu/idatt2003/controller/ExceptionHandler.java @@ -2,7 +2,14 @@ package edu.ntnu.idatt2003.controller; import javafx.scene.control.Alert; +/** + * This class is responsible for handling exceptions. + */ public class ExceptionHandler { + + /** + * Method to handle an invalid integer input. + */ public void showAlertIntegerInvalid(String input) { Alert alert = new Alert(Alert.AlertType.ERROR); alert.setTitle("Error"); diff --git a/src/main/java/edu/ntnu/idatt2003/controller/LabelObserver.java b/src/main/java/edu/ntnu/idatt2003/controller/LabelObserver.java index ab17fd9..40ef587 100644 --- a/src/main/java/edu/ntnu/idatt2003/controller/LabelObserver.java +++ b/src/main/java/edu/ntnu/idatt2003/controller/LabelObserver.java @@ -6,6 +6,9 @@ import edu.ntnu.idatt2003.view.components.TextFields; import javafx.scene.control.Label; import javafx.scene.control.TextField; +/** + * This class is responsible for handling label events. + */ public class LabelObserver implements Observer { private Buttons buttons; private ComboBoxes comboBoxes; @@ -13,8 +16,16 @@ public class LabelObserver implements Observer { private Label iterationLabel; private int iterations = 0; - - public LabelObserver(Buttons buttons, ComboBoxes comboBoxes, TextFields textFields, Label iterationLabel) { + /** + * Constructs a LabelObserver with the given buttons, comboBoxes, textFields and iterationLabel. + * + * @param buttons the buttons + * @param comboBoxes the comboBoxes + * @param textFields the textFields + * @param iterationLabel the iterationLabel + */ + public LabelObserver(Buttons buttons, ComboBoxes comboBoxes, TextFields textFields, + Label iterationLabel) { this.buttons = buttons; this.comboBoxes = comboBoxes; this.textFields = textFields; @@ -22,20 +33,28 @@ public class LabelObserver implements Observer { buttons.attach(this); comboBoxes.attach(this); textFields.attach(this); - } + + /** + * Updates the label observer depending on action from other components. + * + * @param label the label updated by other components being pressed + */ @Override public void update(String label) { switch (label) { case "btnAdd10": iterations += 10; break; + case "btnAdd100": iterations += 100; break; + case "btnAdd1000": iterations += 1000; break; + case "btnReset": iterations = 0; break; @@ -65,19 +84,27 @@ public class LabelObserver implements Observer { } } break; + case "Sierpinski Triangle": iterations = 0; break; + case "Julia Set": iterations = 0; break; + case "Barnsley Fern": iterations = 0; break; + case "Fractal From File": iterations = 0; break; + + default: + break; } + // Update the label with the new number of iterations iterationLabel.setText("Iterations: " + iterations); } } diff --git a/src/main/java/edu/ntnu/idatt2003/controller/Observer.java b/src/main/java/edu/ntnu/idatt2003/controller/Observer.java index 49fbeb2..17b78ee 100644 --- a/src/main/java/edu/ntnu/idatt2003/controller/Observer.java +++ b/src/main/java/edu/ntnu/idatt2003/controller/Observer.java @@ -1,5 +1,14 @@ package edu.ntnu.idatt2003.controller; +/** + * This interface is responsible for handling observer events. + */ public interface Observer { + + /** + * Updates the observer depending on the event. + * + * @param string the event + */ void update(String string); } diff --git a/src/main/java/edu/ntnu/idatt2003/controller/Subject.java b/src/main/java/edu/ntnu/idatt2003/controller/Subject.java index b09f653..9883170 100644 --- a/src/main/java/edu/ntnu/idatt2003/controller/Subject.java +++ b/src/main/java/edu/ntnu/idatt2003/controller/Subject.java @@ -18,20 +18,13 @@ public abstract class Subject { /** * Attach an observer to the subject. + * * @param observer The observer to attach. */ public void attach(Observer observer) { observers.add(observer); } - /** - * Detach an observer from the subject. - * @param observer The observer to detach. - */ - public void detach(Observer observer) { - observers.remove(observer); - } - /** * Notify all observers of the subject. */ diff --git a/src/main/java/edu/ntnu/idatt2003/controller/TextFieldObserver.java b/src/main/java/edu/ntnu/idatt2003/controller/TextFieldObserver.java index 8aa2aac..0c6e989 100644 --- a/src/main/java/edu/ntnu/idatt2003/controller/TextFieldObserver.java +++ b/src/main/java/edu/ntnu/idatt2003/controller/TextFieldObserver.java @@ -2,27 +2,48 @@ package edu.ntnu.idatt2003.controller; import edu.ntnu.idatt2003.view.components.FractalOperations; import edu.ntnu.idatt2003.view.components.TextFields; -import javafx.scene.control.Alert; -public class TextFieldObserver implements Observer{ +/** + * This class is responsible for handling textfield events. + */ +public class TextFieldObserver implements Observer { private ExceptionHandler exceptionHandler = new ExceptionHandler(); private FractalOperations fractalOperations; private TextFields textFields; + /** + * Constructs a TextFieldObserver with the given fractalOperations and textFields. + * + * @param fractalOperations the fractalOperations + * @param textFields the textFields + */ public TextFieldObserver(FractalOperations fractalOperations, TextFields textFields) { this.fractalOperations = fractalOperations; this.textFields = textFields; textFields.attach(this); } + + /** + * Updates the textfield observer depending on the textfield entered. + * + * @param textField the textfield entered + */ @Override public void update(String textField) { switch (textField) { case "addIterationInput": handleAddIterationInput(); break; + + default: + break; } } + /** + * Handles the add iteration input. Parses the input and adds the iterations to the fractal. + * If the input is not an integer number, an alert is shown. + */ public void handleAddIterationInput() { String input = textFields.addIterationInput.getText(); try { diff --git a/src/main/java/edu/ntnu/idatt2003/model/AffineTransform2D.java b/src/main/java/edu/ntnu/idatt2003/model/AffineTransform2D.java index 9009d94..3db5e16 100644 --- a/src/main/java/edu/ntnu/idatt2003/model/AffineTransform2D.java +++ b/src/main/java/edu/ntnu/idatt2003/model/AffineTransform2D.java @@ -40,6 +40,11 @@ public class AffineTransform2D implements Transform2D { return vector; } + /** + * Returns a formatted string representation of the transformation. + * + * @return a formatted string representation of the transformation + */ public String toFormattedString() { double a00 = matrix.getA00(); double a01 = matrix.getA01(); @@ -49,7 +54,8 @@ public class AffineTransform2D implements Transform2D { double b0 = vector.getX0(); double b1 = vector.getX1(); - return String.format(Locale.ENGLISH,"%.2f, %.2f, %.2f, %.2f, %.2f, %.2f", a00, a01, a10, a11, b0, b1); + return String.format(Locale.ENGLISH, "%.2f, %.2f, %.2f, %.2f, %.2f, %.2f", + a00, a01, a10, a11, b0, b1); } public String getTransformType() { diff --git a/src/main/java/edu/ntnu/idatt2003/model/ChaosCanvas.java b/src/main/java/edu/ntnu/idatt2003/model/ChaosCanvas.java index 2df7819..5576b30 100644 --- a/src/main/java/edu/ntnu/idatt2003/model/ChaosCanvas.java +++ b/src/main/java/edu/ntnu/idatt2003/model/ChaosCanvas.java @@ -14,13 +14,14 @@ public class ChaosCanvas { /** * Constructs a ChaosCanvas with the given width, height, minCoords and maxCoords. + * * @param width the width of the canvas * @param height the height of the canvas * @param minCoords the minimum coordinates of the canvas * @param maxCoords the maximum coordinates of the canvas * */ -public ChaosCanvas(int width, int height, Vector2D minCoords, Vector2D maxCoords) { + public ChaosCanvas(int width, int height, Vector2D minCoords, Vector2D maxCoords) { this.width = width; this.height = height; this.minCoords = minCoords; @@ -44,21 +45,20 @@ public ChaosCanvas(int width, int height, Vector2D minCoords, Vector2D maxCoords double a01 = (height - 1) / (minCoords.getX1() - maxCoords.getX1()); double a10 = (width - 1) / (maxCoords.getX0() - minCoords.getX0()); - //double bX = -(minCoords.getX1() * a01); - //double bY = -(minCoords.getX0() * a10); - - Matrix2x2 matrix2x2 = new Matrix2x2( 0, a01, a10, 0); + Matrix2x2 matrix2x2 = new Matrix2x2(0, a01, a10, 0); - double bX = (height - 1)*maxCoords.getX1() / (maxCoords.getX1() - minCoords.getX1()); - double bY = (width - 1)*minCoords.getX0() / (minCoords.getX0() - maxCoords.getX0()); + double x = (height - 1) * maxCoords.getX1() / (maxCoords.getX1() - minCoords.getX1()); + double y = (width - 1) * minCoords.getX0() / (minCoords.getX0() - maxCoords.getX0()); - Vector2D vector2D = new Vector2D(bX, bY); + Vector2D vector2D = new Vector2D(x, y); transformCoordsToIndices = new AffineTransform2D(matrix2x2, vector2D); } /** * Returns the pixel at the given point. + * * @param point the point to get the pixel from + * * @return the pixel at the given point */ public int getPixel(Vector2D point) { @@ -75,6 +75,7 @@ public ChaosCanvas(int width, int height, Vector2D minCoords, Vector2D maxCoords /** * Puts a pixel at the given point. + * * @param point the point to put the pixel at */ public void putPixel(Vector2D point) { @@ -89,6 +90,7 @@ public ChaosCanvas(int width, int height, Vector2D minCoords, Vector2D maxCoords /** * Returns the canvas array. + * * @return the canvas array */ public int[][] getCanvasArray() { @@ -106,8 +108,9 @@ public ChaosCanvas(int width, int height, Vector2D minCoords, Vector2D maxCoords } } -/** + /** * Returns the canvas as an ASCII string. + * * @return the canvas as an ASCII string */ public String toAscii() { diff --git a/src/main/java/edu/ntnu/idatt2003/view/components/Buttons.java b/src/main/java/edu/ntnu/idatt2003/view/components/Buttons.java index e59def2..7092e73 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/components/Buttons.java +++ b/src/main/java/edu/ntnu/idatt2003/view/components/Buttons.java @@ -7,6 +7,9 @@ import javafx.scene.control.Alert; import javafx.scene.control.Button; import javafx.scene.control.ButtonType; +/** + * This class is responsible for creating buttons. + */ public class Buttons extends Subject { private Button btnAdd10; private Button btnAdd100; @@ -16,10 +19,16 @@ public class Buttons extends Subject { private Button btnAddFractalFromFile; private Button btnExitApplication; + /** + * Constructs a Buttons object. + */ public Buttons() { initializeButtons(); } + /** + * Initializes the buttons. + */ private void initializeButtons() { btnAdd10 = new Button("Add 10"); btnAdd10.setOnAction(e -> { @@ -79,12 +88,15 @@ public class Buttons extends Subject { public Button getBtnReset() { return btnReset; } + public Button getBtnAddInput() { return btnAddInput; } + public Button getBtnAddFractalFromFile() { return btnAddFractalFromFile; } + public Button getBtnExitApplication() { return btnExitApplication; } diff --git a/src/main/java/edu/ntnu/idatt2003/view/components/ComboBoxes.java b/src/main/java/edu/ntnu/idatt2003/view/components/ComboBoxes.java index c46f3f3..16dde07 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/components/ComboBoxes.java +++ b/src/main/java/edu/ntnu/idatt2003/view/components/ComboBoxes.java @@ -4,14 +4,23 @@ import edu.ntnu.idatt2003.controller.Subject; import javafx.collections.FXCollections; import javafx.scene.control.ComboBox; +/** + * This class is responsible for creating ComboBoxes. + */ public class ComboBoxes extends Subject { private ComboBox<String> comboBoxFractal; private ComboBox<String> comboBoxColor; + /** + * Constructs a ComboBoxes object. + */ public ComboBoxes() { initializeComboBoxes(); } + /** + * Initializes the ComboBoxes. + */ private void initializeComboBoxes() { //ComboBox for choosing fractal comboBoxFractal = new ComboBox<>(); diff --git a/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java b/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java index 7fb63a3..83ef5e4 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java +++ b/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java @@ -1,19 +1,19 @@ package edu.ntnu.idatt2003.view.components; -import static edu.ntnu.idatt2003.model.ChaosGameDescriptionFactory.createJuliaSet; import edu.ntnu.idatt2003.model.*; -import javafx.scene.Scene; +import java.io.IOException; +import java.util.Arrays; import javafx.scene.control.Label; import javafx.scene.image.ImageView; import javafx.scene.image.PixelWriter; import javafx.scene.image.WritableImage; import javafx.scene.paint.Color; -import java.io.IOException; -import java.util.Arrays; - import static edu.ntnu.idatt2003.model.ChaosGameDescriptionFactory.createJuliaSet; +/** + * This class is responsible for performing operations on the fractals. + */ public class FractalOperations { private ChaosGame chaosGame; private int iterations; @@ -22,6 +22,12 @@ public class FractalOperations { private ImageView imageView; private String currentFractal; + /** + * Constructs a FractalOperations object with the given ImageView and initial fractal. + * + * @param imageView the ImageView + * @param initialFractal the initial fractal + */ public FractalOperations(ImageView imageView, String initialFractal) { this.imageView = imageView; this.currentFractal = initialFractal; @@ -51,8 +57,9 @@ public class FractalOperations { drawFractal(0); } - - + /** + * Updates the image of the fractal. + */ public void updateImage() { PixelWriter pixelWriter = writableImage.getPixelWriter(); int[][] canvasArray = chaosGame.getCanvas().getCanvasArray(); @@ -65,26 +72,42 @@ public class FractalOperations { } } + /** + * Sets the fractal to Sierpinski Triangle. + */ public void setFractalToSierpinskiTriangle() { - this.chaosGame = new ChaosGame(ChaosGameDescriptionFactory.createSierpinskiTriangle(), 400, 400); + this.chaosGame = new ChaosGame(ChaosGameDescriptionFactory.createSierpinskiTriangle(), + 400, 400); iterations = 0; drawFractal(0); } + /** + * Sets the fractal to Julia Set. + */ public void setFractalToJuliaSet() { Complex defaultComplex = new Complex(-0.74543, 0.11301); int defaultInt = -1; - this.chaosGame = new ChaosGame(ChaosGameDescriptionFactory.createJuliaSet(defaultComplex, defaultInt), 400, 400); + this.chaosGame = new ChaosGame(ChaosGameDescriptionFactory.createJuliaSet(defaultComplex, + defaultInt), 400, 400); iterations = 0; drawFractal(0); } + /** + * Sets the fractal to Barnsley Fern. + */ public void setFractalToBransleysFern() { this.chaosGame = new ChaosGame(ChaosGameDescriptionFactory.createBarnsleyFern(), 400, 400); iterations = 0; drawFractal(0); } + /** + * Sets the fractal to custom affine. + * + * @param filePath the file path + */ public void setFractalCustomAffine(String filePath) { ChaosGameFileHandler fileHandler = new ChaosGameFileHandler(filePath); try { @@ -97,32 +120,48 @@ public class FractalOperations { } } + /** + * Sets the fractal to custom Julia. + */ public void setBlankImageView() { AffineTransform2D[] defaultTransforms = new AffineTransform2D[0]; Vector2D defaultLowerLeft = new Vector2D(0, 0); Vector2D defaultUpperRight = new Vector2D(0, 0); - ChaosGameDescription description = new ChaosGameDescription(Arrays.asList(defaultTransforms), defaultLowerLeft, defaultUpperRight); + ChaosGameDescription description = new ChaosGameDescription(Arrays.asList(defaultTransforms), + defaultLowerLeft, defaultUpperRight); this.chaosGame = new ChaosGame(description, 400, 400); iterations = 0; drawFractal(0); } + /** + * Updates the fractal to the given complex number. + * + * @param complex the complex number + */ public void updateC(Complex complex) { this.chaosGame = new ChaosGame(createJuliaSet(complex, -1), 400, 400); } + /** + * Updates the fractal to the given matrix and vector. + * + * @param description the ChaosGameDescription + */ public void updateMatrixAndVector(ChaosGameDescription description) { this.chaosGame = new ChaosGame(description, 400, 400); iterations = 0; drawFractal(0); } + public void updateJuliaSet(Complex complex, int sign, Vector2D minCoords, Vector2D maxCoords) { JuliaTransform[] transforms = new JuliaTransform[2]; transforms[0] = new JuliaTransform(complex, sign); transforms[1] = new JuliaTransform(complex, -sign); - ChaosGameDescription newChaosGame = new ChaosGameDescription(Arrays.asList(transforms), minCoords, maxCoords); + ChaosGameDescription newChaosGame = new ChaosGameDescription(Arrays.asList(transforms), + minCoords, maxCoords); this.chaosGame = new ChaosGame(newChaosGame, 400, 400); } @@ -130,12 +169,24 @@ public class FractalOperations { return currentFractal; } + /** + * Getter for the ChaosGame object. + * + * @return the ChaosGame object + */ public ChaosGame getChaosGame() { return chaosGame; } + /** + * Updates the min and max coordinates of the fractal. + * + * @param minCoords the minimum coordinates of the fractal + * @param maxCoords the maximum coordinates of the fractal + */ public void updateMinAndMaxFractal(Vector2D minCoords, Vector2D maxCoords) { - ChaosGameDescription newChaosGame = new ChaosGameDescription(chaosGame.getChaosGameDescription().getTransforms(), minCoords, maxCoords); + ChaosGameDescription newChaosGame = new ChaosGameDescription( + chaosGame.getChaosGameDescription().getTransforms(), minCoords, maxCoords); this.chaosGame = new ChaosGame(newChaosGame, 400, 400); } } diff --git a/src/main/java/edu/ntnu/idatt2003/view/components/Labels.java b/src/main/java/edu/ntnu/idatt2003/view/components/Labels.java index 21628d9..b46234b 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/components/Labels.java +++ b/src/main/java/edu/ntnu/idatt2003/view/components/Labels.java @@ -2,24 +2,31 @@ package edu.ntnu.idatt2003.view.components; import javafx.scene.control.Label; -import java.util.concurrent.Callable; - +/** + * This class is responsible for creating labels for the GUI. + */ public class Labels { private Label iterationLabel; - private Label MaxLabel; - private Label MinLabel; + private Label maxLabel; + private Label minLabel; + /** + * Constructs a Labels object. + */ public Labels() { initializeLabels(); } + /** + * Initializes the labels. + */ public void initializeLabels() { iterationLabel = new Label(); iterationLabel.setText("Iterations: 0"); - MinLabel = new Label(); - MinLabel.setText("Change Min vector"); - MaxLabel = new Label(); - MaxLabel.setText("Change Max vector"); + minLabel = new Label(); + minLabel.setText("Change Min vector"); + maxLabel = new Label(); + maxLabel.setText("Change Max vector"); } public Label getIterationLabel() { @@ -27,11 +34,11 @@ public class Labels { } public Label getMinLabel() { - return MinLabel; + return minLabel; } public Label geMaxLabel() { - return MaxLabel; + return maxLabel; } } diff --git a/src/main/java/edu/ntnu/idatt2003/view/components/TextFields.java b/src/main/java/edu/ntnu/idatt2003/view/components/TextFields.java index 96d7f32..839c84a 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/components/TextFields.java +++ b/src/main/java/edu/ntnu/idatt2003/view/components/TextFields.java @@ -3,17 +3,26 @@ package edu.ntnu.idatt2003.view.components; import edu.ntnu.idatt2003.controller.Subject; import javafx.scene.control.TextField; +/** + * This class is responsible for creating text fields for the GUI. + */ public class TextFields extends Subject { public TextField addIterationInput; - private TextField xMinInput; - private TextField yMinInput; - private TextField xMaxInput; - private TextField yMaxInput; + private TextField xminInput; + private TextField yminInput; + private TextField xmaxInput; + private TextField ymaxInput; + /** + * Constructs a TextFields object. + */ public TextFields() { initializeInputFields(); } + /** + * Initializes the text fields. + */ public void initializeInputFields() { addIterationInput = new TextField(); addIterationInput.setPromptText("Add iterations"); @@ -22,14 +31,14 @@ public class TextFields extends Subject { notifyObservers("addIterationInput"); }); - xMinInput = new TextField(); - xMinInput.setPromptText("X min"); - yMinInput = new TextField(); - yMinInput.setPromptText("Y min"); - xMaxInput = new TextField(); - xMaxInput.setPromptText("X max"); - yMaxInput = new TextField(); - yMaxInput.setPromptText("Y max"); + xminInput = new TextField(); + xminInput.setPromptText("X min"); + yminInput = new TextField(); + yminInput.setPromptText("Y min"); + xmaxInput = new TextField(); + xmaxInput.setPromptText("X max"); + ymaxInput = new TextField(); + ymaxInput.setPromptText("Y max"); } public TextField getAddIterationInput() { @@ -37,19 +46,19 @@ public class TextFields extends Subject { } public TextField getxMinInput() { - return xMinInput; + return xminInput; } public TextField getyMinInput() { - return yMinInput; + return yminInput; } public TextField getxMaxInput() { - return xMaxInput; + return xmaxInput; } public TextField getyMaxInput() { - return yMaxInput; + return ymaxInput; } } -- GitLab From af42b54a49fd19d04873334ad6b837d93c923493 Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Mon, 20 May 2024 15:43:36 +0200 Subject: [PATCH 138/168] Added btnSaveFractalToFile --- .../edu/ntnu/idatt2003/view/components/Buttons.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/main/java/edu/ntnu/idatt2003/view/components/Buttons.java b/src/main/java/edu/ntnu/idatt2003/view/components/Buttons.java index e59def2..e15d4d0 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/components/Buttons.java +++ b/src/main/java/edu/ntnu/idatt2003/view/components/Buttons.java @@ -14,6 +14,7 @@ public class Buttons extends Subject { private Button btnReset; private Button btnAddInput; private Button btnAddFractalFromFile; + private Button btnSaveFractalToFile; private Button btnExitApplication; public Buttons() { @@ -62,6 +63,12 @@ public class Buttons extends Subject { System.out.println("Exiting Application..."); notifyObservers("btnExitApplication"); }); + + btnSaveFractalToFile = new Button("Save Fractal To File"); + btnSaveFractalToFile.setOnAction(e -> { + System.out.println("Save Fractal To File"); + notifyObservers("btnSaveFractalToFile"); + }); } public Button getBtnAdd10() { @@ -88,5 +95,8 @@ public class Buttons extends Subject { public Button getBtnExitApplication() { return btnExitApplication; } + public Button getBtnSaveFractalToFile() { + return btnSaveFractalToFile; + } } -- GitLab From 51b5cf36917c8d5c9c8b858f220dbbdf7836e78d Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Mon, 20 May 2024 15:43:47 +0200 Subject: [PATCH 139/168] Added saveFractalToFile method --- .../idatt2003/view/components/FractalOperations.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java b/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java index 7fb63a3..8ee5c3f 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java +++ b/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java @@ -138,4 +138,13 @@ public class FractalOperations { ChaosGameDescription newChaosGame = new ChaosGameDescription(chaosGame.getChaosGameDescription().getTransforms(), minCoords, maxCoords); this.chaosGame = new ChaosGame(newChaosGame, 400, 400); } + + public void saveFractalToFile(String path) { +ChaosGameFileHandler fileHandler = new ChaosGameFileHandler(path); + try { + fileHandler.writeToFile(path, chaosGame.getChaosGameDescription()); + } catch (IOException e) { + e.printStackTrace(); + } + } } -- GitLab From 59d296ea6c95cbcea342113344061ee73dfa104e Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Mon, 20 May 2024 15:44:12 +0200 Subject: [PATCH 140/168] Added saveFractalToFileButton method --- .../java/edu/ntnu/idatt2003/view/scenes/Scene.java | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/main/java/edu/ntnu/idatt2003/view/scenes/Scene.java b/src/main/java/edu/ntnu/idatt2003/view/scenes/Scene.java index 527318d..11481eb 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/scenes/Scene.java +++ b/src/main/java/edu/ntnu/idatt2003/view/scenes/Scene.java @@ -65,16 +65,19 @@ public class Scene { addCInputBox(); removeMatrixVectorInputBoxes(); removeFractalFromFileBox(); + addSaveFractalToFileButton(); } else if ("Sierpinski Triangle".equals(newValue)) { removeMatrixVectorInputBoxes(); removeCInputBox(); addMatrixVectorInputBoxes(); removeFractalFromFileBox(); + addSaveFractalToFileButton(); } else if ( "Barnsley Fern".equals(newValue)) { removeMatrixVectorInputBoxes(); removeCInputBox(); - addMatrixVectorInputBoxes(); removeFractalFromFileBox(); + addMatrixVectorInputBoxes(); + addSaveFractalToFileButton(); } else if ("Fractal From File".equals(newValue)) { removeCInputBox(); @@ -86,8 +89,10 @@ public class Scene { // Initial setup based on the provided fractal type if ("Julia Set".equals(fractalType)) { addCInputBox(); + addSaveFractalToFileButton(); } else if ("Sierpinski Triangle".equals(fractalType) || "Barnsley Fern".equals(fractalType)) { addMatrixVectorInputBoxes(); + addSaveFractalToFileButton(); } else if ("Fractal From File".equals(fractalType)) { addFractalFromFileBox(); } @@ -467,6 +472,13 @@ public class Scene { fractalOperations.updateMinAndMaxFractal(minCoords, maxCoords); } + public void addSaveFractalToFileButton(){ + Button saveFractalToFileButton = buttons.getBtnSaveFractalToFile(); + if (saveFractalToFileButton != null && !topBox.getChildren().contains(saveFractalToFileButton)) { + topBox.getChildren().add(saveFractalToFileButton); + } + } + public void setUpStage(Stage primaryStage) { primaryStage.setTitle("ChaosGame"); primaryStage.setScene(scene); -- GitLab From 9d1bb9a6cf392305e63482b25ce192209e736695 Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Mon, 20 May 2024 15:44:49 +0200 Subject: [PATCH 141/168] Added btnSaveFractalToFile --- .../edu/ntnu/idatt2003/controller/ButtonObserver.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java b/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java index 55755a6..da297eb 100644 --- a/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java +++ b/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java @@ -73,6 +73,15 @@ public class ButtonObserver implements Observer{ fractalOperations.setFractalCustomAffine(file.getPath()); } break; + + case "btnSaveFractalToFile": + FileChooser fileChooserSave = new FileChooser(); + fileChooserSave.setTitle("Save Fractal To File"); + File fileSave = fileChooserSave.showSaveDialog(new Stage()); + if (fileSave != null) { + fractalOperations.saveFractalToFile(fileSave.getPath()); + } + break; } } } \ No newline at end of file -- GitLab From 6360bb09888c1bf286e2e800f26fee9ba443d479 Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Mon, 20 May 2024 15:47:53 +0200 Subject: [PATCH 142/168] Added default --- .../java/edu/ntnu/idatt2003/controller/ButtonObserver.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java b/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java index da297eb..8f5030c 100644 --- a/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java +++ b/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java @@ -82,6 +82,9 @@ public class ButtonObserver implements Observer{ fractalOperations.saveFractalToFile(fileSave.getPath()); } break; + + default: + break; } } } \ No newline at end of file -- GitLab From 04236d948ee5e456cff9fe73ad2691628785f8d4 Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Mon, 20 May 2024 15:51:51 +0200 Subject: [PATCH 143/168] JavaDoc --- .../java/edu/ntnu/idatt2003/controller/ButtonObserver.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java b/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java index 8f5030c..7712064 100644 --- a/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java +++ b/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java @@ -9,10 +9,12 @@ import javafx.scene.control.ButtonType; import javafx.scene.control.Label; import javafx.scene.control.TextField; import javafx.stage.FileChooser; -import javafx.stage.Stage; - import java.io.File; +import javafx.stage.Stage; +/** + * This class is responsible for handling button events. + */ public class ButtonObserver implements Observer{ private ExceptionHandler exceptionHandler = new ExceptionHandler(); private Buttons buttons; -- GitLab From 520fe117aa0889b2f27e052ccb3d57a291ea14f4 Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Mon, 20 May 2024 16:19:40 +0200 Subject: [PATCH 144/168] added fitWidthProperty to imageview --- src/main/java/edu/ntnu/idatt2003/view/scenes/Scene.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/edu/ntnu/idatt2003/view/scenes/Scene.java b/src/main/java/edu/ntnu/idatt2003/view/scenes/Scene.java index 11481eb..08ee49f 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/scenes/Scene.java +++ b/src/main/java/edu/ntnu/idatt2003/view/scenes/Scene.java @@ -186,6 +186,7 @@ public class Scene { imagePane.setCenter(imageView); imageView.fitHeightProperty().bind(imagePane.heightProperty()); + imageView.fitWidthProperty().bind(imagePane.widthProperty()); imageView.setPreserveRatio(true); // Add components to the root AnchorPane -- GitLab From 2f7f2ffc658b882372f100f62954a40ae7686650 Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Mon, 20 May 2024 17:00:39 +0200 Subject: [PATCH 145/168] Handles negative integers --- .../ntnu/idatt2003/controller/ButtonObserver.java | 3 +++ .../idatt2003/controller/ExceptionHandler.java | 15 +++++++++++++++ .../ntnu/idatt2003/controller/LabelObserver.java | 8 ++++++-- .../idatt2003/controller/TextFieldObserver.java | 3 +++ 4 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java b/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java index 5ffd295..720ca3f 100644 --- a/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java +++ b/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java @@ -70,9 +70,12 @@ public class ButtonObserver implements Observer{ String input = addIterationInput.getText(); try { int iterations = Integer.parseInt(input); + exceptionHandler.validatePostiviteInteger(iterations); fractalOperations.addIterations(iterations); } catch (NumberFormatException ex) { exceptionHandler.showAlertIntegerInvalid(input); + } catch (IllegalArgumentException ex) { + exceptionHandler.showAlertIntegerBelowOne(input); } break; diff --git a/src/main/java/edu/ntnu/idatt2003/controller/ExceptionHandler.java b/src/main/java/edu/ntnu/idatt2003/controller/ExceptionHandler.java index cce2367..8879ca8 100644 --- a/src/main/java/edu/ntnu/idatt2003/controller/ExceptionHandler.java +++ b/src/main/java/edu/ntnu/idatt2003/controller/ExceptionHandler.java @@ -18,4 +18,19 @@ public class ExceptionHandler { alert.showAndWait(); } + public void showAlertIntegerBelowOne(String input) { + Alert alert = new Alert(Alert.AlertType.ERROR); + alert.setTitle("Error"); + alert.setHeaderText("An error occurred"); + alert.setContentText("The input '" + input + "' is invalid. Please enter an integer above 1."); + alert.showAndWait(); + } + + public void validatePostiviteInteger(int number) { + if (number < 1) { + throw new IllegalArgumentException("The number must be greater than 0."); + } + } + + } diff --git a/src/main/java/edu/ntnu/idatt2003/controller/LabelObserver.java b/src/main/java/edu/ntnu/idatt2003/controller/LabelObserver.java index 40ef587..f6e0945 100644 --- a/src/main/java/edu/ntnu/idatt2003/controller/LabelObserver.java +++ b/src/main/java/edu/ntnu/idatt2003/controller/LabelObserver.java @@ -65,7 +65,9 @@ public class LabelObserver implements Observer { if (!input1.isEmpty()) { try { int inputIterations = Integer.parseInt(input1); - iterations += inputIterations; + if (inputIterations >= 1) { + iterations += inputIterations; + } } catch (NumberFormatException ex) { System.out.println("Invalid input. Please enter an integer."); } @@ -78,7 +80,9 @@ public class LabelObserver implements Observer { if (!input.isEmpty()) { try { int inputIterations = Integer.parseInt(input); - iterations += inputIterations; + if (inputIterations >= 1) { + iterations += inputIterations; + } } catch (NumberFormatException ex) { System.out.println("Invalid input. Please enter an integer."); } diff --git a/src/main/java/edu/ntnu/idatt2003/controller/TextFieldObserver.java b/src/main/java/edu/ntnu/idatt2003/controller/TextFieldObserver.java index 0c6e989..474fe8f 100644 --- a/src/main/java/edu/ntnu/idatt2003/controller/TextFieldObserver.java +++ b/src/main/java/edu/ntnu/idatt2003/controller/TextFieldObserver.java @@ -48,9 +48,12 @@ public class TextFieldObserver implements Observer { String input = textFields.addIterationInput.getText(); try { int iterations = Integer.parseInt(input); + exceptionHandler.validatePostiviteInteger(iterations); fractalOperations.addIterations(iterations); } catch (NumberFormatException ex) { exceptionHandler.showAlertIntegerInvalid(input); + } catch (IllegalArgumentException ex) { + exceptionHandler.showAlertIntegerBelowOne(input); } textFields.addIterationInput.clear(); } -- GitLab From a486c3b0d3d7d6b185b21a2585c3d6d8393077da Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Mon, 20 May 2024 18:11:45 +0200 Subject: [PATCH 146/168] Added update all button --- .../edu/ntnu/idatt2003/view/components/Buttons.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/main/java/edu/ntnu/idatt2003/view/components/Buttons.java b/src/main/java/edu/ntnu/idatt2003/view/components/Buttons.java index abd15b6..51f8283 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/components/Buttons.java +++ b/src/main/java/edu/ntnu/idatt2003/view/components/Buttons.java @@ -20,6 +20,8 @@ public class Buttons extends Subject { private Button btnSaveFractalToFile; private Button btnExitApplication; + private Button btnUpdateAll; + /** * Constructs a Buttons object. */ @@ -78,6 +80,12 @@ public class Buttons extends Subject { System.out.println("Save Fractal To File"); notifyObservers("btnSaveFractalToFile"); }); + + btnUpdateAll = new Button("Update All"); + btnUpdateAll.setOnAction(e -> { + System.out.println("Update All"); + notifyObservers("btnUpdateAll"); + }); } public Button getBtnAdd10() { @@ -110,5 +118,9 @@ public class Buttons extends Subject { public Button getBtnSaveFractalToFile() { return btnSaveFractalToFile; } + + public Button getBtnUpdateAll() { + return btnUpdateAll; + } } -- GitLab From ace54c18113540ad0b7417e705dd23e20f8f25fa Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Mon, 20 May 2024 18:12:32 +0200 Subject: [PATCH 147/168] Refactor. All input fields gets added to inputBox --- .../edu/ntnu/idatt2003/view/scenes/Scene.java | 112 ++++++++++-------- 1 file changed, 64 insertions(+), 48 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/view/scenes/Scene.java b/src/main/java/edu/ntnu/idatt2003/view/scenes/Scene.java index 08ee49f..bed5371 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/scenes/Scene.java +++ b/src/main/java/edu/ntnu/idatt2003/view/scenes/Scene.java @@ -35,6 +35,7 @@ public class Scene { private TextFields textFields; private FractalOperations fractalOperations; private VBox cBox; // Container for the C input fields + private VBox inputBox; // Container for all input fields private VBox matrixVectorBox; // Container for the matrix and vector input fields private HBox topBox; private ButtonObserver buttonObserver; @@ -58,19 +59,20 @@ public class Scene { textFieldObserver = new TextFieldObserver(fractalOperations, textFields); fractalOperations.resetIterations(); fractalOperations.addIterations(0); + createMaxMinVectorInput(); // Add listener to ComboBox to handle dynamic addition of C input fields comboBoxes.getComboBoxFractal().getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> { if ("Julia Set".equals(newValue)) { - addCInputBox(); removeMatrixVectorInputBoxes(); removeFractalFromFileBox(); addSaveFractalToFileButton(); + addCInputBox(); } else if ("Sierpinski Triangle".equals(newValue)) { removeMatrixVectorInputBoxes(); removeCInputBox(); - addMatrixVectorInputBoxes(); removeFractalFromFileBox(); + addMatrixVectorInputBoxes(); addSaveFractalToFileButton(); } else if ( "Barnsley Fern".equals(newValue)) { removeMatrixVectorInputBoxes(); @@ -123,21 +125,13 @@ public class Scene { // Initialize Labels iterationsLabel = labels.getIterationLabel(); + MaxLabel = labels.geMaxLabel(); MinLabel = labels.getMinLabel(); // Initialize TextFields TextField addIterationInput = textFields.getAddIterationInput(); - TextField xMinInput = textFields.getxMinInput(); - TextField yMinInput = textFields.getyMinInput(); - TextField xMaxInput = textFields.getxMaxInput(); - TextField yMaxInput = textFields.getyMaxInput(); - // Ensure style classes are added to these text fields - xMinInput.getStyleClass().add("MaxMinInput"); - yMinInput.getStyleClass().add("MaxMinInput"); - xMaxInput.getStyleClass().add("MaxMinInput"); - yMaxInput.getStyleClass().add("MaxMinInput"); // Set the style of the labels iterationsLabel.getStyleClass().add("iterationLabel"); @@ -154,29 +148,6 @@ public class Scene { topBox.getChildren().addAll(comboBoxFractal, comboBoxColor); topBox.setPadding(new Insets(10, 10, 10, 10)); - HBox MinBox = new HBox(5); - HBox MaxBox = new HBox(5); - MinBox.getChildren().addAll(xMinInput, yMinInput); - MaxBox.getChildren().addAll(xMaxInput, yMaxInput); - - Button updateMinMaxButton = new Button("Update Min and Max vector"); - - VBox MinMaxAll = new VBox(5); - MinMaxAll.getChildren().addAll(MaxLabel, MaxBox, MinLabel, MinBox, updateMinMaxButton); - - updateMinMaxButton.setOnAction(event -> { - try { - fractalOperations.resetIterations(); - double xMin = Double.parseDouble(xMinInput.getText()); - double yMin = Double.parseDouble(yMinInput.getText()); - double xMax = Double.parseDouble(xMaxInput.getText()); - double yMax = Double.parseDouble(yMaxInput.getText()); - updateMinAndMax(new Vector2D(xMin, yMin), new Vector2D(xMax, yMax)); - } catch (NumberFormatException e) { - System.out.println("Invalid input for min or max values."); - } - }); - // Initialize the ChaosCanvas and the WritableImage chaosCanvas = new ChaosCanvas(600, 400, new Vector2D(0, 0), new Vector2D(600, 400)); writableImage = new WritableImage(600, 400); @@ -189,8 +160,10 @@ public class Scene { imageView.fitWidthProperty().bind(imagePane.widthProperty()); imageView.setPreserveRatio(true); + inputBox = new VBox(0); + // Add components to the root AnchorPane - root.getChildren().addAll(topBox, imagePane, bottomBox, btnExitApplication, MinMaxAll); + root.getChildren().addAll(topBox, imagePane, bottomBox, btnExitApplication, inputBox); // Anchor the topBox to the top of the pane AnchorPane.setTopAnchor(topBox, 10.0); @@ -213,26 +186,25 @@ public class Scene { AnchorPane.setRightAnchor(btnExitApplication, 10.0); // Anchor the MinMaxBox to the top right corner - AnchorPane.setTopAnchor(MinMaxAll, 65.0); - AnchorPane.setRightAnchor(MinMaxAll, 30.0); + AnchorPane.setTopAnchor(inputBox, 65.0); + AnchorPane.setRightAnchor(inputBox, 30.0); // Create a scene with the root and set the CSS style scene = new javafx.scene.Scene(root, 1400, 830); scene.getStylesheets().add(getClass().getResource("/style.css").toExternalForm()); + } private void addCInputBox() { if (cBox == null) { cBox = createCInputBox(); - AnchorPane.setTopAnchor(cBox, 250.0); - AnchorPane.setRightAnchor(cBox, 60.0); - ((AnchorPane) scene.getRoot()).getChildren().add(cBox); + inputBox.getChildren().add(cBox); } } private void removeCInputBox() { if (cBox != null) { - ((AnchorPane) scene.getRoot()).getChildren().remove(cBox); + inputBox.getChildren().remove(cBox); cBox = null; } } @@ -284,7 +256,7 @@ public class Scene { } private HBox createMatrixVectorInputBox(AffineTransform2D transform) { - HBox matrixVectorBox = new HBox(5); + HBox matrixVectorBox = new HBox(15); matrixVectorBox.setPadding(new Insets(5)); VBox matrixBox = new VBox(5); @@ -343,7 +315,7 @@ public class Scene { matrixVectorBox = new VBox(5); matrixVectorBox.setPadding(new Insets(5)); VBox inputContainer = new VBox(5); - inputContainer.setPadding(new Insets(5)); + inputContainer.setPadding(new Insets(0)); Button addMoreButton = new Button("Add More"); addMoreButton.setOnAction(event -> { @@ -363,10 +335,8 @@ public class Scene { }); resetToDefaultFractal(inputContainer, addMoreButton, updateMatrixVectorButton, resetToDefaultButton); - AnchorPane.setTopAnchor(inputContainer, 230.0); - AnchorPane.setRightAnchor(inputContainer, 30.0); - ((AnchorPane) scene.getRoot()).getChildren().add(inputContainer); - matrixVectorBox = inputContainer; + matrixVectorBox.getChildren().add(inputContainer); + inputBox.getChildren().add(matrixVectorBox); } } @@ -386,7 +356,7 @@ public class Scene { private void removeMatrixVectorInputBoxes() { if (matrixVectorBox != null) { - ((AnchorPane) scene.getRoot()).getChildren().remove(matrixVectorBox); + inputBox.getChildren().remove(matrixVectorBox); matrixVectorBox = null; } } @@ -480,6 +450,52 @@ public class Scene { } } + public void createMaxMinVectorInput(){ + TextField xMinInput = textFields.getxMinInput(); + TextField yMinInput = textFields.getyMinInput(); + TextField xMaxInput = textFields.getxMaxInput(); + TextField yMaxInput = textFields.getyMaxInput(); + + // Ensure style classes are added to these text fields + xMinInput.getStyleClass().add("MaxMinInput"); + yMinInput.getStyleClass().add("MaxMinInput"); + xMaxInput.getStyleClass().add("MaxMinInput"); + yMaxInput.getStyleClass().add("MaxMinInput"); + + Vector2D minCoords = fractalOperations.getChaosGame().getDescription().getMinCoords(); + Vector2D maxCoords = fractalOperations.getChaosGame().getDescription().getMaxCoords(); + + xMinInput.setText(String.valueOf(minCoords.getX0())); + yMinInput.setText(String.valueOf(minCoords.getX1())); + xMaxInput.setText(String.valueOf(maxCoords.getX0())); + yMaxInput.setText(String.valueOf(maxCoords.getX1())); + + HBox MinBox = new HBox(5); + HBox MaxBox = new HBox(5); + MinBox.getChildren().addAll(xMinInput, yMinInput); + MaxBox.getChildren().addAll(xMaxInput, yMaxInput); + + Button updateMinMaxButton = new Button("Update Min and Max vector"); + + VBox MinMaxAll = new VBox(5); + MinMaxAll.getChildren().addAll(MaxLabel, MaxBox, MinLabel, MinBox, updateMinMaxButton); + + updateMinMaxButton.setOnAction(event -> { + try { + fractalOperations.resetIterations(); + double xMin = Double.parseDouble(xMinInput.getText()); + double yMin = Double.parseDouble(yMinInput.getText()); + double xMax = Double.parseDouble(xMaxInput.getText()); + double yMax = Double.parseDouble(yMaxInput.getText()); + updateMinAndMax(new Vector2D(xMin, yMin), new Vector2D(xMax, yMax)); + } catch (NumberFormatException e) { + System.out.println("Invalid input for min or max values."); + } + }); + + inputBox.getChildren().add(MinMaxAll); + } + public void setUpStage(Stage primaryStage) { primaryStage.setTitle("ChaosGame"); primaryStage.setScene(scene); -- GitLab From 605eed9b24193519c5ea531daa4f574fbdca062c Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Mon, 20 May 2024 18:29:50 +0200 Subject: [PATCH 148/168] addIterations removed --- .../ntnu/idatt2003/controller/ButtonObserver.java | 8 ++++---- .../idatt2003/controller/TextFieldObserver.java | 2 +- .../view/components/FractalOperations.java | 13 ------------- .../java/edu/ntnu/idatt2003/view/scenes/Scene.java | 2 -- 4 files changed, 5 insertions(+), 20 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java b/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java index 720ca3f..6194986 100644 --- a/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java +++ b/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java @@ -50,15 +50,15 @@ public class ButtonObserver implements Observer{ public void update(String button) { switch (button) { case "btnAdd10": - fractalOperations.addIterations(10); + fractalOperations.drawFractal(10); break; case "btnAdd100": - fractalOperations.addIterations(100); + fractalOperations.drawFractal(100); break; case "btnAdd1000": - fractalOperations.addIterations(1000); + fractalOperations.drawFractal(1000); break; case "btnReset": @@ -71,7 +71,7 @@ public class ButtonObserver implements Observer{ try { int iterations = Integer.parseInt(input); exceptionHandler.validatePostiviteInteger(iterations); - fractalOperations.addIterations(iterations); + fractalOperations.drawFractal(iterations); } catch (NumberFormatException ex) { exceptionHandler.showAlertIntegerInvalid(input); } catch (IllegalArgumentException ex) { diff --git a/src/main/java/edu/ntnu/idatt2003/controller/TextFieldObserver.java b/src/main/java/edu/ntnu/idatt2003/controller/TextFieldObserver.java index 474fe8f..5f82e99 100644 --- a/src/main/java/edu/ntnu/idatt2003/controller/TextFieldObserver.java +++ b/src/main/java/edu/ntnu/idatt2003/controller/TextFieldObserver.java @@ -49,7 +49,7 @@ public class TextFieldObserver implements Observer { try { int iterations = Integer.parseInt(input); exceptionHandler.validatePostiviteInteger(iterations); - fractalOperations.addIterations(iterations); + fractalOperations.drawFractal(iterations); } catch (NumberFormatException ex) { exceptionHandler.showAlertIntegerInvalid(input); } catch (IllegalArgumentException ex) { diff --git a/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java b/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java index 0f2e8f7..8403235 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java +++ b/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java @@ -16,8 +16,6 @@ import static edu.ntnu.idatt2003.model.ChaosGameDescriptionFactory.createJuliaSe */ public class FractalOperations { private ChaosGame chaosGame; - private int iterations; - private Label iterationsLabel; private WritableImage writableImage; private ImageView imageView; private String currentFractal; @@ -40,7 +38,6 @@ public class FractalOperations { } else if ("Barnsley Fern".equals(initialFractal)) { setFractalToBransleysFern(); } - resetIterations(); } public void drawFractal(int iterations) { @@ -48,10 +45,6 @@ public class FractalOperations { updateImage(); } - public void addIterations(int iterations) { - drawFractal(iterations); - } - public void resetIterations() { chaosGame.getCanvas().clear(); drawFractal(0); @@ -78,7 +71,6 @@ public class FractalOperations { public void setFractalToSierpinskiTriangle() { this.chaosGame = new ChaosGame(ChaosGameDescriptionFactory.createSierpinskiTriangle(), 400, 400); - iterations = 0; drawFractal(0); } @@ -90,7 +82,6 @@ public class FractalOperations { int defaultInt = -1; this.chaosGame = new ChaosGame(ChaosGameDescriptionFactory.createJuliaSet(defaultComplex, defaultInt), 400, 400); - iterations = 0; drawFractal(0); } @@ -99,7 +90,6 @@ public class FractalOperations { */ public void setFractalToBransleysFern() { this.chaosGame = new ChaosGame(ChaosGameDescriptionFactory.createBarnsleyFern(), 400, 400); - iterations = 0; drawFractal(0); } @@ -113,7 +103,6 @@ public class FractalOperations { try { ChaosGameDescription description = fileHandler.readFile(); this.chaosGame = new ChaosGame(description, 400, 400); - iterations = 0; drawFractal(0); } catch (IOException e) { e.printStackTrace(); @@ -131,7 +120,6 @@ public class FractalOperations { ChaosGameDescription description = new ChaosGameDescription(Arrays.asList(defaultTransforms), defaultLowerLeft, defaultUpperRight); this.chaosGame = new ChaosGame(description, 400, 400); - iterations = 0; drawFractal(0); } @@ -151,7 +139,6 @@ public class FractalOperations { */ public void updateMatrixAndVector(ChaosGameDescription description) { this.chaosGame = new ChaosGame(description, 400, 400); - iterations = 0; drawFractal(0); } diff --git a/src/main/java/edu/ntnu/idatt2003/view/scenes/Scene.java b/src/main/java/edu/ntnu/idatt2003/view/scenes/Scene.java index bed5371..10cd4d3 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/scenes/Scene.java +++ b/src/main/java/edu/ntnu/idatt2003/view/scenes/Scene.java @@ -57,8 +57,6 @@ public class Scene { comboBoxObserver = new ComboBoxObserver(comboBoxes, fractalOperations); labelObserver = new LabelObserver(buttons, comboBoxes, textFields, iterationsLabel); textFieldObserver = new TextFieldObserver(fractalOperations, textFields); - fractalOperations.resetIterations(); - fractalOperations.addIterations(0); createMaxMinVectorInput(); // Add listener to ComboBox to handle dynamic addition of C input fields -- GitLab From fa963ebbc52200c971631b3431acea3d4953f238 Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Mon, 20 May 2024 19:49:47 +0200 Subject: [PATCH 149/168] ChaosGameObserver runSteps --- .../controller/ChaosGameObserver.java | 7 +++ .../edu/ntnu/idatt2003/model/ChaosGame.java | 21 +++++++ .../view/components/FractalOperations.java | 61 +++++++++++++------ .../edu/ntnu/idatt2003/view/scenes/Scene.java | 4 +- 4 files changed, 74 insertions(+), 19 deletions(-) create mode 100644 src/main/java/edu/ntnu/idatt2003/controller/ChaosGameObserver.java diff --git a/src/main/java/edu/ntnu/idatt2003/controller/ChaosGameObserver.java b/src/main/java/edu/ntnu/idatt2003/controller/ChaosGameObserver.java new file mode 100644 index 0000000..edef5cb --- /dev/null +++ b/src/main/java/edu/ntnu/idatt2003/controller/ChaosGameObserver.java @@ -0,0 +1,7 @@ +package edu.ntnu.idatt2003.controller; + +import edu.ntnu.idatt2003.model.ChaosGame; + +public interface ChaosGameObserver { + void update(ChaosGame chaosGame); +} diff --git a/src/main/java/edu/ntnu/idatt2003/model/ChaosGame.java b/src/main/java/edu/ntnu/idatt2003/model/ChaosGame.java index e322cae..8be6530 100644 --- a/src/main/java/edu/ntnu/idatt2003/model/ChaosGame.java +++ b/src/main/java/edu/ntnu/idatt2003/model/ChaosGame.java @@ -1,5 +1,9 @@ package edu.ntnu.idatt2003.model; +import edu.ntnu.idatt2003.controller.ChaosGameObserver; + +import java.util.ArrayList; +import java.util.List; import java.util.Random; /** @@ -10,6 +14,7 @@ public class ChaosGame { private final ChaosGameDescription description; private Vector2D currentPoint; private final Random random; + private final List<ChaosGameObserver> observers; /** * Constructs a ChaosGame with the given ChaosGameDescription, width and height. @@ -24,6 +29,7 @@ public class ChaosGame { description.getMaxCoords()); this.currentPoint = new Vector2D(0, 0); this.random = new Random(); + this.observers = new ArrayList<>(); } /** @@ -51,6 +57,7 @@ public class ChaosGame { currentPoint = transform.transform(currentPoint); canvas.putPixel(currentPoint); // currentPoint is of type Vector2D } + notifyObservers(); } public ChaosGameDescription getDescription() { @@ -60,4 +67,18 @@ public class ChaosGame { public ChaosGameDescription getChaosGameDescription() { return description; } + + public void addObserver(ChaosGameObserver observer) { + observers.add(observer); + } + + public void removeObserer(ChaosGameObserver observer) { + observers.remove(observer); + } + + private void notifyObservers() { + for (ChaosGameObserver observer : observers) { + observer.update(this); + } + } } diff --git a/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java b/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java index 8403235..1071905 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java +++ b/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java @@ -1,9 +1,9 @@ package edu.ntnu.idatt2003.view.components; +import edu.ntnu.idatt2003.controller.ChaosGameObserver; import edu.ntnu.idatt2003.model.*; import java.io.IOException; import java.util.Arrays; -import javafx.scene.control.Label; import javafx.scene.image.ImageView; import javafx.scene.image.PixelWriter; import javafx.scene.image.WritableImage; @@ -14,7 +14,7 @@ import static edu.ntnu.idatt2003.model.ChaosGameDescriptionFactory.createJuliaSe /** * This class is responsible for performing operations on the fractals. */ -public class FractalOperations { +public class FractalOperations implements ChaosGameObserver { private ChaosGame chaosGame; private WritableImage writableImage; private ImageView imageView; @@ -31,12 +31,24 @@ public class FractalOperations { this.currentFractal = initialFractal; this.writableImage = new WritableImage(400, 400); this.imageView.setImage(writableImage); - if ("Sierpinski Triangle".equals(initialFractal)) { - setFractalToSierpinskiTriangle(); - } else if ("Julia Set".equals(initialFractal)) { - setFractalToJuliaSet(); - } else if ("Barnsley Fern".equals(initialFractal)) { - setFractalToBransleysFern(); + setFractal(initialFractal); + resetIterations(); + } + + private void setFractal(String initialFractal) { + switch (initialFractal) { + case "Sierpinski Triangle": + setFractalToSierpinskiTriangle(); + break; + case "Julia Set": + setFractalToJuliaSet(); + break; + case "Barnsley Fern": + setFractalToBransleysFern(); + break; + default: + setBlankImageView(); + break; } } @@ -47,6 +59,7 @@ public class FractalOperations { public void resetIterations() { chaosGame.getCanvas().clear(); + this.chaosGame.addObserver(this); drawFractal(0); } @@ -71,6 +84,7 @@ public class FractalOperations { public void setFractalToSierpinskiTriangle() { this.chaosGame = new ChaosGame(ChaosGameDescriptionFactory.createSierpinskiTriangle(), 400, 400); + this.chaosGame.addObserver(this); drawFractal(0); } @@ -78,10 +92,9 @@ public class FractalOperations { * Sets the fractal to Julia Set. */ public void setFractalToJuliaSet() { - Complex defaultComplex = new Complex(-0.74543, 0.11301); - int defaultInt = -1; - this.chaosGame = new ChaosGame(ChaosGameDescriptionFactory.createJuliaSet(defaultComplex, - defaultInt), 400, 400); + this.chaosGame = new ChaosGame(ChaosGameDescriptionFactory.createJuliaSet(new Complex(-0.74543, 0.11301), + 1), 400, 400); + this.chaosGame.addObserver(this); drawFractal(0); } @@ -90,7 +103,8 @@ public class FractalOperations { */ public void setFractalToBransleysFern() { this.chaosGame = new ChaosGame(ChaosGameDescriptionFactory.createBarnsleyFern(), 400, 400); - drawFractal(0); + this.chaosGame.addObserver(this); + //drawFractal(0); } /** @@ -103,7 +117,8 @@ public class FractalOperations { try { ChaosGameDescription description = fileHandler.readFile(); this.chaosGame = new ChaosGame(description, 400, 400); - drawFractal(0); + this.chaosGame.addObserver(this); + //drawFractal(0); } catch (IOException e) { e.printStackTrace(); } @@ -120,7 +135,8 @@ public class FractalOperations { ChaosGameDescription description = new ChaosGameDescription(Arrays.asList(defaultTransforms), defaultLowerLeft, defaultUpperRight); this.chaosGame = new ChaosGame(description, 400, 400); - drawFractal(0); + this.chaosGame.addObserver(this); + //drawFractal(0); } /** @@ -130,6 +146,7 @@ public class FractalOperations { */ public void updateC(Complex complex) { this.chaosGame = new ChaosGame(createJuliaSet(complex, -1), 400, 400); + this.chaosGame.addObserver(this); } /** @@ -139,7 +156,8 @@ public class FractalOperations { */ public void updateMatrixAndVector(ChaosGameDescription description) { this.chaosGame = new ChaosGame(description, 400, 400); - drawFractal(0); + this.chaosGame.addObserver(this); + //drawFractal(0); } @@ -175,14 +193,23 @@ public class FractalOperations { ChaosGameDescription newChaosGame = new ChaosGameDescription( chaosGame.getChaosGameDescription().getTransforms(), minCoords, maxCoords); this.chaosGame = new ChaosGame(newChaosGame, 400, 400); + this.chaosGame.addObserver(this); } public void saveFractalToFile(String path) { -ChaosGameFileHandler fileHandler = new ChaosGameFileHandler(path); + ChaosGameFileHandler fileHandler = new ChaosGameFileHandler(path); try { fileHandler.writeToFile(path, chaosGame.getChaosGameDescription()); } catch (IOException e) { e.printStackTrace(); } } + + public ChaosGameDescription getDescription() { + return chaosGame.getDescription(); + } + @Override + public void update(ChaosGame chaosGame) { + updateImage(); + } } diff --git a/src/main/java/edu/ntnu/idatt2003/view/scenes/Scene.java b/src/main/java/edu/ntnu/idatt2003/view/scenes/Scene.java index 10cd4d3..c6efe6d 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/scenes/Scene.java +++ b/src/main/java/edu/ntnu/idatt2003/view/scenes/Scene.java @@ -428,11 +428,11 @@ public class Scene { inputContainer.getChildren().clear(); if ("Barnsley Fern".equals(comboBoxes.getComboBoxFractal().getValue())) { fractalOperations.setFractalToBransleysFern(); - AffineTransform2D[] transforms = fractalOperations.getChaosGame().getDescription().getTransforms().toArray(new AffineTransform2D[0]); + AffineTransform2D[] transforms = fractalOperations.getDescription().getTransforms().toArray(new AffineTransform2D[0]); inputContainer.getChildren().addAll(createMatrixVectorInputBox(transforms[0]), createMatrixVectorInputBox(transforms[1]), createMatrixVectorInputBox(transforms[2]), createMatrixVectorInputBox(transforms[3]), addMoreButton, updateMatrixVectorButton, resetToDefaultButton); } else if ("Sierpinski Triangle".equals(comboBoxes.getComboBoxFractal().getValue())) { fractalOperations.setFractalToSierpinskiTriangle(); - AffineTransform2D[] transforms = fractalOperations.getChaosGame().getDescription().getTransforms().toArray(new AffineTransform2D[0]); + AffineTransform2D[] transforms = fractalOperations.getDescription().getTransforms().toArray(new AffineTransform2D[0]); inputContainer.getChildren().addAll(createMatrixVectorInputBox(transforms[0]), createMatrixVectorInputBox(transforms[1]), createMatrixVectorInputBox(transforms[2]), addMoreButton, updateMatrixVectorButton, resetToDefaultButton); } } -- GitLab From def34858ba4caa2855b10aec1ba6f33ac3565b9e Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Tue, 21 May 2024 10:43:19 +0200 Subject: [PATCH 150/168] Add first on inputfields --- src/main/java/edu/ntnu/idatt2003/view/scenes/Scene.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/view/scenes/Scene.java b/src/main/java/edu/ntnu/idatt2003/view/scenes/Scene.java index c6efe6d..72e22f0 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/scenes/Scene.java +++ b/src/main/java/edu/ntnu/idatt2003/view/scenes/Scene.java @@ -57,7 +57,6 @@ public class Scene { comboBoxObserver = new ComboBoxObserver(comboBoxes, fractalOperations); labelObserver = new LabelObserver(buttons, comboBoxes, textFields, iterationsLabel); textFieldObserver = new TextFieldObserver(fractalOperations, textFields); - createMaxMinVectorInput(); // Add listener to ComboBox to handle dynamic addition of C input fields comboBoxes.getComboBoxFractal().getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> { @@ -96,6 +95,8 @@ public class Scene { } else if ("Fractal From File".equals(fractalType)) { addFractalFromFileBox(); } + + createMaxMinVectorInput(); } private void initializeComponents() { @@ -196,7 +197,7 @@ public class Scene { private void addCInputBox() { if (cBox == null) { cBox = createCInputBox(); - inputBox.getChildren().add(cBox); + inputBox.getChildren().addFirst(cBox); } } @@ -334,7 +335,7 @@ public class Scene { resetToDefaultFractal(inputContainer, addMoreButton, updateMatrixVectorButton, resetToDefaultButton); matrixVectorBox.getChildren().add(inputContainer); - inputBox.getChildren().add(matrixVectorBox); + inputBox.getChildren().addFirst(matrixVectorBox); } } -- GitLab From 7d534b49dcf9e98d19ffcd05e3f0f71431c3d189 Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Tue, 21 May 2024 13:17:40 +0200 Subject: [PATCH 151/168] Refactor --- .../idatt2003/controller/ButtonObserver.java | 2 + .../idatt2003/view/components/Buttons.java | 3 +- .../view/components/FractalOperations.java | 2 +- .../edu/ntnu/idatt2003/view/scenes/Scene.java | 179 ++++++++++-------- 4 files changed, 107 insertions(+), 79 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java b/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java index 6194986..43c0663 100644 --- a/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java +++ b/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java @@ -109,6 +109,8 @@ public class ButtonObserver implements Observer{ } break; + case "btnUpdateAll": + default: break; } diff --git a/src/main/java/edu/ntnu/idatt2003/view/components/Buttons.java b/src/main/java/edu/ntnu/idatt2003/view/components/Buttons.java index 51f8283..014158a 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/components/Buttons.java +++ b/src/main/java/edu/ntnu/idatt2003/view/components/Buttons.java @@ -19,7 +19,6 @@ public class Buttons extends Subject { private Button btnAddFractalFromFile; private Button btnSaveFractalToFile; private Button btnExitApplication; - private Button btnUpdateAll; /** @@ -81,7 +80,7 @@ public class Buttons extends Subject { notifyObservers("btnSaveFractalToFile"); }); - btnUpdateAll = new Button("Update All"); + btnUpdateAll = new Button("Update all values"); btnUpdateAll.setOnAction(e -> { System.out.println("Update All"); notifyObservers("btnUpdateAll"); diff --git a/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java b/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java index 1071905..8454673 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java +++ b/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java @@ -54,7 +54,7 @@ public class FractalOperations implements ChaosGameObserver { public void drawFractal(int iterations) { chaosGame.runSteps(iterations); - updateImage(); + //updateImage(); } public void resetIterations() { diff --git a/src/main/java/edu/ntnu/idatt2003/view/scenes/Scene.java b/src/main/java/edu/ntnu/idatt2003/view/scenes/Scene.java index 72e22f0..9a72d21 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/scenes/Scene.java +++ b/src/main/java/edu/ntnu/idatt2003/view/scenes/Scene.java @@ -1,7 +1,6 @@ package edu.ntnu.idatt2003.view.scenes; import edu.ntnu.idatt2003.controller.*; -import edu.ntnu.idatt2003.controller.LabelObserver; import edu.ntnu.idatt2003.model.*; import edu.ntnu.idatt2003.view.components.*; import javafx.geometry.Insets; @@ -33,11 +32,20 @@ public class Scene { private ComboBoxes comboBoxes; private Labels labels; private TextFields textFields; + + private TextField xMinInput; + private TextField yMinInput; + private TextField xMaxInput; + private TextField yMaxInput; private FractalOperations fractalOperations; private VBox cBox; // Container for the C input fields private VBox inputBox; // Container for all input fields private VBox matrixVectorBox; // Container for the matrix and vector input fields private HBox topBox; + private VBox inputContainer; + + private TextField realPartInput; + private TextField imaginaryPartInput; private ButtonObserver buttonObserver; private ComboBoxObserver comboBoxObserver; private LabelObserver labelObserver; @@ -65,23 +73,26 @@ public class Scene { removeFractalFromFileBox(); addSaveFractalToFileButton(); addCInputBox(); + updateVectorInputFields(); } else if ("Sierpinski Triangle".equals(newValue)) { removeMatrixVectorInputBoxes(); removeCInputBox(); removeFractalFromFileBox(); addMatrixVectorInputBoxes(); addSaveFractalToFileButton(); - } else if ( "Barnsley Fern".equals(newValue)) { + updateVectorInputFields(); + } else if ("Barnsley Fern".equals(newValue)) { removeMatrixVectorInputBoxes(); removeCInputBox(); removeFractalFromFileBox(); addMatrixVectorInputBoxes(); addSaveFractalToFileButton(); - } - else if ("Fractal From File".equals(newValue)) { + updateVectorInputFields(); + } else if ("Fractal From File".equals(newValue)) { removeCInputBox(); removeMatrixVectorInputBoxes(); addFractalFromFileBox(); + updateVectorInputFields(); } }); @@ -96,7 +107,7 @@ public class Scene { addFractalFromFileBox(); } - createMaxMinVectorInput(); + createMaxMinVectorInputAndUpdateAll(); } private void initializeComponents() { @@ -131,7 +142,6 @@ public class Scene { // Initialize TextFields TextField addIterationInput = textFields.getAddIterationInput(); - // Set the style of the labels iterationsLabel.getStyleClass().add("iterationLabel"); addIterationInput.getStyleClass().add("addIterationInput"); @@ -191,7 +201,6 @@ public class Scene { // Create a scene with the root and set the CSS style scene = new javafx.scene.Scene(root, 1400, 830); scene.getStylesheets().add(getClass().getResource("/style.css").toExternalForm()); - } private void addCInputBox() { @@ -209,14 +218,12 @@ public class Scene { } private VBox createCInputBox() { - Label cLabel = new Label("Update constant C"); - // Initialize the update C button Button updateCButton = new Button("Update C"); Button resetToDefaultButton = new Button("Reset to Default fractal"); - // Initialize TextFields - TextField realPartInput = new TextField(); - TextField imaginaryPartInput = new TextField(); + + realPartInput = new TextField(); + imaginaryPartInput = new TextField(); realPartInput.getStyleClass().add("cInput"); imaginaryPartInput.getStyleClass().add("cInput"); @@ -224,6 +231,11 @@ public class Scene { realPartInput.setPromptText("Real part of C"); imaginaryPartInput.setPromptText("Imaginary part of C"); + JuliaTransform julia = (JuliaTransform) fractalOperations.getChaosGame().getDescription().getTransforms().getFirst(); + + realPartInput.setText(String.valueOf(julia.getPoint().getReal())); + imaginaryPartInput.setText(String.valueOf(julia.getPoint().getImaginary())); + VBox cBox = new VBox(5); cBox.getChildren().addAll(cLabel, realPartInput, imaginaryPartInput, updateCButton, resetToDefaultButton); cBox.setPadding(new Insets(0, 0, 0, 0)); @@ -242,13 +254,13 @@ public class Scene { Vector2D upperRight = new Vector2D(xMax, yMax); fractalOperations.updateMinAndMaxFractal(lowerLeft, upperRight); } catch (NumberFormatException e) { - // Handle invalid input System.out.println("Invalid input for real or imaginary part of C."); } }); resetToDefaultButton.setOnAction(event -> { fractalOperations.setFractalToJuliaSet(); + updateVectorInputFields(); }); return cBox; @@ -302,9 +314,7 @@ public class Scene { lowerMatrixRow.getChildren().addAll(matrixInput3, matrixInput4); matrixBox.getChildren().addAll(upperMatrixRow, lowerMatrixRow); - vectorBox.getChildren().addAll(vectorInput1, vectorInput2); - matrixVectorBox.getChildren().addAll(matrixBox, vectorBox); return matrixVectorBox; } @@ -313,29 +323,25 @@ public class Scene { if (matrixVectorBox == null) { matrixVectorBox = new VBox(5); matrixVectorBox.setPadding(new Insets(5)); - VBox inputContainer = new VBox(5); + inputContainer = new VBox(5); inputContainer.setPadding(new Insets(0)); Button addMoreButton = new Button("Add More"); addMoreButton.setOnAction(event -> { - HBox newInputBox = createMatrixVectorInputBox(new AffineTransform2D(new Matrix2x2(0,0,0,0), new Vector2D(0,0))); + HBox newInputBox = createMatrixVectorInputBox(new AffineTransform2D(new Matrix2x2(0, 0, 0, 0), new Vector2D(0, 0))); inputContainer.getChildren().add(0, newInputBox); }); - Button updateMatrixVectorButton = new Button("Update Matrix and Vector"); - updateMatrixVectorButton.setOnAction(event -> { - // Handle updating the matrix and vector - updateAffineTransforms(inputContainer); - }); - Button resetToDefaultButton = new Button("Reset to Default fractal"); resetToDefaultButton.setOnAction(event -> { - resetToDefaultFractal(inputContainer, addMoreButton, updateMatrixVectorButton, resetToDefaultButton); + resetToDefaultFractal(inputContainer, addMoreButton, resetToDefaultButton); + updateVectorInputFields(); }); - resetToDefaultFractal(inputContainer, addMoreButton, updateMatrixVectorButton, resetToDefaultButton); + resetToDefaultFractal(inputContainer, addMoreButton, resetToDefaultButton); matrixVectorBox.getChildren().add(inputContainer); inputBox.getChildren().addFirst(matrixVectorBox); + } } @@ -362,35 +368,33 @@ public class Scene { private void updateAffineTransforms(VBox inputContainer) { List<AffineTransform2D> transforms = new ArrayList<>(); - for (int i = 0; i < inputContainer.getChildren().size() - 3; i++) { // exclude the last three buttons - HBox matrixVectorBox = (HBox) inputContainer.getChildren().get(i); - VBox matrixBox = (VBox) matrixVectorBox.getChildren().get(0); - VBox vectorBox = (VBox) matrixVectorBox.getChildren().get(1); - - HBox upperMatrixRow = (HBox) matrixBox.getChildren().get(1); - HBox lowerMatrixRow = (HBox) matrixBox.getChildren().get(2); - - TextField matrixInput1 = (TextField) upperMatrixRow.getChildren().get(0); - TextField matrixInput2 = (TextField) upperMatrixRow.getChildren().get(1); - TextField matrixInput3 = (TextField) lowerMatrixRow.getChildren().get(0); - TextField matrixInput4 = (TextField) lowerMatrixRow.getChildren().get(1); - - TextField vectorInput1 = (TextField) vectorBox.getChildren().get(1); // corrected index - TextField vectorInput2 = (TextField) vectorBox.getChildren().get(2); // corrected index - - try { - double m00 = Double.parseDouble(matrixInput1.getText()); - double m01 = Double.parseDouble(matrixInput2.getText()); - double m10 = Double.parseDouble(matrixInput3.getText()); - double m11 = Double.parseDouble(matrixInput4.getText()); - double v0 = Double.parseDouble(vectorInput1.getText()); - double v1 = Double.parseDouble(vectorInput2.getText()); - - AffineTransform2D transform = new AffineTransform2D(new Matrix2x2(m00, m01, m10, m11), new Vector2D(v0, v1)); - transforms.add(transform); - } catch (NumberFormatException e) { - System.out.println("Invalid input for matrix or vector values."); - // You can also add a dialog box here to notify the user + for (int i = 0; i < inputContainer.getChildren().size(); i++) { + if (inputContainer.getChildren().get(i) instanceof HBox) { + HBox matrixVectorBox = (HBox) inputContainer.getChildren().get(i); + VBox matrixBox = (VBox) matrixVectorBox.getChildren().get(0); + VBox vectorBox = (VBox) matrixVectorBox.getChildren().get(1); + + TextField matrixInput1 = (TextField) ((HBox) matrixBox.getChildren().get(1)).getChildren().get(0); + TextField matrixInput2 = (TextField) ((HBox) matrixBox.getChildren().get(1)).getChildren().get(1); + TextField matrixInput3 = (TextField) ((HBox) matrixBox.getChildren().get(2)).getChildren().get(0); + TextField matrixInput4 = (TextField) ((HBox) matrixBox.getChildren().get(2)).getChildren().get(1); + TextField vectorInput1 = (TextField) vectorBox.getChildren().get(1); + TextField vectorInput2 = (TextField) vectorBox.getChildren().get(2); + + try { + double m00 = Double.parseDouble(matrixInput1.getText()); + double m01 = Double.parseDouble(matrixInput2.getText()); + double m10 = Double.parseDouble(matrixInput3.getText()); + double m11 = Double.parseDouble(matrixInput4.getText()); + double v0 = Double.parseDouble(vectorInput1.getText()); + double v1 = Double.parseDouble(vectorInput2.getText()); + + AffineTransform2D transform = new AffineTransform2D(new Matrix2x2(m00, m01, m10, m11), new Vector2D(v0, v1)); + transforms.add(transform); + } catch (NumberFormatException e) { + System.out.println("Invalid input for matrix or vector values."); + // You can also add a dialog box here to notify the user + } } } @@ -409,10 +413,11 @@ public class Scene { xMax = 2.5; yMax = 10; } else { - xMin = 0; - yMin = 0; - xMax = 1; - yMax = 1; + xMin = 0; + yMin = 0; + xMax = 1; + yMax = 1; + } } Vector2D lowerLeft = new Vector2D(xMin, yMin); @@ -420,21 +425,20 @@ public class Scene { ChaosGameDescription description = new ChaosGameDescription(Arrays.asList(transforms.toArray(new AffineTransform2D[0])), lowerLeft, upperRight); -// Update the fractal operations with the new description + // Update the fractal operations with the new description fractalOperations.updateMatrixAndVector(description); - } } - private void resetToDefaultFractal(VBox inputContainer, Button addMoreButton, Button updateMatrixVectorButton, Button resetToDefaultButton) { + private void resetToDefaultFractal(VBox inputContainer, Button addMoreButton, Button resetToDefaultButton) { inputContainer.getChildren().clear(); if ("Barnsley Fern".equals(comboBoxes.getComboBoxFractal().getValue())) { fractalOperations.setFractalToBransleysFern(); - AffineTransform2D[] transforms = fractalOperations.getDescription().getTransforms().toArray(new AffineTransform2D[0]); - inputContainer.getChildren().addAll(createMatrixVectorInputBox(transforms[0]), createMatrixVectorInputBox(transforms[1]), createMatrixVectorInputBox(transforms[2]), createMatrixVectorInputBox(transforms[3]), addMoreButton, updateMatrixVectorButton, resetToDefaultButton); + AffineTransform2D[] transforms = fractalOperations.getDescription().getTransforms().toArray(new AffineTransform2D[0]); + inputContainer.getChildren().addAll(createMatrixVectorInputBox(transforms[0]), createMatrixVectorInputBox(transforms[1]), createMatrixVectorInputBox(transforms[2]), createMatrixVectorInputBox(transforms[3]), addMoreButton, resetToDefaultButton); } else if ("Sierpinski Triangle".equals(comboBoxes.getComboBoxFractal().getValue())) { fractalOperations.setFractalToSierpinskiTriangle(); - AffineTransform2D[] transforms = fractalOperations.getDescription().getTransforms().toArray(new AffineTransform2D[0]); - inputContainer.getChildren().addAll(createMatrixVectorInputBox(transforms[0]), createMatrixVectorInputBox(transforms[1]), createMatrixVectorInputBox(transforms[2]), addMoreButton, updateMatrixVectorButton, resetToDefaultButton); + AffineTransform2D[] transforms = fractalOperations.getDescription().getTransforms().toArray(new AffineTransform2D[0]); + inputContainer.getChildren().addAll(createMatrixVectorInputBox(transforms[0]), createMatrixVectorInputBox(transforms[1]), createMatrixVectorInputBox(transforms[2]), addMoreButton, resetToDefaultButton); } } @@ -442,18 +446,18 @@ public class Scene { fractalOperations.updateMinAndMaxFractal(minCoords, maxCoords); } - public void addSaveFractalToFileButton(){ - Button saveFractalToFileButton = buttons.getBtnSaveFractalToFile(); + public void addSaveFractalToFileButton() { + Button saveFractalToFileButton = buttons.getBtnSaveFractalToFile(); if (saveFractalToFileButton != null && !topBox.getChildren().contains(saveFractalToFileButton)) { topBox.getChildren().add(saveFractalToFileButton); - } + } } - public void createMaxMinVectorInput(){ - TextField xMinInput = textFields.getxMinInput(); - TextField yMinInput = textFields.getyMinInput(); - TextField xMaxInput = textFields.getxMaxInput(); - TextField yMaxInput = textFields.getyMaxInput(); + public void createMaxMinVectorInputAndUpdateAll() { + xMinInput = textFields.getxMinInput(); + yMinInput = textFields.getyMinInput(); + xMaxInput = textFields.getxMaxInput(); + yMaxInput = textFields.getyMaxInput(); // Ensure style classes are added to these text fields xMinInput.getStyleClass().add("MaxMinInput"); @@ -469,17 +473,19 @@ public class Scene { xMaxInput.setText(String.valueOf(maxCoords.getX0())); yMaxInput.setText(String.valueOf(maxCoords.getX1())); + updateVectorInputFields(); + HBox MinBox = new HBox(5); HBox MaxBox = new HBox(5); MinBox.getChildren().addAll(xMinInput, yMinInput); MaxBox.getChildren().addAll(xMaxInput, yMaxInput); - Button updateMinMaxButton = new Button("Update Min and Max vector"); + Button updateAllButton = new Buttons().getBtnUpdateAll(); VBox MinMaxAll = new VBox(5); - MinMaxAll.getChildren().addAll(MaxLabel, MaxBox, MinLabel, MinBox, updateMinMaxButton); + MinMaxAll.getChildren().addAll(MaxLabel, MaxBox, MinLabel, MinBox, updateAllButton); - updateMinMaxButton.setOnAction(event -> { + updateAllButton.setOnAction(event -> { try { fractalOperations.resetIterations(); double xMin = Double.parseDouble(xMinInput.getText()); @@ -487,6 +493,16 @@ public class Scene { double xMax = Double.parseDouble(xMaxInput.getText()); double yMax = Double.parseDouble(yMaxInput.getText()); updateMinAndMax(new Vector2D(xMin, yMin), new Vector2D(xMax, yMax)); + + String selectedFractal = comboBoxes.getComboBoxFractal().getValue(); + if ("Julia Set".equals(selectedFractal)) { + double realPart = Double.parseDouble(realPartInput.getText()); + double imaginaryPart = Double.parseDouble(imaginaryPartInput.getText()); + fractalOperations.updateJuliaSet(new Complex(realPart, imaginaryPart), -1, new Vector2D(xMin, yMin), new Vector2D(xMax, yMax)); + fractalOperations.updateMinAndMaxFractal(new Vector2D(xMin, yMin), new Vector2D(xMax, yMax)); + } else if ("Sierpinski Triangle".equals(selectedFractal) || "Barnsley Fern".equals(selectedFractal)) { + updateAffineTransforms(inputContainer); + } } catch (NumberFormatException e) { System.out.println("Invalid input for min or max values."); } @@ -495,6 +511,17 @@ public class Scene { inputBox.getChildren().add(MinMaxAll); } + public void removeMaxMinVectorInput() { + inputBox.getChildren().remove(1); + } + + public void updateVectorInputFields() { + xMinInput.setText(String.valueOf(fractalOperations.getChaosGame().getDescription().getMinCoords().getX0())); + yMinInput.setText(String.valueOf(fractalOperations.getChaosGame().getDescription().getMinCoords().getX1())); + xMaxInput.setText(String.valueOf(fractalOperations.getChaosGame().getDescription().getMaxCoords().getX0())); + yMaxInput.setText(String.valueOf(fractalOperations.getChaosGame().getDescription().getMaxCoords().getX1())); + } + public void setUpStage(Stage primaryStage) { primaryStage.setTitle("ChaosGame"); primaryStage.setScene(scene); -- GitLab From 6bc3649164983176d3b3b19f143ca5aa80d8cfc7 Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Tue, 21 May 2024 15:48:21 +0200 Subject: [PATCH 152/168] moved btnUpdateAll method to ButtonObserver --- .../idatt2003/controller/ButtonObserver.java | 108 +++++++++++++++++- 1 file changed, 103 insertions(+), 5 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java b/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java index 43c0663..16c1c3a 100644 --- a/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java +++ b/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java @@ -1,27 +1,33 @@ package edu.ntnu.idatt2003.controller; +import edu.ntnu.idatt2003.model.*; import edu.ntnu.idatt2003.view.components.Buttons; import edu.ntnu.idatt2003.view.components.FractalOperations; import edu.ntnu.idatt2003.view.components.TextFields; -import java.io.File; import javafx.application.Platform; import javafx.scene.control.Alert; import javafx.scene.control.ButtonType; import javafx.scene.control.Label; import javafx.scene.control.TextField; import javafx.stage.FileChooser; -import java.io.File; import javafx.stage.Stage; +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import javafx.scene.layout.VBox; +import javafx.scene.layout.HBox; +import javafx.scene.Node; /** * This class is responsible for handling button events. */ -public class ButtonObserver implements Observer{ +public class ButtonObserver implements Observer { private ExceptionHandler exceptionHandler = new ExceptionHandler(); private Buttons buttons; private FractalOperations fractalOperations; private TextFields textFields; private Label iterationsLabel; + private VBox inputContainer; // Add this line to include inputContainer /** * Constructs a ButtonObserver with the given buttons, fractalOperations, @@ -33,11 +39,12 @@ public class ButtonObserver implements Observer{ * @param iterationsLabel the iterationsLabel */ public ButtonObserver(Buttons buttons, FractalOperations fractalOperations, - TextFields textFields, Label iterationsLabel) { + TextFields textFields, Label iterationsLabel, VBox inputContainer) { this.buttons = buttons; this.fractalOperations = fractalOperations; this.textFields = textFields; this.iterationsLabel = iterationsLabel; + this.inputContainer = inputContainer; // Add this line to include inputContainer buttons.attach(this); } @@ -110,9 +117,100 @@ public class ButtonObserver implements Observer{ break; case "btnUpdateAll": + try { + double xMin = Double.parseDouble(textFields.getxMinInput().getText()); + double yMin = Double.parseDouble(textFields.getyMinInput().getText()); + double xMax = Double.parseDouble(textFields.getxMaxInput().getText()); + double yMax = Double.parseDouble(textFields.getyMaxInput().getText()); + //updateMinAndMax(new Vector2D(xMin, yMin), new Vector2D(xMax, yMax)); + + String selectedFractal = fractalOperations.getChaosGame().getChaosGameDescription().getTransforms().getFirst().getTransformType(); + if ("Julia".equals(selectedFractal)) { + double realPart = Double.parseDouble(textFields.getRealPartInput().getText()); + double imaginaryPart = Double.parseDouble(textFields.getImaginaryPartInput().getText()); + fractalOperations.updateJuliaSet(new Complex(realPart, imaginaryPart), -1, new Vector2D(xMin, yMin), new Vector2D(xMax, yMax)); + fractalOperations.updateMinAndMaxFractal(new Vector2D(xMin, yMin), new Vector2D(xMax, yMax)); + fractalOperations.resetIterations(); + } else if ("Affine2D".equals(selectedFractal)) { + updateAffineTransforms(inputContainer); + fractalOperations.resetIterations(); + } + } catch (NumberFormatException e) { + System.out.println("Invalid input for min or max values."); + } + break; default: break; } } -} \ No newline at end of file + + private void updateMinAndMax(Vector2D minCoords, Vector2D maxCoords) { + fractalOperations.updateMinAndMaxFractal(minCoords, maxCoords); + } + + private void updateAffineTransforms(VBox inputContainer) { + List<Transform2D> transforms = new ArrayList<>(); + for (Node node : inputContainer.getChildren()) { + if (node instanceof HBox) { + HBox matrixVectorBox = (HBox) node; + VBox matrixBox = (VBox) matrixVectorBox.getChildren().get(0); + VBox vectorBox = (VBox) matrixVectorBox.getChildren().get(1); + + TextField matrixInput1 = (TextField) ((HBox) matrixBox.getChildren().get(1)).getChildren().get(0); + TextField matrixInput2 = (TextField) ((HBox) matrixBox.getChildren().get(1)).getChildren().get(1); + TextField matrixInput3 = (TextField) ((HBox) matrixBox.getChildren().get(2)).getChildren().get(0); + TextField matrixInput4 = (TextField) ((HBox) matrixBox.getChildren().get(2)).getChildren().get(1); + TextField vectorInput1 = (TextField) vectorBox.getChildren().get(1); + TextField vectorInput2 = (TextField) vectorBox.getChildren().get(2); + + try { + double m00 = Double.parseDouble(matrixInput1.getText()); + double m01 = Double.parseDouble(matrixInput2.getText()); + double m10 = Double.parseDouble(matrixInput3.getText()); + double m11 = Double.parseDouble(matrixInput4.getText()); + double v0 = Double.parseDouble(vectorInput1.getText()); + double v1 = Double.parseDouble(vectorInput2.getText()); + + Transform2D transform = new AffineTransform2D(new Matrix2x2(m00, m01, m10, m11), new Vector2D(v0, v1)); + transforms.add(transform); + } catch (NumberFormatException e) { + System.out.println("Invalid input for matrix or vector values."); + } + } + } + + double xMin, yMin, xMax, yMax; + + try { + xMin = Double.parseDouble(textFields.getxMinInput().getText()); + yMin = Double.parseDouble(textFields.getyMinInput().getText()); + xMax = Double.parseDouble(textFields.getxMaxInput().getText()); + yMax = Double.parseDouble(textFields.getyMaxInput().getText()); + } catch (NumberFormatException e) { + // Set to default values if parsing fails + if ("Barnsley Fern".equals(fractalOperations.getCurrentFractal())) { + xMin = -2.5; + yMin = 0; + xMax = 2.5; + yMax = 10; + } else { + xMin = 0; + yMin = 0; + xMax = 1; + yMax = 1; + } + } + + Vector2D lowerLeft = new Vector2D(xMin, yMin); + Vector2D upperRight = new Vector2D(xMax, yMax); + + ChaosGameDescription description = new ChaosGameDescription(transforms, lowerLeft, upperRight); + System.out.println("Transforms updated: " + transforms.size()); + fractalOperations.updateMatrixAndVector(description); + } + + public void setInputContainer(VBox inputContainer) { + this.inputContainer = inputContainer; + } +} -- GitLab From a76b9bf05149cae2c41e234a125a2d561eb5bd17 Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Tue, 21 May 2024 15:51:28 +0200 Subject: [PATCH 153/168] Moved textfileds and some buttons to components, and functonallity to observer --- .../view/components/FractalOperations.java | 32 +++++----- .../edu/ntnu/idatt2003/view/scenes/Scene.java | 63 +++++-------------- 2 files changed, 35 insertions(+), 60 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java b/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java index 8454673..31332ff 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java +++ b/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java @@ -54,13 +54,15 @@ public class FractalOperations implements ChaosGameObserver { public void drawFractal(int iterations) { chaosGame.runSteps(iterations); - //updateImage(); + updateImage(); } public void resetIterations() { - chaosGame.getCanvas().clear(); - this.chaosGame.addObserver(this); - drawFractal(0); + if (chaosGame != null) { + chaosGame.getCanvas().clear(); + this.chaosGame.addObserver(this); + drawFractal(0); + } } /** @@ -83,7 +85,7 @@ public class FractalOperations implements ChaosGameObserver { */ public void setFractalToSierpinskiTriangle() { this.chaosGame = new ChaosGame(ChaosGameDescriptionFactory.createSierpinskiTriangle(), - 400, 400); + 400, 400); this.chaosGame.addObserver(this); drawFractal(0); } @@ -93,7 +95,7 @@ public class FractalOperations implements ChaosGameObserver { */ public void setFractalToJuliaSet() { this.chaosGame = new ChaosGame(ChaosGameDescriptionFactory.createJuliaSet(new Complex(-0.74543, 0.11301), - 1), 400, 400); + 1), 400, 400); this.chaosGame.addObserver(this); drawFractal(0); } @@ -104,7 +106,7 @@ public class FractalOperations implements ChaosGameObserver { public void setFractalToBransleysFern() { this.chaosGame = new ChaosGame(ChaosGameDescriptionFactory.createBarnsleyFern(), 400, 400); this.chaosGame.addObserver(this); - //drawFractal(0); + drawFractal(0); } /** @@ -118,7 +120,7 @@ public class FractalOperations implements ChaosGameObserver { ChaosGameDescription description = fileHandler.readFile(); this.chaosGame = new ChaosGame(description, 400, 400); this.chaosGame.addObserver(this); - //drawFractal(0); + drawFractal(0); } catch (IOException e) { e.printStackTrace(); } @@ -133,10 +135,10 @@ public class FractalOperations implements ChaosGameObserver { Vector2D defaultUpperRight = new Vector2D(0, 0); ChaosGameDescription description = new ChaosGameDescription(Arrays.asList(defaultTransforms), - defaultLowerLeft, defaultUpperRight); + defaultLowerLeft, defaultUpperRight); this.chaosGame = new ChaosGame(description, 400, 400); this.chaosGame.addObserver(this); - //drawFractal(0); + drawFractal(0); } /** @@ -147,6 +149,7 @@ public class FractalOperations implements ChaosGameObserver { public void updateC(Complex complex) { this.chaosGame = new ChaosGame(createJuliaSet(complex, -1), 400, 400); this.chaosGame.addObserver(this); + drawFractal(0); } /** @@ -157,17 +160,17 @@ public class FractalOperations implements ChaosGameObserver { public void updateMatrixAndVector(ChaosGameDescription description) { this.chaosGame = new ChaosGame(description, 400, 400); this.chaosGame.addObserver(this); - //drawFractal(0); + drawFractal(0); } - public void updateJuliaSet(Complex complex, int sign, Vector2D minCoords, Vector2D maxCoords) { JuliaTransform[] transforms = new JuliaTransform[2]; transforms[0] = new JuliaTransform(complex, sign); transforms[1] = new JuliaTransform(complex, -sign); ChaosGameDescription newChaosGame = new ChaosGameDescription(Arrays.asList(transforms), - minCoords, maxCoords); + minCoords, maxCoords); this.chaosGame = new ChaosGame(newChaosGame, 400, 400); + drawFractal(0); } public String getCurrentFractal() { @@ -191,7 +194,7 @@ public class FractalOperations implements ChaosGameObserver { */ public void updateMinAndMaxFractal(Vector2D minCoords, Vector2D maxCoords) { ChaosGameDescription newChaosGame = new ChaosGameDescription( - chaosGame.getChaosGameDescription().getTransforms(), minCoords, maxCoords); + chaosGame.getChaosGameDescription().getTransforms(), minCoords, maxCoords); this.chaosGame = new ChaosGame(newChaosGame, 400, 400); this.chaosGame.addObserver(this); } @@ -208,6 +211,7 @@ public class FractalOperations implements ChaosGameObserver { public ChaosGameDescription getDescription() { return chaosGame.getDescription(); } + @Override public void update(ChaosGame chaosGame) { updateImage(); diff --git a/src/main/java/edu/ntnu/idatt2003/view/scenes/Scene.java b/src/main/java/edu/ntnu/idatt2003/view/scenes/Scene.java index 9a72d21..fef59f2 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/scenes/Scene.java +++ b/src/main/java/edu/ntnu/idatt2003/view/scenes/Scene.java @@ -32,11 +32,6 @@ public class Scene { private ComboBoxes comboBoxes; private Labels labels; private TextFields textFields; - - private TextField xMinInput; - private TextField yMinInput; - private TextField xMaxInput; - private TextField yMaxInput; private FractalOperations fractalOperations; private VBox cBox; // Container for the C input fields private VBox inputBox; // Container for all input fields @@ -44,8 +39,6 @@ public class Scene { private HBox topBox; private VBox inputContainer; - private TextField realPartInput; - private TextField imaginaryPartInput; private ButtonObserver buttonObserver; private ComboBoxObserver comboBoxObserver; private LabelObserver labelObserver; @@ -61,7 +54,7 @@ public class Scene { textFields = new TextFields(); initializeComponents(); fractalOperations = new FractalOperations(imageView, fractalType); - buttonObserver = new ButtonObserver(buttons, fractalOperations, textFields, iterationsLabel); + buttonObserver = new ButtonObserver(buttons, fractalOperations, textFields, iterationsLabel, inputContainer); comboBoxObserver = new ComboBoxObserver(comboBoxes, fractalOperations); labelObserver = new LabelObserver(buttons, comboBoxes, textFields, iterationsLabel); textFieldObserver = new TextFieldObserver(fractalOperations, textFields); @@ -73,26 +66,25 @@ public class Scene { removeFractalFromFileBox(); addSaveFractalToFileButton(); addCInputBox(); - updateVectorInputFields(); + buttonObserver.setInputContainer(inputContainer); } else if ("Sierpinski Triangle".equals(newValue)) { removeMatrixVectorInputBoxes(); removeCInputBox(); removeFractalFromFileBox(); addMatrixVectorInputBoxes(); addSaveFractalToFileButton(); - updateVectorInputFields(); + buttonObserver.setInputContainer(inputContainer); } else if ("Barnsley Fern".equals(newValue)) { removeMatrixVectorInputBoxes(); removeCInputBox(); removeFractalFromFileBox(); addMatrixVectorInputBoxes(); addSaveFractalToFileButton(); - updateVectorInputFields(); + buttonObserver.setInputContainer(inputContainer); } else if ("Fractal From File".equals(newValue)) { removeCInputBox(); removeMatrixVectorInputBoxes(); addFractalFromFileBox(); - updateVectorInputFields(); } }); @@ -222,8 +214,8 @@ public class Scene { Button updateCButton = new Button("Update C"); Button resetToDefaultButton = new Button("Reset to Default fractal"); - realPartInput = new TextField(); - imaginaryPartInput = new TextField(); + TextField realPartInput = textFields.getRealPartInput(); + TextField imaginaryPartInput = textFields.getImaginaryPartInput(); realPartInput.getStyleClass().add("cInput"); imaginaryPartInput.getStyleClass().add("cInput"); @@ -454,10 +446,10 @@ public class Scene { } public void createMaxMinVectorInputAndUpdateAll() { - xMinInput = textFields.getxMinInput(); - yMinInput = textFields.getyMinInput(); - xMaxInput = textFields.getxMaxInput(); - yMaxInput = textFields.getyMaxInput(); + TextField xMinInput = textFields.getxMinInput(); + TextField yMinInput = textFields.getyMinInput(); + TextField xMaxInput = textFields.getxMaxInput(); + TextField yMaxInput = textFields.getyMaxInput(); // Ensure style classes are added to these text fields xMinInput.getStyleClass().add("MaxMinInput"); @@ -480,34 +472,13 @@ public class Scene { MinBox.getChildren().addAll(xMinInput, yMinInput); MaxBox.getChildren().addAll(xMaxInput, yMaxInput); - Button updateAllButton = new Buttons().getBtnUpdateAll(); + buttonObserver.setInputContainer(inputBox); + + Button updateAllButton = buttons.getBtnUpdateAll(); VBox MinMaxAll = new VBox(5); MinMaxAll.getChildren().addAll(MaxLabel, MaxBox, MinLabel, MinBox, updateAllButton); - updateAllButton.setOnAction(event -> { - try { - fractalOperations.resetIterations(); - double xMin = Double.parseDouble(xMinInput.getText()); - double yMin = Double.parseDouble(yMinInput.getText()); - double xMax = Double.parseDouble(xMaxInput.getText()); - double yMax = Double.parseDouble(yMaxInput.getText()); - updateMinAndMax(new Vector2D(xMin, yMin), new Vector2D(xMax, yMax)); - - String selectedFractal = comboBoxes.getComboBoxFractal().getValue(); - if ("Julia Set".equals(selectedFractal)) { - double realPart = Double.parseDouble(realPartInput.getText()); - double imaginaryPart = Double.parseDouble(imaginaryPartInput.getText()); - fractalOperations.updateJuliaSet(new Complex(realPart, imaginaryPart), -1, new Vector2D(xMin, yMin), new Vector2D(xMax, yMax)); - fractalOperations.updateMinAndMaxFractal(new Vector2D(xMin, yMin), new Vector2D(xMax, yMax)); - } else if ("Sierpinski Triangle".equals(selectedFractal) || "Barnsley Fern".equals(selectedFractal)) { - updateAffineTransforms(inputContainer); - } - } catch (NumberFormatException e) { - System.out.println("Invalid input for min or max values."); - } - }); - inputBox.getChildren().add(MinMaxAll); } @@ -516,10 +487,10 @@ public class Scene { } public void updateVectorInputFields() { - xMinInput.setText(String.valueOf(fractalOperations.getChaosGame().getDescription().getMinCoords().getX0())); - yMinInput.setText(String.valueOf(fractalOperations.getChaosGame().getDescription().getMinCoords().getX1())); - xMaxInput.setText(String.valueOf(fractalOperations.getChaosGame().getDescription().getMaxCoords().getX0())); - yMaxInput.setText(String.valueOf(fractalOperations.getChaosGame().getDescription().getMaxCoords().getX1())); + textFields.getxMinInput().setText(String.valueOf(fractalOperations.getChaosGame().getDescription().getMinCoords().getX0())); + textFields.getyMinInput().setText(String.valueOf(fractalOperations.getChaosGame().getDescription().getMinCoords().getX1())); + textFields.getxMaxInput().setText(String.valueOf(fractalOperations.getChaosGame().getDescription().getMaxCoords().getX0())); + textFields.getyMaxInput().setText(String.valueOf(fractalOperations.getChaosGame().getDescription().getMaxCoords().getX1())); } public void setUpStage(Stage primaryStage) { -- GitLab From d3bb8f01a7deab6efda62d6b175914b69d7b8775 Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Tue, 21 May 2024 15:52:05 +0200 Subject: [PATCH 154/168] added realPartInput and imaginaryPartInput --- .../idatt2003/view/components/TextFields.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/main/java/edu/ntnu/idatt2003/view/components/TextFields.java b/src/main/java/edu/ntnu/idatt2003/view/components/TextFields.java index 839c84a..ed7e354 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/components/TextFields.java +++ b/src/main/java/edu/ntnu/idatt2003/view/components/TextFields.java @@ -12,6 +12,8 @@ public class TextFields extends Subject { private TextField yminInput; private TextField xmaxInput; private TextField ymaxInput; + private TextField realPartInput; + private TextField imaginaryPartInput; /** * Constructs a TextFields object. @@ -39,6 +41,11 @@ public class TextFields extends Subject { xmaxInput.setPromptText("X max"); ymaxInput = new TextField(); ymaxInput.setPromptText("Y max"); + + realPartInput = new TextField(); + realPartInput.setPromptText("Real part"); + imaginaryPartInput = new TextField(); + imaginaryPartInput.setPromptText("Imaginary part"); } public TextField getAddIterationInput() { @@ -60,5 +67,14 @@ public class TextFields extends Subject { public TextField getyMaxInput() { return ymaxInput; } + + public TextField getRealPartInput() { + return realPartInput; + } + + public TextField getImaginaryPartInput() { + return imaginaryPartInput; + } + } -- GitLab From d73f33565377248e430db7748f85339e56f39620 Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Tue, 21 May 2024 15:56:30 +0200 Subject: [PATCH 155/168] Removed updateAffineTransforms since it now is in ButtonObserver --- .../edu/ntnu/idatt2003/view/scenes/Scene.java | 64 ------------------- 1 file changed, 64 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/view/scenes/Scene.java b/src/main/java/edu/ntnu/idatt2003/view/scenes/Scene.java index fef59f2..66500ee 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/scenes/Scene.java +++ b/src/main/java/edu/ntnu/idatt2003/view/scenes/Scene.java @@ -38,7 +38,6 @@ public class Scene { private VBox matrixVectorBox; // Container for the matrix and vector input fields private HBox topBox; private VBox inputContainer; - private ButtonObserver buttonObserver; private ComboBoxObserver comboBoxObserver; private LabelObserver labelObserver; @@ -358,69 +357,6 @@ public class Scene { } } - private void updateAffineTransforms(VBox inputContainer) { - List<AffineTransform2D> transforms = new ArrayList<>(); - for (int i = 0; i < inputContainer.getChildren().size(); i++) { - if (inputContainer.getChildren().get(i) instanceof HBox) { - HBox matrixVectorBox = (HBox) inputContainer.getChildren().get(i); - VBox matrixBox = (VBox) matrixVectorBox.getChildren().get(0); - VBox vectorBox = (VBox) matrixVectorBox.getChildren().get(1); - - TextField matrixInput1 = (TextField) ((HBox) matrixBox.getChildren().get(1)).getChildren().get(0); - TextField matrixInput2 = (TextField) ((HBox) matrixBox.getChildren().get(1)).getChildren().get(1); - TextField matrixInput3 = (TextField) ((HBox) matrixBox.getChildren().get(2)).getChildren().get(0); - TextField matrixInput4 = (TextField) ((HBox) matrixBox.getChildren().get(2)).getChildren().get(1); - TextField vectorInput1 = (TextField) vectorBox.getChildren().get(1); - TextField vectorInput2 = (TextField) vectorBox.getChildren().get(2); - - try { - double m00 = Double.parseDouble(matrixInput1.getText()); - double m01 = Double.parseDouble(matrixInput2.getText()); - double m10 = Double.parseDouble(matrixInput3.getText()); - double m11 = Double.parseDouble(matrixInput4.getText()); - double v0 = Double.parseDouble(vectorInput1.getText()); - double v1 = Double.parseDouble(vectorInput2.getText()); - - AffineTransform2D transform = new AffineTransform2D(new Matrix2x2(m00, m01, m10, m11), new Vector2D(v0, v1)); - transforms.add(transform); - } catch (NumberFormatException e) { - System.out.println("Invalid input for matrix or vector values."); - // You can also add a dialog box here to notify the user - } - } - } - - double xMin, yMin, xMax, yMax; - - try { - xMin = Double.parseDouble(textFields.getxMinInput().getText()); - yMin = Double.parseDouble(textFields.getyMinInput().getText()); - xMax = Double.parseDouble(textFields.getxMaxInput().getText()); - yMax = Double.parseDouble(textFields.getyMaxInput().getText()); - } catch (NumberFormatException e) { - // Set to default values if parsing fails - if ("Barnsley Fern".equals(comboBoxes.getComboBoxFractal().getValue())) { - xMin = -2.5; - yMin = 0; - xMax = 2.5; - yMax = 10; - } else { - xMin = 0; - yMin = 0; - xMax = 1; - yMax = 1; - } - } - - Vector2D lowerLeft = new Vector2D(xMin, yMin); - Vector2D upperRight = new Vector2D(xMax, yMax); - - ChaosGameDescription description = new ChaosGameDescription(Arrays.asList(transforms.toArray(new AffineTransform2D[0])), lowerLeft, upperRight); - - // Update the fractal operations with the new description - fractalOperations.updateMatrixAndVector(description); - } - private void resetToDefaultFractal(VBox inputContainer, Button addMoreButton, Button resetToDefaultButton) { inputContainer.getChildren().clear(); if ("Barnsley Fern".equals(comboBoxes.getComboBoxFractal().getValue())) { -- GitLab From fc118b39893025096bf808abf377a82a50c4872d Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Tue, 21 May 2024 16:12:51 +0200 Subject: [PATCH 156/168] Update vectorinputfields when swapping fractal --- src/main/java/edu/ntnu/idatt2003/view/scenes/Scene.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/edu/ntnu/idatt2003/view/scenes/Scene.java b/src/main/java/edu/ntnu/idatt2003/view/scenes/Scene.java index 66500ee..fe94966 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/scenes/Scene.java +++ b/src/main/java/edu/ntnu/idatt2003/view/scenes/Scene.java @@ -65,6 +65,7 @@ public class Scene { removeFractalFromFileBox(); addSaveFractalToFileButton(); addCInputBox(); + updateVectorInputFields(); buttonObserver.setInputContainer(inputContainer); } else if ("Sierpinski Triangle".equals(newValue)) { removeMatrixVectorInputBoxes(); @@ -72,6 +73,7 @@ public class Scene { removeFractalFromFileBox(); addMatrixVectorInputBoxes(); addSaveFractalToFileButton(); + updateVectorInputFields(); buttonObserver.setInputContainer(inputContainer); } else if ("Barnsley Fern".equals(newValue)) { removeMatrixVectorInputBoxes(); @@ -79,11 +81,13 @@ public class Scene { removeFractalFromFileBox(); addMatrixVectorInputBoxes(); addSaveFractalToFileButton(); + updateVectorInputFields(); buttonObserver.setInputContainer(inputContainer); } else if ("Fractal From File".equals(newValue)) { removeCInputBox(); removeMatrixVectorInputBoxes(); addFractalFromFileBox(); + updateVectorInputFields(); } }); -- GitLab From a3e33710802caed5621caa35794bdb7571c83cdc Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Tue, 21 May 2024 19:53:27 +0200 Subject: [PATCH 157/168] Add InvalidInputException class for handling invalid user inputs --- .../controller/InvalidInputException.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 src/main/java/edu/ntnu/idatt2003/controller/InvalidInputException.java diff --git a/src/main/java/edu/ntnu/idatt2003/controller/InvalidInputException.java b/src/main/java/edu/ntnu/idatt2003/controller/InvalidInputException.java new file mode 100644 index 0000000..fad9bf5 --- /dev/null +++ b/src/main/java/edu/ntnu/idatt2003/controller/InvalidInputException.java @@ -0,0 +1,17 @@ +package edu.ntnu.idatt2003.controller; + +/** + * Custom exception for invalid input. + */ +public class InvalidInputException extends Exception { + private String invalidInput; + + public InvalidInputException(String message, String invalidInput) { + super(message); + this.invalidInput = invalidInput; + } + + public String getInvalidInput() { + return invalidInput; + } +} -- GitLab From 9d6a0e3ca1a95dbf410c1de7542bca1a3396572d Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Tue, 21 May 2024 19:54:07 +0200 Subject: [PATCH 158/168] showAlertDoubleInvalid() added --- .../edu/ntnu/idatt2003/controller/ExceptionHandler.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/java/edu/ntnu/idatt2003/controller/ExceptionHandler.java b/src/main/java/edu/ntnu/idatt2003/controller/ExceptionHandler.java index 8879ca8..72777b1 100644 --- a/src/main/java/edu/ntnu/idatt2003/controller/ExceptionHandler.java +++ b/src/main/java/edu/ntnu/idatt2003/controller/ExceptionHandler.java @@ -26,6 +26,14 @@ public class ExceptionHandler { alert.showAndWait(); } + public void showAlertDoubleInvalid(String input) { + Alert alert = new Alert(Alert.AlertType.ERROR); + alert.setTitle("Error"); + alert.setHeaderText("An error occurred"); + alert.setContentText("The input '" + input + "' is invalid. Please enter a number."); + alert.showAndWait(); + } + public void validatePostiviteInteger(int number) { if (number < 1) { throw new IllegalArgumentException("The number must be greater than 0."); -- GitLab From aaf077abf9ad7f75e50d9e45647ef2748454a4e5 Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Tue, 21 May 2024 19:54:31 +0200 Subject: [PATCH 159/168] Refactored --- .../edu/ntnu/idatt2003/view/scenes/Scene.java | 40 ++++--------------- 1 file changed, 7 insertions(+), 33 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/view/scenes/Scene.java b/src/main/java/edu/ntnu/idatt2003/view/scenes/Scene.java index fe94966..6521e2d 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/scenes/Scene.java +++ b/src/main/java/edu/ntnu/idatt2003/view/scenes/Scene.java @@ -214,7 +214,6 @@ public class Scene { private VBox createCInputBox() { Label cLabel = new Label("Update constant C"); - Button updateCButton = new Button("Update C"); Button resetToDefaultButton = new Button("Reset to Default fractal"); TextField realPartInput = textFields.getRealPartInput(); @@ -232,27 +231,9 @@ public class Scene { imaginaryPartInput.setText(String.valueOf(julia.getPoint().getImaginary())); VBox cBox = new VBox(5); - cBox.getChildren().addAll(cLabel, realPartInput, imaginaryPartInput, updateCButton, resetToDefaultButton); + cBox.getChildren().addAll(cLabel, realPartInput, imaginaryPartInput, resetToDefaultButton); cBox.setPadding(new Insets(0, 0, 0, 0)); - updateCButton.setOnAction(event -> { - try { - double realPart = Double.parseDouble(realPartInput.getText()); - double imaginaryPart = Double.parseDouble(imaginaryPartInput.getText()); - fractalOperations.updateC(new Complex(realPart, imaginaryPart)); - double xMin = Double.parseDouble(textFields.getxMinInput().getText()); - double yMin = Double.parseDouble(textFields.getyMinInput().getText()); - double xMax = Double.parseDouble(textFields.getxMaxInput().getText()); - double yMax = Double.parseDouble(textFields.getyMaxInput().getText()); - - Vector2D lowerLeft = new Vector2D(xMin, yMin); - Vector2D upperRight = new Vector2D(xMax, yMax); - fractalOperations.updateMinAndMaxFractal(lowerLeft, upperRight); - } catch (NumberFormatException e) { - System.out.println("Invalid input for real or imaginary part of C."); - } - }); - resetToDefaultButton.setOnAction(event -> { fractalOperations.setFractalToJuliaSet(); updateVectorInputFields(); @@ -274,12 +255,12 @@ public class Scene { matrixBox.getChildren().add(matrixLabel); vectorBox.getChildren().add(vectorLabel); - TextField matrixInput1 = new TextField(); - TextField matrixInput2 = new TextField(); - TextField matrixInput3 = new TextField(); - TextField matrixInput4 = new TextField(); - TextField vectorInput1 = new TextField(); - TextField vectorInput2 = new TextField(); + TextField matrixInput1 = textFields.getMatrixInput1(); + TextField matrixInput2 = textFields.getMatrixInput2(); + TextField matrixInput3 = textFields.getMatrixInput3(); + TextField matrixInput4 = textFields.getMatrixInput4(); + TextField vectorInput1 = textFields.getVectorInput1(); + TextField vectorInput2 = textFields.getVectorInput2(); matrixInput1.setText(String.valueOf(transform.getMatrix().getA00())); matrixInput2.setText(String.valueOf(transform.getMatrix().getA01())); @@ -295,13 +276,6 @@ public class Scene { vectorInput1.getStyleClass().add("matrixInput"); vectorInput2.getStyleClass().add("matrixInput"); - matrixInput1.setPromptText("a00"); - matrixInput2.setPromptText("a01"); - matrixInput3.setPromptText("a10"); - matrixInput4.setPromptText("a11"); - vectorInput1.setPromptText("b0"); - vectorInput2.setPromptText("b1"); - HBox upperMatrixRow = new HBox(5); HBox lowerMatrixRow = new HBox(5); -- GitLab From d5fa97e6e0b11a05258fe24c09548aa89310679a Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Tue, 21 May 2024 19:55:20 +0200 Subject: [PATCH 160/168] Refactored to accept exceptions --- .../idatt2003/controller/ButtonObserver.java | 49 ++++++++++--------- .../idatt2003/view/components/TextFields.java | 49 +++++++++++++++++++ 2 files changed, 76 insertions(+), 22 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java b/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java index 16c1c3a..66c6ebf 100644 --- a/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java +++ b/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java @@ -117,17 +117,17 @@ public class ButtonObserver implements Observer { break; case "btnUpdateAll": + try { - double xMin = Double.parseDouble(textFields.getxMinInput().getText()); - double yMin = Double.parseDouble(textFields.getyMinInput().getText()); - double xMax = Double.parseDouble(textFields.getxMaxInput().getText()); - double yMax = Double.parseDouble(textFields.getyMaxInput().getText()); - //updateMinAndMax(new Vector2D(xMin, yMin), new Vector2D(xMax, yMax)); + double xMin = parseInput(textFields.getxMinInput()); + double yMin = parseInput(textFields.getyMinInput()); + double xMax = parseInput(textFields.getxMaxInput()); + double yMax = parseInput(textFields.getyMaxInput()); String selectedFractal = fractalOperations.getChaosGame().getChaosGameDescription().getTransforms().getFirst().getTransformType(); if ("Julia".equals(selectedFractal)) { - double realPart = Double.parseDouble(textFields.getRealPartInput().getText()); - double imaginaryPart = Double.parseDouble(textFields.getImaginaryPartInput().getText()); + double realPart = parseInput(textFields.getRealPartInput()); + double imaginaryPart = parseInput(textFields.getImaginaryPartInput()); fractalOperations.updateJuliaSet(new Complex(realPart, imaginaryPart), -1, new Vector2D(xMin, yMin), new Vector2D(xMax, yMax)); fractalOperations.updateMinAndMaxFractal(new Vector2D(xMin, yMin), new Vector2D(xMax, yMax)); fractalOperations.resetIterations(); @@ -135,20 +135,16 @@ public class ButtonObserver implements Observer { updateAffineTransforms(inputContainer); fractalOperations.resetIterations(); } - } catch (NumberFormatException e) { - System.out.println("Invalid input for min or max values."); + } catch (InvalidInputException e) { + exceptionHandler.showAlertDoubleInvalid(e.getInvalidInput()); + break; } - break; default: break; } } - private void updateMinAndMax(Vector2D minCoords, Vector2D maxCoords) { - fractalOperations.updateMinAndMaxFractal(minCoords, maxCoords); - } - private void updateAffineTransforms(VBox inputContainer) { List<Transform2D> transforms = new ArrayList<>(); for (Node node : inputContainer.getChildren()) { @@ -165,17 +161,17 @@ public class ButtonObserver implements Observer { TextField vectorInput2 = (TextField) vectorBox.getChildren().get(2); try { - double m00 = Double.parseDouble(matrixInput1.getText()); - double m01 = Double.parseDouble(matrixInput2.getText()); - double m10 = Double.parseDouble(matrixInput3.getText()); - double m11 = Double.parseDouble(matrixInput4.getText()); - double v0 = Double.parseDouble(vectorInput1.getText()); - double v1 = Double.parseDouble(vectorInput2.getText()); + double m00 = parseInput(matrixInput1); + double m01 = parseInput(matrixInput2); + double m10 = parseInput(matrixInput3); + double m11 = parseInput(matrixInput4); + double v0 = parseInput(vectorInput1); + double v1 = parseInput(vectorInput2); Transform2D transform = new AffineTransform2D(new Matrix2x2(m00, m01, m10, m11), new Vector2D(v0, v1)); transforms.add(transform); - } catch (NumberFormatException e) { - System.out.println("Invalid input for matrix or vector values."); + } catch (InvalidInputException e) { + exceptionHandler.showAlertDoubleInvalid(e.getInvalidInput()); } } } @@ -210,6 +206,15 @@ public class ButtonObserver implements Observer { fractalOperations.updateMatrixAndVector(description); } + private double parseInput(TextField textField) throws InvalidInputException { + String input = textField.getText(); + try { + return Double.parseDouble(input); + } catch (NumberFormatException e) { + throw new InvalidInputException("Invalid input: " + input, input); + } + } + public void setInputContainer(VBox inputContainer) { this.inputContainer = inputContainer; } diff --git a/src/main/java/edu/ntnu/idatt2003/view/components/TextFields.java b/src/main/java/edu/ntnu/idatt2003/view/components/TextFields.java index ed7e354..75a4808 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/components/TextFields.java +++ b/src/main/java/edu/ntnu/idatt2003/view/components/TextFields.java @@ -14,6 +14,12 @@ public class TextFields extends Subject { private TextField ymaxInput; private TextField realPartInput; private TextField imaginaryPartInput; + private TextField matrixInput1; + private TextField matrixInput2; + private TextField matrixInput3; + private TextField matrixInput4; + private TextField vectorInput1; + private TextField vectorInput2; /** * Constructs a TextFields object. @@ -46,6 +52,20 @@ public class TextFields extends Subject { realPartInput.setPromptText("Real part"); imaginaryPartInput = new TextField(); imaginaryPartInput.setPromptText("Imaginary part"); + + matrixInput1 = new TextField(); + matrixInput1.setPromptText("a00"); + matrixInput2 = new TextField(); + matrixInput2.setPromptText("a01"); + matrixInput3 = new TextField(); + matrixInput3.setPromptText("a10"); + matrixInput4 = new TextField(); + matrixInput4.setPromptText("a11"); + + vectorInput1 = new TextField(); + vectorInput1.setPromptText("b0"); + vectorInput2 = new TextField(); + vectorInput2.setPromptText("b1"); } public TextField getAddIterationInput() { @@ -75,6 +95,35 @@ public class TextFields extends Subject { public TextField getImaginaryPartInput() { return imaginaryPartInput; } + public TextField getMatrixInput1() { + return createMatrixInputField("a00"); + } + + public TextField getMatrixInput2() { + return createMatrixInputField("a01"); + } + + public TextField getMatrixInput3() { + return createMatrixInputField("a10"); + } + + public TextField getMatrixInput4() { + return createMatrixInputField("a11"); + } + + public TextField getVectorInput1() { + return createMatrixInputField("b0"); + } + + public TextField getVectorInput2() { + return createMatrixInputField("b1"); + } + + private TextField createMatrixInputField(String promptText) { + TextField textField = new TextField(); + textField.setPromptText(promptText); + return textField; + } } -- GitLab From 278e6f701a856e2e0d2f2a3ec7f97e1d33f8bf8b Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Tue, 21 May 2024 20:24:18 +0200 Subject: [PATCH 161/168] Added zoom --- .../edu/ntnu/idatt2003/view/scenes/Scene.java | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/src/main/java/edu/ntnu/idatt2003/view/scenes/Scene.java b/src/main/java/edu/ntnu/idatt2003/view/scenes/Scene.java index 6521e2d..c1c3134 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/scenes/Scene.java +++ b/src/main/java/edu/ntnu/idatt2003/view/scenes/Scene.java @@ -14,8 +14,12 @@ import javafx.scene.layout.AnchorPane; import javafx.scene.layout.BorderPane; import javafx.scene.layout.HBox; import javafx.scene.layout.VBox; +import javafx.scene.paint.Paint; import javafx.stage.Stage; +import java.awt.*; +import java.awt.event.MouseEvent; +import javafx.scene.shape.Rectangle; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -42,6 +46,8 @@ public class Scene { private ComboBoxObserver comboBoxObserver; private LabelObserver labelObserver; private TextFieldObserver textFieldObserver; + private double startX, startY, endX, endY; + private Rectangle selectionRectangle; /** * Constructor for the AffineScene class @@ -193,6 +199,17 @@ public class Scene { AnchorPane.setTopAnchor(inputBox, 65.0); AnchorPane.setRightAnchor(inputBox, 30.0); + selectionRectangle = new Rectangle(); + selectionRectangle.setFill(null); + selectionRectangle.setStroke(Paint.valueOf("BLACK")); + root.getChildren().add(selectionRectangle); + + // Add mouse event handlers to the ImageView + imageView.setOnMousePressed(this::handleMousePressed); + imageView.setOnMouseDragged(this::handleMouseDragged); + imageView.setOnMouseReleased(this::handleMouseReleased); + + // Create a scene with the root and set the CSS style scene = new javafx.scene.Scene(root, 1400, 830); scene.getStylesheets().add(getClass().getResource("/style.css").toExternalForm()); @@ -407,6 +424,56 @@ public class Scene { textFields.getyMaxInput().setText(String.valueOf(fractalOperations.getChaosGame().getDescription().getMaxCoords().getX1())); } + private void handleMousePressed(javafx.scene.input.MouseEvent event) { + startX = event.getX(); + startY = event.getY(); + selectionRectangle.setX(startX); + selectionRectangle.setY(startY); + selectionRectangle.setWidth(0); + selectionRectangle.setHeight(0); + } + + private void handleMouseDragged(javafx.scene.input.MouseEvent event) { + endX = event.getX(); + endY = event.getY(); + selectionRectangle.setWidth(Math.abs(endX - startX)); + selectionRectangle.setHeight(Math.abs(endY - startY)); + selectionRectangle.setX(Math.min(startX, endX)); + selectionRectangle.setY(Math.min(startY, endY)); + } + + private void handleMouseReleased(javafx.scene.input.MouseEvent event) { + endX = event.getX(); + endY = event.getY(); + if (Math.abs(endX - startX) > 5 && Math.abs(endY - startY) > 5) { + applyZoom(); + } + selectionRectangle.setWidth(0); + selectionRectangle.setHeight(0); + } + + private void applyZoom() { + double imageWidth = imageView.getBoundsInLocal().getWidth(); + double imageHeight = imageView.getBoundsInLocal().getHeight(); + + double xMin = fractalOperations.getChaosGame().getDescription().getMinCoords().getX0(); + double yMin = fractalOperations.getChaosGame().getDescription().getMinCoords().getX1(); + double xMax = fractalOperations.getChaosGame().getDescription().getMaxCoords().getX0(); + double yMax = fractalOperations.getChaosGame().getDescription().getMaxCoords().getX1(); + + double newMinX = xMin + (startX / imageWidth) * (xMax - xMin); + double newMaxX = xMin + (endX / imageWidth) * (xMax - xMin); + double newMinY = yMin + (startY / imageHeight) * (yMax - yMin); + double newMaxY = yMin + (endY / imageHeight) * (yMax - yMin); + + Vector2D newMinCoords = new Vector2D(Math.min(newMinX, newMaxX), Math.min(newMinY, newMaxY)); + Vector2D newMaxCoords = new Vector2D(Math.max(newMinX, newMaxX), Math.max(newMinY, newMaxY)); + + fractalOperations.updateMinAndMaxFractal(newMinCoords, newMaxCoords); + updateVectorInputFields(); + fractalOperations.drawFractal(100000000); // Optionally redraw with initial iterations + } + public void setUpStage(Stage primaryStage) { primaryStage.setTitle("ChaosGame"); primaryStage.setScene(scene); -- GitLab From cc855a3b429b600ba5389dc27a96d1a85ea90113 Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Tue, 21 May 2024 22:17:29 +0200 Subject: [PATCH 162/168] Refactoring and exception handling for files added --- .../java/edu/ntnu/idatt2003/ChaosGameCLI.java | 12 +++--- .../idatt2003/controller/ButtonObserver.java | 13 ++++++- .../controller/TextFieldObserver.java | 1 + .../{model => util}/ChaosGameFileHandler.java | 26 +++++++------ .../ExceptionHandler.java | 10 ++++- .../util/InvalidFileFormatException.java | 7 ++++ .../InvalidInputException.java | 2 +- .../java/edu/ntnu/idatt2003/view/App.java | 2 +- .../view/components/FractalOperations.java | 39 ++++--------------- .../edu/ntnu/idatt2003/view/scenes/Scene.java | 20 +++++++--- .../model/ChaosGameFileHandlerTest.java | 18 ++++----- 11 files changed, 83 insertions(+), 67 deletions(-) rename src/main/java/edu/ntnu/idatt2003/{model => util}/ChaosGameFileHandler.java (87%) rename src/main/java/edu/ntnu/idatt2003/{controller => util}/ExceptionHandler.java (82%) create mode 100644 src/main/java/edu/ntnu/idatt2003/util/InvalidFileFormatException.java rename src/main/java/edu/ntnu/idatt2003/{controller => util}/InvalidInputException.java (89%) diff --git a/src/main/java/edu/ntnu/idatt2003/ChaosGameCLI.java b/src/main/java/edu/ntnu/idatt2003/ChaosGameCLI.java index 469f55a..884fd54 100644 --- a/src/main/java/edu/ntnu/idatt2003/ChaosGameCLI.java +++ b/src/main/java/edu/ntnu/idatt2003/ChaosGameCLI.java @@ -1,10 +1,10 @@ package edu.ntnu.idatt2003; +import edu.ntnu.idatt2003.util.ChaosGameFileHandler; +import edu.ntnu.idatt2003.util.InvalidFileFormatException; import edu.ntnu.idatt2003.model.*; import java.io.IOException; -import java.util.ArrayList; -import java.util.List; import java.util.Scanner; public class ChaosGameCLI { @@ -58,12 +58,12 @@ public class ChaosGameCLI { System.out.println("Enter the file path: "); String filePath = scanner.nextLine(); try { - ChaosGameFileHandler handler = new ChaosGameFileHandler(filePath); - ChaosGameDescription description= handler.readFile(); + ChaosGameFileHandler handler = new ChaosGameFileHandler(filePath); + ChaosGameDescription description = handler.readFile(); chaosGame = new ChaosGame(description, 100, 100); System.out.println("Description loaded successfully"); - } catch (IOException e) { - System.out.println("Failed to load description from file"); + } catch (IOException | InvalidFileFormatException e) { + System.out.println("Failed to load description from file: " + e.getMessage()); } } diff --git a/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java b/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java index 66c6ebf..6b8274e 100644 --- a/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java +++ b/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java @@ -1,6 +1,10 @@ package edu.ntnu.idatt2003.controller; import edu.ntnu.idatt2003.model.*; +import edu.ntnu.idatt2003.util.ChaosGameFileHandler; +import edu.ntnu.idatt2003.util.ExceptionHandler; +import edu.ntnu.idatt2003.util.InvalidFileFormatException; +import edu.ntnu.idatt2003.util.InvalidInputException; import edu.ntnu.idatt2003.view.components.Buttons; import edu.ntnu.idatt2003.view.components.FractalOperations; import edu.ntnu.idatt2003.view.components.TextFields; @@ -12,6 +16,7 @@ import javafx.scene.control.TextField; import javafx.stage.FileChooser; import javafx.stage.Stage; import java.io.File; +import java.io.IOException; import java.util.ArrayList; import java.util.List; import javafx.scene.layout.VBox; @@ -103,7 +108,13 @@ public class ButtonObserver implements Observer { fileChooser.setTitle("Select Fractal From File"); File file = fileChooser.showOpenDialog(new Stage()); if (file != null) { - fractalOperations.setFractalCustomAffine(file.getPath()); + try { + ChaosGameFileHandler fileHandler = new ChaosGameFileHandler(file.getPath()); + ChaosGameDescription description = fileHandler.readFile(); + fractalOperations.setFractalCustomAffine(description); + } catch (IOException | InvalidFileFormatException e) { + exceptionHandler.showAlertFileError(e.getMessage()); + } } break; diff --git a/src/main/java/edu/ntnu/idatt2003/controller/TextFieldObserver.java b/src/main/java/edu/ntnu/idatt2003/controller/TextFieldObserver.java index 5f82e99..29746a2 100644 --- a/src/main/java/edu/ntnu/idatt2003/controller/TextFieldObserver.java +++ b/src/main/java/edu/ntnu/idatt2003/controller/TextFieldObserver.java @@ -1,5 +1,6 @@ package edu.ntnu.idatt2003.controller; +import edu.ntnu.idatt2003.util.ExceptionHandler; import edu.ntnu.idatt2003.view.components.FractalOperations; import edu.ntnu.idatt2003.view.components.TextFields; diff --git a/src/main/java/edu/ntnu/idatt2003/model/ChaosGameFileHandler.java b/src/main/java/edu/ntnu/idatt2003/util/ChaosGameFileHandler.java similarity index 87% rename from src/main/java/edu/ntnu/idatt2003/model/ChaosGameFileHandler.java rename to src/main/java/edu/ntnu/idatt2003/util/ChaosGameFileHandler.java index cce3c37..33c4d7e 100644 --- a/src/main/java/edu/ntnu/idatt2003/model/ChaosGameFileHandler.java +++ b/src/main/java/edu/ntnu/idatt2003/util/ChaosGameFileHandler.java @@ -1,6 +1,8 @@ -package edu.ntnu.idatt2003.model; +package edu.ntnu.idatt2003.util; +import edu.ntnu.idatt2003.model.*; + import java.io.BufferedWriter; import java.io.File; import java.io.FileNotFoundException; @@ -31,7 +33,7 @@ public class ChaosGameFileHandler { * @return a ChaosGameDescription * @throws IOException if an I/O error occurs */ - public ChaosGameDescription readFile() throws IOException { + public ChaosGameDescription readFile() throws IOException, InvalidFileFormatException { File file = new File(filePath); List<Transform2D> transforms = new ArrayList<>(); Vector2D minCoords = null; @@ -41,9 +43,13 @@ public class ChaosGameFileHandler { try (Scanner scanner = new Scanner(file)) { while (scanner.hasNextLine()) { String line = scanner.nextLine().trim(); - if (line.isEmpty() || line.startsWith("#") || line.contains("Type of transform")) { + if (line.isEmpty() || line.startsWith("#")) { + continue; // Ignore comments and empty lines + } + + if (line.contains("Type of transform")) { type = line.split("#")[0].trim(); - continue; // Ignore comments and header information + continue; } if (line.contains("Lower left")) { @@ -57,15 +63,12 @@ public class ChaosGameFileHandler { } try { - Transform2D transform; - assert type != null; - if (type.equals("Julia")) { + if (type != null && type.equals("Julia")) { transforms = parseJulia(line.split("#")[0].trim()); } else { - transform = parseAffineTransform(line.split("#")[0].trim()); + Transform2D transform = parseAffineTransform(line.split("#")[0].trim()); transforms.add(transform); } - } catch (IllegalArgumentException e) { System.err.println("Error parsing transform from line: " + line); } @@ -75,13 +78,14 @@ public class ChaosGameFileHandler { throw new IOException("File not found: " + filePath, e); } - if (minCoords == null || maxCoords == null || transforms.isEmpty()) { - throw new IOException("Failed to properly parse the file: Missing essential data."); + if (type == null || minCoords == null || maxCoords == null || transforms.isEmpty()) { + throw new InvalidFileFormatException("Failed to properly parse the file: Missing essential data."); } return new ChaosGameDescription(transforms, minCoords, maxCoords); } + /** * Parses a line of text to create an AffineTransform2D. * diff --git a/src/main/java/edu/ntnu/idatt2003/controller/ExceptionHandler.java b/src/main/java/edu/ntnu/idatt2003/util/ExceptionHandler.java similarity index 82% rename from src/main/java/edu/ntnu/idatt2003/controller/ExceptionHandler.java rename to src/main/java/edu/ntnu/idatt2003/util/ExceptionHandler.java index 72777b1..95e1e1f 100644 --- a/src/main/java/edu/ntnu/idatt2003/controller/ExceptionHandler.java +++ b/src/main/java/edu/ntnu/idatt2003/util/ExceptionHandler.java @@ -1,4 +1,4 @@ -package edu.ntnu.idatt2003.controller; +package edu.ntnu.idatt2003.util; import javafx.scene.control.Alert; @@ -34,6 +34,14 @@ public class ExceptionHandler { alert.showAndWait(); } + public void showAlertFileError(String message) { + Alert alert = new Alert(Alert.AlertType.ERROR); + alert.setTitle("File Error"); + alert.setHeaderText("An error occurred"); + alert.setContentText(message); + alert.showAndWait(); + } + public void validatePostiviteInteger(int number) { if (number < 1) { throw new IllegalArgumentException("The number must be greater than 0."); diff --git a/src/main/java/edu/ntnu/idatt2003/util/InvalidFileFormatException.java b/src/main/java/edu/ntnu/idatt2003/util/InvalidFileFormatException.java new file mode 100644 index 0000000..6b8a0bd --- /dev/null +++ b/src/main/java/edu/ntnu/idatt2003/util/InvalidFileFormatException.java @@ -0,0 +1,7 @@ +package edu.ntnu.idatt2003.util; + +public class InvalidFileFormatException extends Exception { + public InvalidFileFormatException(String message) { + super(message); + } +} diff --git a/src/main/java/edu/ntnu/idatt2003/controller/InvalidInputException.java b/src/main/java/edu/ntnu/idatt2003/util/InvalidInputException.java similarity index 89% rename from src/main/java/edu/ntnu/idatt2003/controller/InvalidInputException.java rename to src/main/java/edu/ntnu/idatt2003/util/InvalidInputException.java index fad9bf5..6c2522b 100644 --- a/src/main/java/edu/ntnu/idatt2003/controller/InvalidInputException.java +++ b/src/main/java/edu/ntnu/idatt2003/util/InvalidInputException.java @@ -1,4 +1,4 @@ -package edu.ntnu.idatt2003.controller; +package edu.ntnu.idatt2003.util; /** * Custom exception for invalid input. diff --git a/src/main/java/edu/ntnu/idatt2003/view/App.java b/src/main/java/edu/ntnu/idatt2003/view/App.java index c4a6c51..b5d4e45 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/App.java +++ b/src/main/java/edu/ntnu/idatt2003/view/App.java @@ -11,7 +11,7 @@ public class App extends Application { @Override public void start(Stage primaryStage) { - Scene scene = new Scene("Sierpinski Triangle"); + Scene scene = new Scene(); scene.setUpStage(primaryStage); } } diff --git a/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java b/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java index 31332ff..d72dc26 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java +++ b/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java @@ -1,5 +1,6 @@ package edu.ntnu.idatt2003.view.components; +import edu.ntnu.idatt2003.util.ChaosGameFileHandler; import edu.ntnu.idatt2003.controller.ChaosGameObserver; import edu.ntnu.idatt2003.model.*; import java.io.IOException; @@ -26,30 +27,12 @@ public class FractalOperations implements ChaosGameObserver { * @param imageView the ImageView * @param initialFractal the initial fractal */ - public FractalOperations(ImageView imageView, String initialFractal) { + public FractalOperations(ImageView imageView) { this.imageView = imageView; - this.currentFractal = initialFractal; + this.currentFractal = "initialFractal"; this.writableImage = new WritableImage(400, 400); this.imageView.setImage(writableImage); - setFractal(initialFractal); - resetIterations(); - } - - private void setFractal(String initialFractal) { - switch (initialFractal) { - case "Sierpinski Triangle": - setFractalToSierpinskiTriangle(); - break; - case "Julia Set": - setFractalToJuliaSet(); - break; - case "Barnsley Fern": - setFractalToBransleysFern(); - break; - default: - setBlankImageView(); - break; - } + setBlankImageView(); } public void drawFractal(int iterations) { @@ -114,16 +97,10 @@ public class FractalOperations implements ChaosGameObserver { * * @param filePath the file path */ - public void setFractalCustomAffine(String filePath) { - ChaosGameFileHandler fileHandler = new ChaosGameFileHandler(filePath); - try { - ChaosGameDescription description = fileHandler.readFile(); - this.chaosGame = new ChaosGame(description, 400, 400); - this.chaosGame.addObserver(this); - drawFractal(0); - } catch (IOException e) { - e.printStackTrace(); - } + public void setFractalCustomAffine(ChaosGameDescription description) { + this.chaosGame = new ChaosGame(description, 400, 400); + this.chaosGame.addObserver(this); + drawFractal(0); } /** diff --git a/src/main/java/edu/ntnu/idatt2003/view/scenes/Scene.java b/src/main/java/edu/ntnu/idatt2003/view/scenes/Scene.java index 6521e2d..8119fb6 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/scenes/Scene.java +++ b/src/main/java/edu/ntnu/idatt2003/view/scenes/Scene.java @@ -46,13 +46,13 @@ public class Scene { /** * Constructor for the AffineScene class */ - public Scene(String fractalType) { + public Scene() { buttons = new Buttons(); comboBoxes = new ComboBoxes(); labels = new Labels(); textFields = new TextFields(); initializeComponents(); - fractalOperations = new FractalOperations(imageView, fractalType); + fractalOperations = new FractalOperations(imageView); buttonObserver = new ButtonObserver(buttons, fractalOperations, textFields, iterationsLabel, inputContainer); comboBoxObserver = new ComboBoxObserver(comboBoxes, fractalOperations); labelObserver = new LabelObserver(buttons, comboBoxes, textFields, iterationsLabel); @@ -65,6 +65,7 @@ public class Scene { removeFractalFromFileBox(); addSaveFractalToFileButton(); addCInputBox(); + createMaxMinVectorInputAndUpdateAll(); updateVectorInputFields(); buttonObserver.setInputContainer(inputContainer); } else if ("Sierpinski Triangle".equals(newValue)) { @@ -73,6 +74,7 @@ public class Scene { removeFractalFromFileBox(); addMatrixVectorInputBoxes(); addSaveFractalToFileButton(); + createMaxMinVectorInputAndUpdateAll(); updateVectorInputFields(); buttonObserver.setInputContainer(inputContainer); } else if ("Barnsley Fern".equals(newValue)) { @@ -80,18 +82,21 @@ public class Scene { removeCInputBox(); removeFractalFromFileBox(); addMatrixVectorInputBoxes(); + createMaxMinVectorInputAndUpdateAll(); addSaveFractalToFileButton(); updateVectorInputFields(); buttonObserver.setInputContainer(inputContainer); } else if ("Fractal From File".equals(newValue)) { removeCInputBox(); removeMatrixVectorInputBoxes(); + removeMaxMinVectorInput(); + addSaveFractalToFileButton(); addFractalFromFileBox(); - updateVectorInputFields(); } }); // Initial setup based on the provided fractal type + /* if ("Julia Set".equals(fractalType)) { addCInputBox(); addSaveFractalToFileButton(); @@ -101,8 +106,7 @@ public class Scene { } else if ("Fractal From File".equals(fractalType)) { addFractalFromFileBox(); } - - createMaxMinVectorInputAndUpdateAll(); + */ } private void initializeComponents() { @@ -397,7 +401,11 @@ public class Scene { } public void removeMaxMinVectorInput() { - inputBox.getChildren().remove(1); + if (inputBox.getChildren().size() > 1) { + inputBox.getChildren().remove(1); + } else if (inputBox.getChildren().size() == 1) { + inputBox.getChildren().remove(0); + } } public void updateVectorInputFields() { diff --git a/src/test/java/edu/ntnu/idatt2003/model/ChaosGameFileHandlerTest.java b/src/test/java/edu/ntnu/idatt2003/model/ChaosGameFileHandlerTest.java index 0237238..5705380 100644 --- a/src/test/java/edu/ntnu/idatt2003/model/ChaosGameFileHandlerTest.java +++ b/src/test/java/edu/ntnu/idatt2003/model/ChaosGameFileHandlerTest.java @@ -1,5 +1,7 @@ package edu.ntnu.idatt2003.model; +import edu.ntnu.idatt2003.util.InvalidFileFormatException; +import edu.ntnu.idatt2003.util.ChaosGameFileHandler; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; @@ -28,7 +30,7 @@ public class ChaosGameFileHandlerTest { } @Test - public void testReadFileAffine() throws IOException { + public void testReadFileAffine() throws IOException, InvalidFileFormatException { createTestFileAffine(); ChaosGameDescription description = fileHandler.readFile(); assertNotNull(description); @@ -43,7 +45,7 @@ public class ChaosGameFileHandlerTest { @Test @DisplayName("Positive test for readFile() with Julia transform") - public void testReadFileJulia() throws IOException { + public void testReadFileJulia() throws IOException, InvalidFileFormatException { createTestFileJulia(); ChaosGameDescription description = fileHandler.readFile(); assertNotNull(description); @@ -57,11 +59,11 @@ public class ChaosGameFileHandlerTest { } @Test - public void testWriteToFile() throws IOException { + public void testWriteToFile() throws IOException, InvalidFileFormatException { ChaosGameDescription description = new ChaosGameDescription( - List.of(new AffineTransform2D(new Matrix2x2(1, 0, 0, 1), new Vector2D(0, 0))), - new Vector2D(-1, -1), - new Vector2D(1, 1) + List.of(new AffineTransform2D(new Matrix2x2(1, 0, 0, 1), new Vector2D(0, 0))), + new Vector2D(-1, -1), + new Vector2D(1, 1) ); String filePath = "outputTestFile.txt"; @@ -92,12 +94,10 @@ public class ChaosGameFileHandlerTest { @Test public void testReadEmptyFile() throws IOException { createEmptyFile(); - Exception exception = assertThrows(IOException.class, () -> fileHandler.readFile()); + Exception exception = assertThrows(InvalidFileFormatException.class, () -> fileHandler.readFile()); assertTrue(exception.getMessage().contains("Missing essential data")); } - - private void createTestFileJulia() { try (PrintWriter out = new PrintWriter(new FileWriter(TEST_FILE_PATH))) { out.println("Julia # Type of transform"); -- GitLab From 0927c975902f015e8337729ec81ebf7e39b41251 Mon Sep 17 00:00:00 2001 From: Anders <alunde@stud.ntnu.no> Date: Wed, 22 May 2024 10:16:37 +0200 Subject: [PATCH 163/168] Added negative tests to ChaosGameFileHandlerTest and added javadoc to test classes --- pom.xml | 7 +- .../model/AffineTransform2dTest.java | 84 ++++---- .../ntnu/idatt2003/model/ChaosCanvasTest.java | 21 ++ .../ChaosGameDescriptionFactoryTest.java | 12 ++ .../model/ChaosGameFileHandlerTest.java | 115 ----------- .../ntnu/idatt2003/model/ChaosGameTest.java | 15 ++ .../edu/ntnu/idatt2003/model/ComplexTest.java | 10 + .../idatt2003/model/JuliaTransformTest.java | 115 +++++++---- .../ntnu/idatt2003/model/Matrix2x2Test.java | 19 ++ .../ntnu/idatt2003/model/Vector2dTest.java | 12 ++ .../util/ChaosGameFileHandlerTest.java | 188 ++++++++++++++++++ 11 files changed, 408 insertions(+), 190 deletions(-) delete mode 100644 src/test/java/edu/ntnu/idatt2003/model/ChaosGameFileHandlerTest.java create mode 100644 src/test/java/edu/ntnu/idatt2003/util/ChaosGameFileHandlerTest.java diff --git a/pom.xml b/pom.xml index 87f2985..0124f4f 100644 --- a/pom.xml +++ b/pom.xml @@ -51,7 +51,12 @@ <artifactId>javafx-controls</artifactId> <version>21.0.1</version> </dependency> - + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-core</artifactId> + <version>4.0.0</version> + <scope>test</scope> + </dependency> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter</artifactId> diff --git a/src/test/java/edu/ntnu/idatt2003/model/AffineTransform2dTest.java b/src/test/java/edu/ntnu/idatt2003/model/AffineTransform2dTest.java index 9446024..bd4128c 100644 --- a/src/test/java/edu/ntnu/idatt2003/model/AffineTransform2dTest.java +++ b/src/test/java/edu/ntnu/idatt2003/model/AffineTransform2dTest.java @@ -7,11 +7,17 @@ import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; +/** + * Test class for the AffineTransform2d class. + */ public class AffineTransform2dTest { private Matrix2x2 matrix; private Vector2D vector; private Vector2D point; + /** + * Sets up the test objects before each test. + */ @BeforeEach public void setUp() { matrix = new Matrix2x2(1, 2, 3, 4); @@ -19,46 +25,52 @@ public class AffineTransform2dTest { point = new Vector2D(1.0, 2.0); } - @Nested - @DisplayName("Positive tests for the AffineTransform2d class.") - class PositiveAffineTransform2dTest { - @Test - void testTransform() { - AffineTransform2D transform = new AffineTransform2D(matrix, point); - Vector2D result = transform.transform(vector); + /** + * Tests the transform method. + */ + @Test + void testTransform() { + AffineTransform2D transform = new AffineTransform2D(matrix, point); + Vector2D result = transform.transform(vector); - assertEquals(6, result.getX0()); - assertEquals(13, result.getX1()); - } - - @Test - void testGetMatrix() { - AffineTransform2D transform = new AffineTransform2D(matrix, point); - assertEquals(matrix, transform.getMatrix()); - } + assertEquals(6, result.getX0()); + assertEquals(13, result.getX1()); + } - @Test - void testGetVector() { - AffineTransform2D transform = new AffineTransform2D(matrix, point); - assertEquals(point, transform.getVector()); - } + /** + * Tests the getMatrix method. + */ + @Test + void testGetMatrix() { + AffineTransform2D transform = new AffineTransform2D(matrix, point); + assertEquals(matrix, transform.getMatrix()); + } - @Test - void testToFormattedString() { - AffineTransform2D transform = new AffineTransform2D(matrix, point); - String result = transform.toFormattedString(); - assertEquals("1.00, 2.00, 3.00, 4.00, 1.00, 2.00", result); - } + /** + * Tests the getVector method. + */ + @Test + void testGetVector() { + AffineTransform2D transform = new AffineTransform2D(matrix, point); + assertEquals(point, transform.getVector()); + } - @Test - void getTransformType() { - AffineTransform2D transform = new AffineTransform2D(matrix, point); - assertEquals("Affine2D", transform.getTransformType()); - } + /** + * Tests the toFormattedString method. + */ + @Test + void testToFormattedString() { + AffineTransform2D transform = new AffineTransform2D(matrix, point); + String result = transform.toFormattedString(); + assertEquals("1.00, 2.00, 3.00, 4.00, 1.00, 2.00", result); + } - @Nested - @DisplayName("Negative tests for the AffineTransform2d class.") - class NegativeAffineTransform2dTest { - } + /** + * Tests the getTransformType method. + */ + @Test + void getTransformType() { + AffineTransform2D transform = new AffineTransform2D(matrix, point); + assertEquals("Affine2D", transform.getTransformType()); } } diff --git a/src/test/java/edu/ntnu/idatt2003/model/ChaosCanvasTest.java b/src/test/java/edu/ntnu/idatt2003/model/ChaosCanvasTest.java index 963ad1d..f5e1e1b 100644 --- a/src/test/java/edu/ntnu/idatt2003/model/ChaosCanvasTest.java +++ b/src/test/java/edu/ntnu/idatt2003/model/ChaosCanvasTest.java @@ -4,14 +4,23 @@ import static org.junit.Assert.*; import org.junit.Before; import org.junit.Test; +/** + * Test class for the ChaosCanvas class. + */ public class ChaosCanvasTest { private ChaosCanvas canvas; + /** + * Set up a new canvas before each test. + */ @Before public void setUp() { canvas = new ChaosCanvas(100, 100, new Vector2D(0, 0), new Vector2D(1, 1)); } + /** + * Test the initial state of the canvas. + */ @Test public void testInitialCanvasState() { assertEquals(100, canvas.getWidth()); @@ -19,6 +28,9 @@ public class ChaosCanvasTest { assertNotNull(canvas.getCanvasArray()); } + /** + * Test that the putPixel and getPixel methods work as expected. + */ @Test public void testPutAndGetPixel() { Vector2D point = new Vector2D(0.5, 0.5); @@ -27,6 +39,9 @@ public class ChaosCanvasTest { assertEquals(-1, canvas.getPixel(new Vector2D(-1, -1))); // Test out of bounds } + /** + * Test that the clear method resets the canvas. + */ @Test public void testClear() { Vector2D point = new Vector2D(0.5, 0.5); @@ -35,6 +50,9 @@ public class ChaosCanvasTest { assertEquals(0, canvas.getPixel(point)); } + /** + * Test that the getWidth and getHeight methods work as expected. + */ @Test public void testTransformationAccuracy() { // Place a pixel at a specific point. @@ -51,6 +69,9 @@ public class ChaosCanvasTest { assertEquals(0, canvas.getPixel(new Vector2D(0.49, 0.5))); } + /** + * Test that the toAscii method works as expected. + */ @Test public void testToAscii() { Vector2D point = new Vector2D(0.5, 0.5); diff --git a/src/test/java/edu/ntnu/idatt2003/model/ChaosGameDescriptionFactoryTest.java b/src/test/java/edu/ntnu/idatt2003/model/ChaosGameDescriptionFactoryTest.java index 8f0b7a6..d2b79f5 100644 --- a/src/test/java/edu/ntnu/idatt2003/model/ChaosGameDescriptionFactoryTest.java +++ b/src/test/java/edu/ntnu/idatt2003/model/ChaosGameDescriptionFactoryTest.java @@ -3,8 +3,14 @@ package edu.ntnu.idatt2003.model; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; +/** + * Test class for the ChaosGameDescriptionFactory class. + */ public class ChaosGameDescriptionFactoryTest { + /** + * Tests the createSierpinskiTriangle method. + */ @Test public void testCreateSierpinskiTriangle() { ChaosGameDescription description = ChaosGameDescriptionFactory.createSierpinskiTriangle(); @@ -13,6 +19,9 @@ public class ChaosGameDescriptionFactoryTest { assertInstanceOf(AffineTransform2D.class, description.getTransforms().getFirst()); } + /** + * Tests the createBarnsleyFern method. + */ @Test public void testCreateBarnsleyFern() { ChaosGameDescription description = ChaosGameDescriptionFactory.createBarnsleyFern(); @@ -21,6 +30,9 @@ public class ChaosGameDescriptionFactoryTest { assertInstanceOf(AffineTransform2D.class, description.getTransforms().getFirst()); } + /** + * Tests the createJuliaSet method. + */ @Test public void testCreateJuliaSet() { Complex c = new Complex(0.285, 0.01); diff --git a/src/test/java/edu/ntnu/idatt2003/model/ChaosGameFileHandlerTest.java b/src/test/java/edu/ntnu/idatt2003/model/ChaosGameFileHandlerTest.java deleted file mode 100644 index 5705380..0000000 --- a/src/test/java/edu/ntnu/idatt2003/model/ChaosGameFileHandlerTest.java +++ /dev/null @@ -1,115 +0,0 @@ -package edu.ntnu.idatt2003.model; - -import edu.ntnu.idatt2003.util.InvalidFileFormatException; -import edu.ntnu.idatt2003.util.ChaosGameFileHandler; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.*; - -import java.io.*; -import java.util.List; - -public class ChaosGameFileHandlerTest { - private static final String TEST_FILE_PATH = "testChaosGameDescription.txt"; - private ChaosGameFileHandler fileHandler; - - @BeforeEach - public void setup() { - fileHandler = new ChaosGameFileHandler(TEST_FILE_PATH); - } - - @AfterEach - public void tearDown() { - File file = new File(TEST_FILE_PATH); - if (file.exists()) { - file.delete(); - } - } - - @Test - public void testReadFileAffine() throws IOException, InvalidFileFormatException { - createTestFileAffine(); - ChaosGameDescription description = fileHandler.readFile(); - assertNotNull(description); - assertEquals(.0, description.getMinCoords().getX0()); - assertEquals(.0, description.getMinCoords().getX1()); - assertEquals(1.0, description.getMaxCoords().getX0()); - assertEquals(1.0, description.getMaxCoords().getX1()); - assertFalse(description.getTransforms().isEmpty()); - assertInstanceOf(AffineTransform2D.class, description.getTransforms().getFirst()); - assertEquals("Affine2D", description.getTransforms().getFirst().getTransformType()); - } - - @Test - @DisplayName("Positive test for readFile() with Julia transform") - public void testReadFileJulia() throws IOException, InvalidFileFormatException { - createTestFileJulia(); - ChaosGameDescription description = fileHandler.readFile(); - assertNotNull(description); - assertEquals(0.0, description.getMinCoords().getX0()); - assertEquals(0.0, description.getMinCoords().getX1()); - assertEquals(1.0, description.getMaxCoords().getX0()); - assertEquals(1.0, description.getMaxCoords().getX1()); - assertFalse(description.getTransforms().isEmpty()); - assertInstanceOf(JuliaTransform.class, description.getTransforms().getFirst()); - assertEquals("Julia", description.getTransforms().getFirst().getTransformType()); - } - - @Test - public void testWriteToFile() throws IOException, InvalidFileFormatException { - ChaosGameDescription description = new ChaosGameDescription( - List.of(new AffineTransform2D(new Matrix2x2(1, 0, 0, 1), new Vector2D(0, 0))), - new Vector2D(-1, -1), - new Vector2D(1, 1) - ); - - String filePath = "outputTestFile.txt"; - fileHandler.writeToFile(filePath, description); - - File outputFile = new File(filePath); - assertTrue(outputFile.exists()); - - ChaosGameFileHandler readHandler = new ChaosGameFileHandler(filePath); - ChaosGameDescription readDescription = readHandler.readFile(); - assertNotNull(readDescription); - outputFile.delete(); // Clean up after test - } - - private void createTestFileAffine() { - try (PrintWriter out = new PrintWriter(new FileWriter(TEST_FILE_PATH))) { - out.println("Affine2D # Type of transform"); - out.println(".0, .0 # Lower left"); - out.println("1.0, 1.0 # Upper right"); - out.println("0.5, 0, 0, 0.5, 0, 0 # 1st transform"); - out.println("0.5, 0, 0, 0.5, 0.25, 0.5 # 2nd transform"); - out.println("0.5, 0, 0, 0.5, 0.5, 0 # 3rd transform"); - } catch (IOException e) { - fail("Failed to create test file."); - } - } - - @Test - public void testReadEmptyFile() throws IOException { - createEmptyFile(); - Exception exception = assertThrows(InvalidFileFormatException.class, () -> fileHandler.readFile()); - assertTrue(exception.getMessage().contains("Missing essential data")); - } - - private void createTestFileJulia() { - try (PrintWriter out = new PrintWriter(new FileWriter(TEST_FILE_PATH))) { - out.println("Julia # Type of transform"); - out.println("0.0, 0.0 # Lower left"); - out.println("1.0, 1.0 # Upper right"); - out.println("0.5, 0.5 #"); - } catch (IOException e) { - fail("Failed to create test file."); - } - } - - private void createEmptyFile() throws IOException { - new PrintWriter(TEST_FILE_PATH).close(); - } -} diff --git a/src/test/java/edu/ntnu/idatt2003/model/ChaosGameTest.java b/src/test/java/edu/ntnu/idatt2003/model/ChaosGameTest.java index 0395be9..e0e6028 100644 --- a/src/test/java/edu/ntnu/idatt2003/model/ChaosGameTest.java +++ b/src/test/java/edu/ntnu/idatt2003/model/ChaosGameTest.java @@ -7,12 +7,18 @@ import java.util.List; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +/** + * Test class for the ChaosGame class. + */ public class ChaosGameTest { private ChaosGame chaosGame; private ChaosGameDescription description; private Vector2D minCoords; private Vector2D maxCoords; + /** + * Sets up the test objects before each test. + */ @BeforeEach void setUp() { // Define the bounds and a simple transform for the test @@ -25,6 +31,9 @@ public class ChaosGameTest { chaosGame = new ChaosGame(description, 100, 100); } + /** + * Tests the initial state of the ChaosGame object. + */ @Test void testInitialSetup() { assertNotNull(chaosGame.getCanvas()); @@ -33,6 +42,9 @@ public class ChaosGameTest { assertEquals(description, chaosGame.getDescription()); } + /** + * Tests the runSteps method. + */ @Test void testRunSteps() { chaosGame.runSteps(10); @@ -40,6 +52,9 @@ public class ChaosGameTest { assertTrue(Arrays.stream(chaosGame.getCanvas().getCanvasArray()).flatMapToInt(Arrays::stream).sum() > 0); } + /** + * Tests a ChaosGame without any transforms. + */ @Test void testNoTransforms() { ChaosGame gameWithNoTransforms = new ChaosGame(new ChaosGameDescription(List.of(), minCoords, maxCoords), 100, 100); diff --git a/src/test/java/edu/ntnu/idatt2003/model/ComplexTest.java b/src/test/java/edu/ntnu/idatt2003/model/ComplexTest.java index 320cb27..043b8df 100644 --- a/src/test/java/edu/ntnu/idatt2003/model/ComplexTest.java +++ b/src/test/java/edu/ntnu/idatt2003/model/ComplexTest.java @@ -7,9 +7,15 @@ import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; +/** + * Test class for the Complex class. + */ public class ComplexTest { private Complex complex; + /** + * Sets up the test objects before each test. + */ @BeforeEach public void setUp() { complex = new Complex(1, 2); @@ -18,6 +24,10 @@ public class ComplexTest { @Nested @DisplayName("Positive tests for the Complex class.") class PositiveComplexTest { + + /** + * Tests the sqrt method + */ @Test void testSqrt() { Complex result = complex.sqrt(); diff --git a/src/test/java/edu/ntnu/idatt2003/model/JuliaTransformTest.java b/src/test/java/edu/ntnu/idatt2003/model/JuliaTransformTest.java index c89690f..d388b3e 100644 --- a/src/test/java/edu/ntnu/idatt2003/model/JuliaTransformTest.java +++ b/src/test/java/edu/ntnu/idatt2003/model/JuliaTransformTest.java @@ -3,13 +3,21 @@ package edu.ntnu.idatt2003.model; import static org.junit.Assert.*; import org.junit.Before; import org.junit.Test; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +/** + * Test class for the JuliaTransform class. + */ public class JuliaTransformTest { private JuliaTransform juliaTransformPos; private JuliaTransform juliaTransformNeg; private Complex testPoint; + /** + * Set up a new JuliaTransform before each test. + */ @Before public void setUp() { testPoint = new Complex(0.285, 0.01); @@ -17,50 +25,81 @@ public class JuliaTransformTest { juliaTransformNeg = new JuliaTransform(testPoint, -1); } - @Test - public void testConstructor_ValidSign() { - assertNotNull("JuliaTransform should not be null with sign 1", juliaTransformPos); - assertNotNull("JuliaTransform should not be null with sign -1", juliaTransformNeg); - } + @Nested + @DisplayName("Positive tests for the JuliaTransform class.") + class PositiveJuliaTransformTest { + /** + * Tests the constructor of the JuliaTransform class. + */ + @Test + public void testConstructor_ValidSign() { + assertNotNull("JuliaTransform should not be null with sign 1", juliaTransformPos); + assertNotNull("JuliaTransform should not be null with sign -1", juliaTransformNeg); + } - @Test(expected = IllegalArgumentException.class) - public void testConstructor_InvalidSign() { - new JuliaTransform(testPoint, 0); - } - @Test - public void testTransform_PositiveSign() { - Vector2D z = new Vector2D(0.5, 0.5); - Vector2D result = juliaTransformPos.transform(z); - Complex expected = new Complex(z.getX0() - testPoint.getReal(), z.getX1() - testPoint.getImaginary()).sqrt(); - assertEquals("The transformed X coordinate does not match", expected.getReal(), result.getX0(), 0.001); - assertEquals("The transformed Y coordinate does not match", expected.getImaginary(), result.getX1(), 0.001); - } + /** + * Tests the transform method with a positive sign. + */ + @Test + public void testTransform_PositiveSign() { + Vector2D z = new Vector2D(0.5, 0.5); + Vector2D result = juliaTransformPos.transform(z); + Complex expected = new Complex(z.getX0() - testPoint.getReal(), z.getX1() - testPoint.getImaginary()).sqrt(); + assertEquals("The transformed X coordinate does not match", expected.getReal(), result.getX0(), 0.001); + assertEquals("The transformed Y coordinate does not match", expected.getImaginary(), result.getX1(), 0.001); + } - @Test - public void testTransform_NegativeSign() { - Vector2D z = new Vector2D(0.5, 0.5); - Vector2D result = juliaTransformNeg.transform(z); - Complex expected = new Complex(z.getX0() - testPoint.getReal(), z.getX1() - testPoint.getImaginary()).sqrt(); - assertEquals("The transformed X coordinate does not match for negative sign", -expected.getReal(), result.getX0(), 0.001); - assertEquals("The transformed Y coordinate does not match for negative sign", -expected.getImaginary(), result.getX1(), 0.001); - } + /** + * Tests the transform method with a negative sign. + */ + @Test + public void testTransform_NegativeSign() { + Vector2D z = new Vector2D(0.5, 0.5); + Vector2D result = juliaTransformNeg.transform(z); + Complex expected = new Complex(z.getX0() - testPoint.getReal(), z.getX1() - testPoint.getImaginary()).sqrt(); + assertEquals("The transformed X coordinate does not match for negative sign", -expected.getReal(), result.getX0(), 0.001); + assertEquals("The transformed Y coordinate does not match for negative sign", -expected.getImaginary(), result.getX1(), 0.001); + } - @Test - public void testGetTransformType() { - String result = juliaTransformNeg.getTransformType(); - assertEquals("Julia", result); - } + /** + * Tests the getTransformType method. + */ + @Test + public void testGetTransformType() { + String result = juliaTransformNeg.getTransformType(); + assertEquals("Julia", result); + } + + /** + * Tests the toFormattedString method. + */ + @Test + public void testToFormattedString() { + String result = juliaTransformNeg.toFormattedString(); + assertEquals("0.28500, 0.01000", result); + } - @Test - public void testToFormattedString() { - String result = juliaTransformNeg.toFormattedString(); - assertEquals("0.28500, 0.01000", result); + /** + * Tests the getPoint method. + */ + @Test + public void testGetPoint() { + Complex result = juliaTransformNeg.getPoint(); + assertEquals(testPoint, result); + } } - @Test - public void testGetPoint() { - Complex result = juliaTransformNeg.getPoint(); - assertEquals(testPoint, result); + @Nested + @DisplayName("Negative tests for the JuliaTransform class.") + class NegativeJuliaTransformTest { + + /** + * Tests the constructor of the JuliaTransform class with an invalid sign. + */ + @Test(expected = IllegalArgumentException.class) + public void testConstructor_InvalidSign() { + new JuliaTransform(testPoint, 0); + } } } diff --git a/src/test/java/edu/ntnu/idatt2003/model/Matrix2x2Test.java b/src/test/java/edu/ntnu/idatt2003/model/Matrix2x2Test.java index 25b3b07..0bdc5a3 100644 --- a/src/test/java/edu/ntnu/idatt2003/model/Matrix2x2Test.java +++ b/src/test/java/edu/ntnu/idatt2003/model/Matrix2x2Test.java @@ -8,6 +8,9 @@ import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotEquals; +/** + * Test class for the Matrix2x2 class. + */ public class Matrix2x2Test { private Matrix2x2 matrix; private Vector2D vector; @@ -21,6 +24,10 @@ public class Matrix2x2Test { @Nested @DisplayName("Positive tests for the Matrix2x2 class.") class PositiveMatrix2x2Test { + + /** + * Tests the multiply method. + */ @Test void testMultiply() { Vector2D result = matrix.multiply(vector); @@ -28,21 +35,33 @@ public class Matrix2x2Test { assertEquals(11, result.getX1()); } + /** + * Tests the getA00 method. + */ @Test void testGetA00() { assertEquals(1, matrix.getA00()); } + /** + * Tests the getA01 method. + */ @Test void testGetA01() { assertEquals(2, matrix.getA01()); } + /** + * Tests the getA10 method. + */ @Test void testGetA10() { assertEquals(3, matrix.getA10()); } + /** + * Tests the getA11 method. + */ @Test void testGetA11() { assertEquals(4, matrix.getA11()); diff --git a/src/test/java/edu/ntnu/idatt2003/model/Vector2dTest.java b/src/test/java/edu/ntnu/idatt2003/model/Vector2dTest.java index d039a18..f1e2962 100644 --- a/src/test/java/edu/ntnu/idatt2003/model/Vector2dTest.java +++ b/src/test/java/edu/ntnu/idatt2003/model/Vector2dTest.java @@ -8,10 +8,16 @@ import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotEquals; +/** + * Test class for the Vector2D class. + */ public class Vector2dTest { private Vector2D vector1; private Vector2D vector2; +/** + * Sets up the test objects before each test. + */ @BeforeEach void setUp() { vector1 = new Vector2D(1, 2); @@ -21,6 +27,9 @@ void setUp() { @DisplayName("Positive tests for the Vector2d class.") class PositiveVector2dTests { + /** + * Tests the add method. + */ @Test void testAdd() { Vector2D result = vector1.add(vector2); @@ -28,6 +37,9 @@ void setUp() { assertEquals(6, result.getX1()); } + /** + * Tests the subtract method. + */ @Test void testSubtract() { Vector2D result = vector1.subtract(vector2); diff --git a/src/test/java/edu/ntnu/idatt2003/util/ChaosGameFileHandlerTest.java b/src/test/java/edu/ntnu/idatt2003/util/ChaosGameFileHandlerTest.java new file mode 100644 index 0000000..2287bd5 --- /dev/null +++ b/src/test/java/edu/ntnu/idatt2003/util/ChaosGameFileHandlerTest.java @@ -0,0 +1,188 @@ +package edu.ntnu.idatt2003.util; + +import edu.ntnu.idatt2003.model.*; +import edu.ntnu.idatt2003.util.InvalidFileFormatException; +import edu.ntnu.idatt2003.util.ChaosGameFileHandler; +import org.junit.jupiter.api.*; + +import static org.junit.jupiter.api.Assertions.*; + +import java.io.*; +import java.util.List; + +/** + * Test class for the ChaosGameFileHandler class. + */ +public class ChaosGameFileHandlerTest { + private static final String TEST_FILE_PATH = "testChaosGameDescription.txt"; + private ChaosGameFileHandler fileHandler; + + /** + * Set up a new ChaosGameFileHandler object before each test. + */ + @BeforeEach + public void setup() { + fileHandler = new ChaosGameFileHandler(TEST_FILE_PATH); + } + + /** + * Clean up after each test. + */ + @AfterEach + public void tearDown() { + File file = new File(TEST_FILE_PATH); + if (file.exists()) { + file.delete(); + } + } + + @Nested + @DisplayName("Positive tests") + class PositiveChaosGameFileHandlerTest { + + /** + * Test reading a file with affine transforms. + * @throws IOException if an I/O error occurs. + * @throws InvalidFileFormatException if the file is not properly formatted. + */ + @Test + void testReadFileAffine() throws IOException, InvalidFileFormatException { + createTestFileAffine(); + ChaosGameDescription description = fileHandler.readFile(); + assertNotNull(description); + assertEquals(.0, description.getMinCoords().getX0()); + assertEquals(.0, description.getMinCoords().getX1()); + assertEquals(1.0, description.getMaxCoords().getX0()); + assertEquals(1.0, description.getMaxCoords().getX1()); + assertFalse(description.getTransforms().isEmpty()); + assertInstanceOf(AffineTransform2D.class, description.getTransforms().getFirst()); + assertEquals("Affine2D", description.getTransforms().getFirst().getTransformType()); + } + + /** + * Test reading a file with a Julia transform. + * @throws IOException if an I/O error occurs. + * @throws InvalidFileFormatException if the file is not properly formatted. + */ + @Test + void testReadFileJulia() throws IOException, InvalidFileFormatException { + createTestFileJulia(); + ChaosGameDescription description = fileHandler.readFile(); + assertNotNull(description); + assertEquals(0.0, description.getMinCoords().getX0()); + assertEquals(0.0, description.getMinCoords().getX1()); + assertEquals(1.0, description.getMaxCoords().getX0()); + assertEquals(1.0, description.getMaxCoords().getX1()); + assertFalse(description.getTransforms().isEmpty()); + assertInstanceOf(JuliaTransform.class, description.getTransforms().getFirst()); + assertEquals("Julia", description.getTransforms().getFirst().getTransformType()); + } + + /** + * Test writing a ChaosGameDescription to a file. + * @throws IOException if an I/O error occurs. + * @throws InvalidFileFormatException if the file is not properly formatted. + */ + @Test + public void testWriteToFile() throws IOException, InvalidFileFormatException { + ChaosGameDescription description = new ChaosGameDescription( + List.of(new AffineTransform2D(new Matrix2x2(1, 0, 0, 1), new Vector2D(0, 0))), + new Vector2D(-1, -1), + new Vector2D(1, 1) + ); + + String filePath = "outputTestFile.txt"; + fileHandler.writeToFile(filePath, description); + + File outputFile = new File(filePath); + assertTrue(outputFile.exists()); + + ChaosGameFileHandler readHandler = new ChaosGameFileHandler(filePath); + ChaosGameDescription readDescription = readHandler.readFile(); + assertNotNull(readDescription); + outputFile.delete(); // Clean up after test + } + + /** + * Create a test file with affine transforms. + */ + private void createTestFileAffine() { + try (PrintWriter out = new PrintWriter(new FileWriter(TEST_FILE_PATH))) { + out.println("Affine2D # Type of transform"); + out.println(".0, .0 # Lower left"); + out.println("1.0, 1.0 # Upper right"); + out.println("0.5, 0, 0, 0.5, 0, 0 # 1st transform"); + out.println("0.5, 0, 0, 0.5, 0.25, 0.5 # 2nd transform"); + out.println("0.5, 0, 0, 0.5, 0.5, 0 # 3rd transform"); + } catch (IOException e) { + fail("Failed to create test file."); + } + } + + + /** + * Create a test file with a Julia transform. + */ + private void createTestFileJulia() { + try (PrintWriter out = new PrintWriter(new FileWriter(TEST_FILE_PATH))) { + out.println("Julia # Type of transform"); + out.println("0.0, 0.0 # Lower left"); + out.println("1.0, 1.0 # Upper right"); + out.println("0.5, 0.5 #"); + } catch (IOException e) { + fail("Failed to create test file."); + } + } + + + + @Nested + @DisplayName("Negative tests") + class NegativeChaosGameFileHandlerTest { + + /** + * Test reading a file with invalid data. + * @throws IOException if an I/O error occurs. + */ + @Test + public void testReadFileInvalidData() throws IOException { + createInvalidDataFile(); + Exception exception = assertThrows(InvalidFileFormatException.class, () -> fileHandler.readFile()); + assertTrue(exception.getMessage().contains("Failed to properly parse the file")); + } + + /** + * Test reading an empty file. + * @throws IOException if an I/O error occurs. + */ + @Test + public void testReadEmptyFile() throws IOException { + createEmptyFile(); + Exception exception = assertThrows(InvalidFileFormatException.class, () -> fileHandler.readFile()); + assertTrue(exception.getMessage().contains("Missing essential data")); + } + + /** + * Create a file with invalid data. + */ + private void createInvalidDataFile() { + try (PrintWriter out = new PrintWriter(new FileWriter(TEST_FILE_PATH))) { + out.println("InvalidTransform # Type of transform"); + out.println(".0, .0 # Lower left"); + out.println("1.0, 1.0 # Upper right"); + out.println("invalid, data, for, transform # Invalid transform data"); + } catch (IOException e) { + fail("Failed to create test file."); + } + } + + /** + * Create an empty file. + * @throws IOException if an I/O error occurs. + */ + private void createEmptyFile() throws IOException { + new PrintWriter(TEST_FILE_PATH).close(); + } + } + } +} -- GitLab From e363de9b45e040a3009fcebc1bf89eae14115d7b Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Wed, 22 May 2024 10:50:02 +0200 Subject: [PATCH 164/168] changed name from updateMatrixAndVector to updateDescription --- .../idatt2003/controller/ButtonObserver.java | 2 +- .../view/components/FractalOperations.java | 38 +++++++++---------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java b/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java index 66c6ebf..76e6e3c 100644 --- a/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java +++ b/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java @@ -203,7 +203,7 @@ public class ButtonObserver implements Observer { ChaosGameDescription description = new ChaosGameDescription(transforms, lowerLeft, upperRight); System.out.println("Transforms updated: " + transforms.size()); - fractalOperations.updateMatrixAndVector(description); + fractalOperations.updateDescription(description); } private double parseInput(TextField textField) throws InvalidInputException { diff --git a/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java b/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java index 31332ff..917ba62 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java +++ b/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java @@ -54,7 +54,6 @@ public class FractalOperations implements ChaosGameObserver { public void drawFractal(int iterations) { chaosGame.runSteps(iterations); - updateImage(); } public void resetIterations() { @@ -65,21 +64,6 @@ public class FractalOperations implements ChaosGameObserver { } } - /** - * Updates the image of the fractal. - */ - public void updateImage() { - PixelWriter pixelWriter = writableImage.getPixelWriter(); - int[][] canvasArray = chaosGame.getCanvas().getCanvasArray(); - for (int y = 0; y < chaosGame.getCanvas().getHeight(); y++) { - for (int x = 0; x < chaosGame.getCanvas().getWidth(); x++) { - int pixel = canvasArray[y][x]; - Color color = pixel == 1 ? Color.BLACK : Color.WHITE; - pixelWriter.setColor(x, y, color); - } - } - } - /** * Sets the fractal to Sierpinski Triangle. */ @@ -138,7 +122,8 @@ public class FractalOperations implements ChaosGameObserver { defaultLowerLeft, defaultUpperRight); this.chaosGame = new ChaosGame(description, 400, 400); this.chaosGame.addObserver(this); - drawFractal(0); + //drawFractal(0); + updateImage(); } /** @@ -157,7 +142,7 @@ public class FractalOperations implements ChaosGameObserver { * * @param description the ChaosGameDescription */ - public void updateMatrixAndVector(ChaosGameDescription description) { + public void updateDescription(ChaosGameDescription description) { this.chaosGame = new ChaosGame(description, 400, 400); this.chaosGame.addObserver(this); drawFractal(0); @@ -208,12 +193,27 @@ public class FractalOperations implements ChaosGameObserver { } } + /** + * Updates the image of the fractal. + */ + public void updateImage() { + PixelWriter pixelWriter = writableImage.getPixelWriter(); + int[][] canvasArray = chaosGame.getCanvas().getCanvasArray(); + for (int y = 0; y < chaosGame.getCanvas().getHeight(); y++) { + for (int x = 0; x < chaosGame.getCanvas().getWidth(); x++) { + int pixel = canvasArray[y][x]; + Color color = pixel == 1 ? Color.BLACK : Color.WHITE; + pixelWriter.setColor(x, y, color); + } + } + } + public ChaosGameDescription getDescription() { return chaosGame.getDescription(); } @Override - public void update(ChaosGame chaosGame) { + public void update() { updateImage(); } } -- GitLab From 4b89039c71de5e372d45670b3b7023e78e1e207c Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Wed, 22 May 2024 10:50:48 +0200 Subject: [PATCH 165/168] removed redundant input parameter in update --- .../edu/ntnu/idatt2003/controller/ChaosGameObserver.java | 2 +- src/main/java/edu/ntnu/idatt2003/model/ChaosGame.java | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/controller/ChaosGameObserver.java b/src/main/java/edu/ntnu/idatt2003/controller/ChaosGameObserver.java index edef5cb..f0d253f 100644 --- a/src/main/java/edu/ntnu/idatt2003/controller/ChaosGameObserver.java +++ b/src/main/java/edu/ntnu/idatt2003/controller/ChaosGameObserver.java @@ -3,5 +3,5 @@ package edu.ntnu.idatt2003.controller; import edu.ntnu.idatt2003.model.ChaosGame; public interface ChaosGameObserver { - void update(ChaosGame chaosGame); + void update(); } diff --git a/src/main/java/edu/ntnu/idatt2003/model/ChaosGame.java b/src/main/java/edu/ntnu/idatt2003/model/ChaosGame.java index 8be6530..2c04924 100644 --- a/src/main/java/edu/ntnu/idatt2003/model/ChaosGame.java +++ b/src/main/java/edu/ntnu/idatt2003/model/ChaosGame.java @@ -11,7 +11,7 @@ import java.util.Random; */ public class ChaosGame { private final ChaosCanvas canvas; - private final ChaosGameDescription description; + private ChaosGameDescription description; private Vector2D currentPoint; private final Random random; private final List<ChaosGameObserver> observers; @@ -68,6 +68,10 @@ public class ChaosGame { return description; } + public void setDescription(ChaosGameDescription description) { + this.description = description; + } + public void addObserver(ChaosGameObserver observer) { observers.add(observer); } @@ -78,7 +82,7 @@ public class ChaosGame { private void notifyObservers() { for (ChaosGameObserver observer : observers) { - observer.update(this); + observer.update(); } } } -- GitLab From 8222f934d4f24f968d5ad5d11477d617dd107eb2 Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Wed, 22 May 2024 13:13:11 +0200 Subject: [PATCH 166/168] Checkstyle --- .../java/edu/ntnu/idatt2003/ChaosGameCLI.java | 10 +- src/main/java/edu/ntnu/idatt2003/Main.java | 3 + .../idatt2003/controller/ButtonObserver.java | 90 +++--- .../controller/ChaosGameObserver.java | 5 +- .../controller/ComboBoxObserver.java | 1 - .../FractalOperations.java | 46 ++- .../controller/TextFieldObserver.java | 1 - .../java/edu/ntnu/idatt2003/view/App.java | 3 + .../idatt2003/view/components/Buttons.java | 1 + .../idatt2003/view/components/TextFields.java | 1 + .../edu/ntnu/idatt2003/view/scenes/Scene.java | 281 ++++++++++-------- 11 files changed, 260 insertions(+), 182 deletions(-) rename src/main/java/edu/ntnu/idatt2003/{view/components => controller}/FractalOperations.java (84%) diff --git a/src/main/java/edu/ntnu/idatt2003/ChaosGameCLI.java b/src/main/java/edu/ntnu/idatt2003/ChaosGameCLI.java index 884fd54..6376f22 100644 --- a/src/main/java/edu/ntnu/idatt2003/ChaosGameCLI.java +++ b/src/main/java/edu/ntnu/idatt2003/ChaosGameCLI.java @@ -1,12 +1,15 @@ package edu.ntnu.idatt2003; +import edu.ntnu.idatt2003.model.ChaosGame; +import edu.ntnu.idatt2003.model.ChaosGameDescription; import edu.ntnu.idatt2003.util.ChaosGameFileHandler; import edu.ntnu.idatt2003.util.InvalidFileFormatException; -import edu.ntnu.idatt2003.model.*; - import java.io.IOException; import java.util.Scanner; +/** + * This class is responsible for handling the command line interface for the Chaos Game. + */ public class ChaosGameCLI { private static Scanner scanner = new Scanner(System.in); private static ChaosGame chaosGame; @@ -16,6 +19,9 @@ public class ChaosGameCLI { cli.run(); } + /** + * Runs the command line interface. + */ public void run() { Scanner scanner = new Scanner(System.in); boolean running = true; diff --git a/src/main/java/edu/ntnu/idatt2003/Main.java b/src/main/java/edu/ntnu/idatt2003/Main.java index dcb0edf..d7c33ab 100644 --- a/src/main/java/edu/ntnu/idatt2003/Main.java +++ b/src/main/java/edu/ntnu/idatt2003/Main.java @@ -3,6 +3,9 @@ package edu.ntnu.idatt2003; import edu.ntnu.idatt2003.view.App; import javafx.application.Application; +/** + * The main class of the application. + */ public class Main extends App { public static void main(String[] args) { Application.launch(App.class, args); diff --git a/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java b/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java index 63f0db5..a3762d9 100644 --- a/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java +++ b/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java @@ -1,27 +1,31 @@ package edu.ntnu.idatt2003.controller; -import edu.ntnu.idatt2003.model.*; +import edu.ntnu.idatt2003.model.AffineTransform2D; +import edu.ntnu.idatt2003.model.ChaosGameDescription; +import edu.ntnu.idatt2003.model.Complex; +import edu.ntnu.idatt2003.model.Matrix2x2; +import edu.ntnu.idatt2003.model.Transform2D; +import edu.ntnu.idatt2003.model.Vector2D; import edu.ntnu.idatt2003.util.ChaosGameFileHandler; import edu.ntnu.idatt2003.util.ExceptionHandler; import edu.ntnu.idatt2003.util.InvalidFileFormatException; import edu.ntnu.idatt2003.util.InvalidInputException; import edu.ntnu.idatt2003.view.components.Buttons; -import edu.ntnu.idatt2003.view.components.FractalOperations; import edu.ntnu.idatt2003.view.components.TextFields; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; import javafx.application.Platform; +import javafx.scene.Node; import javafx.scene.control.Alert; import javafx.scene.control.ButtonType; import javafx.scene.control.Label; import javafx.scene.control.TextField; +import javafx.scene.layout.HBox; +import javafx.scene.layout.VBox; import javafx.stage.FileChooser; import javafx.stage.Stage; -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import javafx.scene.layout.VBox; -import javafx.scene.layout.HBox; -import javafx.scene.Node; /** * This class is responsible for handling button events. @@ -130,17 +134,20 @@ public class ButtonObserver implements Observer { case "btnUpdateAll": try { - double xMin = parseInput(textFields.getxMinInput()); - double yMin = parseInput(textFields.getyMinInput()); - double xMax = parseInput(textFields.getxMaxInput()); - double yMax = parseInput(textFields.getyMaxInput()); + double xmin = parseInput(textFields.getxMinInput()); + double ymin = parseInput(textFields.getyMinInput()); + double xmax = parseInput(textFields.getxMaxInput()); + double ymax = parseInput(textFields.getyMaxInput()); - String selectedFractal = fractalOperations.getChaosGame().getChaosGameDescription().getTransforms().getFirst().getTransformType(); + String selectedFractal = fractalOperations.getChaosGame().getChaosGameDescription() + .getTransforms().getFirst().getTransformType(); if ("Julia".equals(selectedFractal)) { double realPart = parseInput(textFields.getRealPartInput()); double imaginaryPart = parseInput(textFields.getImaginaryPartInput()); - fractalOperations.updateJuliaSet(new Complex(realPart, imaginaryPart), -1, new Vector2D(xMin, yMin), new Vector2D(xMax, yMax)); - fractalOperations.updateMinAndMaxFractal(new Vector2D(xMin, yMin), new Vector2D(xMax, yMax)); + fractalOperations.updateJuliaSet(new Complex(realPart, imaginaryPart), -1, + new Vector2D(xmin, ymin), new Vector2D(xmax, ymax)); + fractalOperations.updateMinAndMaxFractal(new Vector2D(xmin, ymin), + new Vector2D(xmax, ymax)); fractalOperations.resetIterations(); } else if ("Affine2D".equals(selectedFractal)) { updateAffineTransforms(inputContainer); @@ -148,9 +155,8 @@ public class ButtonObserver implements Observer { } } catch (InvalidInputException e) { exceptionHandler.showAlertDoubleInvalid(e.getInvalidInput()); - break; } - + break; default: break; } @@ -164,10 +170,14 @@ public class ButtonObserver implements Observer { VBox matrixBox = (VBox) matrixVectorBox.getChildren().get(0); VBox vectorBox = (VBox) matrixVectorBox.getChildren().get(1); - TextField matrixInput1 = (TextField) ((HBox) matrixBox.getChildren().get(1)).getChildren().get(0); - TextField matrixInput2 = (TextField) ((HBox) matrixBox.getChildren().get(1)).getChildren().get(1); - TextField matrixInput3 = (TextField) ((HBox) matrixBox.getChildren().get(2)).getChildren().get(0); - TextField matrixInput4 = (TextField) ((HBox) matrixBox.getChildren().get(2)).getChildren().get(1); + TextField matrixInput1 = (TextField) ((HBox) matrixBox.getChildren() + .get(1)).getChildren().get(0); + TextField matrixInput2 = (TextField) ((HBox) matrixBox.getChildren() + .get(1)).getChildren().get(1); + TextField matrixInput3 = (TextField) ((HBox) matrixBox.getChildren() + .get(2)).getChildren().get(0); + TextField matrixInput4 = (TextField) ((HBox) matrixBox.getChildren() + .get(2)).getChildren().get(1); TextField vectorInput1 = (TextField) vectorBox.getChildren().get(1); TextField vectorInput2 = (TextField) vectorBox.getChildren().get(2); @@ -179,7 +189,8 @@ public class ButtonObserver implements Observer { double v0 = parseInput(vectorInput1); double v1 = parseInput(vectorInput2); - Transform2D transform = new AffineTransform2D(new Matrix2x2(m00, m01, m10, m11), new Vector2D(v0, v1)); + Transform2D transform = new AffineTransform2D(new Matrix2x2(m00, m01, m10, m11), + new Vector2D(v0, v1)); transforms.add(transform); } catch (InvalidInputException e) { exceptionHandler.showAlertDoubleInvalid(e.getInvalidInput()); @@ -187,30 +198,33 @@ public class ButtonObserver implements Observer { } } - double xMin, yMin, xMax, yMax; + double xmin; + double ymin; + double xmax; + double ymax; try { - xMin = Double.parseDouble(textFields.getxMinInput().getText()); - yMin = Double.parseDouble(textFields.getyMinInput().getText()); - xMax = Double.parseDouble(textFields.getxMaxInput().getText()); - yMax = Double.parseDouble(textFields.getyMaxInput().getText()); + xmin = Double.parseDouble(textFields.getxMinInput().getText()); + ymin = Double.parseDouble(textFields.getyMinInput().getText()); + xmax = Double.parseDouble(textFields.getxMaxInput().getText()); + ymax = Double.parseDouble(textFields.getyMaxInput().getText()); } catch (NumberFormatException e) { // Set to default values if parsing fails if ("Barnsley Fern".equals(fractalOperations.getCurrentFractal())) { - xMin = -2.5; - yMin = 0; - xMax = 2.5; - yMax = 10; + xmin = -2.5; + ymin = 0; + xmax = 2.5; + ymax = 10; } else { - xMin = 0; - yMin = 0; - xMax = 1; - yMax = 1; + xmin = 0; + ymin = 0; + xmax = 1; + ymax = 1; } } - Vector2D lowerLeft = new Vector2D(xMin, yMin); - Vector2D upperRight = new Vector2D(xMax, yMax); + Vector2D lowerLeft = new Vector2D(xmin, ymin); + Vector2D upperRight = new Vector2D(xmax, ymax); ChaosGameDescription description = new ChaosGameDescription(transforms, lowerLeft, upperRight); System.out.println("Transforms updated: " + transforms.size()); diff --git a/src/main/java/edu/ntnu/idatt2003/controller/ChaosGameObserver.java b/src/main/java/edu/ntnu/idatt2003/controller/ChaosGameObserver.java index f0d253f..f27d136 100644 --- a/src/main/java/edu/ntnu/idatt2003/controller/ChaosGameObserver.java +++ b/src/main/java/edu/ntnu/idatt2003/controller/ChaosGameObserver.java @@ -1,7 +1,8 @@ package edu.ntnu.idatt2003.controller; -import edu.ntnu.idatt2003.model.ChaosGame; - +/** + * This interface is responsible for handling observer events. + */ public interface ChaosGameObserver { void update(); } diff --git a/src/main/java/edu/ntnu/idatt2003/controller/ComboBoxObserver.java b/src/main/java/edu/ntnu/idatt2003/controller/ComboBoxObserver.java index 9ffc509..2ac7ac3 100644 --- a/src/main/java/edu/ntnu/idatt2003/controller/ComboBoxObserver.java +++ b/src/main/java/edu/ntnu/idatt2003/controller/ComboBoxObserver.java @@ -1,7 +1,6 @@ package edu.ntnu.idatt2003.controller; import edu.ntnu.idatt2003.view.components.ComboBoxes; -import edu.ntnu.idatt2003.view.components.FractalOperations; /** * This class is responsible for handling combobox events. diff --git a/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java b/src/main/java/edu/ntnu/idatt2003/controller/FractalOperations.java similarity index 84% rename from src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java rename to src/main/java/edu/ntnu/idatt2003/controller/FractalOperations.java index 59056ae..1fbd536 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/components/FractalOperations.java +++ b/src/main/java/edu/ntnu/idatt2003/controller/FractalOperations.java @@ -1,8 +1,15 @@ -package edu.ntnu.idatt2003.view.components; +package edu.ntnu.idatt2003.controller; +import static edu.ntnu.idatt2003.model.ChaosGameDescriptionFactory.createJuliaSet; + +import edu.ntnu.idatt2003.model.AffineTransform2D; +import edu.ntnu.idatt2003.model.ChaosGame; +import edu.ntnu.idatt2003.model.ChaosGameDescription; +import edu.ntnu.idatt2003.model.ChaosGameDescriptionFactory; +import edu.ntnu.idatt2003.model.Complex; +import edu.ntnu.idatt2003.model.JuliaTransform; +import edu.ntnu.idatt2003.model.Vector2D; import edu.ntnu.idatt2003.util.ChaosGameFileHandler; -import edu.ntnu.idatt2003.controller.ChaosGameObserver; -import edu.ntnu.idatt2003.model.*; import java.io.IOException; import java.util.Arrays; import javafx.scene.image.ImageView; @@ -10,8 +17,6 @@ import javafx.scene.image.PixelWriter; import javafx.scene.image.WritableImage; import javafx.scene.paint.Color; -import static edu.ntnu.idatt2003.model.ChaosGameDescriptionFactory.createJuliaSet; - /** * This class is responsible for performing operations on the fractals. */ @@ -22,10 +27,10 @@ public class FractalOperations implements ChaosGameObserver { private String currentFractal; /** - * Constructs a FractalOperations object with the given ImageView and initial fractal. + * Constructs a FractalOperations object with the given ImageView. * * @param imageView the ImageView - * @param initialFractal the initial fractal + l */ public FractalOperations(ImageView imageView) { this.imageView = imageView; @@ -39,6 +44,9 @@ public class FractalOperations implements ChaosGameObserver { chaosGame.runSteps(iterations); } + /** + * Resets the iterations of the fractal. + */ public void resetIterations() { if (chaosGame != null) { chaosGame.getCanvas().clear(); @@ -61,7 +69,8 @@ public class FractalOperations implements ChaosGameObserver { * Sets the fractal to Julia Set. */ public void setFractalToJuliaSet() { - this.chaosGame = new ChaosGame(ChaosGameDescriptionFactory.createJuliaSet(new Complex(-0.74543, 0.11301), + this.chaosGame = new ChaosGame(ChaosGameDescriptionFactory + .createJuliaSet(new Complex(-0.74543, 0.11301), 1), 400, 400); this.chaosGame.addObserver(this); drawFractal(0); @@ -78,8 +87,6 @@ public class FractalOperations implements ChaosGameObserver { /** * Sets the fractal to custom affine. - * - * @param filePath the file path */ public void setFractalCustomAffine(ChaosGameDescription description) { this.chaosGame = new ChaosGame(description, 400, 400); @@ -96,7 +103,7 @@ public class FractalOperations implements ChaosGameObserver { Vector2D defaultUpperRight = new Vector2D(0, 0); ChaosGameDescription description = new ChaosGameDescription(Arrays.asList(defaultTransforms), - defaultLowerLeft, defaultUpperRight); + defaultLowerLeft, defaultUpperRight); this.chaosGame = new ChaosGame(description, 400, 400); this.chaosGame.addObserver(this); //drawFractal(0); @@ -125,12 +132,20 @@ public class FractalOperations implements ChaosGameObserver { drawFractal(0); } + /** + * Updates the Julia Set fractal. + * + * @param complex the complex number + * @param sign the sign + * @param minCoords the minimum coordinates + * @param maxCoords the maximum coordinates + */ public void updateJuliaSet(Complex complex, int sign, Vector2D minCoords, Vector2D maxCoords) { JuliaTransform[] transforms = new JuliaTransform[2]; transforms[0] = new JuliaTransform(complex, sign); transforms[1] = new JuliaTransform(complex, -sign); ChaosGameDescription newChaosGame = new ChaosGameDescription(Arrays.asList(transforms), - minCoords, maxCoords); + minCoords, maxCoords); this.chaosGame = new ChaosGame(newChaosGame, 400, 400); drawFractal(0); } @@ -156,11 +171,16 @@ public class FractalOperations implements ChaosGameObserver { */ public void updateMinAndMaxFractal(Vector2D minCoords, Vector2D maxCoords) { ChaosGameDescription newChaosGame = new ChaosGameDescription( - chaosGame.getChaosGameDescription().getTransforms(), minCoords, maxCoords); + chaosGame.getChaosGameDescription().getTransforms(), minCoords, maxCoords); this.chaosGame = new ChaosGame(newChaosGame, 400, 400); this.chaosGame.addObserver(this); } + /** + * Loads a fractal from a file. + * + * @param path the path to the file + */ public void saveFractalToFile(String path) { ChaosGameFileHandler fileHandler = new ChaosGameFileHandler(path); try { diff --git a/src/main/java/edu/ntnu/idatt2003/controller/TextFieldObserver.java b/src/main/java/edu/ntnu/idatt2003/controller/TextFieldObserver.java index 29746a2..999fd3a 100644 --- a/src/main/java/edu/ntnu/idatt2003/controller/TextFieldObserver.java +++ b/src/main/java/edu/ntnu/idatt2003/controller/TextFieldObserver.java @@ -1,7 +1,6 @@ package edu.ntnu.idatt2003.controller; import edu.ntnu.idatt2003.util.ExceptionHandler; -import edu.ntnu.idatt2003.view.components.FractalOperations; import edu.ntnu.idatt2003.view.components.TextFields; /** diff --git a/src/main/java/edu/ntnu/idatt2003/view/App.java b/src/main/java/edu/ntnu/idatt2003/view/App.java index b5d4e45..e793ff3 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/App.java +++ b/src/main/java/edu/ntnu/idatt2003/view/App.java @@ -4,6 +4,9 @@ import edu.ntnu.idatt2003.view.scenes.Scene; import javafx.application.Application; import javafx.stage.Stage; +/** + * The main class of the application. + */ public class App extends Application { public static void main(String[] args) { launch(args); diff --git a/src/main/java/edu/ntnu/idatt2003/view/components/Buttons.java b/src/main/java/edu/ntnu/idatt2003/view/components/Buttons.java index 014158a..7cf156c 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/components/Buttons.java +++ b/src/main/java/edu/ntnu/idatt2003/view/components/Buttons.java @@ -114,6 +114,7 @@ public class Buttons extends Subject { public Button getBtnExitApplication() { return btnExitApplication; } + public Button getBtnSaveFractalToFile() { return btnSaveFractalToFile; } diff --git a/src/main/java/edu/ntnu/idatt2003/view/components/TextFields.java b/src/main/java/edu/ntnu/idatt2003/view/components/TextFields.java index 75a4808..08cff4a 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/components/TextFields.java +++ b/src/main/java/edu/ntnu/idatt2003/view/components/TextFields.java @@ -95,6 +95,7 @@ public class TextFields extends Subject { public TextField getImaginaryPartInput() { return imaginaryPartInput; } + public TextField getMatrixInput1() { return createMatrixInputField("a00"); } diff --git a/src/main/java/edu/ntnu/idatt2003/view/scenes/Scene.java b/src/main/java/edu/ntnu/idatt2003/view/scenes/Scene.java index c0f34e1..2bb3f10 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/scenes/Scene.java +++ b/src/main/java/edu/ntnu/idatt2003/view/scenes/Scene.java @@ -1,8 +1,20 @@ package edu.ntnu.idatt2003.view.scenes; -import edu.ntnu.idatt2003.controller.*; -import edu.ntnu.idatt2003.model.*; -import edu.ntnu.idatt2003.view.components.*; + +import edu.ntnu.idatt2003.controller.ButtonObserver; +import edu.ntnu.idatt2003.controller.ComboBoxObserver; +import edu.ntnu.idatt2003.controller.FractalOperations; +import edu.ntnu.idatt2003.controller.LabelObserver; +import edu.ntnu.idatt2003.controller.TextFieldObserver; +import edu.ntnu.idatt2003.model.AffineTransform2D; +import edu.ntnu.idatt2003.model.ChaosCanvas; +import edu.ntnu.idatt2003.model.JuliaTransform; +import edu.ntnu.idatt2003.model.Matrix2x2; +import edu.ntnu.idatt2003.model.Vector2D; +import edu.ntnu.idatt2003.view.components.Buttons; +import edu.ntnu.idatt2003.view.components.ComboBoxes; +import edu.ntnu.idatt2003.view.components.Labels; +import edu.ntnu.idatt2003.view.components.TextFields; import javafx.geometry.Insets; import javafx.scene.control.Button; import javafx.scene.control.ComboBox; @@ -15,19 +27,16 @@ import javafx.scene.layout.BorderPane; import javafx.scene.layout.HBox; import javafx.scene.layout.VBox; import javafx.scene.paint.Paint; -import javafx.stage.Stage; - -import java.awt.*; -import java.awt.event.MouseEvent; import javafx.scene.shape.Rectangle; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; +import javafx.stage.Stage; +/** + * This class is responsible for creating the scene of the application. + */ public class Scene { private Label iterationsLabel; - private Label MaxLabel; - private Label MinLabel; + private Label maxLabel; + private Label minLabel; private javafx.scene.Scene scene; private WritableImage writableImage; private ImageView imageView; @@ -37,7 +46,7 @@ public class Scene { private Labels labels; private TextFields textFields; private FractalOperations fractalOperations; - private VBox cBox; // Container for the C input fields + private VBox cbox; // Container for the C input fields private VBox inputBox; // Container for all input fields private VBox matrixVectorBox; // Container for the matrix and vector input fields private HBox topBox; @@ -46,11 +55,14 @@ public class Scene { private ComboBoxObserver comboBoxObserver; private LabelObserver labelObserver; private TextFieldObserver textFieldObserver; - private double startX, startY, endX, endY; + private double startX; + private double startY; + private double endX; + private double endY; private Rectangle selectionRectangle; /** - * Constructor for the AffineScene class + * Constructor for the AffineScene class. */ public Scene() { buttons = new Buttons(); @@ -59,65 +71,54 @@ public class Scene { textFields = new TextFields(); initializeComponents(); fractalOperations = new FractalOperations(imageView); - buttonObserver = new ButtonObserver(buttons, fractalOperations, textFields, iterationsLabel, inputContainer); + buttonObserver = new ButtonObserver(buttons, fractalOperations, textFields, + iterationsLabel, inputContainer); comboBoxObserver = new ComboBoxObserver(comboBoxes, fractalOperations); labelObserver = new LabelObserver(buttons, comboBoxes, textFields, iterationsLabel); textFieldObserver = new TextFieldObserver(fractalOperations, textFields); // Add listener to ComboBox to handle dynamic addition of C input fields - comboBoxes.getComboBoxFractal().getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> { - if ("Julia Set".equals(newValue)) { - removeMatrixVectorInputBoxes(); - removeFractalFromFileBox(); - addSaveFractalToFileButton(); - addCInputBox(); - createMaxMinVectorInputAndUpdateAll(); - updateVectorInputFields(); - buttonObserver.setInputContainer(inputContainer); - } else if ("Sierpinski Triangle".equals(newValue)) { - removeMatrixVectorInputBoxes(); - removeCInputBox(); - removeFractalFromFileBox(); - addMatrixVectorInputBoxes(); - addSaveFractalToFileButton(); - createMaxMinVectorInputAndUpdateAll(); - updateVectorInputFields(); - buttonObserver.setInputContainer(inputContainer); - } else if ("Barnsley Fern".equals(newValue)) { - removeMatrixVectorInputBoxes(); - removeCInputBox(); - removeFractalFromFileBox(); - addMatrixVectorInputBoxes(); - createMaxMinVectorInputAndUpdateAll(); - addSaveFractalToFileButton(); - updateVectorInputFields(); - buttonObserver.setInputContainer(inputContainer); - } else if ("Fractal From File".equals(newValue)) { - removeCInputBox(); - removeMatrixVectorInputBoxes(); - removeMaxMinVectorInput(); - addSaveFractalToFileButton(); - addFractalFromFileBox(); - } - }); + comboBoxes.getComboBoxFractal().getSelectionModel().selectedItemProperty() + .addListener((observable, oldValue, newValue) -> { + if ("Julia Set".equals(newValue)) { + removeMatrixVectorInputBoxes(); + removeFractalFromFileBox(); + addSaveFractalToFileButton(); + addcInputbox(); + createMaxMinVectorInputAndUpdateAll(); + updateVectorInputFields(); + buttonObserver.setInputContainer(inputContainer); + } else if ("Sierpinski Triangle".equals(newValue)) { + removeMatrixVectorInputBoxes(); + removeCinputBox(); + removeFractalFromFileBox(); + addMatrixVectorInputBoxes(); + addSaveFractalToFileButton(); + createMaxMinVectorInputAndUpdateAll(); + updateVectorInputFields(); + buttonObserver.setInputContainer(inputContainer); + } else if ("Barnsley Fern".equals(newValue)) { + removeMatrixVectorInputBoxes(); + removeCinputBox(); + removeFractalFromFileBox(); + addMatrixVectorInputBoxes(); + createMaxMinVectorInputAndUpdateAll(); + addSaveFractalToFileButton(); + updateVectorInputFields(); + buttonObserver.setInputContainer(inputContainer); + } else if ("Fractal From File".equals(newValue)) { + removeCinputBox(); + removeMatrixVectorInputBoxes(); + removeMaxMinVectorInput(); + addSaveFractalToFileButton(); + addFractalFromFileBox(); + } + }); - // Initial setup based on the provided fractal type - /* - if ("Julia Set".equals(fractalType)) { - addCInputBox(); - addSaveFractalToFileButton(); - } else if ("Sierpinski Triangle".equals(fractalType) || "Barnsley Fern".equals(fractalType)) { - addMatrixVectorInputBoxes(); - addSaveFractalToFileButton(); - } else if ("Fractal From File".equals(fractalType)) { - addFractalFromFileBox(); - } - */ } private void initializeComponents() { // Creating the root AnchorPane - AnchorPane root = new AnchorPane(); // HBox for buttons HBox bottomBox = new HBox(50); // spacing between buttons @@ -141,8 +142,8 @@ public class Scene { // Initialize Labels iterationsLabel = labels.getIterationLabel(); - MaxLabel = labels.geMaxLabel(); - MinLabel = labels.getMinLabel(); + maxLabel = labels.geMaxLabel(); + minLabel = labels.getMinLabel(); // Initialize TextFields TextField addIterationInput = textFields.getAddIterationInput(); @@ -156,7 +157,8 @@ public class Scene { addInputBox.getChildren().addAll(addIterationInput, btnAddInput); // Add buttons to the HBox - bottomBox.getChildren().addAll(btnAdd10, btnAdd100, btnAdd1000, addInputBox, btnReset, iterationsLabel); + bottomBox.getChildren().addAll(btnAdd10, btnAdd100, btnAdd1000, + addInputBox, btnReset, iterationsLabel); bottomBox.setPadding(new Insets(10, 10, 10, 10)); topBox.getChildren().addAll(comboBoxFractal, comboBoxColor); @@ -176,6 +178,8 @@ public class Scene { inputBox = new VBox(0); + AnchorPane root = new AnchorPane(); + // Add components to the root AnchorPane root.getChildren().addAll(topBox, imagePane, bottomBox, btnExitApplication, inputBox); @@ -219,22 +223,22 @@ public class Scene { scene.getStylesheets().add(getClass().getResource("/style.css").toExternalForm()); } - private void addCInputBox() { - if (cBox == null) { - cBox = createCInputBox(); - inputBox.getChildren().addFirst(cBox); + private void addcInputbox() { + if (cbox == null) { + cbox = createCinputBox(); + inputBox.getChildren().addFirst(cbox); } } - private void removeCInputBox() { - if (cBox != null) { - inputBox.getChildren().remove(cBox); - cBox = null; + private void removeCinputBox() { + if (cbox != null) { + inputBox.getChildren().remove(cbox); + cbox = null; } } - private VBox createCInputBox() { - Label cLabel = new Label("Update constant C"); + private VBox createCinputBox() { + Label clabel = new Label("Update constant C"); Button resetToDefaultButton = new Button("Reset to Default fractal"); TextField realPartInput = textFields.getRealPartInput(); @@ -246,21 +250,22 @@ public class Scene { realPartInput.setPromptText("Real part of C"); imaginaryPartInput.setPromptText("Imaginary part of C"); - JuliaTransform julia = (JuliaTransform) fractalOperations.getChaosGame().getDescription().getTransforms().getFirst(); + JuliaTransform julia = (JuliaTransform) fractalOperations.getChaosGame() + .getDescription().getTransforms().getFirst(); realPartInput.setText(String.valueOf(julia.getPoint().getReal())); imaginaryPartInput.setText(String.valueOf(julia.getPoint().getImaginary())); - VBox cBox = new VBox(5); - cBox.getChildren().addAll(cLabel, realPartInput, imaginaryPartInput, resetToDefaultButton); - cBox.setPadding(new Insets(0, 0, 0, 0)); + VBox cbox = new VBox(5); + cbox.getChildren().addAll(clabel, realPartInput, imaginaryPartInput, resetToDefaultButton); + cbox.setPadding(new Insets(0, 0, 0, 0)); resetToDefaultButton.setOnAction(event -> { fractalOperations.setFractalToJuliaSet(); updateVectorInputFields(); }); - return cBox; + return cbox; } private HBox createMatrixVectorInputBox(AffineTransform2D transform) { @@ -318,7 +323,8 @@ public class Scene { Button addMoreButton = new Button("Add More"); addMoreButton.setOnAction(event -> { - HBox newInputBox = createMatrixVectorInputBox(new AffineTransform2D(new Matrix2x2(0, 0, 0, 0), new Vector2D(0, 0))); + HBox newInputBox = createMatrixVectorInputBox(new AffineTransform2D( + new Matrix2x2(0, 0, 0, 0), new Vector2D(0, 0))); inputContainer.getChildren().add(0, newInputBox); }); @@ -356,16 +362,23 @@ public class Scene { } } - private void resetToDefaultFractal(VBox inputContainer, Button addMoreButton, Button resetToDefaultButton) { + private void resetToDefaultFractal(VBox inputContainer, Button addMoreButton, + Button resetToDefaultButton) { inputContainer.getChildren().clear(); if ("Barnsley Fern".equals(comboBoxes.getComboBoxFractal().getValue())) { fractalOperations.setFractalToBransleysFern(); - AffineTransform2D[] transforms = fractalOperations.getDescription().getTransforms().toArray(new AffineTransform2D[0]); - inputContainer.getChildren().addAll(createMatrixVectorInputBox(transforms[0]), createMatrixVectorInputBox(transforms[1]), createMatrixVectorInputBox(transforms[2]), createMatrixVectorInputBox(transforms[3]), addMoreButton, resetToDefaultButton); + AffineTransform2D[] transforms = fractalOperations.getDescription().getTransforms() + .toArray(new AffineTransform2D[0]); + inputContainer.getChildren().addAll(createMatrixVectorInputBox(transforms[0]), + createMatrixVectorInputBox(transforms[1]), createMatrixVectorInputBox(transforms[2]), + createMatrixVectorInputBox(transforms[3]), addMoreButton, resetToDefaultButton); } else if ("Sierpinski Triangle".equals(comboBoxes.getComboBoxFractal().getValue())) { fractalOperations.setFractalToSierpinskiTriangle(); - AffineTransform2D[] transforms = fractalOperations.getDescription().getTransforms().toArray(new AffineTransform2D[0]); - inputContainer.getChildren().addAll(createMatrixVectorInputBox(transforms[0]), createMatrixVectorInputBox(transforms[1]), createMatrixVectorInputBox(transforms[2]), addMoreButton, resetToDefaultButton); + AffineTransform2D[] transforms = fractalOperations.getDescription().getTransforms() + .toArray(new AffineTransform2D[0]); + inputContainer.getChildren().addAll(createMatrixVectorInputBox(transforms[0]), + createMatrixVectorInputBox(transforms[1]), createMatrixVectorInputBox(transforms[2]), + addMoreButton, resetToDefaultButton); } } @@ -373,50 +386,60 @@ public class Scene { fractalOperations.updateMinAndMaxFractal(minCoords, maxCoords); } + /** + * Adds the save fractal to file button to the top box. + */ public void addSaveFractalToFileButton() { Button saveFractalToFileButton = buttons.getBtnSaveFractalToFile(); - if (saveFractalToFileButton != null && !topBox.getChildren().contains(saveFractalToFileButton)) { + if (saveFractalToFileButton != null && !topBox.getChildren() + .contains(saveFractalToFileButton)) { topBox.getChildren().add(saveFractalToFileButton); } } + /** + * Removes the save fractal to file button from the top box. + */ public void createMaxMinVectorInputAndUpdateAll() { - TextField xMinInput = textFields.getxMinInput(); - TextField yMinInput = textFields.getyMinInput(); - TextField xMaxInput = textFields.getxMaxInput(); - TextField yMaxInput = textFields.getyMaxInput(); + TextField xmininput = textFields.getxMinInput(); + TextField ymininput = textFields.getyMinInput(); + TextField xmaxinput = textFields.getxMaxInput(); + TextField ymaxinput = textFields.getyMaxInput(); // Ensure style classes are added to these text fields - xMinInput.getStyleClass().add("MaxMinInput"); - yMinInput.getStyleClass().add("MaxMinInput"); - xMaxInput.getStyleClass().add("MaxMinInput"); - yMaxInput.getStyleClass().add("MaxMinInput"); + xmininput.getStyleClass().add("MaxMinInput"); + ymininput.getStyleClass().add("MaxMinInput"); + xmaxinput.getStyleClass().add("MaxMinInput"); + ymaxinput.getStyleClass().add("MaxMinInput"); Vector2D minCoords = fractalOperations.getChaosGame().getDescription().getMinCoords(); Vector2D maxCoords = fractalOperations.getChaosGame().getDescription().getMaxCoords(); - xMinInput.setText(String.valueOf(minCoords.getX0())); - yMinInput.setText(String.valueOf(minCoords.getX1())); - xMaxInput.setText(String.valueOf(maxCoords.getX0())); - yMaxInput.setText(String.valueOf(maxCoords.getX1())); + xmininput.setText(String.valueOf(minCoords.getX0())); + ymininput.setText(String.valueOf(minCoords.getX1())); + xmaxinput.setText(String.valueOf(maxCoords.getX0())); + ymaxinput.setText(String.valueOf(maxCoords.getX1())); updateVectorInputFields(); - HBox MinBox = new HBox(5); - HBox MaxBox = new HBox(5); - MinBox.getChildren().addAll(xMinInput, yMinInput); - MaxBox.getChildren().addAll(xMaxInput, yMaxInput); + HBox minBox = new HBox(5); + HBox maxBox = new HBox(5); + minBox.getChildren().addAll(xmininput, ymininput); + maxBox.getChildren().addAll(xmaxinput, ymaxinput); buttonObserver.setInputContainer(inputBox); Button updateAllButton = buttons.getBtnUpdateAll(); - VBox MinMaxAll = new VBox(5); - MinMaxAll.getChildren().addAll(MaxLabel, MaxBox, MinLabel, MinBox, updateAllButton); + VBox minMaxAll = new VBox(5); + minMaxAll.getChildren().addAll(maxLabel, maxBox, minLabel, minBox, updateAllButton); - inputBox.getChildren().add(MinMaxAll); + inputBox.getChildren().add(minMaxAll); } + /** + * Removes the save fractal to file button from the top box. + */ public void removeMaxMinVectorInput() { if (inputBox.getChildren().size() > 1) { inputBox.getChildren().remove(1); @@ -425,11 +448,18 @@ public class Scene { } } - public void updateVectorInputFields() { - textFields.getxMinInput().setText(String.valueOf(fractalOperations.getChaosGame().getDescription().getMinCoords().getX0())); - textFields.getyMinInput().setText(String.valueOf(fractalOperations.getChaosGame().getDescription().getMinCoords().getX1())); - textFields.getxMaxInput().setText(String.valueOf(fractalOperations.getChaosGame().getDescription().getMaxCoords().getX0())); - textFields.getyMaxInput().setText(String.valueOf(fractalOperations.getChaosGame().getDescription().getMaxCoords().getX1())); + /** + * Updates the vector input fields with the current min and max coordinates. + */ + public void updateVectorInputFields() { + textFields.getxMinInput().setText(String.valueOf(fractalOperations.getChaosGame() + .getDescription().getMinCoords().getX0())); + textFields.getyMinInput().setText(String.valueOf(fractalOperations.getChaosGame() + .getDescription().getMinCoords().getX1())); + textFields.getxMaxInput().setText(String.valueOf(fractalOperations.getChaosGame() + .getDescription().getMaxCoords().getX0())); + textFields.getyMaxInput().setText(String.valueOf(fractalOperations.getChaosGame() + .getDescription().getMaxCoords().getX1())); } private void handleMousePressed(javafx.scene.input.MouseEvent event) { @@ -464,15 +494,15 @@ public class Scene { double imageWidth = imageView.getBoundsInLocal().getWidth(); double imageHeight = imageView.getBoundsInLocal().getHeight(); - double xMin = fractalOperations.getChaosGame().getDescription().getMinCoords().getX0(); - double yMin = fractalOperations.getChaosGame().getDescription().getMinCoords().getX1(); - double xMax = fractalOperations.getChaosGame().getDescription().getMaxCoords().getX0(); - double yMax = fractalOperations.getChaosGame().getDescription().getMaxCoords().getX1(); + double xmin = fractalOperations.getChaosGame().getDescription().getMinCoords().getX0(); + double ymin = fractalOperations.getChaosGame().getDescription().getMinCoords().getX1(); + double xmax = fractalOperations.getChaosGame().getDescription().getMaxCoords().getX0(); + double ymax = fractalOperations.getChaosGame().getDescription().getMaxCoords().getX1(); - double newMinX = xMin + (startX / imageWidth) * (xMax - xMin); - double newMaxX = xMin + (endX / imageWidth) * (xMax - xMin); - double newMinY = yMin + (startY / imageHeight) * (yMax - yMin); - double newMaxY = yMin + (endY / imageHeight) * (yMax - yMin); + double newMinX = xmin + (startX / imageWidth) * (xmax - xmin); + double newMaxX = xmin + (endX / imageWidth) * (xmax - xmin); + double newMinY = ymin + (startY / imageHeight) * (ymax - ymin); + double newMaxY = ymin + (endY / imageHeight) * (ymax - ymin); Vector2D newMinCoords = new Vector2D(Math.min(newMinX, newMaxX), Math.min(newMinY, newMaxY)); Vector2D newMaxCoords = new Vector2D(Math.max(newMinX, newMaxX), Math.max(newMinY, newMaxY)); @@ -482,13 +512,14 @@ public class Scene { fractalOperations.drawFractal(100000000); // Optionally redraw with initial iterations } + /** + * Sets up the stage with the scene. + * + * @param primaryStage the stage to set up + */ public void setUpStage(Stage primaryStage) { primaryStage.setTitle("ChaosGame"); primaryStage.setScene(scene); primaryStage.show(); } - - public Stage getStage() { - return (Stage) scene.getWindow(); - } } -- GitLab From 63c7f36c7e22eac2d8e902fe89ed97134d22d2ca Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Wed, 22 May 2024 13:19:01 +0200 Subject: [PATCH 167/168] Added Logger insted of system.ou.print --- .../idatt2003/controller/ButtonObserver.java | 1 - .../edu/ntnu/idatt2003/model/ChaosGame.java | 3 ++- .../idatt2003/view/components/Buttons.java | 20 ++++++++++--------- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java b/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java index a3762d9..6e64596 100644 --- a/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java +++ b/src/main/java/edu/ntnu/idatt2003/controller/ButtonObserver.java @@ -227,7 +227,6 @@ public class ButtonObserver implements Observer { Vector2D upperRight = new Vector2D(xmax, ymax); ChaosGameDescription description = new ChaosGameDescription(transforms, lowerLeft, upperRight); - System.out.println("Transforms updated: " + transforms.size()); fractalOperations.updateDescription(description); } diff --git a/src/main/java/edu/ntnu/idatt2003/model/ChaosGame.java b/src/main/java/edu/ntnu/idatt2003/model/ChaosGame.java index 2c04924..33e1c06 100644 --- a/src/main/java/edu/ntnu/idatt2003/model/ChaosGame.java +++ b/src/main/java/edu/ntnu/idatt2003/model/ChaosGame.java @@ -5,6 +5,7 @@ import edu.ntnu.idatt2003.controller.ChaosGameObserver; import java.util.ArrayList; import java.util.List; import java.util.Random; +import java.util.logging.Logger; /** * Represents a chaos game. @@ -48,7 +49,7 @@ public class ChaosGame { */ public void runSteps(int steps) { if (description.getTransforms().isEmpty() || description.getTransforms() == null) { - System.out.println("No transforms in description "); + Logger.getGlobal().info("No transforms in description "); return; } for (int i = 0; i < steps; i++) { diff --git a/src/main/java/edu/ntnu/idatt2003/view/components/Buttons.java b/src/main/java/edu/ntnu/idatt2003/view/components/Buttons.java index 7cf156c..f7cc564 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/components/Buttons.java +++ b/src/main/java/edu/ntnu/idatt2003/view/components/Buttons.java @@ -7,6 +7,8 @@ import javafx.scene.control.Alert; import javafx.scene.control.Button; import javafx.scene.control.ButtonType; +import java.util.logging.Logger; + /** * This class is responsible for creating buttons. */ @@ -34,55 +36,55 @@ public class Buttons extends Subject { private void initializeButtons() { btnAdd10 = new Button("Add 10"); btnAdd10.setOnAction(e -> { - System.out.println("Add 10"); + Logger.getGlobal().info("Add 10"); notifyObservers("btnAdd10"); }); btnAdd100 = new Button("Add 100"); btnAdd100.setOnAction(e -> { - System.out.println("Add 100"); + Logger.getGlobal().info("Add 100"); notifyObservers("btnAdd100"); }); btnAdd1000 = new Button("Add 1000"); btnAdd1000.setOnAction(e -> { - System.out.println("Add 1000"); + Logger.getGlobal().info("Add 1000"); notifyObservers("btnAdd1000"); }); btnReset = new Button("Reset"); btnReset.setOnAction(e -> { - System.out.println("Reset"); + Logger.getGlobal().info("Reset"); notifyObservers("btnReset"); }); btnAddInput = new Button("Add"); btnAddInput.setOnAction(e -> { - System.out.println("Iterations added"); + Logger.getGlobal().info("Add Input"); notifyObservers("btnAddInput"); }); btnAddFractalFromFile = new Button("Load Fractal From File"); btnAddFractalFromFile.setOnAction(e -> { - System.out.println("Fractal From File"); + Logger.getGlobal().info("Load Fractal From File"); notifyObservers("btnAddFractalFromFile"); }); btnExitApplication = new Button("Exit"); btnExitApplication.setOnAction(e -> { - System.out.println("Exiting Application..."); + Logger.getGlobal().info("Exit Application"); notifyObservers("btnExitApplication"); }); btnSaveFractalToFile = new Button("Save Fractal To File"); btnSaveFractalToFile.setOnAction(e -> { - System.out.println("Save Fractal To File"); + Logger.getGlobal().info("Save Fractal To File"); notifyObservers("btnSaveFractalToFile"); }); btnUpdateAll = new Button("Update all values"); btnUpdateAll.setOnAction(e -> { - System.out.println("Update All"); + Logger.getGlobal().info("Update all values"); notifyObservers("btnUpdateAll"); }); } -- GitLab From f8bd18a1f79d1d1c4f1be0866346807961528d5a Mon Sep 17 00:00:00 2001 From: emilruud <emilruud@ntnu.no> Date: Wed, 22 May 2024 13:24:31 +0200 Subject: [PATCH 168/168] Added Logger insted of system.ou.print --- .../edu/ntnu/idatt2003/view/components/ComboBoxes.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main/java/edu/ntnu/idatt2003/view/components/ComboBoxes.java b/src/main/java/edu/ntnu/idatt2003/view/components/ComboBoxes.java index 16dde07..aeb53b9 100644 --- a/src/main/java/edu/ntnu/idatt2003/view/components/ComboBoxes.java +++ b/src/main/java/edu/ntnu/idatt2003/view/components/ComboBoxes.java @@ -4,6 +4,8 @@ import edu.ntnu.idatt2003.controller.Subject; import javafx.collections.FXCollections; import javafx.scene.control.ComboBox; +import java.util.logging.Logger; + /** * This class is responsible for creating ComboBoxes. */ @@ -32,19 +34,19 @@ public class ComboBoxes extends Subject { String selectedFractal = getComboBoxFractal().getValue(); if ("Sierpinski Triangle".equals(selectedFractal)) { - System.out.println("Sierpinski Triangle"); + Logger.getGlobal().info("Sierpinski Triangle"); notifyObservers("Sierpinski Triangle"); } else if ("Julia Set".equals(selectedFractal)) { - System.out.println("Julia Set"); + Logger.getGlobal().info("Julia Set"); notifyObservers("Julia Set"); } else if ("Barnsley Fern".equals(selectedFractal)) { - System.out.println("Barnsley Fern"); + Logger.getGlobal().info("Barnsley Fern"); notifyObservers("Barnsley Fern"); } else if ("Fractal From File".equals(selectedFractal)) { - System.out.println("Fractal From File"); + Logger.getGlobal().info("Fractal From File"); notifyObservers("Fractal From File"); } }); -- GitLab