Parameters in GUI and stopping the program/calculation

This commit is contained in:
nora 2020-11-22 11:30:53 +01:00
parent 5673c99d4e
commit 9d68fe1521
5 changed files with 114 additions and 57 deletions

View file

@ -11,26 +11,26 @@ import java.io.IOException;
public class CalculationThread implements Runnable { public class CalculationThread implements Runnable {
private boolean running;
private Thread thread; private Thread thread;
int threadNumber; private int threadNumber;
int threadAmount; private int threadAmount;
int frameAmount; private int frameAmount;
int width; private int width;
int height; private int height;
int iterations; private int iterations;
int threshold; private int threshold;
double[][] zoomValues; private double[][] zoomValues;
CNumber[][] samples; private CNumber[][] samples;
final MandelbrotSet set; private final MandelbrotSet set;
final Controller controller; private final Controller controller;
public void start() { public void start() {
if (thread == null) { if (thread == null) {
synchronized (controller){ controller.printOutput("Thread " + threadNumber + " started");
controller.printOutput("Thread " + threadNumber + " started");
}
thread = new Thread(this, String.valueOf(threadNumber)); thread = new Thread(this, String.valueOf(threadNumber));
thread.start(); thread.start();
} }
@ -38,7 +38,7 @@ public class CalculationThread implements Runnable {
@Override @Override
public void run() { public void run() {
running = true;
long totalStartTime = System.currentTimeMillis(); long totalStartTime = System.currentTimeMillis();
samples = new CNumber[width][height]; samples = new CNumber[width][height];
@ -60,37 +60,31 @@ public class CalculationThread implements Runnable {
// calculate values // calculate values
double[][] values = new double[width][height]; // new array of booleans for the drawing double[][] values = new double[width][height]; // new array of booleans for the drawing
for (int i = 0; i < width; i++) { for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) { if (running) {
values[i][j] = checkMandelbrot(samples[i][j], iterations, threshold); // check if the number is inside of th set for (int j = 0; j < height; j++) {
values[i][j] = checkMandelbrot(samples[i][j], iterations, threshold); // check if the number is inside of th set
}
} else {
controller.printOutput("Thread " + threadNumber + " stopped");
set.setFinished(threadNumber);
return;
} }
} }
createImage(image, frameCounter, width, height, values, iterations); createImage(image, frameCounter, width, height, values, iterations);
set.frameFinished(frameCounter);
synchronized (set) {
set.frameFinished(frameCounter);
}
long frameTime = System.currentTimeMillis() - startTime; long frameTime = System.currentTimeMillis() - startTime;
System.out.println("Frame " + frameCounter + " finished in " + ((double) frameTime / 1000) + "s"); System.out.println("Frame " + frameCounter + " finished in " + ((double) frameTime / 1000) + "s");
synchronized (controller) { controller.printOutput("Frame " + frameCounter + " finished in " + ((double) frameTime / 1000) + "s");
controller.printOutput("Frame " + frameCounter + " finished in " + ((double) frameTime / 1000) + "s");
}
} }
long totalTime = System.currentTimeMillis() - totalStartTime; long totalTime = System.currentTimeMillis() - totalStartTime;
System.out.println("--Thread " + threadNumber + " completed. Process took " + ((double) totalTime / 1000) + "s"); System.out.println("--Thread " + threadNumber + " completed. Process took " + ((double) totalTime / 1000) + "s");
synchronized (controller) { controller.printOutput("--Thread " + threadNumber + " completed. Process took " + ((double) totalTime / 1000) + "s");
controller.printOutput("--Thread " + threadNumber + " completed. Process took " + ((double) totalTime / 1000) + "s"); set.setFinished(threadNumber);
}
synchronized (set) {
set.setFinished(threadNumber);
}
} }
public CalculationThread(Controller controller, MandelbrotSet set, int number, int threads, int frames, int widthC, int heightC, int iterationsC, int thresholdC, double[][] zoomValuesC) { public CalculationThread(Controller controller, MandelbrotSet set, int number, int threads, int frames, int widthC, int heightC, int iterationsC, int thresholdC, double[][] zoomValuesC) {
@ -173,4 +167,7 @@ public class CalculationThread implements Runnable {
return (a << 24) | (r << 16) | (g << 8) | b; return (a << 24) | (r << 16) | (g << 8) | b;
} }
public void stop() {
running = false;
}
} }

View file

