0% found this document useful (0 votes)
2 views25 pages

StudentManagementSystem Assignment

The document outlines the design and functionality of a Student Management System (SMS) developed using Java's Swing GUI framework for managing student records, course enrollments, and grades. The application features an event-driven architecture, a user-friendly interface with tabbed navigation, and is contained within a single source file, making it easy to compile and run. It includes sample data for immediate use and provides functionalities for adding, updating, and viewing student information, all while maintaining data integrity through controlled dialog forms.

Uploaded by

j.beseka
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views25 pages

StudentManagementSystem Assignment

The document outlines the design and functionality of a Student Management System (SMS) developed using Java's Swing GUI framework for managing student records, course enrollments, and grades. The application features an event-driven architecture, a user-friendly interface with tabbed navigation, and is contained within a single source file, making it easy to compile and run. It includes sample data for immediate use and provides functionalities for adding, updating, and viewing student information, all while maintaining data integrity through controlled dialog forms.

Uploaded by

j.beseka
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd

Student Management System

A Java Swing GUI Application

University of the People

CS 1102 – Programming 1: Introduction to Programming Using Java

Instructor Khushboo Sharma

March 19, 2026


Introduction

This report documents the design, implementation, and functionality of a Student Management

System (SMS) developed using Java's Swing GUI framework. The application is intended for

use by administrators who need to manage student records, enrol students in courses, and assign

and track grades through a single, unified graphical interface.

According to Eck (2022), GUI programs differ fundamentally from traditional sequential

programs in that they are event-driven: user actions such as clicking a button or selecting an item

from a dropdown menu generate events, and the program must respond to these events as they

occur (p. 271). This event-driven paradigm is the architectural foundation of the Student

Management System. All user interactions — adding a student, enrolling in a course, assigning a

grade — are handled through registered event listeners that execute the appropriate logic in

response to user-generated events.

The application is built entirely using Java Swing, which is the standard Java library for desktop

GUI development. Swing provides a rich set of pre-built components such as JButton, JLabel,

JTextField, JTable, JComboBox, and JMenuBar, all of which are used in this project. As Eck

(2022) explains, each GUI component in a Java interface is represented by an object in the

program, and these objects communicate with the rest of the application through the event-

handling mechanism (p. 273). The Student Management System leverages all of these features to

create an interface that is both functionally complete and easy to navigate.

The entire application is contained in a single source file named

[Link]. This design keeps the project self-contained and


straightforward to compile and run without any build tools or external dependencies. The file

contains three static inner classes that act as data models, the main JFrame subclass that

constructs the GUI, all event handler implementations, and a set of refresh utility methods that

keep all views synchronised after every data change.

The system is pre-loaded with sample data — three students, four courses, and four enrollment

records — so that administrators can explore all features immediately upon launch without

needing to enter data from scratch.

How to Run the Program

Java Development Kit (JDK) version 8 or higher must be installed on the host machine. The

application depends only on the standard Java SE libraries, specifically [Link] and

[Link], so no additional frameworks, build tools, or external JAR files are required.

Save the file [Link] to any directory on the local machine. Open a

terminal or command prompt, navigate to that directory, and run the following command to

compile:

javac [Link]

If the compilation succeeds, a set of .class files will be created in the same directory. These

include the compiled inner classes for Student, Course, and Enrollment, as well as the main

application class. After successful compilation, launch the application with the following

command:

java StudentManagementSystem
The main application window will appear, sized at 900 by 620 pixels and centred on the screen.

The system is pre-loaded with three sample students (Alice Johnson, Bob Martinez, and Carol

Williams), four courses (Introduction to Programming, Calculus II, General Physics, and Data

Structures), and four initial enrollment records. All features described in this document are

immediately accessible from the tabbed interface or from the menu bar.

The interface is divided into three tabs. The Student Management tab is the default view on

launch. Administrators can navigate to the Course Enrollment and Grade Management tabs by

clicking on them. All major actions are also available through the menu bar at the top of the

window, providing keyboard-accessible shortcuts for users who prefer menu navigation over

button clicks. All data entered during a session is held in memory and will be cleared when the

application is closed, as no persistent storage mechanism is implemented in this version.

GUI Design and Layout

The GUI design of the Student Management System follows the principles of event-driven

programming outlined in Chapter 6 of Eck (2022). The application window is a JFrame, which is

the top-level container for any Java Swing desktop application. As Eck (2022) explains, a

JFrame represents the main window of a program, and its content is divided into a content pane

that holds all visible components (p. 273). In this project, the JFrame is configured with a

BorderLayout, which divides the window into five regions: North, South, East, West, and

Centre. The menu bar occupies the North, the tabbed panel occupies the Centre, and a status bar

occupies the South.

The main application class extends JFrame and sets the window title, default close operation,

size, and initial position in its constructor. The use of setLocationRelativeTo(null) centres the
window on the screen regardless of screen resolution. The system look and feel is applied at

startup so the application adopts the visual style of the operating system on which it runs,

whether Windows, macOS, or Linux.

public StudentManagementSystem() {
super("Student Management System");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(900, 620);
setLocationRelativeTo(null);

seedData();
buildMenuBar();

JTabbedPane tabs = new JTabbedPane();


[Link]("Student Management", buildStudentPanel());
[Link]("Course Enrollment", buildEnrollmentPanel());
[Link]("Grade Management", buildGradePanel());

add(tabs, [Link]);

JLabel statusBar =
new JLabel(" Student Management System — Ready");
[Link]([Link]());
add(statusBar, [Link]);
setVisible(true);
}

The JTabbedPane component organises the three functional areas of the system into named tabs

that users can switch between by clicking. This is an effective organisational technique that

reduces clutter and allows each functional section to occupy the full available space when

selected. The tabs are labelled Student Management, Course Enrollment, and Grade

Management, corresponding directly to the three major requirements of the assignment.

A JMenuBar is attached to the JFrame and provides menu-based access to all major operations.

Eck (2022) describes the structure of a Swing menu system: menu items are added to menus,

menus are added to a menu bar, and ActionListeners are registered with each menu item to

handle the corresponding action (p. 333). The menu bar in this application contains five menus:
File, Students, Enrollment, Grades, and Help. The Students menu provides three items: Add

Student, Update Student, and View All Students. The Enrollment menu provides an Enroll

Student item that switches focus to Tab 2. The Grades menu provides an Assign Grade item that

switches to Tab 3. The File menu contains an Exit item. The Help menu displays an About

dialog.

JMenu studentsMenu = new JMenu("Students");


JMenuItem addStudentItem = new JMenuItem("Add Student");
JMenuItem updateStudentItem = new JMenuItem("Update Student");
JMenuItem viewStudentsItem = new JMenuItem("View All Students");

[Link](e -> showAddStudentDialog());


[Link](e -> showUpdateStudentDialog());

[Link](addStudentItem);
[Link](updateStudentItem);
[Link]();
[Link](viewStudentsItem);

The Student Management tab displays a scrollable JTable that lists all student records in four

columns: Student ID, Name, Email, and Major. The table is backed by a DefaultTableModel,

which allows data to be updated programmatically by calling setRowCount(0) to clear it and then

repopulating it row by row. The cells are set to non-editable so that data can only be modified

through the controlled dialog forms, protecting data integrity. Four JButton components are

arranged in a FlowLayout panel below the table: Add Student, Update Student, Delete Student,

and View Details. As Eck (2022) notes, a JButton object draws itself and processes mouse,

keyboard, and focus events on its own, and the programmer only needs to handle the

ActionEvent that is generated when the button is triggered (p. 310). Each button registers an

ActionListener using a lambda expression, keeping the code concise.

String[] cols = {"Student ID", "Name", "Email", "Major"};


studentTableModel = new DefaultTableModel(cols, 0) {
@Override
public boolean isCellEditable(int r, int c) { return false; }
};
JTable table = new JTable(studentTableModel);
[Link](ListSelectionModel.SINGLE_SELECTION);
[Link]().setReorderingAllowed(false);
[Link](new JScrollPane(table), [Link]);

The Course Enrollment tab is structured with a BorderLayout. A titled panel in the North region

contains the enrollment form, consisting of two JComboBox dropdowns (one for students and

one for courses) and an Enroll Student button. A second titled panel occupies the Centre region

and contains the enrollment table with a Remove button below it. The use of titled borders

created with [Link]() visually groups related components and makes

the tab self-explanatory. As Eck (2022) describes, borders in Swing are represented by objects

that can be added to any JComponent using the setBorder() method, and the BorderFactory class

provides static methods for creating a variety of border styles (p. 321).

The Grade Management tab follows the same structural pattern as the enrollment tab: a form

panel in the North with dropdowns and an input field, and an overview table in the Centre. The

distinguishing feature of this tab is that the course dropdown is not statically populated. Instead,

it is repopulated dynamically every time the administrator selects a different student, showing

only the courses in which that student is currently enrolled. This dynamic filtering prevents the

assignment of grades to courses that a student has not joined, and it is achieved through an

ActionListener registered with the student dropdown.

A JLabel at the bottom of the main window serves as a persistent status indicator. It displays the

text Student Management System — Ready after the application loads. The label has an etched

border applied via [Link]() to visually distinguish it from the main

content area.
Data Models

The application uses three static inner classes to represent the core data entities: Student, Course,

and Enrollment. All records are stored in ArrayList collections maintained by the main JFrame

class. There is no file I/O or database connection in this version; all data exists only in memory

for the duration of a session.

The Student class stores four fields: a unique string identifier (id), the student's full name (name),

email address (email), and academic major (major). The toString() method is overridden to

return a formatted string in the form id - name, which is the text that Swing displays when a

Student object is placed inside a JComboBox dropdown. The Course class stores a course code

and a descriptive title. Its toString() method returns code: title for clean display in dropdown

components. The Enrollment class links a student to a course by storing the studentId and

courseCode as string references. The grade field defaults to the string N/A when the enrollment

is first created, indicating that no grade has yet been assigned.

static class Student {


String id, name, email, major;
Student(String id, String name,
String email, String major) {
[Link] = id; [Link] = name;
[Link] = email; [Link] = major;
}
public String toString() { return id + " - " + name; }
}

static class Course {


String code, title;
Course(String code, String title) {
[Link] = code; [Link] = title;
}
public String toString() { return code + ": " + title; }
}

static class Enrollment {


String studentId, courseCode, grade;
Enrollment(String studentId, String courseCode) {
[Link] = studentId;
[Link] = courseCode;
[Link] = "N/A";
}
}

The three ArrayList collections — students, courses, and enrollments — are instance variables of

the main application class. All GUI components that display data read from these lists, and all

operations that modify data write to these lists. This single-source-of-truth design is what makes

the dynamic refresh mechanism reliable: because all views read from the same collections,

refreshing them after any modification guarantees consistency across the entire interface.

The application is seeded with initial data in the seedData() method, which is called in the

constructor before the GUI is built. This ensures the tables and dropdowns are populated the first

time they are rendered.

private void seedData() {


[Link](new Student("S001", "Alice Johnson",
"alice@[Link]", "Computer Science"));
[Link](new Student("S002", "Bob Martinez",
"bob@[Link]", "Mathematics"));
[Link](new Student("S003", "Carol Williams",
"carol@[Link]", "Physics"));

[Link](new Course("CS101",
"Introduction to Programming"));
[Link](new Course("MA201", "Calculus II"));
[Link](new Course("PH101", "General Physics"));
[Link](new Course("CS202", "Data Structures"));

[Link](new Enrollment("S001", "CS101"));


[Link](new Enrollment("S001", "MA201"));
[Link](new Enrollment("S002", "MA201"));
[Link](new Enrollment("S003", "PH101"));
}

Student Management Functionality

Student management is the central feature of the application and covers adding new students,

updating existing student information, deleting students, and viewing individual student details.
All four operations are accessible from the buttons on the Student Management tab and from the

Students menu in the menu bar.

When the administrator clicks the Add Student button or the corresponding menu item, the

showAddStudentDialog() method is called. This method creates a modal JDialog with a

GridLayout form containing four labelled JTextField components for the Student ID, Full Name,

Email, and Major fields. A Save button and a Cancel button are arranged in a FlowLayout panel

at the bottom of the dialog.

Eck (2022) explains that the structure of containers and components sets up the physical

appearance of a GUI, while event listeners define its behaviour (p. 276). This is precisely the

design pattern followed here: the dialog's layout establishes the visual form, while the

ActionListener on the Save button provides the behavioural logic. The listener performs the

following validation steps in order before any data is written: it checks that no field is blank; it

checks that no existing student already has the entered ID; and it verifies that the email address

contains the @ symbol. If any check fails, the showError() helper is called, which presents a

JOptionPane error dialog to the administrator and leaves the form open so that no already-

entered data is lost.

[Link](e -> {
String id = [Link]().trim();
String name = [Link]().trim();
String email = [Link]().trim();
String major = [Link]().trim();

if ([Link]() || [Link]() ||
[Link]() || [Link]()) {
showError("All fields are required.");
return;
}
if (findStudentById(id) != null) {
showError("A student with ID \"" + id
+ "\" already exists.");
return;
}
if (![Link]("@")) {
showError("Please enter a valid email address.");
return;
}
[Link](new Student(id, name, email, major));
refreshAll();
[Link]();
[Link](this,
"Student added successfully.",
"Success", JOptionPane.INFORMATION_MESSAGE);
});

Once all validations pass, the new Student object is added to the students list, refreshAll() is

called to update all views, the dialog is closed, and a success message is displayed. The new

student immediately appears in the table and in the student dropdowns on the enrollment and

grade management tabs.

The Update Student button calls showUpdateStudentDialog(), which first verifies that the

students list is not empty. A [Link]() is then presented, displaying all

current Student objects in a selection list. Once the administrator selects a student, the chosen

Student is passed to showUpdateStudentDialogFor(). The update dialog pre-populates the

JTextField components with the student's existing values. The Student ID is displayed as a non-

editable JLabel rather than a JTextField, preventing accidental changes to the primary key. As

Eck (2022) notes regarding text components, calling setEditable(false) prevents the user from

modifying the text while still allowing the text to be displayed (p. 314). On saving, the Student

object's fields are updated directly in place and refreshAll() propagates the changes to all views.

[Link](e -> {
String name = [Link]().trim();
String email = [Link]().trim();
String major = [Link]().trim();

if ([Link]() || [Link]() || [Link]()) {


showError("All fields are required."); return;
}
if (![Link]("@")) {
showError("Please enter a valid email address.");
return;
}
[Link] = name;
[Link] = email;
[Link] = major;
refreshAll();
[Link]();
[Link](this,
"Student updated successfully.",
"Success", JOptionPane.INFORMATION_MESSAGE);
});

The Delete Student button reads the index of the currently selected row from the student JTable

using getSelectedRow(). If no row is selected, the showError() helper prompts the administrator

to make a selection first. If a row is selected, the Student ID is retrieved and a confirmation

dialog is presented using [Link]() with YES and NO options. This

safety step prevents accidental deletions. On confirmation, the students list and the enrollments

list are both filtered using removeIf() to remove the matching records. This cascade deletion

ensures there are no orphaned enrollment records for a student who no longer exists in the

system.

[Link](e -> {
int row = [Link]();
if (row == -1) {
showError("Please select a student to delete.");
return;
}
String id = (String) [Link](row, 0);
int confirm = [Link](this,
"Delete student " + id
+ "? This will also remove their enrollments.",
"Confirm Delete", JOptionPane.YES_NO_OPTION);
if (confirm == JOptionPane.YES_OPTION) {
[Link](s -> [Link](id));
[Link](en -> [Link](id));
refreshAll();
}
});
The View Details button calls showStudentDetails(), which assembles a multi-line summary

string for the selected student and displays it in a JOptionPane information dialog. The summary

includes the student's ID, name, email address, major, and a list of all enrolled courses with their

current grades. If the student has no enrollments, the text indicates this explicitly.

private void showStudentDetails(Student s) {


StringBuilder sb = new StringBuilder();
for (Enrollment en : enrollments) {
if ([Link]([Link])) {
Course c = findCourseByCode([Link]);
if (c != null)
[Link](" ").append([Link])
.append(": ").append([Link])
.append(" [Grade: ")
.append([Link]).append("]\n");
}
}
if ([Link]() == 0) [Link](" (No enrollments)");
String msg = "ID: " + [Link] + "\n"
+ "Name: " + [Link] + "\n"
+ "Email: " + [Link] + "\n"
+ "Major: " + [Link] + "\n\n"
+ "Enrolled Courses:\n" + sb;
[Link](this, msg,
"Student Details — " + [Link],
JOptionPane.INFORMATION_MESSAGE);
}

Course Enrollment Functionality

The Course Enrollment tab enables administrators to enrol students in courses and to view or

remove existing enrollment records. The enrollment form at the top of the tab contains two

JComboBox dropdown components: enrollStudentCombo, which lists all current students, and

enrollCourseCombo, which lists all available courses. Both are populated by the

refreshEnrollmentCombos() method, which is called as part of refreshAll() after every data-

modifying operation.

JComboBox allows the user to select one item from a list, with the selected item being displayed

in a box. The items in the list are objects whose toString() methods return the appropriate display
labels (Eck, 2022, p. 311). In this application, the JComboBox items are actual Student and

Course objects, and their toString() methods provide the display text, so no additional String

arrays or mapping logic are needed.

When the Enroll Student button is clicked, the handleEnroll() method is invoked. This method

retrieves the selected items from both dropdowns using getSelectedItem(). It then checks

whether either selection is null, which would indicate an empty list. If both selections are valid, it

scans the enrollments list to check whether an enrollment record already exists for that student-

course combination. If a duplicate is found, an error is shown and the method returns without

creating a new record.

private void handleEnroll() {


Student s = (Student) [Link]();
Course c = (Course) [Link]();

if (s == null || c == null) {
showError("Please select both a student and a course.");
return;
}
for (Enrollment en : enrollments) {
if ([Link]([Link]) &&
[Link]([Link])) {
showError([Link] + " is already enrolled in "
+ [Link] + ".");
return;
}
}
[Link](new Enrollment([Link], [Link]));
refreshAll();
[Link](this,
[Link] + " has been successfully enrolled in "
+ [Link] + ".",
"Enrollment Successful",
JOptionPane.INFORMATION_MESSAGE);
}

If no duplicate is found, a new Enrollment object is created and added to the enrollments list.

The refreshAll() method is then called, which immediately updates the enrollment table and the

grades overview table. A success dialog is displayed to confirm the action. The enrollment table
below the form displays all current enrollment records in four columns: Student ID, Student

Name, Course Code, and Course Title. The administrator can select any row and click the

Remove Selected Enrollment button to delete that record. The remove action filters out the

matching record and calls refreshAll() to update all views.

[Link](e -> {
int row = [Link]();
if (row == -1) {
showError("Please select an enrollment to remove.");
return;
}
String sid = (String)
[Link](row, 0);
String code = (String)
[Link](row, 2);
[Link](en ->
[Link](sid) &&
[Link](code));
refreshAll();
});

Grade Management Functionality

The Grade Management tab provides the interface for assigning grades to students for their

enrolled courses. It combines two JComboBox dropdowns, a JTextField for the grade value, and

an Assign Grade button in the form panel, with a comprehensive grades overview table

occupying the lower half of the tab.

A key feature of this tab is the dynamic relationship between the student dropdown and the

course dropdown. When the administrator selects a student in the gradeStudentCombo

dropdown, an ActionListener fires and immediately calls refreshGradeCourseCombo(). This

method clears the gradeCourseCombo and repopulates it with only the courses in which the

currently selected student is enrolled, by scanning the enrollments list and looking up each

matching course.
[Link](
e -> refreshGradeCourseCombo());

private void refreshGradeCourseCombo() {


[Link]();
Student s = (Student) [Link]();
if (s == null) return;
for (Enrollment en : enrollments) {
if ([Link]([Link])) {
Course c = findCourseByCode([Link]);
if (c != null) [Link](c);
}
}
}

This dynamic filtering is a direct application of the event listener pattern described by Eck

(2022), who explains that a listener is an object that includes one or more event-handling

methods, and when an event is detected, the listener is notified and its event-handling method is

executed (p. 276). Here, the ActionEvent generated by a change in the student dropdown

selection triggers the course dropdown refresh, creating a cascading update that keeps the form

internally consistent.

When the administrator clicks Assign Grade, the handleAssignGrade() method executes. It

retrieves the selected student and course from the dropdowns, reads the grade string from the

gradeField JTextField, and performs three validation checks: both dropdowns must have a

selection, the grade field must not be blank, and the grade string must be no longer than three

characters. It then searches the enrollments list for the record matching the selected student and

course. If a match is found, the grade field of the Enrollment object is updated and refreshAll() is

called.

private void handleAssignGrade() {


Student s = (Student) [Link]();
Course c = (Course) [Link]();
String grade = [Link]().trim();

if (s == null || c == null) {
showError("Please select a student and a course.");
return;
}
if ([Link]()) {
showError("Please enter a grade."); return;
}
if ([Link]() > 3) {
showError("Grade should be a value such as A, B+, or C-.");
return;
}
Enrollment target = null;
for (Enrollment en : enrollments) {
if ([Link]([Link]) &&
[Link]([Link])) {
target = en; break;
}
}
if (target == null) {
showError([Link] + " is not enrolled in "
+ [Link] + "."); return;
}
[Link] = [Link]();
refreshAll();
[Link]("");
[Link](this,
"Grade \"" + [Link]() + "\" assigned to "
+ [Link] + " for " + [Link] + ".",
"Grade Assigned",
JOptionPane.INFORMATION_MESSAGE);
}

The grades overview table at the bottom of the tab displays five columns: Student ID, Student

Name, Course Code, Course Title, and Grade. Every enrollment record in the system is shown

here, with the grade displayed as N/A until it is formally assigned. This gives administrators a

complete view of the grade status for all students across all enrolled courses at a glance.

Dynamic Interface Updates

One of the core requirements of the Student Management System is that the interface updates

dynamically and in real time to reflect all changes in the underlying data. This is achieved

through a centralised refreshAll() method that is called at the conclusion of every operation that

modifies the students, courses, or enrollments lists.


The refreshAll() method calls six individual refresh functions in sequence. Each function is

responsible for clearing and repopulating one specific view or control. Because all views read

from the same shared data collections, clearing and repopulating them guarantees that each view

reflects the latest state of the data at the time of the refresh.

private void refreshAll() {


refreshStudentTable();
refreshEnrollmentCombos();
refreshEnrollmentTable();
refreshGradeCombos();
refreshGradeCourseCombo();
refreshGradeTable();
}

The refreshStudentTable() method calls [Link](0) to remove all

existing rows, then iterates over the students list and adds each student as a new row using

addRow(). This pattern of clear-and-repopulate is the standard approach for programmatically

updating a JTable backed by a DefaultTableModel.

private void refreshStudentTable() {


[Link](0);
for (Student s : students)
[Link](
new Object[]{[Link], [Link], [Link], [Link]});
}

The refreshEnrollmentCombos() method calls removeAllItems() on both JComboBox

dropdowns on the enrollment tab, then repopulates them from the students and courses lists. The

refreshGradeCombos() method does the same for the student dropdown on the grade

management tab, and then calls refreshGradeCourseCombo() to synchronise the course

dropdown with the currently selected student.

private void refreshEnrollmentCombos() {


if (enrollStudentCombo == null ||
enrollCourseCombo == null) return;
[Link]();
for (Student s : students)
[Link](s);
[Link]();
for (Course c : courses)
[Link](c);
}

The refreshEnrollmentTable() and refreshGradeTable() methods use the same clear-and-

repopulate pattern. The grade table iterates over all enrollment records and includes the grade

field in each row.

private void refreshGradeTable() {


[Link](0);
for (Enrollment en : enrollments) {
Student s = findStudentById([Link]);
Course c = findCourseByCode([Link]);
if (s != null && c != null)
[Link](new Object[]{
[Link], [Link], [Link], [Link], [Link]});
}
}

Because refreshAll() is called after every add, update, delete, enroll, remove, and grade

assignment operation, the administrator never sees stale data in any part of the interface. For

example, when a student is added, their name immediately appears in the student dropdowns on

the enrollment and grade management tabs. When a grade is assigned, the updated grade appears

instantly in the grades table without requiring any user action. This approach mirrors the event-

driven update philosophy described by Eck (2022), who explains that the system redraws

components as soon as it gets a chance to do so after processing pending events (p. 279).

Error Handling

Robust error handling is essential in any interactive application. The Student Management

System implements a consistent error handling strategy throughout, using a centralised helper

method to ensure that all error messages are displayed in a uniform and user-friendly manner. All

error messages are routed through the showError() method, which wraps a
[Link]() call with the ERROR_MESSAGE message type. This

causes Swing to display the message in a dialog box with an error icon, which is immediately

recognisable to users as an error condition. As Eck (2022) notes, JOptionPane provides a static

method showMessageDialog() that creates a dialog box with a message, title, and an icon that

depends on the message type parameter (p. 272).

private void showError(String message) {


[Link](this, message,
"Error", JOptionPane.ERROR_MESSAGE);
}

In both the Add Student and Update Student dialogs, the Save button's ActionListener checks

every required JTextField for an empty string after calling trim(). If any field is blank,

showError() is called and the dialog remains open so that any data the administrator has already

entered is preserved. This follows Eck's (2022) recommendation that requestFocusInWindow()

can be used to return focus to the field containing the error, helping the user see where the error

occurred and begin correcting it immediately (p. 314).

Before adding a new student, the findStudentById() utility method checks whether an existing

student already has the same ID. If a duplicate is found, the administrator is shown an error

message that includes the conflicting ID. The email field is also validated to contain the @

symbol, catching the most common input mistakes.

The Update Student, Delete Student, View Details, and Remove Selected Enrollment buttons

each begin by calling getSelectedRow() on the relevant JTable. If the return value is -1,

indicating that no row is selected, showError() is called to prompt the administrator to make a

selection before proceeding. This prevents NullPointerExceptions that would occur if the code

attempted to retrieve data from a non-existent selection.


The handleEnroll() method scans the enrollments list before creating a new record. If an

enrollment already exists for the selected student-course combination, an error is shown that

names both the student and the course code. The handleAssignGrade() method similarly searches

for a matching enrollment record before writing the grade. If no match is found, an error is

shown. Grade values longer than three characters are rejected with an explanatory message that

gives examples of acceptable values such as A, B+, or C-.

The [Link]() call in the main() method is wrapped in a try-catch block.

Any exception thrown during this process is silently caught and ignored, and the application

continues to launch with the default Swing look and feel. This ensures the application is robust

across different operating systems.

public static void main(String[] args) {


try {
[Link](
[Link]());
} catch (Exception ignored) {}
[Link](
StudentManagementSystem::new);
}
Output Screenshot:
Screenshot 1: Main Application Window — Student Management Tab

Screenshot 2: Add Student Dialog

Screenshot 3: Update Student Dialog

Screenshot 4: View Student Details Dialog


Screenshot 5: Delete Student Confirmation Dialog

Screenshot 6: Course Enrollment Tab with Enrollment Table

Screenshot 7: Enrollment Success Confirmation Dialog

Screenshot 8: Duplicate Enrollment Error Dialog

Screenshot 9: Grade Management Tab


Screenshot 10: Dynamic Course Dropdown Filtering

Screenshot 11: Grade Assignment Confirmation Dialog

Screenshot 12: Empty Fields Error Dialog


References

 Eck, D. J. (2022). Introduction to programming using Java (9th ed.). Hobart and William

Smith Colleges. [Link]

 Oracle Corporation. (2023). Class JButton. Java SE 17 & JDK 17.

[Link]

 Oracle Corporation. (2023). Class JTable. Java SE 17 & JDK 17.

[Link]

 Oracle Corporation. (2023). Class JComboBox. Java SE 17 & JDK 17.

[Link]

 Oracle Corporation. (2023). How to use tables. The Java Tutorials.

[Link]

 Oracle Corporation. (2023). How to use combo boxes. The Java Tutorials.

[Link]

You might also like