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
- for examining individual characters of the sequence,
- for comparing strings,
- for searching strings,
- for extracting substrings,
- for creating a copy of a string with all characters translated to
uppercase or to lowercase
- and much more
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.
- Go to the API page
- Scroll down to the java.lang package. Click on it.
- 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
- Read the introduction to the String Class with its examples.
- Skim through the whole API page and look at the method descriptions in the Method Summary
- Notice that its Constructor is very overloaded with 15 different possibilities!
- 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?
- Go to the Graphics class and find the drawString method.
- Do you see that there are two? Look at them for anything familiar.
Their signatures are
- (1) drawString(AttributedCharacterIterator iterator, int x, int y)
- (2) drawString(String str, int x, int y)
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.
- Go to the method description: drawString(String str, int x, int y).
- 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:
- 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);
}
}
- Save it, compile it, and Run it.
- 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.
- 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);
}
}
- Save it, Compile it, and Run it.
- 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
- Change the line to
g.drawString("The perimeter of this rectangle will be " + (2*width + 2*length), 10, 70);
- 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.
- 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);
}
}
- Save it, Compile it, and Run it.
- 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
- Check out the replace and substring methods of String in the API
- 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);
}
}
- Save it, Compile it, and Run it.
- 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);
- Make a New Class and name it JavaCup.java
- 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);
}
}
- Save it, Compile it, and Run it.
- 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.
- Make another New | Class and name it Burger.java
- 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);
}
}
- Save it, Compile it, and Run it.
- Again, make the window larger
- Go to the Font class and look at its constructors.
- In the Burger class, go to the line
Font Title = new Font("TimesRoman",3,28);
- 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.
- Create a New | Class and name it DemoNumbers.java
- 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);
}
}
- Save it, Compile it, and Run it.
- 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.
- 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);
}
}
- Save it, Compile it, and Run it.
- Look at the new output
Do you like it?
- 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.
- 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);
}
}
- Save it, Compile it, and Run it.
- Compare the output to the code to see how it was done
- 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
- 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);
}
}
- Save it, Compile it, and Run it.
- 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.

- 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);
}
}
- Save it, Compile it, and Run it.
- 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!