Added JavaFX UI with TabPane navigation (5 tabs)

This commit is contained in:
sabazadam
2025-12-11 00:06:25 +03:00
parent 0d8c2661d6
commit 393751bc8b
12 changed files with 543 additions and 1 deletions

16
.gitignore vendored
View File

@@ -38,4 +38,20 @@ build/
### Mac OS ###
.DS_Store
### Claude Code & AI Tools ###
.claude/
.claude_code/
claude_desktop_config.json
.mcp/
mcp-server-*/
.ai/
.anthropic/
*_mcp_logs/
.memory/
.context/
*.md
*.txt
*.pdf
projectDescriptionFiles
.mcp.json

6
.idea/vcs.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View File

@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<VBox xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
fx:controller="org.example.se302.controller.ClassroomsController"
spacing="10" styleClass="content-pane">
<padding>
<Insets top="20" right="20" bottom="20" left="20"/>
</padding>
<!-- Header -->
<Label text="Classroom Management" styleClass="section-title"/>
<!-- Classroom Table -->
<TableView fx:id="classroomsTable" VBox.vgrow="ALWAYS">
<columns>
<TableColumn fx:id="classroomIdColumn" text="Classroom ID" prefWidth="200"/>
<TableColumn fx:id="capacityColumn" text="Capacity" prefWidth="150"/>
<TableColumn fx:id="statusColumn" text="Status" prefWidth="150"/>
<TableColumn fx:id="utilizationColumn" text="Utilization" prefWidth="150"/>
</columns>
</TableView>
<!-- Summary Statistics -->
<Separator/>
<HBox spacing="20" alignment="CENTER_LEFT" styleClass="summary-box">
<padding>
<Insets top="10" right="0" bottom="10" left="0"/>
</padding>
<Label fx:id="totalClassroomsLabel" text="Total Classrooms: 0" styleClass="summary-label"/>
<Label fx:id="totalCapacityLabel" text="Total Capacity: 0" styleClass="summary-label"/>
<Label fx:id="averageCapacityLabel" text="Average Capacity: 0" styleClass="summary-label"/>
</HBox>
</VBox>

View File

@@ -0,0 +1,65 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<BorderPane xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
fx:controller="org.example.se302.controller.CoursesController"
styleClass="content-pane">
<!-- Top: Search Bar -->
<top>
<VBox spacing="10">
<padding>
<Insets top="20" right="20" bottom="10" left="20"/>
</padding>
<Label text="Course Management" styleClass="section-title"/>
<HBox spacing="10" alignment="CENTER_LEFT">
<TextField fx:id="searchField" promptText="Search by Course Code..." HBox.hgrow="ALWAYS"/>
<Button text="Clear" onAction="#onClearSearch"/>
</HBox>
<Label fx:id="resultCountLabel" text="Total: 0 courses"/>
</VBox>
</top>
<!-- Center: Course Table -->
<center>
<VBox spacing="5">
<padding>
<Insets top="0" right="20" bottom="10" left="20"/>
</padding>
<TableView fx:id="coursesTable" VBox.vgrow="ALWAYS">
<columns>
<TableColumn fx:id="courseCodeColumn" text="Course Code" prefWidth="200"/>
<TableColumn fx:id="studentCountColumn" text="Enrolled Students" prefWidth="150"/>
<TableColumn fx:id="classroomColumn" text="Assigned Classroom" prefWidth="150"/>
<TableColumn fx:id="examDateColumn" text="Exam Date/Time" prefWidth="150"/>
<TableColumn fx:id="actionColumn" text="Actions" prefWidth="150"/>
</columns>
</TableView>
</VBox>
</center>
<!-- Bottom: Student List Panel (initially hidden) -->
<bottom>
<VBox fx:id="studentListPanel" spacing="10" styleClass="detail-panel" visible="false" managed="false"
prefHeight="250">
<padding>
<Insets top="10" right="20" bottom="20" left="20"/>
</padding>
<HBox alignment="CENTER_LEFT" spacing="10">
<Label fx:id="studentListTitleLabel" text="Students Enrolled" styleClass="subsection-title" HBox.hgrow="ALWAYS"/>
<Button text="Close" onAction="#onCloseStudentList" styleClass="small-button"/>
</HBox>
<Separator/>
<TableView fx:id="enrolledStudentsTable" VBox.vgrow="ALWAYS">
<columns>
<TableColumn fx:id="enrolledStudentIdColumn" text="Student ID" prefWidth="300"/>
</columns>
</TableView>
<Label fx:id="enrolledCountLabel" text="Total: 0 students"/>
</VBox>
</bottom>
</BorderPane>

View File

@@ -0,0 +1,76 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<VBox xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
fx:controller="org.example.se302.controller.ImportController"
spacing="20" styleClass="content-pane">
<padding>
<Insets top="20" right="20" bottom="20" left="20"/>
</padding>
<!-- Header -->
<Label text="Import Data from CSV Files" styleClass="section-title"/>
<Label text="Select CSV files to import student, course, classroom, and enrollment data." wrapText="true"/>
<Separator/>
<!-- Students Import Section -->
<VBox spacing="8">
<Label text="Student Data" styleClass="subsection-title"/>
<HBox spacing="10" alignment="CENTER_LEFT">
<TextField fx:id="studentFileField" promptText="No file selected" editable="false" HBox.hgrow="ALWAYS"/>
<Button fx:id="studentBrowseButton" text="Browse..." onAction="#onBrowseStudents"/>
</HBox>
<Label fx:id="studentStatusLabel" text="Not Loaded" styleClass="status-label"/>
</VBox>
<!-- Courses Import Section -->
<VBox spacing="8">
<Label text="Course Data" styleClass="subsection-title"/>
<HBox spacing="10" alignment="CENTER_LEFT">
<TextField fx:id="courseFileField" promptText="No file selected" editable="false" HBox.hgrow="ALWAYS"/>
<Button fx:id="courseBrowseButton" text="Browse..." onAction="#onBrowseCourses"/>
</HBox>
<Label fx:id="courseStatusLabel" text="Not Loaded" styleClass="status-label"/>
</VBox>
<!-- Classrooms Import Section -->
<VBox spacing="8">
<Label text="Classroom Data" styleClass="subsection-title"/>
<HBox spacing="10" alignment="CENTER_LEFT">
<TextField fx:id="classroomFileField" promptText="No file selected" editable="false" HBox.hgrow="ALWAYS"/>
<Button fx:id="classroomBrowseButton" text="Browse..." onAction="#onBrowseClassrooms"/>
</HBox>
<Label fx:id="classroomStatusLabel" text="Not Loaded" styleClass="status-label"/>
</VBox>
<!-- Enrollments Import Section -->
<VBox spacing="8">
<Label text="Enrollment Data" styleClass="subsection-title"/>
<HBox spacing="10" alignment="CENTER_LEFT">
<TextField fx:id="enrollmentFileField" promptText="No file selected" editable="false" HBox.hgrow="ALWAYS"/>
<Button fx:id="enrollmentBrowseButton" text="Browse..." onAction="#onBrowseEnrollments"/>
</HBox>
<Label fx:id="enrollmentStatusLabel" text="Not Loaded" styleClass="status-label"/>
</VBox>
<Separator/>
<!-- Import Messages Area -->
<VBox spacing="5" VBox.vgrow="ALWAYS">
<Label text="Import Messages" styleClass="subsection-title"/>
<TextArea fx:id="messagesArea" editable="false" wrapText="true" VBox.vgrow="ALWAYS"
promptText="Validation messages and import results will appear here..."/>
</VBox>
<!-- Action Buttons -->
<HBox spacing="10" alignment="CENTER_RIGHT">
<Button fx:id="importAllButton" text="Import All" onAction="#onImportAll"
styleClass="primary-button" disable="true"/>
<Button text="Clear All" onAction="#onClearAll"/>
</HBox>
</VBox>

View File

@@ -0,0 +1,59 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<BorderPane xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
fx:controller="org.example.se302.controller.MainController"
prefHeight="800.0" prefWidth="1200.0">
<!-- Top: Title Bar -->
<top>
<VBox styleClass="header">
<Label text="Exam Scheduling System" styleClass="title-label"/>
<Separator/>
</VBox>
</top>
<!-- Center: Main TabPane -->
<center>
<TabPane fx:id="mainTabPane" tabClosingPolicy="UNAVAILABLE">
<!-- Import Data Tab -->
<Tab fx:id="importTab" text="Import Data">
<fx:include source="import-view.fxml"/>
</Tab>
<!-- Students Tab -->
<Tab fx:id="studentsTab" text="Students">
<fx:include source="students-view.fxml"/>
</Tab>
<!-- Courses Tab -->
<Tab fx:id="coursesTab" text="Courses">
<fx:include source="courses-view.fxml"/>
</Tab>
<!-- Classrooms Tab -->
<Tab fx:id="classroomsTab" text="Classrooms">
<fx:include source="classrooms-view.fxml"/>
</Tab>
<!-- Schedule Views Tab -->
<Tab fx:id="scheduleTab" text="Schedule Views">
<fx:include source="schedule-views.fxml"/>
</Tab>
</TabPane>
</center>
<!-- Bottom: Status Bar -->
<bottom>
<HBox styleClass="status-bar" spacing="10">
<padding>
<Insets top="5" right="10" bottom="5" left="10"/>
</padding>
<Label fx:id="statusLabel" text="Ready - No data loaded"/>
</HBox>
</bottom>
</BorderPane>

View File

@@ -0,0 +1,67 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<BorderPane xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
fx:controller="org.example.se302.controller.ScheduleCalendarController"
styleClass="content-pane">
<top>
<VBox spacing="10">
<padding>
<Insets top="20" right="20" bottom="10" left="20"/>
</padding>
<Label text="Calendar View - Exam Schedule" styleClass="section-title"/>
<HBox spacing="10" alignment="CENTER_LEFT">
<Label text="Exam Period:"/>
<DatePicker fx:id="startDatePicker" promptText="Start Date"/>
<Label text="to"/>
<DatePicker fx:id="endDatePicker" promptText="End Date"/>
<Button text="Generate Schedule" onAction="#onGenerateSchedule" styleClass="primary-button"/>
</HBox>
</VBox>
</top>
<center>
<VBox spacing="10" alignment="CENTER">
<padding>
<Insets top="50" right="20" bottom="50" left="20"/>
</padding>
<Label text="📅" style="-fx-font-size: 48px;"/>
<Label text="Schedule Generation Coming Soon" styleClass="info-title"/>
<Label text="The calendar grid will display exam schedules across days and time slots."
wrapText="true" textAlignment="CENTER" maxWidth="500"/>
<Separator prefWidth="300"/>
<Label text="Preview: Grid Layout" styleClass="subsection-title"/>
<GridPane gridLinesVisible="true" styleClass="schedule-grid">
<padding>
<Insets top="10" right="10" bottom="10" left="10"/>
</padding>
<!-- Header row -->
<Label text="" GridPane.columnIndex="0" GridPane.rowIndex="0" styleClass="grid-header"/>
<Label text="Day 1" GridPane.columnIndex="1" GridPane.rowIndex="0" styleClass="grid-header"/>
<Label text="Day 2" GridPane.columnIndex="2" GridPane.rowIndex="0" styleClass="grid-header"/>
<Label text="Day 3" GridPane.columnIndex="3" GridPane.rowIndex="0" styleClass="grid-header"/>
<!-- Time slots -->
<Label text="09:00" GridPane.columnIndex="0" GridPane.rowIndex="1" styleClass="grid-header"/>
<Label text="-" GridPane.columnIndex="1" GridPane.rowIndex="1" styleClass="grid-cell"/>
<Label text="-" GridPane.columnIndex="2" GridPane.rowIndex="1" styleClass="grid-cell"/>
<Label text="-" GridPane.columnIndex="3" GridPane.rowIndex="1" styleClass="grid-cell"/>
<Label text="11:00" GridPane.columnIndex="0" GridPane.rowIndex="2" styleClass="grid-header"/>
<Label text="-" GridPane.columnIndex="1" GridPane.rowIndex="2" styleClass="grid-cell"/>
<Label text="-" GridPane.columnIndex="2" GridPane.rowIndex="2" styleClass="grid-cell"/>
<Label text="-" GridPane.columnIndex="3" GridPane.rowIndex="2" styleClass="grid-cell"/>
<Label text="14:00" GridPane.columnIndex="0" GridPane.rowIndex="3" styleClass="grid-header"/>
<Label text="-" GridPane.columnIndex="1" GridPane.rowIndex="3" styleClass="grid-cell"/>
<Label text="-" GridPane.columnIndex="2" GridPane.rowIndex="3" styleClass="grid-cell"/>
<Label text="-" GridPane.columnIndex="3" GridPane.rowIndex="3" styleClass="grid-cell"/>
</GridPane>
</VBox>
</center>
</BorderPane>

View File

@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<BorderPane xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
fx:controller="org.example.se302.controller.ScheduleClassroomController"
styleClass="content-pane">
<top>
<VBox spacing="10">
<padding>
<Insets top="20" right="20" bottom="10" left="20"/>
</padding>
<Label text="Classroom Schedule View" styleClass="section-title"/>
<HBox spacing="10" alignment="CENTER_LEFT">
<Label text="Select Classroom:"/>
<ComboBox fx:id="classroomComboBox" promptText="Choose a classroom..." prefWidth="200"/>
<Button text="Show Schedule" onAction="#onShowSchedule" styleClass="primary-button"/>
</HBox>
</VBox>
</top>
<center>
<VBox spacing="10">
<padding>
<Insets top="10" right="20" bottom="20" left="20"/>
</padding>
<Label fx:id="selectedClassroomLabel" text="No classroom selected" styleClass="subsection-title"/>
<TableView fx:id="scheduleTable" VBox.vgrow="ALWAYS">
<columns>
<TableColumn fx:id="dateColumn" text="Date" prefWidth="150"/>
<TableColumn fx:id="timeColumn" text="Time" prefWidth="150"/>
<TableColumn fx:id="courseColumn" text="Course" prefWidth="150"/>
<TableColumn fx:id="studentsColumn" text="Students" prefWidth="100"/>
<TableColumn fx:id="utilizationColumn" text="Utilization" prefWidth="100"/>
</columns>
<placeholder>
<Label text="Select a classroom to view its exam schedule"/>
</placeholder>
</TableView>
<Label fx:id="utilizationLabel" text="Overall Utilization: 0%"/>
</VBox>
</center>
</BorderPane>

View File

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<BorderPane xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
fx:controller="org.example.se302.controller.ScheduleCourseController"
styleClass="content-pane">
<center>
<VBox spacing="10">
<padding>
<Insets top="20" right="20" bottom="20" left="20"/>
</padding>
<Label text="Course Schedule View" styleClass="section-title"/>
<Label text="All courses and their exam assignments" wrapText="true"/>
<Separator/>
<TableView fx:id="courseScheduleTable" VBox.vgrow="ALWAYS">
<columns>
<TableColumn fx:id="courseCodeColumn" text="Course Code" prefWidth="150"/>
<TableColumn fx:id="enrolledColumn" text="Enrolled Students" prefWidth="120"/>
<TableColumn fx:id="dateColumn" text="Exam Date" prefWidth="150"/>
<TableColumn fx:id="timeColumn" text="Exam Time" prefWidth="150"/>
<TableColumn fx:id="classroomColumn" text="Classroom" prefWidth="150"/>
</columns>
</TableView>
</VBox>
</center>
</BorderPane>

View File

@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<BorderPane xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
fx:controller="org.example.se302.controller.ScheduleStudentController"
styleClass="content-pane">
<top>
<VBox spacing="10">
<padding>
<Insets top="20" right="20" bottom="10" left="20"/>
</padding>
<Label text="Student Schedule View" styleClass="section-title"/>
<HBox spacing="10" alignment="CENTER_LEFT">
<Label text="Select Student:"/>
<ComboBox fx:id="studentComboBox" promptText="Choose a student..." prefWidth="200"/>
<Button text="Show Schedule" onAction="#onShowSchedule" styleClass="primary-button"/>
</HBox>
</VBox>
</top>
<center>
<VBox spacing="10">
<padding>
<Insets top="10" right="20" bottom="20" left="20"/>
</padding>
<Label fx:id="selectedStudentLabel" text="No student selected" styleClass="subsection-title"/>
<TableView fx:id="scheduleTable" VBox.vgrow="ALWAYS">
<columns>
<TableColumn fx:id="courseColumn" text="Course" prefWidth="150"/>
<TableColumn fx:id="dateColumn" text="Date" prefWidth="150"/>
<TableColumn fx:id="timeColumn" text="Time" prefWidth="150"/>
<TableColumn fx:id="classroomColumn" text="Classroom" prefWidth="150"/>
</columns>
<placeholder>
<Label text="Select a student to view their exam schedule"/>
</placeholder>
</TableView>
</VBox>
</center>
</BorderPane>

View File

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<VBox xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
styleClass="content-pane">
<TabPane tabClosingPolicy="UNAVAILABLE" VBox.vgrow="ALWAYS">
<!-- Calendar/Day View -->
<Tab text="Calendar View">
<fx:include source="schedule-calendar-view.fxml"/>
</Tab>
<!-- Student Schedule View -->
<Tab text="Student Schedule">
<fx:include source="schedule-student-view.fxml"/>
</Tab>
<!-- Course Schedule View -->
<Tab text="Course Schedule">
<fx:include source="schedule-course-view.fxml"/>
</Tab>
<!-- Classroom Schedule View -->
<Tab text="Classroom Schedule">
<fx:include source="schedule-classroom-view.fxml"/>
</Tab>
</TabPane>
</VBox>

View File

@@ -0,0 +1,61 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<BorderPane xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
fx:controller="org.example.se302.controller.StudentsController"
styleClass="content-pane">
<!-- Top: Search Bar -->
<top>
<VBox spacing="10">
<padding>
<Insets top="20" right="20" bottom="10" left="20"/>
</padding>
<Label text="Student Management" styleClass="section-title"/>
<HBox spacing="10" alignment="CENTER_LEFT">
<TextField fx:id="searchField" promptText="Search by Student ID..." HBox.hgrow="ALWAYS"/>
<Button text="Clear" onAction="#onClearSearch"/>
</HBox>
<Label fx:id="resultCountLabel" text="Total: 0 students"/>
</VBox>
</top>
<!-- Center: Student Table -->
<center>
<VBox spacing="5">
<padding>
<Insets top="0" right="20" bottom="20" left="20"/>
</padding>
<TableView fx:id="studentsTable" VBox.vgrow="ALWAYS">
<columns>
<TableColumn fx:id="studentIdColumn" text="Student ID" prefWidth="200"/>
<TableColumn fx:id="courseCountColumn" text="Enrolled Courses" prefWidth="150"/>
<TableColumn fx:id="actionColumn" text="Actions" prefWidth="150"/>
</columns>
</TableView>
</VBox>
</center>
<!-- Right: Detail Panel (initially hidden) -->
<right>
<VBox fx:id="detailPanel" spacing="10" styleClass="detail-panel" visible="false" managed="false"
prefWidth="300" minWidth="250">
<padding>
<Insets top="20" right="20" bottom="20" left="20"/>
</padding>
<HBox alignment="CENTER_RIGHT">
<Button text="Close" onAction="#onCloseDetail" styleClass="small-button"/>
</HBox>
<Label text="Student Details" styleClass="subsection-title"/>
<Separator/>
<Label fx:id="detailStudentIdLabel" text="Student ID: -" wrapText="true"/>
<Label text="Enrolled Courses:" styleClass="subsection-title"/>
<ListView fx:id="coursesList" VBox.vgrow="ALWAYS"/>
<Label fx:id="detailCourseCountLabel" text="Total: 0 courses"/>
</VBox>
</right>
</BorderPane>