aboutsummaryrefslogtreecommitdiff
path: root/src/com.example.portfolio2/com/example/portfolio2/Window.java
blob: 774b012cb8785299363789d118a3540c83d8c441 (plain)
  1. // SPDX-FileCopyrightText: 2025 Jonas Smedegaard <dr@jones.dk>
  2. // SPDX-FileCopyrightText: 2025 <Alexander Marthin Klemensen stud-marthin@ruc.dk>
  3. // SPDX-FileCopyrightText: 2025 <Ian Valentin Christensen stud-ianc@ruc.dk>
  4. // SPDX-FileCopyrightText: 2025 <Zahed Noos zahed@ruc.dk>
  5. // SPDX-License-Identifier: GPL-3.0-or-later
  6. package com.example.portfolio2;
  7. import javafx.application.Application;
  8. import javafx.scene.Scene;
  9. import javafx.scene.control.ComboBox;
  10. import javafx.scene.control.Label;
  11. import javafx.scene.control.TextArea;
  12. import javafx.scene.layout.HBox;
  13. import javafx.scene.layout.VBox;
  14. import javafx.stage.Stage;
  15. import java.io.IOException;
  16. import java.util.List;
  17. /// Bachelorizer - JavaFX Window view
  18. // Class is final to forbid subclassing,
  19. // because object is passed to controller during instantiation
  20. public final class Window extends Application {
  21. /// Default constructor
  22. // (declared explicitly only to silence javadoc)
  23. public Window() { }
  24. /// window width
  25. private static final int WINDOW_WIDTH = 1000;
  26. /// window height
  27. private static final int WINDOW_HEIGHT = 500;
  28. /// box width
  29. private static final int LIST_WIDTH = 250;
  30. /// box height
  31. private static final int LIST_HEIGHT = 35;
  32. /// Label styling
  33. private static final String LABEL_STYLE =
  34. "-fx-font-weight: bold;"
  35. + "-fx-font-size: 18;"
  36. + "-fx-padding: 10";
  37. /// Storage model
  38. private Database store = new Database();
  39. /// UI model
  40. ///
  41. /// Must be subclass GUI to cover columns.
  42. private GUI ui = new GUI();
  43. /// Application controller
  44. private Controller con = new Controller(store, ui, this);
  45. /// column state data as List of ActivityColumn objects
  46. private List<ActivityColumn> columns;
  47. @Override
  48. public void start(final Stage stage) throws IOException {
  49. // clear old insertions into participation table
  50. con.initialize();
  51. // define list of columns based on their names
  52. columns = List.of(
  53. new ActivityColumn(GUI.Section.PROGRAM),
  54. new ActivityColumn(GUI.Section.SUBJECT1),
  55. new ActivityColumn(GUI.Section.SUBJECT2),
  56. new ActivityColumn(GUI.Section.ELECTIVE)
  57. );
  58. // define button functionality for each activity column
  59. for (ActivityColumn col : columns) {
  60. col.nameLabel.setStyle(LABEL_STYLE);
  61. col.ectsLabel.setStyle(LABEL_STYLE);
  62. col.categoryCombo.setPrefSize(
  63. LIST_WIDTH, LIST_HEIGHT);
  64. col.activitySelect.setPrefSize(
  65. LIST_WIDTH, LIST_HEIGHT);
  66. col.area.setPrefWidth(LIST_WIDTH);
  67. // all boxes share same activity logic
  68. col.activitySelect.setOnAction(event -> {
  69. con.onActivitySelected(
  70. col.categoryCombo,
  71. col.activitySelect,
  72. col.area);
  73. con.updateEcts(
  74. col.ectsLabel,
  75. col.categoryCombo);
  76. });
  77. // handle each category box
  78. switch (col.section) {
  79. case GUI.Section.PROGRAM -> {
  80. col.categoryCombo.getItems().addAll(
  81. "HumTek", "NatBach");
  82. col.categoryCombo.setOnAction(event -> {
  83. con.onCategorySelected(
  84. col.section,
  85. col.categoryCombo.getValue());
  86. });
  87. }
  88. // TODO: use the list for filling the box
  89. case GUI.Section.SUBJECT1 -> {
  90. col.categoryCombo.getItems().addAll(
  91. "Computer Science",
  92. "Informatik",
  93. "Astrology");
  94. col.categoryCombo.setOnAction(event -> {
  95. con.onSubjectModuleSelected(
  96. col.categoryCombo,
  97. columns.get(
  98. GUI.Section.SUBJECT2.column)
  99. .categoryCombo);
  100. con.onCategorySelected(
  101. col.section,
  102. col.categoryCombo.getValue());
  103. });
  104. }
  105. case GUI.Section.SUBJECT2 -> {
  106. col.categoryCombo.getItems().addAll(
  107. "Computer Science",
  108. "Informatik",
  109. "Astrology");
  110. // TODO: figure out a better way...
  111. col.categoryCombo.setOnAction(event -> {
  112. con.onSubjectModuleSelected(
  113. col.categoryCombo,
  114. columns.get(
  115. GUI.Section.SUBJECT1.column)
  116. .categoryCombo);
  117. con.onCategorySelected(
  118. col.section,
  119. col.categoryCombo.getValue());
  120. });
  121. }
  122. case GUI.Section.ELECTIVE -> {
  123. // hide useless box
  124. col.categoryCombo.setVisible(false);
  125. con.fillElective(col.activitySelect);
  126. }
  127. }
  128. }
  129. // define HBox and scene for columns
  130. HBox root = new HBox(
  131. columns.get(GUI.Section.PROGRAM.column)
  132. .asVBox(),
  133. columns.get(GUI.Section.SUBJECT1.column)
  134. .asVBox(),
  135. columns.get(GUI.Section.SUBJECT2.column)
  136. .asVBox(),
  137. columns.get(GUI.Section.ELECTIVE.column)
  138. .asVBox());
  139. Scene scene = new Scene(
  140. root, WINDOW_WIDTH, WINDOW_HEIGHT);
  141. stage.setTitle(
  142. "Course Selector RUC: Ultimate Deluxe Edition");
  143. stage.setScene(scene);
  144. stage.show();
  145. }
  146. /// JVM entry point
  147. ///
  148. /// @param args command-line arguments
  149. public static void main(final String[] args) {
  150. launch();
  151. }
  152. /// column of activities
  153. ///
  154. /// @param section structural section for column
  155. /// @param nameLabel display text
  156. /// @param categoryCombo dropdown list for categories
  157. /// @param activitySelect dropdown list for activities
  158. /// @param area description of chosen activities
  159. /// @param ectsLabel text to display ECTS points
  160. private record ActivityColumn(
  161. GUI.Section section,
  162. Label nameLabel,
  163. ComboBox<String> categoryCombo,
  164. ComboBox<String> activitySelect,
  165. TextArea area,
  166. Label ectsLabel
  167. ) {
  168. /// column of activities
  169. ///
  170. /// @param section structural section for column
  171. public ActivityColumn(GUI.Section section) {
  172. this(
  173. section,
  174. new Label(section.label),
  175. new ComboBox<>(),
  176. new ComboBox<>(),
  177. new TextArea(),
  178. new Label()
  179. );
  180. }
  181. /// activity columne as VBox
  182. ///
  183. /// @return column of activities as VBox
  184. VBox asVBox() {
  185. return new VBox(
  186. nameLabel,
  187. categoryCombo,
  188. activitySelect,
  189. area,
  190. ectsLabel);
  191. }
  192. }
  193. /// populate activities for a category
  194. ///
  195. /// @param section structural section to operate on
  196. /// @param activities activities to apply as string
  197. public void setOptions(
  198. final GUI.Section section, final List<String> activities
  199. ) {
  200. // clear the activity selection box
  201. columns.get(section.column).activitySelect
  202. .getItems().clear();
  203. // fill activity box from data in store
  204. columns.get(section.column).activitySelect
  205. .getItems().addAll(activities);
  206. }
  207. /// remove selections from a category
  208. ///
  209. /// @param section structural section to operate on
  210. public void clearSelections(final GUI.Section section) {
  211. // clear text area
  212. columns.get(section.column).area.clear();
  213. }
  214. }