Skip to content
Snippets Groups Projects
Commit f1457f95 authored by Nicklas Persia Tufteland's avatar Nicklas Persia Tufteland
Browse files

Merge branch '34-improve-code-quality-in-mainpageview' into 'dev'

Resolve "Improve code quality in MainPageView"

Closes #34

See merge request !39
parents 3af803f6 e91ade27
No related branches found
No related tags found
2 merge requests!41final delivery,!39Resolve "Improve code quality in MainPageView"
Pipeline #288841 passed
package edu.ntnu.idatt2003.view;
import static edu.ntnu.idatt2003.view.components.TextBoxAndTextFieldContainerFactory.createTextBoxWithTextFieldsContainer;
import edu.ntnu.idatt2003.controller.MainPageController;
import edu.ntnu.idatt2003.model.ChaosGameDescriptionFactory;
import java.io.File;
import java.util.List;
import java.util.Locale;
import javafx.scene.control.ComboBox;
import javafx.scene.control.TextField;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
/**
* An event handler for the main page view. The event handler is responsible for
* handling events from the main page view and calling the appropriate methods
* in the main page controller.
*/
public class EventHandler {
private final MainPageController controller;
private final MainPageView view;
/**
* Creates a new event handler with the specified controller and view.
* The event handler is responsible for handling events from the main page
* view and calling the appropriate methods in the main page controller.
*
* @param controller The controller to call methods on.
* @param view The view to handle events from.
*/
protected EventHandler(MainPageController controller, MainPageView view) {
this.controller = controller;
this.view = view;
}
/**
* Handles the event of the user pressing a run steps button. The event handler
* calls the controller's runSteps method with the number of steps to run.
*
* @param steps The number of steps to run.
*/
protected void handleRunSteps(int steps) {
controller.runSteps(steps);
}
/**
* Handles the event of the user pressing a reset button. The event handler
* calls the controller's runSteps method with -1 as the number of steps to run.
*/
protected void handleReset() {
controller.runSteps(-1);
}
/**
* Handles the event of the user running steps from a TextField. The event handler
* calls the controller's runCustomSteps method with the steps to run.
*
* @param stepsField The text field containing the steps to run.
*/
protected void handleRunCustomSteps(TextField stepsField) {
controller.runCustomSteps(stepsField.getText());
stepsField.clear();
}
/**
* Handles the event of the user pressing a save button. The event handler
* calls the controller's save-method with the fractal name, transformations,
*
* @param fractalName The name of the fractal.
* @param transformations The transformations of the fractal.
* @param startVector The start vector of the fractal.
* @param endVector The end vector of the fractal.
*/
protected void handleSave(String fractalName, List<String[]> transformations,
String[] startVector, String[] endVector) {
controller.addCustomFractal(startVector, endVector, transformations, fractalName);
}
/**
* Handles the event of the user pressing a cancel button. The event handler
* calls the view's render method to render the main page view.
*/
protected void handleCancel() {
view.render();
}
/**
* Handles the event of the user pressing a save locally button. The event handler
* asks for a location to save from user and calls the controller's saveToLocalDirectory
* method with the location to save to.
*/
protected void handleSaveLocally() {
FileChooser fileChooser = new FileChooser();
fileChooser.getExtensionFilters().add(
new FileChooser.ExtensionFilter("Text Files", "*.txt"));
controller.saveToLocalDirectory(fileChooser.showSaveDialog(null));
}
/**
* Opens a file chooser dialog that enables the user to upload a custom
* text file with a chaos game description. The file is then uploaded
* by the controller. If an exception occurs, an alert is shown.
*/
protected void handleUploadFile() {
FileChooser fileChooser = new FileChooser();
fileChooser.getExtensionFilters().add(
new FileChooser.ExtensionFilter("Text Files", "*.txt"));
Stage fileChooserStage = new Stage();
File file = fileChooser.showOpenDialog(fileChooserStage);
if (file != null) {
controller.uploadFile(file);
}
}
/**
* Handles the event of the user pressing addTransformation button. It adds a new
* text box with text fields for the user to input the transformation matrix and vector
* to the vbox.
*
* @param vbox the vbox to add the text box with fields to.
* @param textBoxText the text to display in the text box.
* @param spacing the spacing between the elements.
*/
public void handleAddTransformation(VBox vbox, String textBoxText, int spacing) {
vbox.getChildren().add(createTextBoxWithTextFieldsContainer(spacing,
textBoxText, 55, 20, "a00", "a01",
"a10", "a11", "v0", "v1"));
}
/**
* Handles the event of the user using a ComboBox to change fractal. It calls the controller's
* changeFractal method with the selected fractal.
*
* @param box The ComboBox containing the fractal to change to.
*/
protected <T> void handleChangeFractal(ComboBox<T> box) {
if (box.getValue()
instanceof ChaosGameDescriptionFactory.DescriptionTypeEnum descriptionTypeEnum) {
controller.changeFractal(descriptionTypeEnum);
} else if (box.getValue() instanceof String string) {
controller.changeFractal(string);
}
}
/**
* Handles the event of the user using the edit ComboBox. The event handler
* sets the selected transformation in the view. The controller then changes
* the fractal to "add new".
*
* @param box The ComboBox containing the transformationType.
*/
protected <T> void handleEditTransformationChoice(ComboBox<T> box) {
view.setSelectedTransformation((MainPageView.TransformationType) box.getValue());
controller.changeFractal("add new");
}
/**
* Handles the mouse event on hovering over the mouse box. The event handler
* calls the controller's changeJuliaTransformationDynamic method with the
* x and y coordinates of the mouse, and sets the text of the x0Field and x1Field
* to the new coordinates.
*
* @param x0Field TextField to display the x coordinate.
* @param x1Field TextField to display the y coordinate.
* @param box The mouse-hover-box
* @param e The mouse event.
*/
protected void handleMouseHoverOnMouseBox(TextField x0Field, TextField x1Field,
Pane box, MouseEvent e) {
double x = (e.getX() / box.getWidth()) * 2 - 1;
double y = (e.getY() / box.getHeight()) * 2 - 1;
controller.changeJuliaTransformationDynamic(x, y);
x0Field.setText(String.format(Locale.ENGLISH, "%.5f", x));
x1Field.setText(String.format(Locale.ENGLISH, "%.5f", y));
}
}
This diff is collapsed.
package edu.ntnu.idatt2003.view.components; package edu.ntnu.idatt2003.view.components;
import java.util.List; import java.util.List;
import java.util.function.BiConsumer;
import javafx.event.ActionEvent;
import javafx.scene.control.ComboBox; import javafx.scene.control.ComboBox;
/** /**
...@@ -8,7 +10,14 @@ import javafx.scene.control.ComboBox; ...@@ -8,7 +10,14 @@ import javafx.scene.control.ComboBox;
* The combo box has a style class "combo-box" and the values are set to the specified values. * The combo box has a style class "combo-box" and the values are set to the specified values.
* Goal: Create a styled combo box with a specified prompt text, width, height and values. * Goal: Create a styled combo box with a specified prompt text, width, height and values.
*/ */
public class StyledComboBox<T> extends ComboBox<T> { public class ComboBoxFactory {
/**
* Private constructor to prevent instantiation.
*/
private ComboBoxFactory() {
}
/** /**
* Creates a styled combo box with a specified prompt text, width, height and values. * Creates a styled combo box with a specified prompt text, width, height and values.
* The combo box has a style class "combo-box" and the values are set to the specified values. * The combo box has a style class "combo-box" and the values are set to the specified values.
...@@ -18,13 +27,40 @@ public class StyledComboBox<T> extends ComboBox<T> { ...@@ -18,13 +27,40 @@ public class StyledComboBox<T> extends ComboBox<T> {
* @param height The preferred height of the combo box. * @param height The preferred height of the combo box.
* @param values The values to set in the combo box. * @param values The values to set in the combo box.
*/ */
public StyledComboBox(String promptText, int width, int height, List<T> values) { public static <T> ComboBox<T> createComboBox(String promptText, int width, int height, List<T> values,
super(); BiConsumer<ComboBox<T>, ActionEvent> eventHandler) {
this.setPromptText(promptText); return createComboBoxWithStyle(promptText, width, height, values, eventHandler);
this.setPrefSize(width, height); }
this.getStyleClass().add("combo-box");
public static <T> ComboBox<T> createComboBox(String promptText, int width, int height, List<T> values,
BiConsumer<ComboBox<T>, ActionEvent> eventHandler, T defaultValue) {
ComboBox<T> comboBox = createComboBoxWithStyle(promptText, width, height, values, eventHandler);
comboBox.setValue(defaultValue);
return comboBox;
}
/**
* Creates a styled combo box with a specified prompt text, width, height, values and events
* to be used in other methods in class.
*
* @param promptText The text to display in the combo box when it is empty.
* @param width The preferred width of the combo box.
* @param height The preferred height of the combo box.
* @param values The values to set in the combo box.
* @param eventHandler The event handler to set on the combo box.
* @return The styled combo box.
*/
private static <T> ComboBox<T> createComboBoxWithStyle(String promptText, int width, int height, List<T> values,
BiConsumer<ComboBox<T>, ActionEvent> eventHandler) {
ComboBox<T> comboBox = new ComboBox<>();
comboBox.setPromptText(promptText);
comboBox.setPromptText(promptText);
comboBox.setPrefSize(width, height);
comboBox.getStyleClass().add("combo-box");
comboBox.setOnAction(e -> eventHandler.accept(comboBox, e));
if (values != null) { if (values != null) {
this.getItems().addAll(values); comboBox.getItems().addAll(values);
} }
return comboBox;
} }
} }
package edu.ntnu.idatt2003.view.components;
import java.util.function.BiConsumer;
import javafx.scene.control.Label;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
/**
* A factory for creating mouse hover boxes. The mouse hover boxes are styled with the "mouse-box"
* style class, and has a label in the center.
* Goal: Create mouse hover boxes.
*/
public class MouseHoverBoxFactory {
/**
* Private constructor to prevent instantiation.
*/
private MouseHoverBoxFactory() {
}
/**
* Creates a mouse hover box with the specified text and width, and event. The mouse hover box
* is styled with the "mouse-box" style class, and has a label in the center. The box grows
* vertically to fill available space, and has a preferred width. The mouse hover
* box is configured to call the specified event handler when the mouse is moved over it.
*
* @param text The text to display in the mouse hover box.
* @param width The preferred width of the mouse hover box.
* @param eventHandler The event handler to call when the mouse is moved over the mouse hover box.
* @return The mouse hover box.
*/
public static Pane createMouseHoverBox(String text, double width,
BiConsumer<Pane, MouseEvent> eventHandler) {
Pane box = new StackPane();
box.setPrefWidth(width);
box.getStyleClass().add("mouse-box");
box.getChildren().add(new Label(text));
box.setOnMouseMoved(e -> eventHandler.accept(box, e));
return box;
}
}
package edu.ntnu.idatt2003.view.components;
import javafx.scene.control.TextField;
import java.util.Locale;
/**
* A styled text field with a specified prompt text, width and height.
* The text field has a style class "text-field".
* Goal: Create a styled text field with a specified prompt text, width and height.
*/
public class StyledTextField extends TextField {
/**
* Creates a styled text field with a specified prompt text, width and height.
* The text field has a style class "text-field".
*
* @param promptText The text to display in the text field when it is empty.
* @param width The preferred width of the text field.
* @param height The preferred height of the text field.
*/
public StyledTextField(String promptText, int width, int height) {
super();
this.setPromptText(promptText);
this.setPrefSize(width, height);
this.getStyleClass().add("text-field");
}
/**
* Creates a styled text field with a specified coordinate, width and height.
* The coordinate is formatted to two decimal places, and is set as the text
* of the text field.
*
* @param coordinate the coordinate to display in the text field.
* @param width the preferred width of the text field.
* @param height the preferred height of the text field.
*/
public StyledTextField(double coordinate, int width, int height) {
super(String.format(Locale.US, "%.2f", coordinate));
this.setPrefSize(width, height);
this.getStyleClass().add("text-field");
}
}
package edu.ntnu.idatt2003.view.components;
import static edu.ntnu.idatt2003.view.components.TextBoxFactory.createTextBox;
import static edu.ntnu.idatt2003.view.components.TextFieldFactory.createTextField;
import javafx.scene.layout.HBox;
/**
* A factory for creating containers containing a text box and text fields.
* Goal: Create containers containing a text box and text fields.
*/
public class TextBoxAndTextFieldContainerFactory {
/**
* Private constructor to prevent instantiation.
*/
private TextBoxAndTextFieldContainerFactory() {
}
/**
* Creates a HBox containing a text box with the specified text and as many text fields
* as the length of the doubles array, which gets the height and with given as parameters.
*
* @param spacing Spacing between the elements.
* @param textBoxText The text for the text box.
* @param textFieldWidth The width of the text fields.
* @param textFieldHeight The height of the text field.
* @param textFieldCoords The coordinates for the TextFields.
* @return The HBox containing the text box and text fields.
*/
public static HBox createTextBoxWithTextFieldsContainer(int spacing,
String textBoxText,
int textFieldWidth,
int textFieldHeight,
double[] textFieldCoords) {
HBox container = new HBox(spacing);
container.getChildren().add(createTextBox(textBoxText));
for (double coordinate : textFieldCoords) {
container.getChildren().add(createTextField(coordinate,
textFieldWidth, textFieldHeight));
}
return container;
}
/**
* Creates a HBox containing a text box with the specified text and as many text fields
* as specified is given prompt text to, which gets the size given as parameters.
*
* @param spacing Spacing between the elements.
* @param textBoxText The text to display in the text box.
* @param textFieldWidth The width of the text field.
* @param textFieldHeight The height of the text field.
* @param promptTexts The prompt texts for the text fields.
* @return The HBox containing the text box and text fields.
*/
public static HBox createTextBoxWithTextFieldsContainer(int spacing,
String textBoxText,
int textFieldWidth,
int textFieldHeight,
String... promptTexts) {
HBox container = new HBox(spacing);
container.getChildren().add(createTextBox(textBoxText));
for (String promptText : promptTexts) {
container.getChildren().add(createTextField(promptText,
textFieldWidth, textFieldHeight));
}
return container;
}
}
package edu.ntnu.idatt2003.view.components;
import javafx.scene.control.Label;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.StackPane;
/**
* A factory for creating text boxes. The text boxes are styled with the "text-box"
* style class.
* Goal: Creating text boxes.
*/
public class TextBoxFactory {
/**
* Private constructor to prevent instantiation.
*/
private TextBoxFactory() {
}
/**
* Creates a text box with the specified text. The text box is styled with the
* "text-box" style class. The text box is a StackPane with a Label as a child.
* The text box is configured to grow horizontally.
*
* @param text The text to display in the text box.
* @return The text box.
*/
public static StackPane createTextBox(String text) {
StackPane textBox = new StackPane();
textBox.getStyleClass().add("text-box");
HBox.setHgrow(textBox, Priority.ALWAYS);
textBox.getChildren().add(new Label(text));
return textBox;
}
}
package edu.ntnu.idatt2003.view.components;
import java.util.Locale;
import java.util.function.BiConsumer;
import javafx.event.ActionEvent;
import javafx.scene.control.TextField;
/**
* A styled text field with a specified prompt text, width and height.
* The text field has a style class "text-field".
* Goal: Create a styled text field with a specified prompt text, width and height.
*/
public class TextFieldFactory {
/**
* Private constructor to prevent instantiation.
*/
private TextFieldFactory() {
}
/**
* Creates a styled text field with a specified prompt text, width and height.
* The text field has a style class "text-field".
*
* @param promptText The text to display in the text field when it is empty.
* @param width The preferred width of the text field.
* @param height The preferred height of the text field.
*/
public static TextField createTextField(String promptText, int width, int height) {
TextField textField = new TextField();
textField.setPromptText(promptText);
textField.setPrefSize(width, height);
textField.getStyleClass().add("text-field");
return textField;
}
/**
* Creates a styled text field with a specified coordinate, width and height.
* The coordinate is formatted to two decimal places, and is set as the text
* of the text field.
*
* @param coordinate the coordinate to display in the text field.
* @param width the preferred width of the text field.
* @param height the preferred height of the text field.
*/
public static TextField createTextField(double coordinate, int width, int height) {
TextField textField = new TextField(String.format(Locale.US, "%.2f", coordinate));
textField.setPrefSize(width, height);
textField.getStyleClass().add("text-field");
return textField;
}
/**
* Creates a styled text field with a specified coordinate, width and height, in addition to this
* it also takes an BiConsumer as a parameter to set the action event.
*
* @param promptText The text to display in the text field when it is empty.
* @param width The preferred width of the text field.
* @param height The preferred height of the text field.
* @param eventHandler The event handler to set on the text field.
* @return The styled text field with action event.
*/
public static TextField createTextField(String promptText, int width, int height,
BiConsumer<TextField, ActionEvent> eventHandler) {
TextField textField = new TextField();
textField.setPromptText(promptText);
textField.setPrefSize(width, height);
textField.getStyleClass().add("button");
textField.setOnAction(e -> eventHandler.accept(textField, e));
return textField;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment