I am making a simple program where I can keep track of my savings. I have included week no., income, and saved fields. I save this data to a text file and then can retrieve it to a text area. How can I keep track of my running total, "total", when closing the program then running it again. I have used an array as a running total, but this starts over when I kill it then reopen it (obviously).
here is my code for the save and read. to sum up I want to be able to retrieve the last field "total" as a variable so it can be added onto the new input.
//get week and validate:
strWeek = txtWeek.getText();
if (strWeek.isEmpty())
{
JOptionPane.showMessageDialog(null, "Enter Week Number");
return;
}
else
week = Integer.parseInt(strWeek);
//get income and validate:
strIncome = txtIncome.getText();
if (strIncome.isEmpty())
{
JOptionPane.showMessageDialog(null, "Enter Income");
return;
}
else
income = Double.parseDouble(strIncome);
//get saved:
strSaved = txtSaved.getText();
if (strSaved.isEmpty())
{
JOptionPane.showMessageDialog(null, "Enter Saved");
return;
}
else
saved = Double.parseDouble(strSaved);
total = total + saved;
txtOutput.append(week + "\t" + income + "\t" + saved + "\t" + total + "\n");
txtWeek.setText(null);
txtIncome.setText(null);
txtSaved.setText(null);
try
{
File output = new File("C:\\savingsApp/Savings.txt");
BufferedWriter outFile = new BufferedWriter (new FileWriter(output.getPath(), true));
outFile.write(week + "\t" + income + "\t" + saved + "\t" + total);
outFile.newLine();
outFile.close();
JOptionPane.showMessageDialog(null, "Savings updated");
}
catch (Exception e)
{
JOptionPane.showMessageDialog(null, "IO file error");
}
txtOutput.setText(null);
//Declare:
String incomingString = "";
int counter = 0;
//get file:
try
{
File inputFile = new File ("C:\\savingsApp/savings.txt");
BufferedReader inFile = new BufferedReader (new FileReader(inputFile));
incomingString = inFile.readLine();
while (incomingString != null)
{
counter++;
txtOutput.append(incomingString + "\n");
incomingString = inFile.readLine();
}
}
catch (Exception e)
{
JOptionPane.showMessageDialog(null, "error loading file");
}
Make runningTotal an ArrayList and save to a separate file before killing your program. This could be in comma (or tab) separated form. For instance runningTotal.csv could look like this:
150,200,50,...,300
When you read in savings.txt you can also read in runningTotal.csv and then add any more totals to the end of the ArrayList. When you close the program again, update runningTotal.csv.
I'm assuming that what you are really asking is a way to parse the text you are getting from the file. The, a way to achieve this could be by using java.util.Scanner for example as shown in here:
private Map<String, String> parseData(String text) {
Map<String, String> data = new HashMap<String, String>();
Scanner scanner = new Scanner(text);
data.put("week", scanner.next());
data.put("income", scanner.next());
data.put("saved", scanner.next());
data.put("total", scanner.next());
return data;
}
Then you could do something like this:
...
while (incomingString != null) {
counter++;
String totalStr = parseData(incomingString).get("total");
txtOutput.append(incomingString + "\n");
incomingString = inFile.readLine();
}
Related
I am in the middle of a university project, the task being to use a scanner to read the appropriate data of several data files. The project involves a superclass and several subclasses. So far the method below works perfectly and reads data corresponding to a class called Tool and all its fields. However I have recently added a subclass ElectricTool which extends class Tool and also which has introduced two new fields which need reading in the same way as before but within the same method shown below. I have tried a number of things but I can't seem to figure it out. Any suggestions? Preferably as clean/simple code as possible, I think it needs to be a read statement but I am struggling. The method is below:
public void readToolData()
{
Frame myFrame = null;
FileDialog fileBox = new FileDialog(myFrame,"Open", FileDialog.LOAD);
fileBox.setVisible(true);
String directoryPath = fileBox.getDirectory();
String fileName = fileBox.getFile();
File dataFile = new File(fileName);
System.out.println(fileName +" "+ directoryPath);
Scanner scanner = null;
try
{
scanner = new Scanner(dataFile);
}
catch (FileNotFoundException e)
{
System.out.println(e);
}
while( scanner.hasNextLine() )
{
String lineOfText = scanner.nextLine().trim().replaceAll("\\s+","");
if(!lineOfText.isEmpty() && !lineOfText.matches("^//.*") && !lineOfText.substring(0,1).equals("["))
{
System.out.println(lineOfText);
}
else{
continue;
}
Scanner scanner2 = new Scanner(lineOfText).useDelimiter("\\s*,\\s*");
while(scanner2.hasNext())
{
Tool tool = new Tool();
tool.readData(scanner2);
storeToolList(tool);
}
}
scanner.close();
}
electric tool class
tool class
data file
public void readToolData() {
Frame myFrame = null
FileDialog fileBox = new FileDialog(myFrame, "Open", FileDialog.LOAD);
fileBox.setVisible(true);
String directoryPath = fileBox.getDirectory();
String fileName = fileBox.getFile();
File dataFile = new File(directoryPath + fileName);
System.out.println(fileName + " " + directoryPath);
Scanner scanner = null;
try {
scanner = new Scanner(dataFile);
} catch (FileNotFoundException e) {
System.out.println(e);
}
// Current tool type
String toolType = null;
while( scanner.hasNextLine() ) {
String lineOfText = scanner.nextLine().trim();
// Skip empty lines and commentaries
if(lineOfText.isEmpty() || lineOfText.startsWith("//")) {
continue;
}
if (lineOfText.startsWith("[")) {
// Extract the tool type name
String withoutBracket = lineOfText.substring(1);
// Split by spaces and take the first word
String[] words = withoutBracket.split(" ");
toolType = words[0];
System.out.println("Reading information about " + toolType);
continue;
}
System.out.println(lineOfText);
Scanner scanner2 = new Scanner(lineOfText).useDelimiter("\\s*,\\s*");
Tool tool = null;
if ("ElectricTool".equals(toolType)) {
tool = new ElectricTool();
}
// In the future here will come more cases for different types, e.g.:
// else if ("HandTool".equals(toolType)) {
// tool = new HandTool();
// }
if (tool != null) {
tool.readData(scanner2);
storeToolList(tool);
}
}
scanner.close();
}
Remove scanner.skip line in Tool.readData:
public class Tool {
public void readData(Scanner scanner) {
toolName = scanner.next();
itemCode = scanner.next();
timesBorrowed = scanner.nextInt();
onLoan = scanner.nextBoolean();
cost = scanner.nextInt();
weight = scanner.nextInt();
scanner.skip(".*"); // Remove this line
}
}
And implement readTool method in ElectricTool:
#Override
public void readData(Scanner scanner) {
super.readData(scanner);
rechargeable = scanner.nextBoolean();
power = scanner.next(); // Or nextInt? what is the type of power field?
}
To print the information about the tools you should use polymorphism.
Modify your printAllTools method in Shop.java like this:
public void printAllTools() {
System.out.println("Information");
System.out.println("---------->");
for (Tool t : toolList) {
System.out.println("You have selected:\n");
t.printDetails();
}
}
Now, your method printDetails in Tool.java must be looking like this:
public void printDetails() {
System.out.println("Tool name: " + toolName + "\n" +
"Item code: " + itemCode + "\n" +
"Times borrowed: " + timesBorrowed + "\n" +
"On load: " + onLoan + "\n" +
"Cost: " + cost + "\n" +
"Weight: " + weight + "g\n"
);
}
and in the ElectricTool.java:
public void printDetails() {
super.printDetails();
System.out.println("Rechargeable: " + rechargeable + "\n" +
"Power: " + power + "\n"
);
}
I have programmed a game were I have made it so that you can save your score, if you have a good score you will be in the top 10. My problem is when I retrieve the data with the saved names, I only want a proportion of that data to be shown, in this case 10 names.
Here is my code.
public static void Highscore(List<Highscore> data) {
String HighscoreList = "";
try {
//Textfilens name
String filname = "Highscore.txt";
Scanner inFil = new Scanner(new File(filname));
while(inFil.hasNext()) {
String name = inFil.next();
String percent = inFil.next();
HighscoreLista += name + "\n" + percent + "%" + "\n\n";
} inFil.close();
} catch (FileNotFoundException e1) {
JOptionPane.showMessageDialog(null,"File was not found!");
}
JOptionPane.showMessageDialog(null, HighscoreList);
}//Highscore ends
How do I only show a proportion of the players in the final message (Highscorelist).
Thank you for helping.
Create a counter variable in the function to track the number of items in the while loop and check the counter variable along with the while condition
public static void Highscore(List<Highscore> data) {
String HighscoreList = "";
int counter =0;
try {
//Textfilens name
String filname = "Highscore.txt";
Scanner inFil = new Scanner(new File(filname));
while(inFil.hasNext() && counter<=10) {
counter++;
String name = inFil.next();
String percent = inFil.next();
HighscoreLista += name + "\n" + percent + "%" + "\n\n";
} inFil.close();
} catch (FileNotFoundException e1) {
JOptionPane.showMessageDialog(null,"File was not found!");
}
JOptionPane.showMessageDialog(null, HighscoreList);
}//Highscore ends
This is what I have:
try{
String filename = "Names.txt";
FileWriter fw = new FileWriter(filename, true);
BufferedWriter buffer = new BufferedWriter(fw);
buffer.append("NAME: " + name + " AGE: " + age + " ID: " + id + "\n\n");
System.out.println("We have succefully created your account.");
buffer.close();
start();
} catch(IOException e){
System.err.println("ERROR");
}
It always overwrites the first line and does not go to a different one. I've used the append. This is my start method:
// this is the start method
public static void start(){
System.out.println("1) Add Account 2) Exit");
System.out.println("What do you want to do: ");
stuff = input.nextInt();
if (stuff == 1) {
try {
x = new Formatter("Names.txt");
} catch (Exception e) {
System.err.println("ERROR" );
}
newRecord();
} else if(stuff == 2) {
System.exit(0);
} else {
System.err.println("ERROR");
}
}
I guess is this line:
x = new Formatter("Names.txt");
From javadoc
public Formatter(String fileName) throws FileNotFoundException
Parameters:
fileName - The name of the file to use as the destination of this formatter. If the file exists then it will be truncated to zero size; otherwise, a new file will be created. The output will be written to the file and is buffered.
(I add emphasis to the part that is cleaning your file).
I want a program that saves what you enter into the Input Dialogs (after you click no on the first message dialog) for the next time you run the program. The next time I run the program and I click yes on the option dialog, I'm trying to get the text field to say what the user entered last time an input was made. The code at the bottom just sets the textfield blank for some reason..
public static String fn;
public static String sn;
public static int n;
File f = new File("test.txt");
public void actionPerformed (ActionEvent e){
Object[] yesNo = {"Yes",
"No",};
n = JOptionPane.showOptionDialog(null,"Would you like to use previously entered data?","Welcome Back?",JOptionPane.YES_NO_OPTION,JOptionPane.QUESTION_MESSAGE, null, yesNo,yesNo[1]);
if (n == 1){
for(fn=JOptionPane.showInputDialog("What is your first name?");!fn.matches("[a-zA-Z]+");fn.isEmpty()){
JOptionPane.showMessageDialog(null, "Alphabet characters only.");
fn=JOptionPane.showInputDialog("What is your first name?");
}
writeToFile();
for(sn=JOptionPane.showInputDialog("What is your second name?");!sn.matches("[a-zA-Z]+");sn.isEmpty()){
JOptionPane.showMessageDialog(null, "Alphabet characters only.");
sn=JOptionPane.showInputDialog("What is your second name?");
}
if (n == 0){
writeToFile();
String fullName = writeToFile();
text.setText("Welcome " + fullName + ".");
}
}
//text.setText("Welcome " + fn + " " + sn + ".");
b.setVisible(false);
b.setEnabled(false);
text.setVisible(true);
text.setBounds(140,0,220,20);
text.setHorizontalAlignment(JLabel.CENTER);
text.setEditable(false);
text.setBackground(Color.YELLOW);
pnlButton.setBackground(Color.DARK_GRAY);
}
private String writeToFile() {
String nameToWrite = fn;
OutputStream outStream = null;
String savedName = "";
try {
outStream = new FileOutputStream(f);
outStream.write(nameToWrite.getBytes());
if (n==0){
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(f)));
savedName = br.readLine();
}
if (n==1){
text.setText("Welcome " + fn + ".");
}
//text.setText("Welcome " + savedName + " " + sn + ".");
//System.out.println(savedName);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (null != outStream) {
try {
outStream.close();
} catch (IOException e) {
// do nothing
}
}
}
return savedName;
}
When you open outputStream each time you call writeToFile, it automatically overwrites what was in the file to begin with. This means when you call writeToFile at the beginning of the if statement to handle the Yes option, you erase the previous contents.
To append, use the line outStream = new FileOutputStream(f, true);.
It may be better to consider moving ALL writing into the if block n==1.
An even better solution would be to have two methods; a readFromFile and a writeToFile. Also, consider using parameters that you pass to the methods instead of global variables.
I have created an application that allows the user to enter their account number, balance(no more than 99999), and last name. The program will take this information and insert it into a .txt file at a location corresponding to the account number(acct). Here is the code for that:
import java.io.*;
public class NationalBank {
public static void main(String[] args) throws Exception{
InputStreamReader temp = null;
BufferedReader input = null;
try {
temp = new InputStreamReader(System.in);
input = new BufferedReader(temp);
int acct;
double amount;
String name;
RandomAccessFile file = new RandomAccessFile("bank.txt", "rw");
while(true) {
// Asks for input
System.out.println("Enter Account Number (0-9999): ");
acct = Integer.parseInt(input.readLine());
System.out.println("Enter Last Name: ");
name = input.readLine();
System.out.println("Enter Balance ");
amount = Double.parseDouble(input.readLine());
// Making sure account numbers are between 0 and 9999
if(acct >=0 && acct <= 9999) {
file.seek(acct*17);
file.write(truncateName(name));
file.writeBytes(" " +amount);
}
else {
continue;
}
// Asks user if more entries are needed
System.out.println("Enter More? (y/n)");
if (input.readLine().toLowerCase().equals("n"))
break;
}
file.close();
}
catch (Exception e) {
}
}
// Truncate/adding spaces to name until 8 characters
public static byte[] truncateName (String name) {
byte[] result = new byte[8];
for (int i = 0; i < 8; i++)
result [i] = i < name.length () ? (byte)name.charAt (i) : (byte)' ';
return result;
}
}
Now, I am trying to make an application that will write back all of the accounts that have information within them(with last name and balance). I need to display the account number, balance, and last name of those accounts. So far, I have:
import java.io.*;
public class DisplayBank {
public static void main(String[] args) throws IOException {
FileInputStream input = new FileInputStream ("bank.txt");
try {
byte[] record = new byte[17];
while (input.read(record) == 17) {
String name = new String(record, 0, 8);
long bits = 0;
for (int i = 8; i < 17; i++) {
bits <<= 8;
bits |= record[i] & 0xFF;
}
double amount = Double.longBitsToDouble(bits);
System.out.println("Account Number: " + record + " Name: " + name + ", amount: " + amount);
}
}
catch (IOException e) {
}
finally {
input.close();
}
}
}
This currently displays only the name correctly. The balance is incorrect, and I don't know how to get the account number. In order to get the account number, I would need to get the position of name. In order to get the amount, I would need to seek name, offset 9 bytes, then read the next 8 bytes...
If you want to parse a text file that contains last names and amounts similar what you provided:
example provided
LastName 93942.12
What I would do is to try something like the following
public void read_file(){
try{
// Open the file that is the first
// command line parameter
FileInputStream fstream = new FileInputStream("C:\\Users\\Alos\\Desktop\\test.txt");
// Use DataInputStream to read binary NOT text.
BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
String strLine;
int record = 0;
//Read File Line By Line
while ((strLine = br.readLine()) != null) {
String[] splits = strLine.split("\t");
String LastName = splits[0];
String Amount = splits[1];
System.out.println("Account Number: " + record + " Name: " + LastName + ", amount: " + Amount);
record++;
}
//Close the input stream
in.close();
}catch (Exception e){//Catch exception if any
System.err.println("Error: " + e.getMessage());
}
}
This might not be exactly what you're looking for but please take a look and update your question if you would like something different.
I it's not a homework, I would strongly recommend to use some RDBMS like Derby or MySQL.