aboutsummaryrefslogtreecommitdiff
path: root/src/dk.biks.bachelorizer/dk/biks/bachelorizer
diff options
context:
space:
mode:
authorJonas Smedegaard <dr@jones.dk>2025-04-27 16:43:17 +0200
committerJonas Smedegaard <dr@jones.dk>2025-04-27 16:43:22 +0200
commit8535a9ca92539bf12ec00cac7a4e47be604f0283 (patch)
tree7a1fb082d5218e18a0186d97a8ed1f7dd87fd41f /src/dk.biks.bachelorizer/dk/biks/bachelorizer
parentd104247b8bcdb2a38b680ac54e7ceb2bba155c0e (diff)
simplify path structure
Diffstat (limited to 'src/dk.biks.bachelorizer/dk/biks/bachelorizer')
-rw-r--r--src/dk.biks.bachelorizer/dk/biks/bachelorizer/Control.java94
-rw-r--r--src/dk.biks.bachelorizer/dk/biks/bachelorizer/Main.java90
-rw-r--r--src/dk.biks.bachelorizer/dk/biks/bachelorizer/model/Combi.java105
-rw-r--r--src/dk.biks.bachelorizer/dk/biks/bachelorizer/model/GUI.java62
-rw-r--r--src/dk.biks.bachelorizer/dk/biks/bachelorizer/model/Person.java18
-rw-r--r--src/dk.biks.bachelorizer/dk/biks/bachelorizer/view/Window.java120
6 files changed, 489 insertions, 0 deletions
diff --git a/src/dk.biks.bachelorizer/dk/biks/bachelorizer/Control.java b/src/dk.biks.bachelorizer/dk/biks/bachelorizer/Control.java
new file mode 100644
index 0000000..b53fb9f
--- /dev/null
+++ b/src/dk.biks.bachelorizer/dk/biks/bachelorizer/Control.java
@@ -0,0 +1,94 @@
+// SPDX-FileCopyrightText: 2025 Jonas Smedegaard <dr@jones.dk>
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package dk.biks.bachelorizer;
+
+import java.util.List;
+
+import dk.biks.bachelorizer.model.GUI;
+import dk.biks.bachelorizer.view.Window;
+
+/// Bachelorizer - Controller
+public class Control{
+
+ /// Application model
+ // (declared explicitly only to silence javadoc)
+ private GUI model;
+
+ /// Application view
+ private Window view;
+
+ /// Parameters passed on command-line and in JNLP file
+ private List<String> parameters;
+
+ /// Default constructor
+ ///
+ /// @param model Application model
+ /// @param view Application view
+ public Control(GUI model, Window view){
+ this.model = model;
+ this.view = view;
+ }
+
+ /// parse application parameters
+ ///
+ /// parse parameters as GNU-style options and arguments,
+ /// i.e. treat dash-prefixed words as options
+ /// until an optional first bare "--",
+ /// taking first non-option argument as name of student
+ /// and remaining ones as activity selections
+ ///
+ /// @param parameters Application parameters
+ public void setParameters(List<String> parameters) {
+ boolean optionsDone = false;
+ boolean studentAssigned = false;
+ for (String item : parameters) {
+ if (!optionsDone && item.matches("--")) {
+ optionsDone = true;
+ } else if (!item.startsWith("-")) {
+ if (!studentAssigned) {
+ model.addStudent(item);
+ studentAssigned = true;
+ showStudent();
+ } else {
+ model.addActivity(item);
+ showActivities();
+ }
+ }
+ }
+ }
+
+ /// Enter activity
+ ///
+ /// @param s String entered
+ public void enterActivity(String s){
+ model.addActivity(s);
+ view.clearActivityEntry();
+ showActivities();
+ }
+
+ /// Display student
+ public void showStudent() {
+ view.setStudentName(model.getStudentName());
+ }
+
+ /// Display list of activity entries
+ public void showActivities() {
+ String toarea = "";
+ for (String t : model.getActivities())
+ toarea += t + "\n";
+ view.setArea(toarea);
+ }
+
+ /// drop last activity entry
+ public void delOne(){
+ model.delOneActivity();
+ showActivities();
+ }
+
+ /// drop all activity entries
+ public void delAll(){
+ model.delAllActivities();
+ showActivities();
+ }
+}
diff --git a/src/dk.biks.bachelorizer/dk/biks/bachelorizer/Main.java b/src/dk.biks.bachelorizer/dk/biks/bachelorizer/Main.java
new file mode 100644
index 0000000..2efd5b8
--- /dev/null
+++ b/src/dk.biks.bachelorizer/dk/biks/bachelorizer/Main.java
@@ -0,0 +1,90 @@
+// SPDX-FileCopyrightText: 2025 Jonas Smedegaard <dr@jones.dk>
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package dk.biks.bachelorizer;
+
+import java.lang.UnsupportedOperationException;
+import java.util.Arrays;
+
+/* TODO
+import dk.biks.bachelorizer.view.Oneshot;
+import dk.biks.bachelorizer.view.Prompt;
+import dk.biks.bachelorizer.view.Pipe;
+import dk.biks.bachelorizer.view.Screen;
+*/
+import dk.biks.bachelorizer.view.Window;
+
+/// Bachelorizer - bachelor programme registrar
+///
+/// Tool for registering students
+/// for activities in their bachelor programme.
+///
+/// Runner class spawning an interactive or non-interactive application
+/// based on passed arguments
+///
+/// Multi-framework MVC structure inspired by project Криптоанализатор
+/// written by Александр Хмелев <akhmelev@gmail.com>.
+///
+/// * v0.0.1-draft
+/// * initial release, as part of delivery "Portfolio 1"
+///
+/// @version 0.0.1-draft
+/// @see <https://moodle.ruc.dk/mod/assign/view.php?id=523186>
+/// @see <https://github.com/demologin/CryptoAnalyzerLed>
+public class Main {
+
+ /// Default constructor
+ ///
+ /// @param args command-line arguments or default demo data
+ public Main(final String[] args) {
+
+ switch (uiFromArgs(args)) {
+ case "gui" -> { Window.main(args); }
+// TODO case "tui" -> { Screen.main(args); }
+// TODO case "cli" -> { Line.main(args); }
+ default -> {
+ throw new UnsupportedOperationException(
+ "Not yet implemented.");
+ }
+ }
+ }
+
+ /// JVM entry point
+ ///
+ /// @param args command-line arguments
+ public static void main(String[] args) {
+
+ // inject initial sample data unless passed as arguments
+ if ((args.length == 0)
+ || (!Arrays.stream(args).anyMatch(
+ s -> s != null && !s.startsWith("-")))
+ ) {
+ args = new String[] {
+ "Jonas Smedegaard",
+ "CS-SMC2",
+ "CS-SMC3",
+ };
+ }
+
+ new Main(args);
+ }
+
+ /// minimal argument parser to detect explicit UI choice
+ ///
+ /// @param args command-line arguments
+ /// @return choice of UI as String
+ public static String uiFromArgs(String[] args) {
+ // TODO: make "cli" the default when implemented
+ String defaultUI = "gui";
+
+ for (String arg : args) {
+ if (arg.matches("--(gui|tui|cli)")) {
+ return (arg.length() == 2)
+ ? defaultUI
+ : arg.substring(2);
+ }
+ }
+
+ return defaultUI;
+ }
+}
diff --git a/src/dk.biks.bachelorizer/dk/biks/bachelorizer/model/Combi.java b/src/dk.biks.bachelorizer/dk/biks/bachelorizer/model/Combi.java
new file mode 100644
index 0000000..371eb79
--- /dev/null
+++ b/src/dk.biks.bachelorizer/dk/biks/bachelorizer/model/Combi.java
@@ -0,0 +1,105 @@
+// SPDX-FileCopyrightText: 2025 Jonas Smedegaard <dr@jones.dk>
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package dk.biks.bachelorizer.model;
+
+import java.util.Collection;
+import java.util.Set;
+
+import com.example.portfolio3.AdjListGraph;
+import com.example.portfolio3.Graph;
+import com.example.portfolio3.GraphAlgorithms;
+import com.example.portfolio3.MatrixGraph;
+import com.example.portfolio3.Vertex;
+
+/// Combi - static sample dataset of course combinations
+///
+/// Slurps and parses data from upstream-provided comma-separated file.
+///
+/// @version 0.0.1
+/// @see <https://moodle.ruc.dk/mod/assign/view.php?id=523186>
+public final class Combi {
+
+ /// data about combinations as a Graph
+ private Graph g;
+
+ /// Default constructor
+ ///
+ /// @param path path to data file
+ private Combi(final String path) {
+
+ // read into temporary graph to resolve vertice count
+ //
+ // use Adjacency List Representation:
+ // * cheap to bootstrap (done once)
+ // * simple to count vertices (done once): O(1)
+ Graph _g = new AdjListGraph();
+ GraphAlgorithms.readGraph(_g, path);
+ Integer _vertice_count = _g.vertices().size();
+
+ // read into final graph
+ //
+ // use Adjacency Matrix Representation:
+ // * expensive to bootstrap (done once)
+ // * simple to add edges but needs vertice count
+ // * simple to get edges (done repeatedly): O(1)
+ //
+ // TODO: avoid reading and parsing file twice
+ Graph g = new MatrixGraph(_vertice_count);
+ GraphAlgorithms.readGraph(g, path);
+
+ // ensure the graph is connected
+ isConnected(g);
+
+ GraphAlgorithms.printGraph(g);
+
+ // release temporary variables for garbage collection
+ _g = null;
+ _vertice_count = null;
+ }
+
+ /// JVM entry point
+ ///
+ /// @param args command-line arguments
+ public static void main(final String[] args) {
+
+ // first argument, if provided, is the data file path;
+ // else use upstream named file in current directory.
+ String path = (args.length > 0)
+ ? args[0]
+ : "combi.txt";
+
+ Combi combi = new Combi(path);
+ }
+
+ /// utility function to check that a graph is connected
+ ///
+ /// If check fails, throw an unchecked exception,
+ /// since it occurs at runtime and is unrecoverable.
+ ///
+ /// Time complexity of the operation is O(n²)
+ /// where n is the amount of vertices,
+ /// since visitDepthFirst() recurses out-edges of all vertices.
+ ///
+ /// @param g Graph to inspect
+ /// @throws IllegalArgumentException
+ /// https://docs.oracle.com/javase/tutorial/essential/exceptions/runtime.html
+ public static void isConnected(Graph g) {
+
+ // collect all vertices in the graph
+ Collection<Vertex> c = g.vertices();
+
+ // pick a random vertice in the graph
+ Vertex v = g.vertices().iterator().next();
+
+ // collect the set of visitable vertices
+ Set<Vertex> visited = GraphAlgorithms.visitDepthFirst(
+ g, v);
+
+ // throw exception if not all vertices were visited
+ if (visited.size() != c.size()) {
+ throw new IllegalArgumentException(
+ "graph is not connected");
+ }
+ }
+}
diff --git a/src/dk.biks.bachelorizer/dk/biks/bachelorizer/model/GUI.java b/src/dk.biks.bachelorizer/dk/biks/bachelorizer/model/GUI.java
new file mode 100644
index 0000000..ca9bd86
--- /dev/null
+++ b/src/dk.biks.bachelorizer/dk/biks/bachelorizer/model/GUI.java
@@ -0,0 +1,62 @@
+// SPDX-FileCopyrightText: 2025 Jonas Smedegaard <dr@jones.dk>
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package dk.biks.bachelorizer.model;
+
+import java.util.ArrayList;
+
+import dk.biks.bachelorizer.model.Person;
+
+/// Bachelorizer - GUI model
+public class GUI{
+
+ /// Default constructor
+ // (declared explicitly only to silence javadoc)
+ public GUI(){
+ }
+
+ /// Activity list
+ private Person student;
+
+ /// Activity list
+ private ArrayList<String> list = new ArrayList<>();
+
+ /// Add student
+ ///
+ /// @param name Name of student
+ public void addStudent(String name){
+ student = new Person(name);
+ }
+
+ /// Get student name
+ ///
+ /// @return name of student
+ public String getStudentName(){
+ return student.name;
+ }
+
+ /// Add activity to list
+ ///
+ /// @param s Activity to add
+ public void addActivity(String s){
+ list.add(s);
+ }
+
+ /// Get list of activities
+ ///
+ /// @return activity list
+ public ArrayList<String> getActivities(){
+ return list;
+ }
+
+ /// Delete last activity from list
+ public void delOneActivity(){
+ if(list.size()>0)
+ list.remove(list.size()-1);
+ }
+
+ /// Delete all activities from list
+ public void delAllActivities(){
+ list.clear();
+ }
+}
diff --git a/src/dk.biks.bachelorizer/dk/biks/bachelorizer/model/Person.java b/src/dk.biks.bachelorizer/dk/biks/bachelorizer/model/Person.java
new file mode 100644
index 0000000..9edb7af
--- /dev/null
+++ b/src/dk.biks.bachelorizer/dk/biks/bachelorizer/model/Person.java
@@ -0,0 +1,18 @@
+// SPDX-FileCopyrightText: 2025 Jonas Smedegaard <dr@jones.dk>
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package dk.biks.bachelorizer.model;
+
+/// Bachelorizer - Person model
+public class Person {
+
+ /// Person name
+ public String name;
+
+ /// Constructor
+ ///
+ /// @param name Name of person
+ public Person (String name) {
+ this.name = name;
+ }
+}
diff --git a/src/dk.biks.bachelorizer/dk/biks/bachelorizer/view/Window.java b/src/dk.biks.bachelorizer/dk/biks/bachelorizer/view/Window.java
new file mode 100644
index 0000000..c75e290
--- /dev/null
+++ b/src/dk.biks.bachelorizer/dk/biks/bachelorizer/view/Window.java
@@ -0,0 +1,120 @@
+// SPDX-FileCopyrightText: 2025 Jonas Smedegaard <dr@jones.dk>
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package dk.biks.bachelorizer.view;
+
+import java.util.List;
+import javafx.application.Application;
+import javafx.scene.control.Button;
+import javafx.scene.control.Label;
+import javafx.scene.control.TextArea;
+import javafx.scene.control.TextField;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.VBox;
+import javafx.scene.Scene;
+import javafx.stage.Stage;
+
+import dk.biks.bachelorizer.Control;
+import dk.biks.bachelorizer.model.GUI;
+
+/// Bachelorizer - JavaFX Window view
+// Class is final to forbid subclassing,
+// because object is passed to controller during instatiation
+public final class Window extends Application { // the View
+
+ /// Default constructor
+ // (declared explicitly only to silence javadoc)
+ public Window() {
+ }
+
+ /// Label styling
+ public static String LABEL_STYLE =
+ "-fx-font-weight: bold; -fx-font-size: 20;";
+
+ /// Application model
+ private GUI model = new GUI();
+
+ /// Application controller
+ private Control control = new Control(model, this);
+
+ /// Name of student
+ private TextField nameEntry = new TextField();
+
+ /// Text entry for adding an activity
+ private TextField activityEntry = new TextField();
+
+ /// Text area for activity entries
+ private TextArea area = new TextArea();
+
+ /// Button to delete one activity
+ private Button delOne = new Button("Delete one");
+
+ /// Button to delete all activities
+ private Button delAll = new Button("Delete all");
+
+ /// Application instantiation
+ ///
+ /// @param args application parameters
+ public static void main(String[] args) {
+ launch(args);
+ }
+
+ @Override
+ public void start(Stage stage) {
+
+ // pass application parameters to controller
+ control.setParameters(getParameters().getRaw());
+
+ // add listeners
+// NameEntry.setOnAction(e -> control.enterName(
+// activityEntry.getText()));
+ activityEntry.setOnAction(e -> control.enterActivity(
+ activityEntry.getText()));
+ delOne.setOnAction(e -> control.delOne());
+ delAll.setOnAction(e -> control.delAll());
+
+ // add buttons
+ VBox root = new VBox(10,
+ ourHBox("Student", nameEntry),
+ ourHBox("Add activity", activityEntry),
+ new HBox(10, delOne, delAll),
+ area);
+
+ // compose stage
+ Scene scene = new Scene(root, 500, 500);
+ stage.setTitle("JavaFX Demo");
+ stage.setScene(scene);
+ stage.show();
+ }
+
+ /// action to apply student name
+ ///
+ /// @param s Text to apply
+ public void setStudentName(String s) {
+ nameEntry.setText(s);
+ }
+
+ /// action to apply text to area
+ ///
+ /// @param s Text to apply
+ public void setArea(String s) {
+ area.setText(s);
+ }
+
+ /// Button action to clear field
+ public void clearActivityEntry() {
+ activityEntry.setText("");
+ }
+
+ /// Styled HBox with label and TextField
+ ///
+ /// @param s Label string
+ /// @param f Text field
+ /// @return HBox containing styled label and text field
+ public HBox ourHBox(String s, TextField f) {
+ Label label = new Label(s+":");
+ label.setStyle(LABEL_STYLE);
+
+ return new HBox(10, label, f);
+ }
+}