I have an program that allows a user to input their employee name and number and then their hourly wage and their total number of regular hours and overtime hours. Then writes out the data to a binary file.

The program I need assistance with reads in that file, adds a new field at the bottom, "Gross Pay", and calculates the gross pay from the values from the input file. If anyone can assist me it would be greatly appreciated

(link to photobucket image of an example of desired output:
http://i108.photobucket.com/albums/n24/zypher89/readPayroll.jpg

Here is my code :

import java.io.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class ReadPayrollFile extends JFrame implements ActionListener, WindowListener {

	public static final int WIDTH = 400;
	public static final int HEIGHT = 300;
	JPanel titlePanel = new JPanel();
	JPanel displayPanel = new JPanel(new GridLayout(7, 1));
	JPanel dPanel1 = new JPanel(new FlowLayout(FlowLayout.LEFT));
	JPanel dPanel2 = new JPanel(new FlowLayout(FlowLayout.LEFT));
	JPanel dPanel3 = new JPanel(new FlowLayout(FlowLayout.LEFT));
	JPanel dPanel4 = new JPanel(new FlowLayout(FlowLayout.LEFT));
	JPanel dPanel5 = new JPanel(new FlowLayout(FlowLayout.LEFT));
	JPanel dPanel6 = new JPanel(new FlowLayout(FlowLayout.LEFT));
	JPanel dPanel7 = new JPanel(new FlowLayout(FlowLayout.LEFT));
	JPanel buttonPanel = new JPanel();
	private JLabel companyName = new JLabel("Payroll INC.");
	Font bigFont = new Font("Helvetica", Font.ITALIC, 24);
	private JLabel prompt = new JLabel("Enter Payroll Information");
	private JTextField employeeName = new JTextField(10);
	private JTextField employeeNumber = new JTextField(10);
	private JTextField hourlyRate = new JTextField(10);
	private JTextField regularHours = new JTextField(10);
	private JTextField overtimeHours = new JTextField(10);
	private JTextField grossPay = new JTextField(10);
	private JLabel enameLabel = new JLabel("Employee Name       ");
	private JLabel enumLabel = new JLabel("Employee Number   ");
	private JLabel hrLabel = new JLabel("Hourly Rate                ");
	private JLabel rhLabel = new JLabel("Regular Hours          ");
	private JLabel orLabel = new JLabel("Overtime Hours       ");
	private JLabel gpLabel = new JLabel ("Gross Pay                 ");
	private JButton nextRecordButton = new JButton("  Next Record  ");
	DataInputStream fstream;

	public ReadPayrollFile() {
		super("Read Payroll File - Assignment 11");

		setSize(WIDTH, HEIGHT);
		try
		{
			fstream = new DataInputStream(new FileInputStream("payroll.dat"));
			
		} catch (IOException e) {
			System.err.println("File not opened");
			System.exit(1);
		}
		Container contentPane = getContentPane();
		contentPane.setLayout(new BorderLayout());

		companyName.setFont(bigFont);
		titlePanel.add(companyName);
		titlePanel.setBackground(Color.white);

		dPanel1.add(prompt);
		displayPanel.add(dPanel1);

		dPanel2.add(enameLabel);
		dPanel2.add(employeeName);
		displayPanel.add(dPanel2);

		dPanel3.add(enumLabel);
		dPanel3.add(employeeNumber);
		displayPanel.add(dPanel3);

		dPanel4.add(hrLabel);
		dPanel4.add(hourlyRate);
		displayPanel.add(dPanel4);

		dPanel5.add(rhLabel);
		dPanel5.add(regularHours);
		displayPanel.add(dPanel5);

		dPanel6.add(orLabel);
		dPanel6.add(overtimeHours);
		displayPanel.add(dPanel6);

		dPanel7.add(gpLabel);
		dPanel7.add(grossPay);
		displayPanel.add(dPanel7);

		buttonPanel.setBackground(Color.white);
		buttonPanel.setLayout(new FlowLayout());
		nextRecordButton.setMnemonic(KeyEvent.VK_E);
		buttonPanel.add(nextRecordButton);
		nextRecordButton.addActionListener(this);

		contentPane.add(titlePanel, BorderLayout.NORTH);
		contentPane.add(displayPanel, BorderLayout.CENTER);
		contentPane.add(buttonPanel, BorderLayout.SOUTH);
		addWindowListener(this);
	}

	private void readRecord(DataInputStream inputFile) {

		String l_employeeName;
		Double l_hourlyRate;
		Integer l_employeeNumber, l_regularHours, l_overtimeHours;
		boolean endOfFile = false;

		try {
			
			while (!endOfFile)
			{
				try
				{
					l_employeeName = inputFile.readUTF();
					l_employeeNumber = inputFile.readInt();
					l_hourlyRate = inputFile.readDouble();
					l_regularHours = inputFile.readInt();
					l_overtimeHours = inputFile.readInt();
					fstream.readUTF(l_employeeName);
					fstream.readInt(l_employeeNumber);
					fstream.readDouble(l_hourlyRate);
					fstream.readInt(l_regularHours);
					fstream.readInt(l_overtimeHours);
					
					calculateGrossPay(l_hourlyRate, l_regularHours, l_overtimeHours);
					
					employeeName.setText("l_employeeName");
					employeeNumber.setText("l_employeeNumber");
					hourlyRate.setText("l_hourlyRate");
					regularHours.setText("l_regularHours");
					overtimeHours.setText("l_overtimeHours");
					grossPay.setText("grossPayAmmount");
				} 
				
				catch (NumberFormatException e2) 
				{
				System.err.println("Invalid number ");
				}
				
				catch (IOException e3) 
				{
				System.err.println("Error reading file");
				System.exit(1);
				}
		}

		public void actionPerformed(ActionEvent e) {
			NextRecord();
		}

		public void windowClosing(WindowEvent e) {
			try {
				fstream.close();
			} catch (IOException e4) {
				System.err.println("File not closed");
				System.exit(1);
			}

			System.exit(0);
		}

		public void windowClosed(WindowEvent e) {
		}

		public void windowDeiconified(WindowEvent e) {
		}

		public void windowIconified(WindowEvent e) {
		}

		public void windowOpened(WindowEvent e) {
		}

		public void windowActivated(WindowEvent e) {
		}

		public void windowDeactivated(WindowEvent e) {
		}

		public static void main(String[] args) {
			ReadPayrollFile cmof = new ReadPayrollFile();
			cmof.setVisible(true);
		}
		public double calculateGrossPay(double l_hourlyRate, int l_regularHours, int l_overtimeHours)
		{
			double grossPayAmmount, overtimePayRate, overtimePay;
			
			overtimePayRate = l_hourlyRate * 1.5;
			overtimePay = l_overtimeHours * overtimePayRate;
			grossPayAmmount = ((l_hourlyRate * l_regularHours) + overtimePay);
			
			return grossPayAmmount;
		}
	}

The part I'm having problems with is

private void readRecord(DataInputStream inputFile) {

	String l_employeeName;
	Double l_hourlyRate;
                Integer l_employeeNumber, l_regularHours, l_overtimeHours;
	boolean endOfFile = false;

	try {
			
	while (!endOfFile)
	{
		try
		{
		l_employeeName = inputFile.readUTF();
		l_employeeNumber = inputFile.readInt();
		l_hourlyRate = inputFile.readDouble();
		l_regularHours = inputFile.readInt();
		l_overtimeHours = inputFile.readInt();

/*On the next set "The method readUTF(DataInput) in the type DataInputStream is not applicable for the arguments (String)" with string replaced with Int or Double respectfully.*/

		fstream.readUTF(l_employeeName);
		fstream.readInt(l_employeeNumber);
		fstream.readDouble(l_hourlyRate);
		fstream.readInt(l_regularHours);
		fstream.readInt(l_overtimeHours);
		
		calculateGrossPay(l_hourlyRate, l_regularHours, l_overtimeHours);
					
		employeeName.setText("l_employeeName");		 
                   employeeNumber.setText("l_employeeNumber");
		hourlyRate.setText("l_hourlyRate");
		regularHours.setText("l_regularHours");
		overtimeHours.setText("l_overtimeHours");
                   grossPay.setText("grossPayAmmount");
	} 
				
	catch (NumberFormatException e2) 
	{
	System.err.println("Invalid number ");
	}
				
	catch (IOException e3) 
	{
	System.err.println("Error reading file");
	System.exit(1);
/*Multiple markers at this line
	- Syntax error, insert "Finally" to complete 
	 BlockStatements
	- Syntax error, insert "}" to complete Block
	- Syntax error, insert "Finally" to complete 
	 TryStatement*/
	}

	public void actionPerformed(ActionEvent e) {
// here I get "The method NextRecord() is undefined for the type ReadPayrollFile"
//But I don't know exactly how to get the button to read in the next set of data
	NextRecord();
	}

Any assistance would be greatly appreciated. Thanks in advance.

Hi Ryujin89,

private void readRecord(DataInputStream inputFile) {

	String l_employeeName;
	Double l_hourlyRate;
                Integer l_employeeNumber, l_regularHours, l_overtimeHours;
	boolean endOfFile = false;

//	try { // remove this line
		
	// the endOfFile will always be false because you don't check the end of file anywhere
	while (!endOfFile)
	{
		try
		{
		l_employeeName = inputFile.readUTF();
		l_employeeNumber = inputFile.readInt();
		l_hourlyRate = inputFile.readDouble();
		l_regularHours = inputFile.readInt();
		l_overtimeHours = inputFile.readInt();
// you should remove the following set and call readRecord(fstream) instead, but if you do need it:
		// the parameter for readUTF must NOT be a String, 
		// but a DataInput or none;
		fstream.readUTF(l_employeeName);
		// the readInt() method returns next four bytes of the
		// fstream interpreted as an int and it has no parameter
		fstream.readInt(l_employeeNumber);
		// you should call it like this
		int intvalue = fstream.readInt(); // same for double
		// the readDouble() method returns next eight bytes of the
		// fstream interpreted as a double and it has no parameter
		fstream.readDouble(l_hourlyRate);
		fstream.readInt(l_regularHours);
		fstream.readInt(l_overtimeHours);
		
		calculateGrossPay(l_hourlyRate, l_regularHours, l_overtimeHours);
					
		employeeName.setText("l_employeeName");		 
                   employeeNumber.setText("l_employeeNumber");
		hourlyRate.setText("l_hourlyRate");
		regularHours.setText("l_regularHours");
		overtimeHours.setText("l_overtimeHours");
                   grossPay.setText("grossPayAmmount");
	} 
				
	catch (NumberFormatException e2) 
	{
	System.err.println("Invalid number ");
	}
				
	catch (IOException e3) 
	{
	System.err.println("Error reading file");
	System.exit(1);
	}
} // insert closing brace for the while block
} // insert closing brace for the method block

	public void actionPerformed(ActionEvent e) {
// here I get "The method NextRecord() is undefined for the type ReadPayrollFile"
//But I don't know exactly how to get the button to read in the next set of data
// you don't have a method  NextRecord() defined in your class, you could define one or use the readRecord() method I guess, with some minor tweaks.
	NextRecord();
	}

... hope this helps ...
GL

If I delete out the line with "try", it takes away the point of the try-catch block. I don't see how that will help.

Also, I'm not just reading in the next 4 bytes for the int. I want to read in a specific set of data from the file. The file is binary, not digits and characters.

I will try to look for a method that reads in the entire next set of data and then selects out the individual parts needed.

Do I need to post my code that creates the file that I'm reading from so that you can see what I'm working with / reading from?

The instructions for an assignment was to create program to make the output file. We turned it in and then he wants us to create a program that reads in that exact file and re-sort the data, plus add the new field with its calculated valued in the text field of the GUI.


Hope that clears things up.

Ok, let's look only at the readRecord() metod:

private void readRecord(DataInputStream inputFile) {

		String l_employeeName;
		Double l_hourlyRate;
		Integer l_employeeNumber, l_regularHours, l_overtimeHours;
		boolean endOfFile = false;

		try { // open first try block
			
			while (!endOfFile)
			{ // open while block
				try // open second try block
				{
					l_employeeName = inputFile.readUTF();
					l_employeeNumber = inputFile.readInt();
					l_hourlyRate = inputFile.readDouble();
					l_regularHours = inputFile.readInt();
					l_overtimeHours = inputFile.readInt();
					
					fstream.readUTF(l_employeeName);
					fstream.readInt(l_employeeNumber);
					fstream.readDouble(l_hourlyRate);
					fstream.readInt(l_regularHours);
					fstream.readInt(l_overtimeHours);
					
					calculateGrossPay(l_hourlyRate, l_regularHours, l_overtimeHours);
					// Double grossyPayAmount = calculateGrossPay(l_hourlyRate, l_regularHours, l_overtimeHours);
					
					employeeName.setText("l_employeeName");
					employeeNumber.setText("l_employeeNumber");
					hourlyRate.setText("l_hourlyRate");
					regularHours.setText("l_regularHours");
					overtimeHours.setText("l_overtimeHours");
					grossPay.setText("grossPayAmmount");
				} // close second try block
				
				catch (NumberFormatException e2) 
				{ // open first catch block associated to second try block
				System.err.println("Invalid number ");
				} // close first catch block
				
				catch (IOException e3) 
				{ // open second catch block associated to second try block
				System.err.println("Error reading file");
				System.exit(1);
				} // close second catch block
		} // close method

1. as you can see you have no closing braces for the first try block and the while block. More ... you don't need the first try block because it contains only the while which throws no error, you can actually remove the first catch block because no NumberFormatException is thrown in the second try block.
2. The method calculateGrossPay() returns a double value, (this is the value for the new field I guess) but you are not doing anything with it.
At line 27 is a commented line about how it should look.
3. When you are setting the texts for the text fields you're just passing STRINGS to the method setText(),

employeeNumber.setText("l_employeeNumber");

you have to pass the value of your variables

employeeNumber.setText(Integer.toString(l_employeeNumber));
// for double values use Double.toString(doubleVar)

4. In the while block, you are reading data again and again until you are reaching the end of the file, but you are not testing it, the loop stops because you get an IOException and after calling the method you will have only the last set of data from the file, all other records are lost

GL

I changed/updated to what you said and have got multiple errors to go away, but I'm still having some errors. I also want to see if the code I used for the action listener for the "read next record" button will do what I want.

private void readRecord(DataInputStream inputFile) {

		DataInput l_employeeName;
		Double l_hourlyRate;
		Integer l_employeeNumber, l_regularHours, l_overtimeHours;
		boolean endOfFile = true;
			
			while (false)
			{
				try
				{
/*I was able to get the filestream to work, but now I get "Type mismatch: cannot convert from String to DataInput*/					
					l_employeeName = inputFile.readUTF();
					l_employeeNumber = inputFile.readInt();
					l_hourlyRate = inputFile.readDouble();
					l_regularHours = inputFile.readInt();
					l_overtimeHours = inputFile.readInt();


/*the readUTF is accepted but it says "The static method readUTF(DataInput) from the type DataInputStream should be accessed in a static way*/
				
					fstream.readUTF(l_employeeName);
/*Also, all of the read in statements following this get "The method readInt() in the type DataInputStream is not applicable for the arguments (Integer)" with Integer replaced to Double respectively*/
					fstream.readInt(l_employeeNumber);
					fstream.readDouble(l_hourlyRate);
					fstream.readInt(l_regularHours);
					fstream.readInt(l_overtimeHours);
					
					Double grossPayAmount = calculateGrossPay(l_hourlyRate, l_regularHours, l_overtimeHours);
					
					employeeName.setText("l_employeeName");
					employeeNumber.setText(Integer.toString(l_employeeNumber));
					hourlyRate.setText(Double.toString(l_hourlyRate));
					regularHours.setText(Integer.toString(l_regularHours));
					overtimeHours.setText(Integer.toString(l_overtimeHours));
					grossPay.setText(Double.toString(grossPayAmount));
				} 
				
				catch (EOFException eof) 
				{
				System.err.println("End of file reached");
				}
				
				catch (IOException e3) 
				{
				System.err.println("Error reading file");
				System.exit(1);
				}
				}
		}
// here is the action listener part that I want to check
public void actionPerformed(ActionEvent e) {
			readRecord(fstream);
		}

I appreciate all your assistance. I have tried to read over the API, but most of it I understand how it's worded, but not how to apply it properly.

Anyone able to offer assistance? I would greatly appreciate it. I'm still looking myself, but not able to make heads or tails of how to get the reading in specific parts of the line to work.

I can post the program that performs the output if it's needed.

Thanks in advance.

So Ryujin89,
you have to read the data from a file, sort it, and then display it, 1 set of data when the next button is pressed?

This is how I will do it...
1 Create a class, to hold the data of a record, let's call it Record, as follows:

public class Record {

	private String employeeName;
	private double hourlyRate;
	private int employeNumber, regularHours, overtimeHours;
	private double grossPayAmount;
	
	// CONSTRUCTOR - create new Record object and init fields
	public Record(){
		setEmployeeName("");
		setHourlyRate(0);
		setEmployeNumber(0);
		setRegularHours(0);
		setOvertimeHours(0);
		setGrossPayAmount(0);
	}
	
	// CONSTRUCTOR - create a new Record object with given values
	public Record(String name, double hourly, int number, int regular, int overtime){
		setEmployeeName(name);
		setHourlyRate(hourly);
		setEmployeNumber(number);
		setRegularHours(regular);
		setOvertimeHours(overtime);
		grossPayAmount = calculateGrossPay(hourlyRate, regularHours, overtimeHours);
	}
	
	
	public double calculateGrossPay(double l_hourlyRate, int l_regularHours, int l_overtimeHours){
	
		double grossPayAmmount, overtimePayRate, overtimePay;	
	 
		overtimePayRate = l_hourlyRate * 1.5;
		overtimePay = l_overtimeHours * overtimePayRate;
		grossPayAmmount = ((l_hourlyRate * l_regularHours) + overtimePay);
		
		return grossPayAmmount;	
	}

	public void setEmployeName(String name){
		employeName = name;
	}

	public String getEmployeeName() {
		return employeeName;
	}

	// create getter and setter for each field
	// . . .

}

then, the readRecord method in your ReadPayrollFile class:

// define as global 
private ArrayList<Record> recordsList = new ArrayList<Record>();\
private int iterator = 0; // to iterate the array
// ...
private void readRecord(DataInputStream inputFile) {

		String l_employeeName;
		Double l_hourlyRate;
		Integer l_employeeNumber, l_regularHours, l_overtimeHours;
		boolean endOfFile = false;
		
		// read the file and add Record objects to an array list
		while (!endOfFile){
			try{
					
				l_employeeName = inputFile.readUTF();
				l_employeeNumber = inputFile.readInt();
				l_hourlyRate = inputFile.readDouble();
				l_regularHours = inputFile.readInt();
				l_overtimeHours = inputFile.readInt();				
				
				Record record = new Record(
						l_employeeName, 
						l_hourlyRate,
						l_employeeNumber, 
						l_regularHours, 
						l_overtimeHours);
				
				recordsList.add(record);	
				
				// test EOF
				if (inputFile.available() == 0){
					endOfFile = true;
				}
			}
			catch (IOException e3){
				System.err.println("Error reading file");
				System.exit(1);
			}
		}
		
		// after reading the data, sort the array
		// use compare method to set the sorting type
		// let's say you need to sort them by employee name
		Collections.sort(recordsList, 
				new Comparator<Object>(){
					public int compare( Object a, Object b ){
						return( (Record)a).getEmployeeName().compareTo(((Record)b).getEmployeeName());
					}
				});
		
	}

... now you can call the readRecord method in your ReadPayrollFile constructor after you open the file, like ...

fstream = new DataInputStream(new FileInputStream("payroll.dat"));
readRecord(fstream);

And finally the action and nextRecord

public void actionPerformed(ActionEvent e) {
		nextRecord();
	}
	
private void nextRecord(){
	Record record;
	if (iterator < recordsList.size()){			
		record = recordsList.get(iterator);
		employeeName.setText(
			record.getEmployeeName());		
		employeeNumber.setText(
			Integer.toString(record.getEmployeNumber()));		
		hourlyRate.setText(
			Double.toString(record.getHourlyRate()));		
		regularHours.setText(
			Integer.toString(record.getRegularHours()));		
		overtimeHours.setText(
			Integer.toString(record.getOvertimeHours()));	
		grossPay.setText(
			Double.toString(record.getGrossPayAmount()));
		}
		iterator++;	
		
	}

GL

You have lost me. I can follow the code in the forum, but haven't figured out how to put it into my code. I have tried to follow how you said, but I keep getting errors for most of the lines when I paste it. I have and will keep working on trying to get everything working.

Looking at it piece by piece, for the 1st part, you say to put create a class, that would be after the ReadPayrollFile1 class which has the GUI interface and the readRecord method, then taking the getters and setters from that I have and copy them over?


From the way the instructor put it, it shouldn't be more than taking the program that created the output file from the user input and modify it to read in and print to the GUI. This project is due Friday and I also have a C++ proj that I'm having to do.

If you can, is it possible to explain how to implement what you provided a different way? I'm not asking to do it for me, I just don't can't get it to work when I paste it into my code and I'm pressed for time.

Thanks again and in advance for all your help. I greatly appreciate it.

Ok Ryujin89,

So you will have 2 class files to make things simple:
1.
the Record class which holds data for 1 record, the class posted before. You will have to create in this class get and set methods for the other variables: hourlyRate, emplyeeNumber, ... just like for the emplyeName

2.
the ReadPayrollFile class which contains the GUI part, the readRecord() method and nextRecord() method.
the ReadPayrollFile class will also have an ArrayList of Record object which will hold all the data from the input file.
The readRecord() method, reads the input stream (file) passed as parameter and appends each record to the ArrayList. After reading all the data a Comparator is used to sort the data in the ArrayList by employeeName. This method will be called only 1 time when the program starts, you can call it after you open the InputStream in your ReadPayrollFile constructor:

public ReadPayrollFile() {
	super("Read Payroll File - Assignment 11");
	setSize(WIDTH, HEIGHT);
	try{
		fstream = new DataInputStream(new FileInputStream("payroll.dat"));
	// call read record
		readRecord(fstream);
	} catch (IOException e) {
	System.err.println("File not opened");
	System.exit(1);
	}
// ...
}

and then the nextRecord method which uses the global variable int iterator to get the next record from the ArrayList and display it in the text fields

hope this helps ...
GL

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.