Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

hello. need a little help to get my code to work. I want to be able to display w

ID: 3766893 • Letter: H

Question

hello. need a little help to get my code to work. I want to be able to display what you input as the operation you want to do. For example i input 3*3... right now my code just shows the 3 --clears --- shows the * --- clears and then shows the 3 ---and clears.... I want it to show 3*3 hit equal shows the result. here is the code i have so far.

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

public class Calculator extends JFrame implements ActionListener {
  
JPanel[] space = new JPanel[5];
  
String[] buttonString = {"7", "8", "9", "+",
"4", "5", "6", "-",
"1", "2", "3", "*",
".", "/", "C", "",
"+/-", "=", "0",
"x^y", "n!","e^x"};


JButton[] button = new JButton[buttonString.length];
int[] dimW = {300,45,100,90};
int[] dimH = {35, 40};
Dimension displayDimension = new Dimension(dimW[0], dimH[0]);
Dimension regularDimension = new Dimension(dimW[1], dimH[1]);
Dimension rColumnDimension = new Dimension(dimW[2], dimH[1]);
Dimension zeroButDimension = new Dimension(dimW[3], dimH[1]);
boolean[] function = new boolean[5];
double[] temporary = {0, 0};
JTextArea display = new JTextArea(1,25);
Font font = new Font("Times new Roman", Font.BOLD, 24);
  
Calculator() {
super("Calculator");
setDesign();
setSize(500, 300);
setResizable(false);
setDefaultCloseOperation(EXIT_ON_CLOSE);
GridLayout grid = new GridLayout(5,5);
setLayout(grid);
  
for(int i = 0; i < 5; i++)
function[i] = false;
  
FlowLayout f1 = new FlowLayout(FlowLayout.CENTER);
FlowLayout f2 = new FlowLayout(FlowLayout.CENTER,1,1);
for(int i = 0; i < 5; i++)
space[i] = new JPanel();
space[0].setLayout(f1);
for(int i = 1; i < 5; i++)
space[i].setLayout(f2);
  
for(int i = 0; i < buttonString.length; i++) {
button[i] = new JButton();
button[i].setText(buttonString[i]);
button[i].setFont(font);
button[i].addActionListener(this);
}
  
display.setFont(font);
display.setEditable(false);
display.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
display.setPreferredSize(displayDimension);
for(int i = 0; i < 14; i++)
button[i].setPreferredSize(regularDimension);
for(int i = 14; i < 18; i++)
button[i].setPreferredSize(rColumnDimension);
button[18].setPreferredSize(zeroButDimension);
for(int i = 19; i < button.length; i++)
button[i].setPreferredSize(zeroButDimension);
  
space[0].add(display);
add(space[0]);
  
for(int i = 0; i < 4; i++)
space[1].add(button[i]);
space[1].add(button[14]);
space[1].add(button[19]);
add(space[1]);
  
for(int i = 4; i < 8; i++)
space[2].add(button[i]);
space[2].add(button[15]);
space[2].add(button[20]);
add(space[2]);
  
for(int i = 8; i < 12; i++)
space[3].add(button[i]);
space[3].add(button[16]);
space[3].add(button[21]);
add(space[3]);
  
space[4].add(button[18]);
for(int i = 12; i < 14; i++)
space[4].add(button[i]);
space[4].add(button[17]);
JButton temp = new JButton(":)");
temp.setPreferredSize(zeroButDimension);
  
space[4].add(temp);
add(space[4]);
setVisible(true);
}
  
public void clear() {
try {
display.setText("");
for(int i = 0; i < 5; i++)
function[i] = false;
for(int i = 0; i < 2; i++)
temporary[i] = 0;
} catch(NullPointerException e) {
}
}
//function to get square root
public void getSqrt() {
try {
double number = Math.sqrt(Double.parseDouble(display.getText()));
display.setText(Double.toString(number));
} catch(NumberFormatException e) {
}
}
//function to get factorial
public void getFactorial() {
try {
int number = Integer.parseInt(display.getText());
int fact =1;
for(int i = 2; i <= number; i++)
fact *=i;
display.setText(Double.toString(fact));
} catch(NumberFormatException e) {
}
}
  
//function to get the exponent of a number
public void getExponent() {
try {
double number = Math.exp(Double.parseDouble(display.getText()));
display.setText(Double.toString(number));
} catch(NumberFormatException e) {
}
}
  
//setting a positive or negative number
public void getPosNeg() {
try {
double number = Double.parseDouble(display.getText());
if(number != 0) {
number = number * (-1);
display.setText(Double.toString(number));
}
else {
}
} catch(NumberFormatException e) {
}
}
//calculating the result
public void getResult() {
double result = 0;
temporary[1] = Double.parseDouble(display.getText());
String t1 = Double.toString(temporary[0]);
String t2 = Double.toString(temporary[1]);
try {
if(t1.contains("-")) {
String[] t3 = t1.split("-", 2);
temporary[0] = (Double.parseDouble(t3[1]) * -1);
}
if(t2.contains("-")) {
String[] temp11 = t2.split("-", 2);
temporary[1] = (Double.parseDouble(temp11[1]) * -1);
}
} catch(ArrayIndexOutOfBoundsException e) {
}
try {
if(function[2] == true)
result = temporary[0] * temporary[1];
else if(function[3] == true)
result = temporary[0] / temporary[1];
else if(function[0] == true)
result = temporary[0] + temporary[1];
else if(function[1] == true)
result = temporary[0] - temporary[1];
else if(function[4] == true)
result = Math.pow(temporary[0],temporary[1]);
  
display.setText(Double.toString(result));
for(int i = 0; i < 5; i++)
function[i] = false;
} catch(NumberFormatException e) {
}
}
  
public final void setDesign() {
try {
UIManager.setLookAndFeel(
"com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
} catch(Exception e) {
}
}
  
@Override
public void actionPerformed(ActionEvent ae) {
if(ae.getSource() == button[0])
display.append("7");
if(ae.getSource() == button[1])
display.append("8");
if(ae.getSource() == button[2])
display.append("9");
if(ae.getSource() == button[3]) {
//add
temporary[0] = Double.parseDouble(display.getText());
function[0] = true;
display.setText("");
}
if(ae.getSource() == button[4])
display.append("4");
if(ae.getSource() == button[5])
display.append("5");
if(ae.getSource() == button[6])
display.append("6");
if(ae.getSource() == button[7]) {
//subtract
temporary[0] = Double.parseDouble(display.getText());
function[1] = true;
display.setText("");
}
if(ae.getSource() == button[8])
display.append("1");
if(ae.getSource() == button[9])
display.append("2");
if(ae.getSource() == button[10])
display.append("3");
if(ae.getSource() == button[11]) {
//multiply
temporary[0] = Double.parseDouble(display.getText());
function[2] = true;
display.setText("");
}
if(ae.getSource() == button[12])
display.append(".");
if(ae.getSource() == button[13]) {
//divide
temporary[0] = Double.parseDouble(display.getText());
function[3] = true;
display.setText("");
}
if(ae.getSource() == button[14])
clear();
if(ae.getSource() == button[15])
getSqrt();
if(ae.getSource() == button[16])
getPosNeg();
if(ae.getSource() == button[17])
getResult();
if(ae.getSource() == button[18])
display.append("0");
if(ae.getSource() == button[19]) {
temporary[0] = Double.parseDouble(display.getText());
function[4] = true;
display.setText("");
getResult();
}
if(ae.getSource() == button[20])
getFactorial();
if(ae.getSource() == button[21])
getExponent();
}
  
public static void main(String[] arguments) {
Calculator c = new Calculator();
}
}

Explanation / Answer

Java Input and Output (I/O)

Here it is:

Integer input

Getting data from the user isn't so hard after all. But, it does require some additional work. There may be even more work to do, if you want to get an integer (or other numeric value) from the user. If the user types in "123", that will be still be returned as a String object by the nextLine method of Scanner. You will need to parse (convert) the String object into an int value if you wish to store it in an int variable or data member. Here's one way to do this:

Here's another way to do this:

As you can see, the Scanner class contains a method named nextInt that returns the next input data available as an int value, that is, if the next input in the input stream is a valid integer format.   If the next input is not a valid integer format, an InputMismatchException is thrown.

You may be wondering why are there two ways to read integers from the user. This flexibility allows you, the programmer, the option of which form is best for your program. The correct form to use depends upon what you wish to do with the rest of the line that remains after an integer is read from the current input line. The first example should be used if the only thing available on the current input line is the integer value. The second example should be used if there are multiple data values to read on the same input line.

What if the user types letters instead of digits?

The parseInt method declares that it may throw a NumberFormatException. If the user types any string of characters that can't be parsed into an int value, a NumberFormatException will be thrown and the program will crash. That can't be a good thing! But, there is something that you as the programmer can do to keep your program from crashing. You can catch the NumberFormatException. If you don't know what an exception is, read about them in Java Exceptions. There is an example on catching a NumberFormatException.

Console Output

We have used System.out.print(...) and System.out.println(...) statements for displaying simple text messages to the user. This is an important output alternative, since graphic user interface (GUI) objects are not readily available in some programming environments. You may of course write your own GUI classes if they're not available, but that is beyond the scope of this course. It is much more likely that you will simply use the available output options of the programming environment that you are working in.

Most programming languages have the ability to display a string of characters to the screen or some other standard display device. We call this console output because the string of characters appears in a console window. The System.out object is an instance of the PrintStream class, which is a type of OutputStream.

Streams

A stream object is used to store information needed to connect a computer program to an input or output device. There is a PrintStream object that adds functionality to output streams. The PrintStream class extends the OutputStream class and contains definitions for all of the versions of the print and println methods that we use to display information like user prompts or results of calculations.

Console output in Java is very easy because the print and println methods will work with any type of data.   There is a separate version of each of these methods in the PrintStream class so that this is possible. There is also a version of the print and println methods that will print information for any object. But, how did we get a PrintStream object in the first place?

The java.lang.System class creates three different I/O streams automatically for us when our application begins execution. Each of these streams is public and static so that we can access them directly without having to create an instance of the System class. We have already used the InputStream object named System.in in the discussion on console input. The other two stream objects are named System.out and System.err. Each of these objects is an instance of the PrintStream class and is available for use in displaying information to the computer screen.

For example, if the following variables are defined,

they can all be printed using print or println as follows:

We can also print other types of data, including other objects, using the print and println methods. The following code fragment shows the command syntax for printing a Wanderer object. The class name Wanderer is used as an example. You can replace Wanderer with any class name that is defined in your program.

