You are being asked to create a system to manage employee records. The system will list a set of employees with details such as ppsnumber, employee name, gender, department, position, salary. This information is displayed in a table like this: see image.

Task

The application has the following menus: File, Employees, Exit. Some of the code is already implemented, but you will need to provide functionality for the following menu options:

1. File -> Print Report. Implement this as an anonymous inner class.

2. File -> Open. Implement this as an anonymous inner class. (hint: look at save functionality that is already done for you)

3. Employee -> "Add" menu item and Add New button should call the same event handler method. This should be implemented using an inner listener class called AddEmployeeListener with an event handler that adds the values in the textfields to the table and creates a new row.

4. Employee -> "Delete" menu item and Delete button should call the same event handler method. This should be implemented using an external listening class called RemoveEmployeeListener

5. When a record is selected in the table the appropriate textboxes and combobox should be correctly updated with the correct values

6. When a record is updated in the "Employee Records Filter" panel and the Update button is clicked the record should be updated in the datamodel and the JTable.

7. Appropriate error handling

Functionality description and details of the task

File menu: contains options Open, Save, Save As, Print Report and Close.

  • Use Open functionality to load the data from employees.dat file into the table (to do). Use the BufferedInputStream, ObjectInputStream and FileInputStreamclasses. When you have selected the file to open display the below JDialog to the user to make sure that they understand that current data will be overridden by the new file. see image.
  • Use Save or Save As button to save the data from the tables to an external file (already implemented).
  • Use Close button to close remove the table that is currently displayed (already implemented).
  • PrintReport (see below)

Implement: the Print Report option, which should take the current data from the table and save it to an external file called EmployeeReport.html. The contents of this file should be a string containing HTML markup something similar to below:

< html>
< body>
< p>Report at: 06-02-2018< /p>
< br />
< table border="1">
< tr>< th>PPS
Number:< /th>< th>Name< /th>< th>Gender< /th>< th>Department< /th>< /tr>
< tr>< td>12732499E< /td>< td>John
Doe< /td>< td>Male< /td>< td>Marketing< /td>< td>CEO< /td>< td>150000.0< /td>< /tr>
< tr>< td>4837563S< /td>< td>Richard
Castle< /td>< td>Male< /td>< td>Sales< /td>< td>Manager< /td>< td>70000.0< /td>< /tr>
< tr>< td>3958337U< /td>< td>Sheldon
Cowne< /td>< td>Male< /td>< td>R&D< /td>< td>Admin< /td>< td>55000.0< /td>< /tr>
< tr>< td>3847562E< /td>< td>Mary
Shelly< /td>< td>Female< /td>< td>Sales< /td>< td>Manager< /td>< td>70000.0< /td>< /t
r>
< tr>< td>7324965T< /td>< td>Jane
Smith< /td>< td>Female< /td>< td>IT< /td>< td>Admin< /td>< td>45000.0< /td>< /tr>
< /table>
< /body>
< /html>

You should supply the code to create this string from the table data and write it to an external file. Use the BufferedWriter and FileWriter classes. Report date should be the actual report date. Try to open the HTML file in the browser to see if there are no mistakes in the HTML code.

Employees menu: contains options Add and Remove.

  • Use Add button should add values from the textboxes to the table and add additional row to the end of the table
  • Use Remove button to remove the selected row/data from the table.

Employee Records Editor

  • When a record is selected all text fields in the "Employee Records Filter" should display the currently selected record.
  • When an update is selected both the table model and the Table should reflect the change.

EmployeeApplication.java

package employeeApp;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Vector;

import javax.swing.BorderFactory;
import javax.swing.DefaultCellEditor;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.border.Border;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.filechooser.FileNameExtensionFilter;

public class EmployeeApplication extends JFrame {
JTable myTable;

// Menu structure
JMenuBar myBar;
JMenu fileMenu, employeeMenu, exitMenu;
JMenuItem fileLoad, fileSave, fileSaveAs, filePrintReport, addEmployee, removeEmployee, exitProgram;

// Array of data types to be used in combo box when defining new structure
String[] dataTypeNames;

JPanel p;
MyTableModel tm;
JScrollPane myPane;

// Subdialog used when defining new structure
//DepositFundsDialog depositDialog;
JLabel lblPPSNo, lblName, lblGender, lblDepartment, lblPosition, lblSalary;
JTextField txtPPSNo, txtName, txtDepartment, txtPosition, txtSalary;
JComboBox cbGender, comboBox;
String[] genderArr = { "Male", "Female" };
JButton btnNew, btnUpdate, btnDelete, btnPrintAll, btnClose;

// Used to indicate whether data is already in a file
File currentFile;


public EmployeeApplication(){
// Create menu bar and table to panel
JMenuBar myBar = createMenuBar();
this.setJMenuBar(myBar);

p = new JPanel();
tm = new MyTableModel();
myTable = new JTable(tm);
myPane = new JScrollPane(myTable, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);

myTable.setSelectionForeground(Color.white);
myTable.setSelectionBackground(Color.red);
myTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);


p.setLayout(new BorderLayout());
myPane.setPreferredSize(new Dimension(450, 110));
p.add(myPane, BorderLayout.NORTH);

JPanel myCenterPanel = createCentrePanel();
Border line = BorderFactory.createLineBorder(Color.black);
myCenterPanel.setBorder(BorderFactory.createTitledBorder(line, "Employee Records Editor"));



p.add(myCenterPanel, BorderLayout.CENTER);

JPanel myBottomPanel = createBottomPanel();
p.add(myBottomPanel, BorderLayout.SOUTH);

// Associating event listeners with menu items
//TODO: on row selection populate all the textfields and combobox with the values from the selected row

//TODO: Add Employee record - both the add button and the add employee menu item should use
//the same event handler/listener to add a record and insert a row


//TODO: Remove Employee record - both the delete button and the remove employee menu item should use
//the same event handler/listener to delete a record


//TODO:Update button



// TODO load the contents of the employee.dat file into the table
fileLoad.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {

}
});


// Saving the file - usually in a different location
fileSaveAs.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JFileChooser fc = new JFileChooser();
int returnVal = fc.showSaveDialog(EmployeeApplication.this);
if (returnVal == JFileChooser.APPROVE_OPTION) {
File file = fc.getSelectedFile();
// Check to see if there is already a file with this name
if (file.exists()) {
int result = JOptionPane.showConfirmDialog(EmployeeApplication.this, "This will overwrite the existing file.n Are you sure you want to do this?");
if (result == 0) {
try {
// We put the implementation of writing into a separate method
writeDataFile(file);
}
catch (IOException ex) {
JOptionPane.showMessageDialog(EmployeeApplication.this, "I/O Exceptionn " + ex.toString(), "Error Message", JOptionPane.ERROR_MESSAGE);
}
}
}
// This is a new file name
else {
try {
writeDataFile(file);
}
catch (IOException ex) {
JOptionPane.showMessageDialog(EmployeeApplication.this, "I/O Exceptionn " + ex.toString(), "Error Message", JOptionPane.ERROR_MESSAGE);
}
}
}
}
});

// Saving the file - usually in the same location
fileSave.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// Data may not yet have been saved to a file
// currentFile not being null means that the file object has been created and we then check that it exists in the file system
if (currentFile != null && currentFile.exists()) {
int result = JOptionPane.showConfirmDialog(EmployeeApplication.this, "This will overwrite the existing file.n Are you sure you want to do this?");
if (result == 0) {
try {
writeDataFile(currentFile);
}
catch (IOException ex) {
JOptionPane.showMessageDialog(EmployeeApplication.this, "I/O Exceptionn " + ex.toString(), "Error Message", JOptionPane.ERROR_MESSAGE);
}
}
}
// Otherwise we need to specify the name to use for this file
else {
JOptionPane.showMessageDialog(EmployeeApplication.this, "File doesn't exist.n", "Error message", JOptionPane.ERROR_MESSAGE);
// Ask user to specify file name (remember user can type in new file name in file chooser)
JFileChooser fc = new JFileChooser();
int returnVal = fc.showSaveDialog(EmployeeApplication.this);
if (returnVal == JFileChooser.APPROVE_OPTION) {
currentFile = fc.getSelectedFile();
if (currentFile.exists()) {
int result = JOptionPane.showConfirmDialog(EmployeeApplication.this, "This will overwrite the existing file.n Are you sure you want to do this?");
if (result == 0) {
try {
writeDataFile(currentFile);
}
catch (IOException ex) {
JOptionPane.showMessageDialog(EmployeeApplication.this, "I/O Exceptionn " + ex.toString(), "Error Message", JOptionPane.ERROR_MESSAGE);
}
}
}
else {
try {
writeDataFile(currentFile);
}
catch (IOException ex) {
JOptionPane.showMessageDialog(EmployeeApplication.this, "I/O Exceptionn " + ex.toString(), "Error Message", JOptionPane.ERROR_MESSAGE);
}
}
}
}
}
});


// Prints report as external HTML file with name BankReport.html

filePrintReport.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {

/* Insert code here */

}
});



// Both of these listeners behave in the same way so we extract their code to a separate method

// exits program from menu
exitProgram.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
closeDown();
}
});

btnClose.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
closeDown();
}
});

// exits program by closing window
this.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
closeDown();
}
}); // end windowlistener

this.setTitle("Employee Application");
this.setContentPane(p);
this.setVisible(true);
this.pack();
} // constructor

public void readDataFile(File f) throws IOException, ClassNotFoundException {
//TODO

}
public void writeDataFile(File f) throws IOException, FileNotFoundException {
ObjectOutputStream out = null;
try {
out = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(f)));
// Write column headers as one object
out.writeObject(tm.getColumnNames());
// Write table data as second object
out.writeObject(tm.getTableData());
// This indicates that there is no unsaved data for the moment
tm.modified = false;
}
catch (FileNotFoundException ex) {
JOptionPane.showMessageDialog(EmployeeApplication.this, "File Not Found Exceptionn " + ex.toString(), "Error Message", JOptionPane.ERROR_MESSAGE);
}
catch (IOException ex) {
JOptionPane.showMessageDialog(EmployeeApplication.this, "I/O Exceptionn " + ex.toString(), "Error Message", JOptionPane.ERROR_MESSAGE);
}
catch (Exception ex) {
JOptionPane.showMessageDialog(EmployeeApplication.this, "Exceptionn " + ex.toString(), "Error Message", JOptionPane.ERROR_MESSAGE);
}
// Make sure to close stream
finally {
out.close();
}
}
// This behaviour will be used whether we close the application by clicking on the X button in the top-right corner or by selecting
// an option from a menu, so it makes sense to have it as an independent method that can be reused.
public void closeDown() {
// Ask user to confirm decision
int result = JOptionPane.showConfirmDialog(EmployeeApplication.this, "This will close the application.n Are you sure you want to do this?");
if (result == 0) {
// Give user second chance if there is unsaved data
if (tm.modified) {
int result2 = JOptionPane.showConfirmDialog(EmployeeApplication.this, "You have unsaved data that will be lost.n Are you sure you want to do this?");
if (result2 == 0) {
System.exit(0);
}
}
else {
System.exit(0);
}
}
}

public JMenuBar createMenuBar(){
// Setting up menu
fileLoad = new JMenuItem("Open");
fileSave = new JMenuItem("Save");
fileSaveAs = new JMenuItem("Save As");
filePrintReport = new JMenuItem("Print Report");

fileMenu = new JMenu("File");
fileMenu.add(fileLoad);
fileMenu.add(fileSave);
fileMenu.add(fileSaveAs);
fileMenu.add(filePrintReport);

addEmployee = new JMenuItem("Add");
removeEmployee = new JMenuItem("Remove");

employeeMenu = new JMenu("Employees");
employeeMenu.add(addEmployee);
employeeMenu.add(removeEmployee);

exitProgram = new JMenuItem("Exit Program");
exitMenu = new JMenu("Exit");
exitMenu.add(exitProgram);

myBar = new JMenuBar();
myBar.add(fileMenu);
myBar.add(employeeMenu);
myBar.add(exitMenu);

return myBar;

}
public JPanel createCentrePanel()
{
JPanel centerPanel = new JPanel(new GridLayout(6, 2));

lblPPSNo = new JLabel("PPS Number", JLabel.LEFT);
lblName = new JLabel("FullName", JLabel.LEFT);
lblGender= new JLabel("Gender", JLabel.LEFT);
lblDepartment= new JLabel("Department", JLabel.LEFT);
lblPosition= new JLabel("Position", JLabel.LEFT);
lblSalary= new JLabel("Salary", JLabel.LEFT);


txtPPSNo= new JTextField(20);
txtName= new JTextField(20);
txtDepartment= new JTextField(20);
txtPosition= new JTextField(20);
txtSalary= new JTextField(20);
txtSalary.setText("0.0");
String[] genderArr = { "Male", "Female" };
cbGender= new JComboBox(genderArr);

centerPanel.add(lblPPSNo);
centerPanel.add(txtPPSNo);
centerPanel.add(lblName);
centerPanel.add(txtName);
centerPanel.add(lblGender);
centerPanel.add(cbGender);
centerPanel.add(lblDepartment);
centerPanel.add(txtDepartment);
centerPanel.add(lblPosition);
centerPanel.add(txtPosition);
centerPanel.add(lblSalary);
centerPanel.add(txtSalary);

return centerPanel;

}

public JPanel createBottomPanel()
{
JPanel BottomPanel = new JPanel();
btnNew = new JButton("Add New");
btnUpdate = new JButton("Update");
btnDelete = new JButton("Delete");;
btnPrintAll = new JButton("Print All");
btnClose = new JButton("Close");
BottomPanel.add(btnNew);
BottomPanel.add(btnUpdate);
BottomPanel.add(btnDelete);
BottomPanel.add(btnPrintAll);
BottomPanel.add(btnClose);

return BottomPanel;

}


