Applet Input
Prerequisites: Read carefully chapter 2 of your textbook. Answer the Review questions at the end of the chapter. Be able to write, run, debug, save, and load a simple Java program in Jbuilder. Know the basic output statements of a Java Applet and how an applet works.
At the end of this lesson you should be able to:
- Get simple input from the user from a Java Applet
- Put that input into the different types in Java
- Know the difference between Java 1.0 and 1.1 or later
- Make and use Java constants
- Do type conversions in Java
- Do string manipulations in Java
- Produce a simple text word processor
Make a new Java Project in Jbuilder. Call it InputProj and input any other info you want in the dialog box. See the previous lessons if you have forgotten how to do this. You will be looking at the html file for your project. Select New and double click on the Applet Icon. Erase the package text and enter Input for the Class name. Your screen should now look like:
Click on Finish. Erase the default code in the Input.java file and replace it with the following code:
import java.applet.Applet; import java.awt.*;
public class Input extends Applet { String n;
Label lab1; TextField t1;
public void init() { lab1 = new Label("Enter a name"); add(lab1); t1 = new TextField(); add(t1); }
public void paint(Graphics g) { g.drawString("Hello "+n,10,100); }
public boolean action(Event e,Object o) { n = t1.getText(); repaint(); return true; } }
Run this program. It should allow you to enter text into the textbox. When you press the Enter key, the name you enter is placed after the word Hello on the screen below the textbox. Before you run the program, you may see ‘Hello null’ on your browser. If you do not get this performance, check your program. Lets see what is happening.
Remember, an applet runs the init method first, then the start method (which we do not have) and then the paint method. After these 3 methods, the program is finished, unless the user does something. The user can do some event that Java will respond to. This usually takes place in the action method for Java 1.0, although you saw in the last lesson that we caught a mouse movement event in another method. Why mess with Java 1.0? It does run on older browsers than 1.1, but this is hardly a problem anymore. The reason we will play with 1.0 sometimes is that it is simpler than 1.1 and the Java logic remains the same. I will give you the 1.1 code a bit later..
Tracing through the code then, we import the applet and awt packages, then come to this code:
public class Input extends Applet { String n;
Label lab1; TextField t1;
Here we are defining our class and telling the compiler that it is an Applet. What follows in the Data part of the class. We are making 3 data items, the Label and the TextField you have seen before. String n; is new. We are making a container (or Variable) into which we can place a word. You can read this as making an object called n that is of Class String. This is a bit misleading, because String is a special class that, unlike other Java classes, does not need a call to new before we can use it (see the init methods in this code). So.. what we have done is to define what data is being used in the class, the top of the 3 parts of a class discussed earlier.
What follows in the code is the init method. Even if it was NOT next in the code, however, it would still be executed next (Why?). Its code:
public void init() { lab1 = new Label("Enter a name"); add(lab1); t1 = new TextField(); add(t1); }
should look familiar. We are making an object called lab1 and the new is making the object in the computers memory. When we make t1 we are using the default constructor. Remember the constructor is the code that makes the object, and is found in the class Label and TextField in this case. In Jbuilder, click on the word TextField in your code, then press the F1 key. You will go to Help and see info about the TextField class. Note what classes it ‘inherits’ from.. (Object, Component, and TextComponent). Now scroll down in the window until you see the following:
Note that the TextField class has 4 constructors. We called the first one, since there was nothing in the () in the line: t1 = new TextField(); Try changing this line to: t1=new TextField(10); Now we are using the second constructor. Try it. What happens?
Now comes the paint method, since there is no start method in this program. public void paint(Graphics g) { g.drawString("Hello "+n,10,100); } This should look familiar, but what about the ‘+n’… We are telling the computer to print the word Hello and then what is in the container (or Variable) called n. You have seen the + symbol before (concat). We will put the entire message 10 over and 100 down on the Applet window. BUT… Where does the value of n come from? Good question! In fact, it does not have a value when it first executes. That is why you will see Hello null when you click in the box. Nothing is another word for null. The container is empty. How do we give it a value? In the action method.
public boolean action(Event e,Object o) { n = t1.getText(); repaint(); return true; } The name of the method is action. Notice the word Boolean before the word action. It says that this method ‘returns’ a Boolean value after it finishes. We will find out more about this later when we write our own methods. Notice the return true; line at the end of the code. This is where the Boolean value (true or false) is returned. Note that the init and paint methods have the word void in front of them. Void means that there IS no returned value. You can pretty much let this go for now, but the action method requires this format. The first line in the code: n = t1.getText(); is the heart of the code. It says to call the getText() method for the object t1 (a TextField) and put the returned value into the container n that we declared earlier as a String. Then we call the repaint() method that just clears the applet screen and runs the paint method again, but this time with the value for n.
But… when does the computer know when to call the action method? When an event occurs. Huh?? Try running the program again. Instead of entering a name in the box, click your mouse anywhere on the screen. Try typing some keys (other than Enter). Nothing happens. But did you not just do something? Why was action not called? Because action only is called from an event on an Object in the applet, and the only object capable of making an event in this program is t1, the TextField object. AND.. the only event it produces is the Enter event when you hit the Enter key after typing in some text. When you do, you go to action and from there back to paint. Later we will see how to listen to a particular object (like a button or Listbox) and to a particular event (like a keypress or mouseclick). For now, we can use this to get input from the user. Lets see the same program in Java 1.1.
import java.applet.Applet; import java.awt.*; import java.awt.event.*;
public class Input extends Applet implements ActionListener { String n; Label lab1; TextField t1;
public void init()
{
lab1 = new Label("Enter a name"); add(lab1); t1 = new TextField(10); add(t1); t1.addActionListener(this); }
public void paint(Graphics g) { g.drawString("Hello "+n,10,100); }
public void actionPerformed(ActionEvent e) { n = t1.getText(); repaint(); } }
Cut, Paste, and Run this program. Fix typos if you get them in the cutting process. Notice the few changes in 1.1. You need to import java.awt.event.*, which was added in 1.1. You need to implement ActionListener, which allows you to tell the computer which objects will produce events, which you do by the addActionListener(this) statement. Notice the action vs actionPerformed syntax. The code is similar but 1.0 is a bit simpler. We will do some examples in each, but you can make the needed tweaks to change between the two if you like. Try to do this on some of the following code examples.
NUMBER INPUT:
Run the above program again, only enter numbers instead of a name. You will get ‘Hello 123’ if you put 123 in the textbox. Looks like you can enter a number in the box as well as text. But wait… Change the code in actionPerformed in the example above to:
public void actionPerformed(ActionEvent e) { n = t1.getText(); n = n + 1; repaint(); } You would expect that if you run this program and enter a 3, you will get a 4 for output. You will not. You will get 31, because the 1 is concatenated, not added! The problem? The statement: n = t1.getText() calls the getText method which returns Text, which is another name for a String. We need to turn the String into a number! How can we? First, we need to make a container to hold a number. Lets make one for an integer first, which is just a whole number without decimals. To make an integer container (or Variable) go back to the start of the program where you make your data. Change: String n; Label lab1; TextField t1;
now add below the TextField t1 line this line:
int num;
We have made an integer container called num of the type integer. Note that int is not capitalized ( it is not Int num). This is a hint that int is not a class- remember that all classes should start with capital letters. Instead it is a data type. The difference? Unlike a class which has data, constructor, and methods, a type only has data. In this case, only the data to hold an integer. This saves space. Read in your text about the different data types such as double, float, char, and boolean. Now we want to input a value into this integer container. Change actionPerformed to:
Make this change to actionPerformed:
public void actionPerformed(ActionEvent e) { num = Integer.parseInt(t1.getText()); num = num + 1; showStatus(String.valueOf(num); repaint(); }
Run this program. It does not work quite right, but it is close. Note the correct number is displayed (via showStatus) in the bottom left corner of the screen. It does not appear next to Hello as you might expect. Problem? Can you find it?? Check paint. Change n to num. Try this. Now, lets see what is happening. num = Integer.parseInt(t1.getText()); This line turns the text that is produced in t1.getText() into an integer. Integer (note this is a class as it starts with a capital I) has a method called parseInt that takes a string and turns it into an integer. We can then put this value into the num container. This is how you read the ‘=’ ( or assignment) statement in Java: Take the value on the right hand side of the = and place it in the container on the right side of the =. For example, x = 3 + 4 would take what is on the right side (3 + 4), figure out what it is (7) and place the results into the container on the left. 5 = x + 1 makes no sense ( 5 is not a container, it is a value), x + 1 = 4 makes no sense (why?) Know how to read an assignment statement.
Once we have a value for num, we can add 1 to it, since it is an integer. Notice the + does two different things depending on what it is applied to. If it is between Strings it concats. If it is between numbers it adds. This is called operator overloading, and is a major idea in Object Oriented Programming.
Run the program again. Now type fred into the textbox and hit Enter. Nothing happens. Well, not quite. Behind the white AppletViewer screen there is a black DOS window. Look at this window. You will see something like the following:
I changed the name of my applet to Input2 for kicks.. This shows a list of error messages sent to the Java Virtual Machine (JVM) that interprets the .class file you compile from the .java. The sin here is that we cannot put ‘fred’ into an integer container. This is called strong TYPING. The C language, for example, would let you put a word into an integer and it would not complain. This is handy in some cases, but it usually is a big pain, because a RUNTIME ERROR is much harder to debug than a COMPILE TIME ERROR. Why? A Runtime error does not show you WHERE the problem is. Try running the program again and enter 3.456 in the textbox. Again you get an error. We can’t put a decimal number into an integer. What is we want to input a decimal number? Then we make an integer container.
In the top of your program, just below the line: int num; enter this line: double d; Now change actionPerformed to the following:
public void actionPerformed(ActionEvent e) { d = Double.parseDouble(t1.getText()); d = d + 1; showStatus(String.valueOf(d)); repaint(); }
Run this program. It works for the showStatus, but not the Hello.. Why? Check above and fix it. See if you can add 1.7 instead of 1 to each input value.
ENTERING 2 VALUES:
Cut and paste the follwing code:
import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
public class Input extends Applet implements ActionListener
{
Label lab1;
TextField t1,t2;
int num;
double d;
public void init()
{
lab1 = new Label("Enter an the quantity and price");
add(lab1);
t1 = new TextField(5);
add(t1);
t2 = new TextField(10);
add(t2);
t2.addActionListener(this);
}
public void paint(Graphics g)
{
g.drawString("The quantity is " + num + " and the cost is " + d ,10,100);
}
public void actionPerformed(ActionEvent e)
{
num = Integer.parseInt(t1.getText());
d = Double.parseDouble(t2.getText());
repaint();
}
}
Run this code. Enter integers for the first box and a decimal number for the second. See if you can figure out this code. Note that only the second textbox has the ActionsListener (find this) This means that if you hit return for the first textbox nothing happens, since the first textbox (t1) is not listening for anything. Also note you get error messages if you input non-numbers in the box or a decimal number in the first box. BUT.. If you enter an integer in the second number, everything is fine. Why? A double has enough memory to hold an integer, so it allows you to enter an integer and changes it (coersion) into a double. Can we change a double into an integer? Yes. Change actionPerformed to:
public void actionPerformed(ActionEvent e) { num = (int) Double.parseDouble(t1.getText()); d = Double.parseDouble(t2.getText()); repaint(); }
Here we get a Double number with Double.parseDouble, but we CAN put it into an integer container, in this case num, by coersing it. The (int) statement allows this to happen. It strips all the decimals from the number, thus allowing to be but into an integer. Remember this, you will need it later..
CONSTANTS:
Variable allow the user to enter values into these containers and they can change throughout the program. Constants are set by the user and cannot change. Under the line: double d; in your program, enter the following line: final double tax = 1.05; Now change actionPerformed to:
public void actionPerformed(ActionEvent e) { num = (int) Double.parseDouble(t1.getText()); d = Double.parseDouble(t2.getText()); d = d * tax; repaint(); }
The word final in the declaration means that the ‘variable’ is FINAL, meaning it cannot change, which makes it a constant. This us useful for values like pi, tax rates, or other things that are set values. You can have String constants. Try adding 1 to tax… tax=tax + 1; No can do.. Why are Constants a good idea. Be ready to discuss at least 3 ways they are useful.
Assignment: You want to make an applet that enters a students name, age, gpa, and year in school (frosh, soph…) When you hit Enter for the year in school, your program will print out the following:
Report for Jim Smith, a student at Lakes HS: This sophomore is 15 years old and has a gpa of 3.21. Next year he will be 16.
Set the name of the school as a constant. Figure the age for the next year. All the bold words come from your textboxes. The next time you run the program input different values. You should get a different report. Put the code for this program and a copy of several runs in your portfolio. Follow the Documentation and Style suggestions given at the end of Chapter 2 of your Text.
|