    Wanderer wanderer1 = new Wanderer( "Wilma", Color.orange );
    System.out.println( wanderer1 );

In this case, the program prints out some cryptic information about the Wanderer object. It is the class name, an @ symbol and the hexidecimal representation of the hashcode. The output looks like the following for the first Wanderer object I created.

    Wanderer@13fac

Each object created has its own hashcode that can be used to distinguish it from other objects. However, hashcodes are not very readable for most users, so there is a way for the programmer to redefine what information is printed. The information that is displayed when an object is printed using the print method is defined by an instance method named toString. Every class has a version of the toString method already defined that returns the information as described above. All classes inherit this method from the java.lang.Object class.

To redefine the toString method, you override the default version by defining a method with the same visibility and method signature as the inherited version of the method. The toString method of my Wanderer class can be overridden as follows:

Now, when the print or println method is used to print a Wanderer object, the new version of the toString method will be called instead of the version defined in the Object class. The String that is printed by the println method will look something like this:

    Wilma is at (11,3)

Each class can (and should!) override the toString method to return a String of characters that is more descriptive of the object than the default version provided by the Object class. This method can be called by any method that needs a String that describes the object.

The print or println methods of the PrintStream class should be adequate to produce most screen output. The only other type of output we will cover in this course is file output. Other output devices require more specialized output objects and won't be covered in this course.

File Input

As mentioned above, data can be read from a variety of different sources, including data files stored on devices such as hard disk drives and floppy drives. The file will need to be opened and a Scanner will be attached to the file object. The process is actually very similar to the console input example above. The difference is that the Scanner will be created from a File object instead of an InputStream object. This section focuses on inputting characters rather than data bytes.

The discussion and examples in this document explain the procedure when the file to be read is a text file that has valid ASCII characters to represent the data. There is one new Java I/O class to learn about:

You will also have to inform the compiler that you are calling a method that may cause a checked exception to occur. Creating a Scanner object from a File object may cause a FileNotFoundException. This is a checked exception, so be sure to catch the exception or add the throws FileNotFoundException clause to the method header. (Since FileNotFoundException is a subclass of IOException, you could put throws IOException in the method header instead of throws FileNotFoundException.) See the Java Exceptions web page for more information on handling checked exceptions.

Here's a code fragment to illustrate reading a text file:

File Input Hints

Parsing strings with split

When you are reading data into your program from a text file, you may need to interpret certain parts of each line differently. This is especially true if you need your program to create objects from text data contained in a file. Individual data items can be placed on different lines of the input data file, but this creates very long files. It is common to place all of the data items for one object on the same line and separate each item with some special character, called a delimiter. In this type of data file, each line of the file represents one record or one object. When you read in from this type of data file, you will need to read in each line of input (as a string of characters) and then divide up that string into its component pieces. This process of dividing up is called parsing. First, some definitions:

parsing

dividing a string into tokens based on the given delimiters

token

one piece of information, a "word"

delimiter

one (or more) characters used to separate tokens

Anytime you have a situation where strings contain multiple pieces of information (for example, when reading in data from a file on a line-by-line basis), then you will need to parse (i.e., divide up) the string to extract the individual pieces.

Parsing Strings in Java

Strings in Java can be parsed using the split method of the String class. ( StringTokenizer can also be used to parse a string; we won't be covering it here). This just gives a brief overview (and some examples) of some of the common (and easiest) ways to use the split method; for more detailed information see the Java API documentation for split.

Issues to consider when parsing a string:

When there is just one character used as a delimiter

Example 1

You want to divide up a phrase into words where spaces are used to separate words. For example

In this case, you have just one delimiter (space) and consecutive delimiters (i.e., several spaces in a row) should be treated as one delimiter. To parse this string in Java, you do

Note that

Example 2

Suppose each string contains an employee's last name, first name, employee ID#, and the number of hours worked for each day of the week, separated by commas. So

represents an employee named Katie Smith, whose ID was 3014, and who worked 8.25 hours on Monday, 6.5 hours on Tuesday, 10.75 hours on Friday, and 8.5 hours on Saturday. In this case, you have just one delimiter (comma) and consecutive delimiters (i.e., more than one comma in a row) should not be treated as one. To parse this string, you do

After this code executes, the tokens array will contain ten strings (note the empty strings): "Smith", "Katie", "3014", "", "8.25", "6.5", "", "", "10.75", "8.5"

There is one small wrinkle to be aware of (regardless of how consecutive delimiters are handled): if the string starts with one (or more) delimiters, then the first token will be the empty string ("").

When there are several characters being used as delimiters

Example 3

Suppose you have a string containing several English sentences that uses only commas, periods, question marks, and exclamation points as punctuation. You wish to extract the individual words in the string (excluding the punctuation). In this situation you have several delimiters (the punctuation marks as well as spaces) and you want to treat consecutive delimiters as one

All you had to do was list all the delimiter characters inside the square brackets ( [ ] ).

Example 4

Suppose you are representing arithmetic expressions using strings and wish to parse out the operands (that is, use the arithmetic operators as delimiters). The arithmetic operators that are allowed are addition (+), subtraction (-), multiplication (*), division (/), and exponentiation (^) and parentheses will not be allowed (to make it a little simpler). This situation is not as straight-forward as it might seem. There are several characters that have a special meaning when they appear inside [ ]. These characters are: ^ - [ and two &s in a row(&&). In order to use one of these characters, we need to put \ in front of the character:

General template for using split

File Output

Writing data to a file is similar to writing data to the screen. You will open a file for writing and then print to that file any data that you would like to store there. You must remember to close the file or risk having some data not be written and saved to the file. We will use of the java.io.PrintStream class for file output.

When you intend to write data to a file, you should consider what is the appropriate action to take if the file already exists. The safest option is to ask the user what to do, and then allow the user to choose overwrite the file, choose a different filename, or cancel the operation. The example shown below assumes that the file opened by the PrintStream object will be overwritten if it already exists. If you do not want to overwrite the file if it already exists, then you must create and test a File object first. The exists method of the File class will return true if the file already exists.

The nice thing about using a PrintStream object is that you are already familiar with the print and println methods that are defined for all PrintStream objects. One important thing to be aware of when doing file output using a PrintStream is that it does not do automatic line flushing. When writing information to a file, it is more efficient to wait until there is a bunch of information to write and then write it all at once than to write one piece of information to the file, then write the next piece, and so on. This process is call buffering the place where the information is stored until it gets written to the file is called the data buffer, or just buffer. When the buffer gets sufficiently full, the buffer is flushed and the information in the buffer is written to the file. If something "bad" should happen before the buffer has been flushed (for example, the program crashes), then the information in the buffer is lost and the file will not contain all the information that you may expect it to. However, even though calls to print and println won't automatically flush the buffer, we can force the buffer to flush by calling the flush method (or by closing the file using the close method). You should always flush the buffer before your code calls another method and you should always remember to close your files in order to prevent losing information.

Here's an example file output:

Java Input and Output (I/O)

Introduction

Input is any information that is needed by your program to complete its execution. There are many forms that program input may take. Some programs use graphical components like a popup dialog box to accept and return the character string that is typed by the user. You are certainly familiar with programs that are controlled simply by clicking the mouse in a specific area of the screen. Still other programs, like word processing programs, get some of their input from a file that is stored on the computer's floppy or hard disk drive. Some programs, like web browsers, get their data from a network connection, while others get data from devices like scanners, digital cameras and microphones. The possibilities are limited only by computer scientists' imagination.

Output is any information that the program must convey to the user. The information you see on your computer screen is being output by one or more programs that are currently running on your computer. When you decide to print a document, a program is told to send some output to the printer. Any sound that your computer makes is because some program sent output to the speakers on your computer. The possibilities for program output are also limited only by our imaginations.

Throughout the semester, we have been performing input and through the use of a Scannerobject connected to System.in and output through the use of a PrintStream object (System.out).

There are several potential error conditions that may occur when a program needs to get input from the user. If a user enters letters when a program is expecting numbers, an exception (error) will occur if the program assumes incorrectly that it has a valid integer to use in calculations. Programs must be written to survive bad input by the user. One way to do this is to ensure that only valid input is accepted.

Standard Java classes do not ensure that only valid input is accepted. They are designed to be very flexible to support the wide variety of input and output options available now and in the future. This flexibility comes at the cost of increased complexity.

Console Input

The console window is the window that is automatically launched when you run a program from within Eclipse. Console input is any input that is entered in the console window instead of typing it into a field or dialog box that pops up in a window. For example, when the nextLine method is called, the program waits for the user to enter information. Whatever the user types is returned to the program in the form of a String object.

There are many ways to get information from the user. In many cases, the user must be told that they should enter some information. This is known as prompting the user. A user prompt is a line of text that is output to the user that explains what information they should input next. We can prompt the user by displaying information in a dialog box, a program frame, or even the console window. All programs that require the user to input information while the program is running must prompt the user for that information in some manner.

When a program is waiting for input at the console, there is sometimes a blinking cursor in the console window indicating that the user should type some information. But, this is not always the case. The user will only know what information to type if the program describes that information in the form of a user prompt. (See Console Output for more information on user prompts.)

The use of several of the Java I/O classes may be required to successfully receive input that is typed by the user. The java.io package contains most, if not all, of the classes you will need to use. The java.util package also contains some classes that are useful for input and output. Don't worry, you won't need to use all 50+ classes. But, you will need to learn about and use at least a couple of them. Either use the fully qualified name shown or import the specified package to use either of these classes.

The Scanner class has a method called nextLine that returns a line of text as typed by the user. There are two available constructors for creating a Scanner object. For console input, we will use the one that requires only one argument, an instance of an InputStream object.

We will use the System.in object as our InputStream object and then use that object to create an instance of the Scanner class.

Steps for console based user input:

Would you like to see some code? I thought so. Here it is:

That's a lot of code for one line of input. Is there a shorter way?

Yes. Subtle bugs are introduced into your program when you connect more than one Scannerobject to the single InputStream object System.in. So, Java programmers create only one instance of the Scanner connected to System.in for use throughout their entire program. All keyboard operations will use that single shared Scanner object. The code below is placed with other class data members and is not inside any method.

I added the above code to my program and I get compiler errors!

Did you remember to import the java.util.Scanner class? The Scanner class is not in the standard java.lang package. You must import the java.util.Scanner class to declare and create instances of the Scanner class. You must import the java.io package to declare and create instances of any of the other Java I/O classes discussed in this document.   It's easiest to add the import java.util.*; statement (and, if you are using the other Java I/O classes, the import java.io.*; statement) to your list of other import statements. Here's a complete program example that prompts the user for input and then repeats that data to the console window:

Integer input

Getting data from the user isn't so hard after all. But, it does require some additional work. There may be even more work to do, if you want to get an integer (or other numeric value) from the user. If the user types in "123", that will be still be returned as a String object by the nextLine method of Scanner. You will need to parse (convert) the String object into an int value if you wish to store it in an int variable or data member. Here's one way to do this:

Here's another way to do this:

As you can see, the Scanner class contains a method named nextInt that returns the next input data available as an int value, that is, if the next input in the input stream is a valid integer format.   If the next input is not a valid integer format, an InputMismatchException is thrown.

You may be wondering why are there two ways to read integers from the user. This flexibility allows you, the programmer, the option of which form is best for your program. The correct form to use depends upon what you wish to do with the rest of the line that remains after an integer is read from the current input line. The first example should be used if the only thing available on the current input line is the integer value. The second example should be used if there are multiple data values to read on the same input line.

What if the user types letters instead of digits?

The parseInt method declares that it may throw a NumberFormatException. If the user types any string of characters that can't be parsed into an int value, a NumberFormatException will be thrown and the program will crash. That can't be a good thing! But, there is something that you as the programmer can do to keep your program from crashing. You can catch the NumberFormatException. If you don't know what an exception is, read about them in Java Exceptions. There is an example on catching a NumberFormatException.

Console Output

We have used System.out.print(...) and System.out.println(...) statements for displaying simple text messages to the user. This is an important output alternative, since graphic user interface (GUI) objects are not readily available in some programming environments. You may of course write your own GUI classes if they're not available, but that is beyond the scope of this course. It is much more likely that you will simply use the available output options of the programming environment that you are working in.

Most programming languages have the ability to display a string of characters to the screen or some other standard display device. We call this console output because the string of characters appears in a console window. The System.out object is an instance of the PrintStream class, which is a type of OutputStream.

Streams

A stream object is used to store information needed to connect a computer program to an input or output device. There is a PrintStream object that adds functionality to output streams. The PrintStream class extends the OutputStream class and contains definitions for all of the versions of the print and println methods that we use to display information like user prompts or results of calculations.

Console output in Java is very easy because the print and println methods will work with any type of data.   There is a separate version of each of these methods in the PrintStream class so that this is possible. There is also a version of the print and println methods that will print information for any object. But, how did we get a PrintStream object in the first place?

The java.lang.System class creates three different I/O streams automatically for us when our application begins execution. Each of these streams is public and static so that we can access them directly without having to create an instance of the System class. We have already used the InputStream object named System.in in the discussion on console input. The other two stream objects are named System.out and System.err. Each of these objects is an instance of the PrintStream class and is available for use in displaying information to the computer screen.

For example, if the following variables are defined,

they can all be printed using print or println as follows:

We can also print other types of data, including other objects, using the print and println methods. The following code fragment shows the command syntax for printing a Wanderer object. The class name Wanderer is used as an example. You can replace Wanderer with any class name that is defined in your program.

    Wanderer wanderer1 = new Wanderer( "Wilma", Color.orange );
    System.out.println( wanderer1 );

In this case, the program prints out some cryptic information about the Wanderer object. It is the class name, an @ symbol and the hexidecimal representation of the hashcode. The output looks like the following for the first Wanderer object I created.

    Wanderer@13fac

Each object created has its own hashcode that can be used to distinguish it from other objects. However, hashcodes are not very readable for most users, so there is a way for the programmer to redefine what information is printed. The information that is displayed when an object is printed using the print method is defined by an instance method named toString. Every class has a version of the toString method already defined that returns the information as described above. All classes inherit this method from the java.lang.Object class.

To redefine the toString method, you override the default version by defining a method with the same visibility and method signature as the inherited version of the method. The toString method of my Wanderer class can be overridden as follows:

Now, when the print or println method is used to print a Wanderer object, the new version of the toString method will be called instead of the version defined in the Object class. The String that is printed by the println method will look something like this:

    Wilma is at (11,3)

Each class can (and should!) override the toString method to return a String of characters that is more descriptive of the object than the default version provided by the Object class. This method can be called by any method that needs a String that describes the object.

The print or println methods of the PrintStream class should be adequate to produce most screen output. The only other type of output we will cover in this course is file output. Other output devices require more specialized output objects and won't be covered in this course.

File Input

As mentioned above, data can be read from a variety of different sources, including data files stored on devices such as hard disk drives and floppy drives. The file will need to be opened and a Scanner will be attached to the file object. The process is actually very similar to the console input example above. The difference is that the Scanner will be created from a File object instead of an InputStream object. This section focuses on inputting characters rather than data bytes.

The discussion and examples in this document explain the procedure when the file to be read is a text file that has valid ASCII characters to represent the data. There is one new Java I/O class to learn about:

You will also have to inform the compiler that you are calling a method that may cause a checked exception to occur. Creating a Scanner object from a File object may cause a FileNotFoundException. This is a checked exception, so be sure to catch the exception or add the throws FileNotFoundException clause to the method header. (Since FileNotFoundException is a subclass of IOException, you could put throws IOException in the method header instead of throws FileNotFoundException.) See the Java Exceptions web page for more information on handling checked exceptions.

Here's a code fragment to illustrate reading a text file:

File Input Hints

Parsing strings with split

When you are reading data into your program from a text file, you may need to interpret certain parts of each line differently. This is especially true if you need your program to create objects from text data contained in a file. Individual data items can be placed on different lines of the input data file, but this creates very long files. It is common to place all of the data items for one object on the same line and separate each item with some special character, called a delimiter. In this type of data file, each line of the file represents one record or one object. When you read in from this type of data file, you will need to read in each line of input (as a string of characters) and then divide up that string into its component pieces. This process of dividing up is called parsing. First, some definitions:

parsing

dividing a string into tokens based on the given delimiters

token

one piece of information, a "word"

delimiter

one (or more) characters used to separate tokens

Anytime you have a situation where strings contain multiple pieces of information (for example, when reading in data from a file on a line-by-line basis), then you will need to parse (i.e., divide up) the string to extract the individual pieces.

Parsing Strings in Java

Strings in Java can be parsed using the split method of the String class. ( StringTokenizer can also be used to parse a string; we won't be covering it here). This just gives a brief overview (and some examples) of some of the common (and easiest) ways to use the split method; for more detailed information see the Java API documentation for split.

Issues to consider when parsing a string:

When there is just one character used as a delimiter

Example 1

You want to divide up a phrase into words where spaces are used to separate words. For example

In this case, you have just one delimiter (space) and consecutive delimiters (i.e., several spaces in a row) should be treated as one delimiter. To parse this string in Java, you do

Note that

Example 2

Suppose each string contains an employee's last name, first name, employee ID#, and the number of hours worked for each day of the week, separated by commas. So

represents an employee named Katie Smith, whose ID was 3014, and who worked 8.25 hours on Monday, 6.5 hours on Tuesday, 10.75 hours on Friday, and 8.5 hours on Saturday. In this case, you have just one delimiter (comma) and consecutive delimiters (i.e., more than one comma in a row) should not be treated as one. To parse this string, you do

After this code executes, the tokens array will contain ten strings (note the empty strings): "Smith", "Katie", "3014", "", "8.25", "6.5", "", "", "10.75", "8.5"

There is one small wrinkle to be aware of (regardless of how consecutive delimiters are handled): if the string starts with one (or more) delimiters, then the first token will be the empty string ("").

When there are several characters being used as delimiters

Example 3

Suppose you have a string containing several English sentences that uses only commas, periods, question marks, and exclamation points as punctuation. You wish to extract the individual words in the string (excluding the punctuation). In this situation you have several delimiters (the punctuation marks as well as spaces) and you want to treat consecutive delimiters as one

All you had to do was list all the delimiter characters inside the square brackets ( [ ] ).

Example 4

Suppose you are representing arithmetic expressions using strings and wish to parse out the operands (that is, use the arithmetic operators as delimiters). The arithmetic operators that are allowed are addition (+), subtraction (-), multiplication (*), division (/), and exponentiation (^) and parentheses will not be allowed (to make it a little simpler). This situation is not as straight-forward as it might seem. There are several characters that have a special meaning when they appear inside [ ]. These characters are: ^ - [ and two &s in a row(&&). In order to use one of these characters, we need to put \ in front of the character:

General template for using split

File Output

Writing data to a file is similar to writing data to the screen. You will open a file for writing and then print to that file any data that you would like to store there. You must remember to close the file or risk having some data not be written and saved to the file. We will use of the java.io.PrintStream class for file output.

When you intend to write data to a file, you should consider what is the appropriate action to take if the file already exists. The safest option is to ask the user what to do, and then allow the user to choose overwrite the file, choose a different filename, or cancel the operation. The example shown below assumes that the file opened by the PrintStream object will be overwritten if it already exists. If you do not want to overwrite the file if it already exists, then you must create and test a File object first. The exists method of the File class will return true if the file already exists.

The nice thing about using a PrintStream object is that you are already familiar with the print and println methods that are defined for all PrintStream objects. One important thing to be aware of when doing file output using a PrintStream is that it does not do automatic line flushing. When writing information to a file, it is more efficient to wait until there is a bunch of information to write and then write it all at once than to write one piece of information to the file, then write the next piece, and so on. This process is call buffering the place where the information is stored until it gets written to the file is called the data buffer, or just buffer. When the buffer gets sufficiently full, the buffer is flushed and the information in the buffer is written to the file. If something "bad" should happen before the buffer has been flushed (for example, the program crashes), then the information in the buffer is lost and the file will not contain all the information that you may expect it to. However, even though calls to print and println won't automatically flush the buffer, we can force the buffer to flush by calling the flush method (or by closing the file using the close method). You should always flush the buffer before your code calls another method and you should always remember to close your files in order to prevent losing information.

Here's an example file output: