The following is an adapted lesson in an online course I have for The O'Reilly School of Technology java course.
It is not nearly as nicely formatted as the real lesson, but I cannot give you exactly the same thing for contract reasons. Since I will not cover this material explicitly in this course, I have provided the notes for you to do independently (the entire course is hands-on independently done). Enjoy.

Output: Strings, Fonts and Numbers

The Graphics class provides us with a lot of capabilities, but as is normal, once we get used to having something, we seem to want more! In this lesson, we will look closely at a number of additional classes that Java provides for us in the API. In particular, we will look at some that help us make nicer output for our programs.

Given our expeditions to the API already,
it is clear that there are a multitude of classes at our disposal; each class having a multitude of methods for our use. In this lesson we will touch on a number of useful classes and a few of their capabilities. Hopefully, after this journey, you will feel inspired and confident to do future API searches regularly on your own.

Strings and Things

When you want to write words in your Applets and applications in Java, you need to use the java.lang.String class. Strings are used whenever you want to write something that is more than one character long.

Strings in Java are called immutable. What this means is once you define it, you cannot get inside of it and change characters. An easier way to say this is that Strings are constant: once you create them, their values cannot be changed. But do not get confused. You can "play" with them all you want; you can create new Strings which are manipulations of the specific string, but you just cannot get into the memory location of a defined String and change it there. (Most of you do not care to do this anyway.)

Be assured that, most definately, the String class does allow you to do lots of mutilations and manipulations using Strings!

As stated in the API, the class String includes methods


Let's look at a couple examples.

Investigating Strings

String is a Java class in the java.lang package. Thus when we use String's, we are using instances of the class String.

  1. Go to the API page
  2. Scroll down to the java.lang package. Click on it.
  3. Scroll down to the Class Summary and the class String.
You could also go to pages directly if we give you links: java.lang.String class
  1. Read the introduction to the String Class with its examples.
  2. Skim through the whole API page and look at the method descriptions in the Method Summary
  3. Notice that its Constructor is very overloaded with 15 different possibilities!
  4. Look at the various signatures to make sure that they are all different in some way.
When we have an overloaded method, they must have parameters that are different in either (1) the number of parameters, (2) the type of parameters, or (3) both. Otherwise, it would be ambiguous and Java would not know which one to use.

Strings allow us to put words into our output.
Remember in the HelloWorld Applet, you gave a command:

g.drawString("Hello World!", 5, 15);

Remember also that g was an instance of the Graphics class?
  1. Go to the Graphics class and find the drawString method.
  2. Do you see that there are two? Look at them for anything familiar.
Their signatures are So, the drawString method in Graphics is also overloaded. Which one did Java use for our method call?

 Our call was g.drawString("Hello World!", 5, 15);
 
The parameters inside the parentheses ( ) of the method call are of types: String, int, int
This indicates to Java to use the second one above.

Specifically, it told Java to go to the instance g of Graphics and in that Graphics instance, call the method 
 drawString(String str, int x, int y)  by assigning the values
String str= "Hello World" 
int x=5 
int y= 15
 
 And then, it "draws" the text given by the specified string at position (x, y) in this graphics context. 
 

  1. Go to the method description: drawString(String str, int x, int y).
  2. Look at it now, remembering the knowledge of how you used it
Hopefully all the information there is starting to make more sense! Once you get used to using the API, it will become invaluable to you!

Using Strings

Because Strings are so widely used, the Java programming language also provides special support for them. For example, you do not need to use the new command to make an instance of a String. You can make Strings in the same fashion that you make primitive data types (next lesson). E.G.,

String myNewString = "Java is wonderfully fun";

Also, when you print out strings, you often print out words mixed with variable values.
In order to do this you use concatentation, which means to append one String to another.

Java provides us with the + sign to do this.

Make our first Class in this project:
  1. Type in the code shown below in a file you create named DemoStrings.java

import java.applet.Applet; import java.awt.*; public class DemoStrings extends Applet { public void paint(Graphics g) { int length = 40; int width = 20; g.drawString("The area of a rectangle is the length times the width", 10, 20); g.drawString("Our width is " + width + " and length is " + length, 10, 40); g.drawString("The area of this rectangle will be " + (width * length), 10, 70); } }

  1. Save it, compile it, and Run it.
  2. You will probably want to expand the applet window with a mouse drag to see everything
Notice the use of concatenation in the lines below.
   Remember that the last two parameters for drawString are the x and y coordinates for placement on the Applet.
   This means that everything before the first comma must be one String ...
     one String possibly the result of concatenations