@ -28,6 +28,7 @@ public class MandelbrotSet {
private boolean[] completeThreads; private boolean[] completeThreads;
private boolean[] completeFrames; private boolean[] completeFrames;
private CalculationThread[] threads;
private long startTime = System.currentTimeMillis(); private long startTime = System.currentTimeMillis();
@ -50,12 +51,12 @@ public class MandelbrotSet {
height = (int) ((float) width * ratio); height = (int) ((float) width * ratio);
iterations = switch (quality){ iterations = switch (quality){
case -1 -> 10; case 0 -> 10;
case 0 -> 50; case 1 -> 50;
case 1 -> 100; case 2 -> 100;
case 2 -> 500; case 3 -> 500;
case 3 -> 1000; case 4 -> 1000;
case 4 -> 5000; case 5 -> 5000;
default -> quality; default -> quality;
}; };
@ -84,7 +85,7 @@ public class MandelbrotSet {
double[][] zoomValues = zoomValues(frames, width, height, forceCenterX, forceCenterY, zoomSpeed, zoom); double[][] zoomValues = zoomValues(frames, width, height, forceCenterX, forceCenterY, zoomSpeed, zoom);
//create the threads //create the threads
CalculationThread[] threads = new CalculationThread[threadAmount]; threads = new CalculationThread[threadAmount];
for (int i = 0; i < threadAmount; i++) { for (int i = 0; i < threadAmount; i++) {
threads[i] = new CalculationThread(controller, this, i, threadAmount, frames, width, height, iterations, threshold, zoomValues); threads[i] = new CalculationThread(controller, this, i, threadAmount, frames, width, height, iterations, threshold, zoomValues);
threads[i].start(); threads[i].start();
@ -129,7 +130,7 @@ public class MandelbrotSet {
* Call when a new frame is finished * Call when a new frame is finished
* @param frameNumber The number of the frame * @param frameNumber The number of the frame
*/ */
public void frameFinished(int frameNumber){ public synchronized void frameFinished(int frameNumber){
completeFrames[frameNumber] = true; completeFrames[frameNumber] = true;
int latestFrame = 0; int latestFrame = 0;
@ -150,7 +151,7 @@ public class MandelbrotSet {
* Call when a new Thread is finished * Call when a new Thread is finished
* @param threadNumber The Threadier * @param threadNumber The Threadier
*/ */
public void setFinished(int threadNumber){ public synchronized void setFinished(int threadNumber){
completeThreads[threadNumber] = true; completeThreads[threadNumber] = true;
boolean finished = true; boolean finished = true;
@ -163,17 +164,19 @@ public class MandelbrotSet {
if(finished){ if(finished){
System.out.println("CALCULATION FINISHED"); System.out.println("CALCULATION FINISHED");
synchronized (controller) { controller.printOutput("CALCULATION FINISHED");
controller.printOutput("CALCULATION FINISHED");
}
// TIME should probably not be here and serves no practical purpose but that doesn't stop me from keeping it here
long endTime = System.currentTimeMillis(); long endTime = System.currentTimeMillis();
long completionTimeLong = endTime - startTime; long completionTimeLong = endTime - startTime;
double completionTimeSec = (double) completionTimeLong / 1000.0; double completionTimeSec = (double) completionTimeLong / 1000.0;
System.out.println("Calculated " + frames + " frame/s in " + completionTimeSec + "s"); System.out.println("Calculated " + frames + " frame/s in " + completionTimeSec + "s");
synchronized (controller) { controller.printOutput("Calculated " + frames + " frame/s in " + completionTimeSec + "s");
controller.printOutput("Calculated " + frames + " frame/s in " + completionTimeSec + "s"); }
} }
public void stop(){
for(CalculationThread c : threads){
c.stop();
} }
} }

View file

@ -1,6 +1,8 @@
package ui; package ui;
import javafx.event.ActionEvent;
import javafx.scene.control.TextArea; import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.image.Image; import javafx.scene.image.Image;
import javafx.scene.image.ImageView; import javafx.scene.image.ImageView;
import mandelbrotCalculator.MandelbrotSet; import mandelbrotCalculator.MandelbrotSet;
@ -14,6 +16,12 @@ public class Controller {
public ImageView setPreview; public ImageView setPreview;
public TextArea output; public TextArea output;
public TextField pointNumberField;
public TextField qualityField;
public TextField zoomSpeedField;
public TextField frameAmountField;
private MandelbrotSet m;
public void nextImage(int frameNumber) throws FileNotFoundException { public void nextImage(int frameNumber) throws FileNotFoundException {
@ -21,13 +29,30 @@ public class Controller {
Image image = new Image(stream); Image image = new Image(stream);
setPreview.setImage(image); setPreview.setImage(image);
} }
public void startCalculation() { public void startCalculation() {
MandelbrotSet m = new MandelbrotSet(2, -1, 2, 100, this); String pointNumber = pointNumberField.getText();
m.startMandelbrot(); String quality = qualityField.getText();
String zoomSpeed = zoomSpeedField.getText();
String frames = frameAmountField.getText();
try{
m = new MandelbrotSet(Integer.parseInt(pointNumber), Integer.parseInt(quality), Double.parseDouble(zoomSpeed), Integer.parseInt(frames), this);
m.startMandelbrot();
} catch (NumberFormatException ignored) {
}
} }
public void printOutput(String s){ public void stop(){
m.stop();
}
public void exitProgram() {
System.exit(0);
}
public synchronized void printOutput(String s){
output.appendText(String.format("%n%s", s)); output.appendText(String.format("%n%s", s));
} }
} }

View file

@ -5,7 +5,7 @@
<?import javafx.scene.layout.*?> <?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?> <?import javafx.scene.text.*?>
<AnchorPane prefHeight="225.0" prefWidth="769.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="ui.Controller"> <AnchorPane prefHeight="508.0" prefWidth="1028.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="ui.Controller">
<children> <children>
<VBox AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"> <VBox AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<children> <children>
@ -35,10 +35,42 @@
</Text> </Text>
<HBox prefHeight="435.0" prefWidth="769.0"> <HBox prefHeight="435.0" prefWidth="769.0">
<children> <children>
<VBox prefHeight="200.0" prefWidth="100.0"> <VBox prefHeight="435.0" prefWidth="85.0">
<children>
<Text strokeType="OUTSIDE" strokeWidth="0.0" text="Settings" wrappingWidth="200.638671875">
<font>
<Font size="18.0" />
</font></Text>
<GridPane prefHeight="135.0" prefWidth="201.0">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<TextField fx:id="pointNumberField" promptText="0 - 2" GridPane.columnIndex="1" />
<Text strokeType="OUTSIDE" strokeWidth="0.0" text="Point Number" />
<TextField fx:id="qualityField" layoutX="111.0" layoutY="13.0" promptText="0 - 5" GridPane.columnIndex="1" GridPane.rowIndex="1" />
<Text layoutX="10.0" layoutY="30.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Quality" GridPane.rowIndex="1" />
<TextField fx:id="zoomSpeedField" layoutX="111.0" layoutY="43.0" promptText=" &gt; 1" GridPane.columnIndex="1" GridPane.rowIndex="2" />
<Text layoutX="10.0" layoutY="60.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Zoom Speed" GridPane.rowIndex="2" />
<TextField fx:id="frameAmountField" layoutX="111.0" layoutY="83.0" promptText="&gt; 0" GridPane.columnIndex="1" GridPane.rowIndex="3" />
<Text layoutX="10.0" layoutY="100.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Frame Amount" GridPane.rowIndex="3" />
</children>
</GridPane>
<Button onAction="#startCalculation" prefHeight="25.0" prefWidth="110.0" text="Start" />
<Button mnemonicParsing="false" onAction="#stop" text="Stop" />
<Button mnemonicParsing="false" onAction="#exitProgram" text="Exit" />
</children>
</VBox>
<VBox>
<children> <children>
<ImageView fx:id="setPreview" fitWidth="500" preserveRatio="true" /> <ImageView fx:id="setPreview" fitWidth="500" preserveRatio="true" />
<Button onAction="#startCalculation" prefHeight="25.0" prefWidth="110.0" text="Start" />
</children> </children>
</VBox> </VBox>
<VBox alignment="TOP_RIGHT"> <VBox alignment="TOP_RIGHT">

View file

@ -2,6 +2,6 @@ package util;
public class Values { public class Values {
public static final String SAVE_IMAGE_PATH = "C:\\Users\\nilsh\\IdeaProjects\\testStuff\\sequence/Sequence"; public static final String SAVE_IMAGE_PATH = "C:\\Users\\nilsh\\Desktop\\testordner/image";
} }