0% found this document useful (0 votes)
603 views23 pages

JavaFX Student Management System

This document contains the code for an application that manages student records stored in a CSV file using JavaFX. It defines a Student class to represent each record and uses properties to bind the data to UI elements like a table. The app loads initial data, allows adding/editing records, and saving changes back to the file. It includes methods to open forms for viewing/editing details and handling data loading/saving in the background.

Uploaded by

Chrisna Badar
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)
603 views23 pages

JavaFX Student Management System

This document contains the code for an application that manages student records stored in a CSV file using JavaFX. It defines a Student class to represent each record and uses properties to bind the data to UI elements like a table. The app loads initial data, allows adding/editing records, and saving changes back to the file. It includes methods to open forms for viewing/editing details and handling data loading/saving in the background.

Uploaded by

Chrisna Badar
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

App.

java

1 import [Link];

2 import [Link];

3 import [Link];

4 import [Link];

5 import [Link];

6 import [Link];

8 import [Link];

9 import [Link];

10 import [Link];

11 import [Link];

12 import [Link];

13 import [Link];

14 import [Link];

15 import [Link];

16 import [Link];

17 import [Link];

18 import [Link];

19 import [Link].*;

20 import [Link].*;

21 import [Link];

22 import [Link];

23

24 public class App extends Application {

25

26 private ObservableList<Student> studentList = [Link]();

27 private TableView<Student> tableView = new TableView<>();

28 private ComboBox<String> courseComboBox = new ComboBox<>();

29
30 // File path for the CSV file

31 private static final String FILE_PATH = "[Link]";

32

33 public static void main(String[] args) {

34 launch(args);

35 }

36

37 @Override

38 public void start(Stage primaryStage) throws IOException {

39 studentList = readDataFromFile();

40 [Link]("Student Management System");

41

42 // Create a table to display student records

43 TableColumn<Student, String> nameColumn = new TableColumn<>("Name");

44 [Link](cellData -> [Link]().nameProperty());

45

46 TableColumn<Student, String> idColumn = new TableColumn<>("ID");

47 [Link](cellData -> [Link]().idProperty());

48

49 TableColumn<Student, String> courseColumn = new TableColumn<>("Course");

50 [Link](cellData -> [Link]().courseProperty());

51

52 [Link]().add(nameColumn);

53 [Link]().add(idColumn);

54 [Link]().add(courseColumn);

55 [Link](studentList);

56

57 // Column for Grades

58 TableColumn<Student, Number> gradeColumn = new TableColumn<>("Grade");

59 [Link](cellData -> [Link]().gradeProperty());


60 [Link]().add(gradeColumn);

61

62 // Adding a button to each row in the table to view details

63 TableColumn<Student, Void> detailsColumn = new TableColumn<>("Details");

64 [Link](param -> new TableCell<Student, Void>() {

65 private final Button detailsButton = new Button("View Details");

66

67 {

68 [Link](event -> {

69 Student student = getTableView().getItems().get(getIndex());

70 showStudentDetails(student);

71 });

72 }

73

74 @Override

75 protected void updateItem(Void item, boolean empty) {

76 [Link](item, empty);

77 if (empty) {

78 setGraphic(null);

79 } else {

80 setGraphic(detailsButton);

81 }

82 }

83 });

84 [Link]().add(detailsColumn);

85

86 // Add Student Button

87 Button addStudentButton = new Button("Add Student");

88 [Link](e -> openAddStudentForm());

89
90 // Save Data Button

91 Button saveButton = new Button("Save Data");

92 [Link](e -> {

93 // Create a popup for the progress indicator

94 Stage progressStage = new Stage();

95 [Link](Modality.APPLICATION_MODAL);

96 [Link]("Saving Data");

97

98 ProgressIndicator progressIndicator = new ProgressIndicator();

99 VBox progressBox = new VBox(10, new Label("Saving..."), progressIndicator);

10 [Link]([Link]);
0
[Link](new Insets(20));
10
1
Scene progressScene = new Scene(progressBox);
10
2 [Link](progressScene);
10 [Link]();
3

10
4 // Run the save operation in a separate thread

10 new Thread(() -> {


5 try {
10 writeDataToFile(studentList);
6
[Link](() -> {
10
7 [Link](); // Close the progress indicator popup

10
8 // Show the confirmation alert
10 Alert alert = new Alert([Link]);
9
[Link]("Save Successful");
11
0 [Link](null);

11 [Link]("Data saved to [Link]");


1
[Link]();
11
2 });

11 } catch (IOException ex) {


3
[Link](() -> {
11
[Link](); // Close the progress indicator popup
4

11
5 // Show error alert
11 Alert errorAlert = new Alert([Link]);
6
[Link]("Error");
11
7 [Link]("Save Failed");

11 [Link]("An error occurred while saving data: " +


8 [Link]());

11 [Link]();
9 });
12 }
0
}).start();
12
1 });

12
2

12
3
// Button Layout
12
4 HBox buttonLayout = new HBox(10);

12 [Link](new Insets(10));
5
[Link]().addAll(addStudentButton, saveButton);
12
6

12
7 // Populate the course ComboBox

12 [Link]().addAll("Math", "Science", "History", "English");


8

12
// Layout for input fields and buttons
9
GridPane inputGrid = new GridPane();
13
0 [Link](new Insets(10, 10, 10, 10));
13 [Link](10);
1
[Link](10);
13
2
// Main layout
13
3 BorderPane borderPane = new BorderPane();
13 [Link](tableView);
4
[Link](buttonLayout);
13
5

13 // Create a layout that combines inputGrid and buttonLayout


6 VBox bottomLayout = new VBox();
13 [Link]().addAll(inputGrid, buttonLayout);
7
[Link](bottomLayout);
13
8

13 [Link](event -> {
9 if (isDataDifferent()) {
14 Alert confirmDialog = new Alert([Link]);
0
[Link]("Unsaved Changes");
14
1 [Link]("Save Changes");

14 [Link]("Would you like to save your last update?");


2

14
Optional<ButtonType> result = [Link]();
3
if ([Link]() && [Link]() == [Link]) {
14
4 try {

14 writeDataToFile(studentList);
5
} catch (IOException ex) {
14
[Link](); // Handle save error
6
}
14
7 }
14 }
8
});
14
9
15
0
Scene scene = new Scene(borderPane, 600, 400);
15
[Link](scene);
1
[Link]();
15
2 }
15
3
private boolean isDataDifferent() {
15
4 try {

15 ObservableList<Student> fileData = readDataFromFile();


5 // Using equals method for comparison
15 return ![Link](fileData);
6
} catch (IOException e) {
15
7 [Link]();

15 return true; // Assume data is different if there's an error reading the file
8 }
15 }
9

16
0

16 private void openAddStudentForm() {


1
Stage addStudentStage = new Stage();
16
[Link]("Add New Student");
2

16
3 TextField nameField = new TextField();

16 [Link]("Name");
4
TextField idField = new TextField();
16
[Link]("ID");
5
ComboBox<String> courseComboBox = new ComboBox<>();
16
6 [Link]().addAll("Math", "Science", "History", "English");
16 [Link]("Course");
7

16
8
16 Button addButton = new Button("Add");
9
[Link](e -> {
17
String name = [Link]();
0
String id = [Link]();
17
1 String course = [Link]();
17 try {
2
Student newStudent = new Student(name, id, course);
17
3 [Link](newStudent);

17 [Link]();
4 [Link]();
17 } catch (NumberFormatException ex) {
5
[Link]("Invalid grade input"); // Replace with error handling logic
17
6 }

17 });
7

17 VBox formLayout = new VBox(10);


8
[Link](new Insets(20));
17
9 [Link]().addAll(

18 new Label("Name:"), nameField,


0
new Label("ID:"), idField,
18
new Label("Course:"), courseComboBox,
1
addButton
18
2 );

18
3
[Link](new Scene(formLayout, 300, 300));
18
[Link]();
4
}
18
5

18 private void showStudentDetails(Student student) {


6
Stage detailsStage = new Stage();
18
7
18 [Link]("Student Details");
8

18
TextField nameField = new TextField([Link]());
9
TextField idField = new TextField([Link]());
19
0

19 // ComboBox for course selection


1
ComboBox<String> courseComboBox = new ComboBox<>();
19
2 [Link]().addAll("Math", "Science", "History", "English"); // Add your
courses here
19
3 [Link]([Link]()); // Set to current course

19
4 TextField gradeField = new TextField([Link]([Link]()));
19
5
Button updateButton = new Button("Update");
19
6 [Link](e -> {

19 // Update the student's information


7 [Link]([Link]());
19 [Link]([Link]());
8
[Link]([Link]());
19
9 try {

20 double grade = [Link]([Link]());


0
[Link](grade);
20
} catch (NumberFormatException ex) {
1
// Handle invalid grade input
20
2 }

20 [Link](); // Refresh the table to show updated data


3
[Link](); // Close the details window
20
});
4

20
5 // Delete Button
20 Button deleteButton = new Button("Delete");
6
20 [Link](e -> {
7
Alert confirmDialog = new Alert([Link]);
20
[Link]("Confirm Deletion");
8
[Link]("Delete Student Record");
20
9 [Link]("Delete " + [Link]() + " from record?");
21
0
// Optional: Customizing the buttons
21
1 ButtonType buttonTypeYes = new ButtonType("Yes", [Link]);

21 ButtonType buttonTypeCancel = new ButtonType("Cancel",


2 [Link].CANCEL_CLOSE);

21 [Link]().setAll(buttonTypeYes, buttonTypeCancel);
3

21 Optional<ButtonType> result = [Link]();


4
if ([Link]() && [Link]() == buttonTypeYes) {
21
5 [Link](student);

21 [Link]();
6 [Link]();
21 }
7
});
21
8

21 // Layout for buttons


9
HBox buttonLayout = new HBox(10);
22
[Link]().addAll(updateButton, deleteButton);
0

22
1 // Layout for the form

22 VBox layout = new VBox(10);


2
[Link](new Insets(20));
22
[Link]().addAll(
3
new Label("Name:"), nameField,
22
4 new Label("ID:"), idField,
22 new Label("Course:"), courseComboBox,
5
22 new Label("Grade:"), gradeField,
6
buttonLayout
22
);
7

22
8 Scene scene = new Scene(layout, 300, 350);
22 [Link](scene);
9
[Link]();
23
0 }

23
1 private void writeDataToFile(ObservableList<Student> studentList) throws IOException {
23 try (FileWriter writer = new FileWriter(FILE_PATH)) {
2
for (Student student : studentList) {
23
3 [Link]([Link]() + "," + [Link]() + "," +

23 [Link]() + "," + [Link]() + "\n");


4 }
23 }
5
}
23
6

23 private ObservableList<Student> readDataFromFile() throws IOException {


7
ObservableList<Student> tempList = [Link]();
23
try (BufferedReader reader = new BufferedReader(new FileReader(FILE_PATH))) {
8
String line;
23
9 while ((line = [Link]()) != null) {

24 String[] data = [Link](",");


0
Student student = new Student(data[0], data[1], data[2]);
24
[Link]([Link](data[3]));
1
[Link](student);
24
2 }
24 } catch (FileNotFoundException e) {
3
// Handle the case where the file does not exist
24
4
24 [Link]("No existing file found. A new file will be created.");
5
}
24
return tempList;
6
}
24
7

24
8

24
9 public static class Student {

25 private final StringProperty name = new SimpleStringProperty();


0 private final StringProperty id = new SimpleStringProperty();
25 private final StringProperty course = new SimpleStringProperty();
1
private final DoubleProperty grade = new SimpleDoubleProperty(0.0);
25
2

25
3 public Student(String name, String id, String course) {
25 setName(name);
4
setId(id);
25
5 setCourse(course);

25 }
6

25
public StringProperty nameProperty() {
7
return name;
25
8 }

25
9
public StringProperty idProperty() {
26
return id;
0
}
26
1

26 public StringProperty courseProperty() {


2
return course;
26
3
26 }
4

26
public String getName() {
5
return [Link]();
26
6 }
26
7
public void setName(String name) {
26
8 [Link](name);

26 }
9

27 public String getId() {


0
return [Link]();
27
1 }

27
2 public void setId(String id) {
27 [Link](id);
3
}
27
4

27 public String getCourse() {


5
return [Link]();
27
}
6

27
7 public void setCourse(String course) {

27 [Link](course);
8
}
27
9
public DoubleProperty gradeProperty() {
28
0 return grade;
28 }
1

28
2
28 public double getGrade() {
3
return [Link]();
28
}
4

28
5 public void setGrade(double grade) {
28 [Link](grade);
6
}
28
7 }

28 }
8

28
9

29
0

29
1

29
2

29
3

29
4

29
5

29
6

29
7

29
8

29
9

30
0

30
1

30
2

30
3

30
4

30
5

30
6

30
7

30
8

30
9

31
0

31
1

31
2

31
3

31
4

31
5

31
6

31
7

31
8

31
9
32
0

32
1

32
2

32
3

32
4

32
5

32
6

32
7

32
8

32
9

33
0

33
1

33
2

33
3

33
4

33
5

33
6

33
7

33
8

33
9

34
0

34
1

34
2

34
3

34
4

34
5

34
6

34
7

34
8

34
9

35
0

35
1

35
2

35
3

35
4

35
5

35
6
35
7

35
8

35
9

36
0

36
1

36
2

36
3

36
4

36
5

36
6

36
7

36
8

36
9

37
0

37
1

37
2

37
3

37
4

37
5

37
6

37
7

37
8

37
9

38
0

38
1

38
2

38
3

38
4

38
5

38
6

38
7

38
8

38
9

39
0

39
1

39
2

39
3
39
4

39
5

39
6

39
7

39
8

Complete code can be reviewed at:


[Link]

Documentation for Student Management System (JavaFX Application)

Overview

This JavaFX application is designed for managing a small group of students, ideal for handling up to
100 students. It provides functionalities to add, update, delete, and save student data, including their
name, ID, course, and grade. The application features a user-friendly interface with a table view for
displaying student records and separate forms for adding and updating student details.

Features

 Add Student: Allows users to add new student records.

 Update Student: Enables users to update existing student records.

 Delete Student: Facilitates the removal of student records.

 Save Data: Offers the functionality to save the current state of student records to a CSV file.

 Automatic Save Prompt: When closing the application, it prompts to save if unsaved changes
are detected.

How to Use

Starting the Application

Run [Link] to launch the application. The main window displays a table with student data.

Adding a New Student

1. Click the "Add Student" button.

2. Fill in the student's details in the new window and click "Add".

Updating a Student

1. Select a student from the table and click the "View Details" button.

2. Update the details in the pop-up window and click "Update".


Deleting a Student

1. Select a student and click the "View Details" button.

2. In the details window, click "Delete" and confirm the deletion.

Saving Data

 Click the "Save Data" button to manually save the current data to [Link].

 On closing the application, if unsaved changes are detected, a prompt will ask whether to
save the changes.

Development Details

Technologies Used

 JavaFX for GUI

 Java I/O for file handling

File Structure

 [Link]: Main application file containing the GUI and logic.

 [Link]: Class representing the student data model.

 [Link]: File where student data is saved.

Known Issues and Limitations

 The application handles a small set of data (up to 100 students) and might not be suitable for
larger datasets. (Somehow there is a performance issues when exceeding 100 students data)

 Basic error handling and data validation are implemented. Further enhancements may be
necessary for broader usage.

Future Enhancements

 Improved error handling and user feedback mechanisms.

 Enhanced data validation for form inputs.

 Additional features like search and sort functionality.


Application Screenshot:

1. Student Table

2. Add Student Data

3. Student data update (course and grade) or delete data.

Common questions

Powered by AI

Data persistence in the application is achieved by writing and reading student data to and from a CSV file. The application saves data using a FileWriter to serialize each student's details into a newline-separated CSV format. The potential points of failure in this process include IOExceptions during file operations, which can occur due to file access issues, incorrect file paths, or system permissions. Additionally, because the CSV format does not inherently support complex data structures, there is a risk of data corruption if the file is edited externally or inconsistencies arise during parsing. The application mitigates some of these risks with error alerts for save failures and the creation of new files if none are found, but further enhancements could improve robustness, such as validating file integrity before read operations .

The `ObservableList` plays a crucial role in the JavaFX application by providing a dynamic data structure that notifies UI components automatically about any changes to the list. This feature ensures that the TableView is automatically updated whenever student records are added, removed, or modified, maintaining synchronization between the model and view without additional manual operations. However, as the application is designed to handle up to 100 students, scaling beyond this may lead to performance issues, primarily due to the increased computational overhead in observing, notifying, and updating UI components in larger datasets. Addressing these concerns might require optimizing the data structure if the student dataset grows, such as implementing virtualized lists .

The application ensures robust file operations by wrapping file reading and writing logic in try-with-resources statements, which automatically close file streams and handle exceptions. For writing data, it uses a FileWriter in conjunction with a BufferedWriter to iterate over student records and save them to a CSV file. During reading, BufferedReader is used to parse each line, constructing student objects which are added to an ObservableList. The application handles FileNotFoundException gracefully by indicating no existing file is found and allowing for the creation of a new file .

The application implements basic error handling mechanisms such as try-catch blocks around file operations to manage IOExceptions, and notifies the user through alerts if errors occur during data saving. Additionally, NumberFormatException is managed when parsing input fields like grades. To expand and improve error handling, the application could implement more detailed logging of errors to assist in debugging and identifying recurring issues. Moreover, incorporating more specific user feedback, such as suggestions for corrective actions when invalid data is entered, would improve user experience. Proactive validation before processing inputs might prevent errors from propagating into the business logic .

The application uses a combination of TableColumn and CellFactory configurations to manage updating student records. When a student is selected and the 'View Details' button is clicked, a separate window appears allowing the user to modify the student's name, ID, course, and grade. Any changes are applied directly to the associated properties of the Student object, utilizing JavaFX's property bindings to automatically update the TableView with the new data. The table is then refreshed to reflect these updates .

Introducing search and sorting functionalities would significantly improve the user experience by making the application more efficient and user-friendly. Currently, users must manually scroll through potentially long lists to find specific records, which can be cumbersome as the number of records approaches the application's threshold of handling 100 students. Implementing search functionality would allow users to quickly locate specific students based on criteria such as name or ID. Sorting would enhance the data organization on the display, enabling users to view records in a sequence that is most useful for their needs, such as alphabetically or by grade. These enhancements could be implemented by integrating sorting and filtering capabilities of JavaFX's TableView, which are well-supported by the JavaFX API .

The `SimpleStringProperty` and `DoubleProperty` are integral to the JavaFX application as they provide a way to encapsulate values and enable property binding, which facilitates automatic updates of the GUI elements. These properties allow bidirectional data binding between the data model (Student class) and the UI components. When a UI component changes, such as a TextField in the 'Add Student' form, the bound property gets automatically updated, ensuring that any changes in the model reflect on the view, and vice versa. This significantly reduces the complexity of keeping the user interface in sync with the underlying data model .

The UI design of the JavaFX application adopts a straightforward layout, making use of JavaFX's TableView to display student records and standard buttons for interactions, like adding or viewing details of students. This makes the application intuitive for simple operations. However, there are several areas for improvement: 1. Adding a search bar and sort options to the TableView can enhance usability by making large datasets easier to navigate. 2. Improving the design aesthetics, such as refining layouts with CSS, could make the application more visually appealing. 3. Incorporating a more responsive layout might improve usability across different screen sizes. Enhancements in error feedback, such as providing more contextually useful error messages, would also improve user interaction .

The application prompts the user with a confirmation dialog when closing, inquiring whether to save changes if any have not been saved. This is accomplished by comparing current student data in memory with the data stored in the file when the user intends to close the application, indicating unsaved changes if discrepancies are detected. This safeguard helps ensure data integrity by preventing inadvertent data loss. However, the consistency of data integrity relies heavily on the user's decision to save changes before exit, leaving room for potential data loss if the user chooses otherwise or if the application crashes unexpectedly before saving .

Future enhancements suggested for the application include improved error handling, data validation, and the implementation of additional features such as sorting and search capabilities. Enhancements in error handling and validation will bolster the application's robustness and user experience by providing more reliable and informative feedback during user interactions. Search functionality would offer users more efficient navigation of the student records, particularly beneficial as the dataset grows. Additionally, sorting capabilities would enhance the usability by allowing the user to organize the data in ways that suit their needs, such as sorting by name, course, or grade. These upgrades would make the application not only more resilient but also more versatile and user-friendly .

App.java
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
    /
60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
90
 91
 92
 93
 94
 95
 96
 97
 98
 99
10
0
10
1
10
2
10
3
10
4
10
5
10
6
10
7
10
8
10
9
11
0
11
1
11
                // Sav
2
11
3
11
4
11
5
11
6
11
7
11
8
11
9
12
0
12
1
12
2
12
3
12
4
12
5
12
6
12
7
12
8
12
9
13
0
                    });
13
1
13
2
13
3
13
4
13
5
13
6
13
7
13
8
13
9
14
0
14
1
14
2
14
3
14
4
14
5
14
6
14
7
14
8
14
9
        inputGrid.setVgap(10);
15
0
15
1
15
2
15
3
15
4
15
5
15
6
15
7
15
8
15
9
16
0
16
1
16
2
16
3
16
4
16
5
16
6
16
7
16
8
        Scene scene = new Scen
16
9
17
0
17
1
17
2
17
3
17
4
17
5
17
6
17
7
17
8
17
9
18
0
18
1
18
2
18
3
18
4
18
5
18
6
18
7
        Button addButton = new
18
8
18
9
19
0
19
1
19
2
19
3
19
4
19
5
19
6
19
7
19
8
19
9
20
0
20
1
20
2
20
3
20
4
20
5
20
6
        detailsStage.setTitle(
20
7
20
8
20
9
21
0
21
1
21
2
21
3
21
4
21
5
21
6
21
7
21
8
21
9
22
0
22
1
22
2
22
3
22
4
22
5
        deleteButton.setOnActi

You might also like