public static void main (String args[]){
new EmployeeApplication();
} // main

}

MyTableModel.java

package employeeApp;

import java.util.Vector;

import javax.swing.JOptionPane;
import javax.swing.table.AbstractTableModel;

class MyTableModel extends AbstractTableModel {
Vector< Object> row;
Vector< Object> newRow;
boolean ibRowNew = false;
boolean ibRowInserted = false;

/* We use vectors rather than arrays to allow the size to vary */
private Vector< String> columnNames;
private Vector< Object> rowData;

// Used to indicate whether data has been modified since it was loaded
public boolean modified;

// Used to indicate row in table that can be modified
int editable;

MyTableModel(){
String[] columns = {"PPS Number:", "Name", "Gender", "Department", "Position", "Salary"};
Object[][] inputData = {
{"", "", "", "", "", new Double(0.0)}
};
columnNames = new Vector< String>();
for (int i = 0; i < columns.length; i++) {
columnNames.addElement(columns[i]);
}
rowData = new Vector< Object>();
for (int i = 0; i < inputData.length; i++) {
newRow = new Vector< Object>();
for (int j = 0; j < inputData[i].length; j++) {
newRow.addElement(inputData[i][j]);
}
rowData.addElement(newRow);
}
// Initialising values
modified = false;
editable = -1;
}

@SuppressWarnings({ "rawtypes", "unchecked" })
public Class getColumnClass(int col){
return getValueAt(0,col).getClass();
}

// Get and set methods for column names and table data

public Vector< String> getColumnNames() {
return columnNames;
}

public Vector< Object> getTableData() {
return rowData;
}

public void setColumnNames(Vector< String> names) {
columnNames = names;
// This is a new structure so we need to tell the renderer this
fireTableStructureChanged();
modified = true;
}

public void setTableData(Vector< Object> data) {
rowData = data;
// This is new data so we need to tell the renderer this
fireTableDataChanged();
modified = true;
}

public void setNewRow(Vector< Object> blankRow) {
newRow = blankRow;
}

public boolean isCellEditable(int row, int col){
// Only selected row can be edited
return true;
/* put back in if (row == editable){
return true;
}
else {
return false;
}*/
}

public String getColumnName(int col){
return columnNames.get(col);
}

public int getRowCount(){
return rowData.size();
}

public int getColumnCount(){
return columnNames.size();
}

@SuppressWarnings("unchecked")
public Object getValueAt(int arow, int col){
row = (Vector< Object>) rowData.elementAt(arow);
return row.elementAt(col);
}

@SuppressWarnings("unchecked")
public void setValueAt(Object aValue, int aRow, int aCol) {
Vector< Object> dataRow = (Vector< Object>) rowData.elementAt(aRow);
dataRow.setElementAt(aValue, aCol);
fireTableCellUpdated(aRow, aCol);
// Modifying a cell implies unsaved data
modified = true;
}

//@SuppressWarnings("unused")
public void deleteRow(int rowToDelete){
try {
rowData.remove(rowToDelete);
fireTableRowsDeleted(rowToDelete,rowToDelete);
}
catch (ArrayIndexOutOfBoundsException e) {
JOptionPane.showMessageDialog(null, "No more rows to deleten " + e.toString(), "Error Message", JOptionPane.ERROR_MESSAGE);
}
}

public void addRow(){
// Get the total number of rows in the Vector
int rowNumber = rowData.size();
int pos;

// Get what a row looks like
int numElements = getColumnCount();
Vector< Object> newRowVect = new Vector< Object>();
for(int i = 0; i < numElements; i++){
String classType = getColumnClass(i).toString();
pos = classType.indexOf("String");
if(pos > 0){ // we have a String
String blankString = new String();
newRowVect.addElement(blankString);
}
pos = classType.indexOf("Double");
if(pos > 0){ // we have a Double
Double blankDouble = new Double("0.0");
newRowVect.addElement(blankDouble);
}
}
rowData.addElement(newRowVect);
editable = rowData.size() - 1;
fireTableRowsInserted(rowNumber,rowNumber);
}
}
Academic Honesty!
It is not our intention to break the school's academic policy. Posted solutions are meant to be used as a reference and should not be submitted as is. We are not held liable for any misuse of the solutions. Please see the frequently asked questions page for further questions and inquiries.
Kindly complete the form. Please provide a valid email address and we will get back to you within 24 hours. Payment is through PayPal, Buy me a Coffee or Cryptocurrency. We are a nonprofit organization however we need funds to keep this organization operating and to be able to complete our research and development projects.