diff options
author | Jonas Smedegaard <dr@jones.dk> | 2025-04-28 15:58:57 +0200 |
---|---|---|
committer | Jonas Smedegaard <dr@jones.dk> | 2025-04-28 15:58:57 +0200 |
commit | de35b79128729a3d2ec1948b332ca625f7f89119 (patch) | |
tree | f13f203d44ed08c81b7b7ecf9032409e8b739157 /src/com.example.portfolio2/com/example/portfolio2/HelloApplication.java | |
parent | 67bfeadd996019799d9f254f3b0e87b3d3de175c (diff) |
add module com.example.portfolio2 from Ian
Diffstat (limited to 'src/com.example.portfolio2/com/example/portfolio2/HelloApplication.java')
-rw-r--r-- | src/com.example.portfolio2/com/example/portfolio2/HelloApplication.java | 318 |
1 files changed, 318 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; + } +} + |