aboutsummaryrefslogtreecommitdiff
path: root/src/com.example.portfolio2/com/example
diff options
context:
space:
mode:
authorJonas Smedegaard <dr@jones.dk>2025-04-28 15:58:57 +0200
committerJonas Smedegaard <dr@jones.dk>2025-04-28 15:58:57 +0200
commitde35b79128729a3d2ec1948b332ca625f7f89119 (patch)
treef13f203d44ed08c81b7b7ecf9032409e8b739157 /src/com.example.portfolio2/com/example
parent67bfeadd996019799d9f254f3b0e87b3d3de175c (diff)
add module com.example.portfolio2 from Ian
Diffstat (limited to 'src/com.example.portfolio2/com/example')
-rw-r--r--src/com.example.portfolio2/com/example/portfolio2/HelloApplication.java318
-rw-r--r--src/com.example.portfolio2/com/example/portfolio2/HelloController.java14
2 files changed, 332 insertions, 0 deletions
diff --git a/src/com.example.portfolio2/com/example/portfolio2/HelloApplication.java b/src/com.example.portfolio2/com/example/portfolio2/HelloApplication.java
new file mode 100644
index 0000000..300f626
--- /dev/null
+++ b/src/com.example.portfolio2/com/example/portfolio2/HelloApplication.java
@@ -0,0 +1,318 @@
+package com.example.portfolio2;
+
+import javafx.application.Application;
+import javafx.scene.Scene;
+import javafx.scene.control.ComboBox;
+import javafx.scene.control.Label;
+import javafx.scene.control.TextArea;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.VBox;
+import javafx.stage.Stage;
+
+import java.io.IOException;
+import java.sql.*;
+import java.util.ArrayList;
+import java.util.List;
+
+public class HelloApplication extends Application {
+ // Initializing model, controller and database objects
+ private Model model = new Model();
+ private Controller con = new Controller(model,this);
+ MyDB myDB = new MyDB();
+
+ /* Below is the original implementation of the UI elements with
+ accompanying, individual calls to setOnAction to specify functionality.
+ Before changing to a list format,
+ we made sure methods in controller and model
+ were generalized to allow for the new structure seamlessly.
+ private ComboBox<String> programCombo = new ComboBox<>();
+ private ComboBox<String> subject1Combo = new ComboBox<>();
+ private ComboBox<String> subject2Combo = new ComboBox<>();
+ private ComboBox<String> electiveCombo = new ComboBox<>();
+
+ private ComboBox<String> programSelect = new ComboBox<>();
+ private ComboBox<String> subject1Select = new ComboBox<>();
+ private ComboBox<String> subject2Select = new ComboBox<>();
+ private ComboBox<String> electiveSelect = new ComboBox<>();
+
+ private TextArea programArea = new TextArea();
+ private TextArea subject1Area = new TextArea();
+ private TextArea subject2Area = new TextArea();
+ private TextArea electiveArea = new TextArea();
+
+ private Label programEcts = new Label();
+ private Label subject1Ects = new Label();
+ private Label subject2Ects = new Label();
+ private Label electiveEcts = new Label();
+
+ private VBox program = new VBox(new Label("Program"), programCombo, programSelect, programArea, programEcts);
+ private VBox subject1 = new VBox(new Label("Subject 1"), subject1Combo, subject1Select, subject1Area, subject1Ects);
+ private VBox subject2 = new VBox(new Label("Subject 2"), subject2Combo, subject2Select, subject2Area, subject2Ects);
+ private VBox elective = new VBox(new Label("Elective"), electiveCombo, electiveSelect, electiveArea, electiveEcts);
+ */
+
+ @Override
+ public void start(Stage stage) throws IOException {
+ // Clears old insertions into the participation table
+ con.initialize();
+
+ // Defines a list of columns based on their names.
+ List<ActivityColumn> columns = List.of(
+ new ActivityColumn("Program"),
+ new ActivityColumn("Subject 1"),
+ new ActivityColumn("Subject 2"),
+ new ActivityColumn("Elective")
+ );
+
+ // Defines a list of subject modules
+ List<String> subjectModules = List.of("Computer Science", "Informatik", "Astrology");
+
+ // Loop for defining button funtionality for each activity column
+ for (ActivityColumn col : columns) {
+ col.nameLabel.setStyle("-fx-font-size: 18px; -fx-padding: 10px;"); // Styling
+ col.ectsLabel.setStyle("-fx-font-size: 18px; -fx-padding: 10px");
+ col.categoryCombo.setPrefSize(250, 35);
+ col.activitySelect.setPrefSize(250, 35);
+ col.area.setPrefWidth(250);
+
+ // All boxes share the same activity logic
+ col.activitySelect.setOnAction(event -> {
+ con.onActivitySelected(col.categoryCombo, col.activitySelect, col.area);
+ con.updateEcts(col.ectsLabel, col.categoryCombo);
+ });
+
+ switch (col.name) { // Switch statement handles different category boxes
+ case "Program" -> {
+ col.categoryCombo.getItems().addAll("HumTek", "NatBach");
+ col.categoryCombo.setOnAction(event -> {
+ con.onComboSelected(col.categoryCombo, col.activitySelect, col.area);
+ });
+ }
+ case "Subject 1" -> { // We considered using the list for filling the box but couldn't figure it out
+ col.categoryCombo.getItems().addAll("Computer Science", "Informatik", "Astrology");
+ col.categoryCombo.setOnAction(event -> {
+ con.onSubjectModuleSelected(col.categoryCombo, columns.get(2).categoryCombo, subjectModules);
+ con.onComboSelected(col.categoryCombo, col.activitySelect, col.area);
+ });
+ }
+ case "Subject 2" -> {
+ col.categoryCombo.getItems().addAll("Computer Science", "Informatik", "Astrology");
+ col.categoryCombo.setOnAction(event -> { // We figured we have to specify
+ // the second column like this but reckon there's a better way.
+ con.onSubjectModuleSelected(col.categoryCombo, columns.get(1).categoryCombo, subjectModules);
+ con.onComboSelected(col.categoryCombo, col.activitySelect, col.area);
+ });
+ }
+ case "Elective" -> {
+ col.categoryCombo.setVisible(false); // Hide useless box
+ con.fillElective(col.activitySelect);
+ }
+ }
+ }
+
+ // Define an HBox based on the columns and define the scene based on it.
+ HBox root = new HBox(columns.get(0).asVBox(), columns.get(1).asVBox(), columns.get(2).asVBox(), columns.get(3).asVBox());
+ Scene scene = new Scene(root, 1000, 500);
+ stage.setTitle("Course Selector RUC: Ultimate Deluxe Edition");
+ stage.setScene(scene);
+ stage.show();
+ }
+
+ public static void main(String[] args) {
+ launch();
+ }
+
+ // Class for each column of activities
+ private class ActivityColumn {
+ // Each column contains these elements
+ String name;
+ Label nameLabel;
+ ComboBox<String> categoryCombo;
+ ComboBox<String> activitySelect;
+ TextArea area;
+ Label ectsLabel;
+
+ ActivityColumn(String name) {
+ this.name = name;
+ nameLabel = new Label(name);
+ categoryCombo = new ComboBox<>();
+ activitySelect = new ComboBox<>();
+ area = new TextArea();
+ ectsLabel = new Label();
+ // new column, "this.name" to define and saved in the text felt,
+ // new "nameLabel" to show visual text.
+ // CategoryCombo creat a dropdown list
+ // activitySelect creat one more dropdown list with Combobox, possible to choose activity.
+ // area = new TextArea helps create a text felt to describe the chosen activity
+ // ectsLabel = new Label shows text for ects points
+
+ }
+
+ VBox asVBox() {
+ return new VBox(nameLabel, categoryCombo, activitySelect, area, ectsLabel);
+ }
+ }
+}
+class Controller{
+ private Model model;
+ private HelloApplication view; // We do this without using the view directly like this, instead passing options.
+ void initialize() { // calls on the database
+ model.initialize();
+ }
+ Controller(Model model, HelloApplication view){
+ this.model=model; this.view=view;
+ }
+ void onComboSelected(ComboBox<String> combo, ComboBox<String> select, TextArea area) {
+ select.getItems().clear(); // Clear the activity selection box
+ area.clear(); // Clear text area
+ select.getItems().addAll(model.selectProgram((String) combo.getValue())); // Fill activity box using model method
+ }
+ void onActivitySelected(ComboBox<String> combo, ComboBox<String> select, TextArea area) {
+ addActivity((String) select.getValue(), area); // Passes the value chosen in the box
+ updateArea(combo, area); // Updates the text area based on the category choice
+ // users can choose from the ComboBox, string (activity) and the area would update.
+ }
+ void onSubjectModuleSelected(ComboBox<String> subject1, ComboBox<String> subject2, List<String> subjectModules) {
+ // Beautiful loop we've created to remove option chosen in one subject module box from the other
+ for (String sub : subjectModules) {
+ if (sub.equals(subject1.getValue())) {
+ subject2.getItems().remove(subject1.getValue());
+ } else if (!sub.equals(subject1.getValue()) && !subject2.getItems().contains(sub)) {
+ subject2.getItems().add(sub);
+ }
+ }
+ }
+ void addActivity(String s, TextArea textArea) { // Calls on model method to add participation in the database
+ model.addParticipation(model.getActivityIndeks(s));
+ }
+ void updateArea(ComboBox combo, TextArea textArea) { // Clears the text area and adds all activity names from activities in participation
+ textArea.clear();
+ for(String s : model.getParticipation((String) combo.getValue())) {
+ textArea.appendText(s + "\n");
+ }
+ }
+ void updateEcts(Label ectslabel, ComboBox<String> comboBox) { // Updates the labels with the current ECTS of the program type
+ ectslabel.setText("ECTS: "+model.getSumEcts(comboBox.getValue()));
+ }
+ void fillElective(ComboBox<String> electiveBox) {
+ electiveBox.getItems().addAll(model.getAllActivities());
+ }
+}
+
+class Model{ // The model handles all interactions with the database
+ MyDB db=new MyDB();
+ Model(){}
+ void initialize() { // When running the program, it clears the participation database
+ clearParticipation();
+ }
+ int getActivityIndeks(String name) { // Returns the integer value of the activity's index
+ if(name ==null) return -1;
+ ArrayList<String> result = db.query("select indeks from activity a where name is '"+name+"';", "indeks");
+ return Integer.parseInt(result.getFirst());
+
+ }
+ void addParticipation(int activityIndex) { // Inserts the given activity into participation using the activity's index
+ db.cmd("insert into participation values(123, "+activityIndex+");");
+ }
+ ArrayList<String> getParticipation(String program) { // Returns all activity names from activities currently in participation
+ return db.query("select name from participation p inner join activity a on p.indeks = a.indeks where program is '" + program + "';", "name");
+ }
+ void clearParticipation() { // Removes all entries in the participation database
+ db.cmd("delete from participation");
+ }
+ ArrayList<String> selectProgram(String program) { // Returns an arraylist of activities within the given program
+ return db.query("select name from activity where program is '" + program + "';", "name");
+ }
+ String getSumEcts(String program){ // Returns the sum of ECTS points under the given category from the student as a string
+ if(program==null)return "0";
+ ArrayList<String> result = db.query("select sum(activity.ects) as total_ects,student.name from student left outer join participation on student.studid = participation.studid inner join activity on participation.indeks = activity.indeks where program is '"+program+"' group by student.studid ;", "total_ects");
+ if (result.isEmpty()) return "0";
+ return result.getFirst();
+ }
+ ArrayList<String> getAllActivities() {
+ return db.query("select name from activity;", "name");
+ }
+}
+
+class MyDB { // MyDB is all standard Database configuration that was gotten from Mads
+ Connection conn = null;
+
+ MyDB() {
+ if (conn == null) open();
+ }
+
+ public void open() {
+ try {
+ String url = "jdbc:sqlite:identifier.sqlite";
+ conn = DriverManager.getConnection(url);
+ } catch (SQLException e) {
+ System.out.println("cannot open");
+ if (conn != null) close();
+ throw new RuntimeException(e);
+ }
+ ;
+ }
+
+ public void close() {
+ try {
+ if (conn != null) conn.close();
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ conn = null;
+ }
+ public void cmd(String sql) {
+ if (conn == null) open();
+ if (conn == null) {
+ System.out.println("No connection");
+ return;
+ }
+ Statement stmt = null;
+ try {
+ stmt = conn.createStatement();
+ stmt.executeUpdate(sql);
+ } catch (SQLException e) {
+ System.out.println("Error in statement " + sql);
+ throw new RuntimeException(e);
+ }
+ try {
+ if (stmt != null) {
+ stmt.close();
+ }
+ } catch (SQLException e) {
+ System.out.println("Error in statement " + sql);
+ throw new RuntimeException(e);
+ }
+ }
+
+ public ArrayList<String> query(String query, String fld) {
+ ArrayList<String> res = new ArrayList<>();
+ if (conn == null) open();
+ if (conn == null) {
+ System.out.println("No connection");
+ throw new RuntimeException("No connection");
+ }
+ Statement stmt = null;
+ try {
+ stmt = conn.createStatement();
+ ResultSet rs = stmt.executeQuery(query);
+ while (rs.next()) {
+ String name = rs.getString(fld);
+ res.add(name);
+ }
+ } catch (SQLException e) {
+ System.out.println("Error in statement " + query + " " + fld);
+ throw new RuntimeException(e);
+ }
+ try {
+ if (stmt != null) {
+ stmt.close();
+ }
+ } catch (SQLException e) {
+ System.out.println("Error in statement " + query + " " + fld);
+ throw new RuntimeException(e);
+ }
+ return res;
+ }
+}
+
diff --git a/src/com.example.portfolio2/com/example/portfolio2/HelloController.java b/src/com.example.portfolio2/com/example/portfolio2/HelloController.java
new file mode 100644
index 0000000..b2abf23
--- /dev/null
+++ b/src/com.example.portfolio2/com/example/portfolio2/HelloController.java
@@ -0,0 +1,14 @@
+package com.example.portfolio2;
+
+import javafx.fxml.FXML;
+import javafx.scene.control.Label;
+
+public class HelloController {
+ @FXML
+ private Label welcomeText;
+
+ @FXML
+ protected void onHelloButtonClick() {
+ welcomeText.setText("Welcome to JavaFX Application!");
+ }
+} \ No newline at end of file