g.drawString("Our width is " + width +  " and length is " + length, 10, 40);

Notice also the skillful technique of leaving a space after the word "is " before ending the String.
This makes it much nicer to read since the words and numbers are then not appended without spaces.
  (Java does what we say, not what we mean!)

Notice below how you can use math expressions - these will be automatically cast into Strings by Java.
The + concatenates the String output to the result of the arithematic operation. 

g.drawString("The area of this rectangle will be " + (width * length), 10, 70);
Here is an example of a common mistake of Java doing what we say and not what we mean that is rather hard to know happened if you are not careful.
  1. Edit the DemoStrings class's paint method as shown.

import java.applet.Applet; import java.awt.*; public class DemoStrings extends Applet { public void paint(Graphics g) { int length = 40; int width = 20; g.drawString("The area of a rectangle is the length times the width", 10, 20); g.drawString("Our width is " + width + " and length is " + length, 10, 40); g.drawString("The perimeter of this rectangle will be " + 2*width + 2*length, 10, 70); } }

  1. Save it, Compile it, and Run it.
  2. Look carefully at the output.

First, you should always look carefully at your source code and your output when programming.
It is a very useful learning technique!

OK, did we get the correct answer?  No, we most certainly did not.

Why?

Because the first parameter of the Graphics  drawString method is a String
When Java sees a + within something that is supposed to be a String, it concatenates rather than adds.

Java did what we said - it
 took width and times it by 2 then made the result -40- a String since that is what the parameter required
 took the length and times it by 2 then made the result -80- a String since that is what the parameter required             
 it then concatenated these two Strings and got 4080

Since Java understands the precedence rule of "parentheses first", we can fix it easily
  1. Change the line to
    g.drawString("The perimeter of this rectangle will be " + (2*width + 2*length), 10, 70);
  2. Save it, Compile it, and Run it

Manipulating Strings

We can probably come up with something a little more interesting than math for examples of Strings.
  1. Edit the DemoStrings class's paint method as shown.

import java.applet.Applet; import java.awt.*; public class DemoStrings extends Applet { public void paint(Graphics g) { int y=15; String str = "Java is Hot"; // normal String g.drawString(str, 10, y*1); String modify = str.replace("v","bb" ).replace('o', 'u').replace("is", "the"); g.drawString(str.substring(0,7) + " still" + str.substring(7,11), 10, y*2); g.drawString("But used to make: ", 10,y*4); g.drawString(modify + "t", 10, y*5); } }
  1. Save it, Compile it, and Run it.
  2. Look at the code and compare it to the output to see what the methods did
Note how we can manipulate the defined instance str of String, but when doing so, we are making a new String.  
  AND, how the original String stays the same.
Hot Java and fat Jabba
  1. Check out the replace and substring methods of String in the API
  2. Edit DemoStrings as given to check some additional methods

import java.applet.Applet; import java.awt.*; public class DemoStrings extends Applet { public void paint(Graphics g) { int y=15; String str = "Java is Hot"; g.drawString(str, 10, y*1); String java = str.substring(0,4); g.drawString("The method substring - from index 0 to 4 gives: " + java, 10, y*2); String sun = "Sun"; g.drawString(sun, 10, y*4); String str2 = sun + str.substring(4, str.length() ); g.drawString("Concatenation and a substring method call: " + str2, 10, y*5); int len = "HotJava".length(); g.drawString("The length of the string HotJava is: " + len, 10, y*7); String obj = new String("A String is an Object"); g.drawString(obj, 10, y*9); // seeing what it prints when it is accessed as the object String objstr = obj; // setting a String value to another object declared as String g.drawString(objstr, 10, y*10); // no big deal String word = "Mississippi"; g.drawString(word, 10, y*12); g.drawString(word.replace('i','a'), 10, y*13); g.drawString(word.toUpperCase(), 10, y*14); g.drawString("The original word is still: " + word, 10, y*16); } }

  1. Save it, Compile it, and Run it.
  2. Compare the code and the output so see how methods in String work

We will use Strings a lot. Given this, it is nice to be able to make them look like we want.

Fonts

Using word editors, we are pretty familiar with changing fonts, sizes, etc. of words. Java provides us with tools to do so for our programming needs as well. The class Graphics has a setFont(Font font) method, so we can set the font we want in our Graphics area.

The class Font allows you to create the font that you want to use in its Constructors:
Font(String name, int style, int size)

Here is an example:
Font bigFont = new Font("Helvetica", Font.BOLD, 20);

  1. Make a New Class and name it JavaCup.java
  2. Type in the code as shown.

// Code courtesy of Michael D. Lewis import java.applet.*; import java.awt.*; public class JavaCup extends Applet { Font bigFont = new Font("Helvetica", Font.BOLD, 56); Font smallFont = new Font("Helvetica", Font.BOLD, 20); //Make a dark red for o'Reilly School or Technology leaf color private static final Color leafRed = new Color(115, 0, 0); // No brown final value in Color, so make one for coffee private static final Color javaBrown = new Color(90, 40, 0); String line1 = "JAVA"; String line2 = "O'REILLY - Learning"; public void paint(Graphics g) { // draw the main body of the cup g.setColor(Color.gray); g.fillOval(150, 175, 200, 50); g.fillArc(150, 375, 200, 50, 180, 180); g.fillRect(150, 200, 200, 200); // draw the handle of the cup g.setColor(Color.black); g.fillArc(100, 225, 100, 150, 90, 180); g.setColor(Color.white); g.fillArc(115, 240, 70, 120, 90, 180); // draw the coffee as an oval a little smaller than the top g.setColor(javaBrown); g.fillOval(155, 180, 190, 40); // draw the wisp of steam g.setColor(Color.black); g.drawArc(198, 100, 100, 100, 90, 180); g.drawArc(198, 10, 100, 100, 90, 180); g.drawArc(243, 100, 10, 10, 270, 180); // draw 2nd wisp of steam over little bit g.drawArc(202, 100, 100, 100, 90, 180); g.drawArc(202, 10, 100, 100, 90, 180); g.drawArc(247, 100, 10, 10, 270, 180); // draw the text on the cup g.setColor(leafRed); g.setFont(bigFont); g.drawString(line1, 175, 300); g.setFont(smallFont); g.drawString(line2, 153, 330); } }

  1. Save it, Compile it, and Run it.
  2. Make the output Applet window larger to see it all

Changing the Color and Font are pretty easy to do.
Here is another example with a different Font type.
  1. Make another New | Class and name it Burger.java
  2. Type in the code as follows

// Code courtesy of Jason Gibson import java.awt.*; import java.applet.*; public class Burger extends Applet{ public void init() { setBackground(Color.gray); } public void paint(Graphics g) { // Bottom Bun using a tan rounded rectangle Color Bun = new Color(153,102,51); g.setColor(Bun); g.fillRoundRect(10,175,200,25,15,15); // Patty using a brown rectangle set partway down bottom bun Color Patty = new Color(106,53,0); g.setColor(Patty); g.fillRect(10,165,200,15); // Cheese using a 3 stacked yellow lines g.setColor(Color.yellow); g.drawLine(10,164,210,164); g.drawLine(10,163,210,163); g.drawLine(10,162,210,162); // Tomato using a red oval g.setColor(Color.red); g.fillOval(0,154,220,8); // Letuce by a strings of offset green ^'s g.setColor(Color.green); //g.setFont(); g.drawString("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^",11,156); g.drawString("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^",10,153); // Top bun using a filled arch g.setColor(Bun); g.fillArc(10,120,200,50,0,180); // Title using string in black g.setColor(Color.black); Font Title = new Font("TimesRoman",3,28); g.setFont(Title); g.drawString("Homage to Burger Time", 20,25); } }

  1. Save it, Compile it, and Run it.
  2. Again, make the window larger
  1. Go to the Font class and look at its constructors.
  2. In the Burger class, go to the line
    Font Title = new Font("TimesRoman",3,28);
  3. Play with the int parameter values (change them, save, compile, run again) to see what different values give you.
This is an excellent way to play and see what Java does at the same time.
I suppose by now you feel pretty good about using the Graphics area to draw in?!

Numbers

Back to math. Not really.

Although Java does have a Number class in the java.lang package, we will not be looking at it here - it is not what you would think at this point. What we want to show in this section is formatting numbers. We will be investigating the class NumberFormat in the java.text package

instead.
  1. Create a New | Class and name it DemoNumbers.java
  2. Type in the code as shown.

import java.applet.Applet; import java.awt.*; public class DemoNumbers extends Applet { public void paint(Graphics g) { double area; double radius = 40; g.drawString("The area of a circle is its radius squared times Pi", 10, 20); g.drawString("Our radius is " + radius, 10, 40); g.drawString("The area of this circle will be " + Math.PI*radius*radius, 10, 70); } }

  1. Save it, Compile it, and Run it.
  2. Look at its output
Pretty ugly.

Do not despair. We can fix it. We will use the java.text.NumberFormat class to make only 2 decimal places.

  1. Add the code as shown below.

import java.applet.Applet; import java.awt.*; import java.text.NumberFormat; public class DemoNumbers extends Applet { public void paint(Graphics g) { NumberFormat nf = NumberFormat.getInstance(); nf.setMaximumFractionDigits(2); double area; double radius = 40; g.drawString("The area of a circle is its radius squared times Pi", 10, 20); g.drawString("Our radius is " + radius, 10, 40); g.drawString("The area of this circle will be " + nf.format(Math.PI*radius*radius), 10, 70); } }
  1. Save it, Compile it, and Run it.
  2. Look at the new output

Do you like it?

  1. Go to the NumberFormat class in the java.text package to find out more about it.

Another class that Java has availabe for the same purposes is the DecimalFormat class which is also in the java.text package. Actually, it is a subclass of NumberFormat, which indicates that it will perform more "specific" actions. A DecimalFormat comprises a pattern and a set of symbols that you define so your number looks just like you want it to.

  1. Edit the DemoNumber class as shown.

import java.applet.Applet; import java.awt.*; import java.text.DecimalFormat; public class DemoNumbers extends Applet { public void paint(Graphics g) { DecimalFormat myFormat1 = new DecimalFormat("###,###.##"); DecimalFormat myFormat2 = new DecimalFormat("####,###"); double area; double radius = 40; g.drawString("The area of a circle is its radius squared times Pi", 10, 20); g.drawString("Our radius is " + radius, 10, 40); g.drawString("The area of this circle will be " + myFormat1.format(Math.PI*radius*radius), 10, 70); g.drawString("An alternate formatting possibility without the decimals and rounded up", 10, 95); g.drawString("The area of this circle will be " + myFormat2.format(Math.PI*radius*radius), 10, 110); } }

  1. Save it, Compile it, and Run it.
  2. Compare the output to the code to see how it was done

  1. Go to the DecimalFormat class in the java.text package to find out more about it.

Although this looks pretty nice, consider a simple edit where we want to represent money so we want exactly two decimal places again

  1. Edit the DemoNumber class by adding two lines as shown.

import java.applet.Applet; import java.awt.*; import java.text.DecimalFormat; public class DemoNumbers extends Applet { public void paint(Graphics g) { DecimalFormat myFormat1 = new DecimalFormat("###,###.##"); DecimalFormat myFormat2 = new DecimalFormat("####,###"); double area; double radius = 40; double amountOwed = 12.00; g.drawString("The area of a circle is its radius squared times Pi", 10, 20); g.drawString("Our radius is " + radius, 10, 40); g.drawString("The area of this circle will be " + myFormat1.format(Math.PI*radius*radius), 10, 70); g.drawString("An alternate formatting possibility without the decimals and rounded up", 10, 95); g.drawString("The area of this circle will be " + myFormat2.format(Math.PI*radius*radius), 10, 110); g.drawString("The money owed will be " + myFormat1.format(amountOwed), 10, 130); } }

  1. Save it, Compile it, and Run it.
  2. Compare the output to the code to see how it was done

The number was formatted, but since there were no values after the decimal, the given format took them off.

With some things, we want the digits even if they are 0's

We will make it do exactly what we want. We can. We have the power.

  1. Edit the DemoNumber class by adding two lines as shown.

import java.applet.Applet; import java.awt.*; import java.text.DecimalFormat; public class DemoNumbers extends Applet { public void paint(Graphics g) { DecimalFormat myFormat1 = new DecimalFormat("###,###.##"); DecimalFormat myFormat2 = new DecimalFormat("####,###"); DecimalFormat df1 = new DecimalFormat("####.00"); double area; double radius = 40; double amountOwed = 12.00; g.drawString("The area of a circle is its radius squared times Pi", 10, 20); g.drawString("Our radius is " + radius, 10, 40); g.drawString("The area of this circle will be " + myFormat1.format(Math.PI*radius*radius), 10, 70); g.drawString("An alternate formatting possibility without the decimals and rounded up", 10, 95); g.drawString("The area of this circle will be " + myFormat2.format(Math.PI*radius*radius), 10, 110); g.drawString("The money owed will be " + df1.format(amountOwed), 10, 130); } }

  1. Save it, Compile it, and Run it.
  2. Compare the output to the code to see how it was done

Rather than me explaining it to you, I will let the API do it.
You know where to go! Have fun and good luck!