CS 110 -- Lab 4

Font Fun

One of the consistent comments about missing information in homework 1 was that people wished that they knew more about using and changing fonts. This lab walks you through some advanced font handing.  With any luck you will be able to apply some of what you do here to some of your future work.

The instructions below ask several questions of you. Be sure that you understand the answers, but there is nothing to hand in.  I will, however, assume that you know and can apply the techniques introduced in this lab.

Step 1: Create an html page

As always, to create an html page do the following:
  1. open XEmacs
  2. C-x C-f html/lab4.html<RET>
  3. Give the document a likely title (e.g., lab4)
  4. add an applet tag below the <h1>tag. Be sure to make the applet wide and high. For example:
    <applet code=FuntFun.class width=500 height=500> </applet>
  5. Save it
You could call your html page something other than lab4.html, but I assume that the file is called lab4.html in the rest of these instructions.

Step 2: Create the Applet and center some text using drawString

Do the usual things to create a new Java applet. E.g.;
  1. open XEmacs
  2. C-x C-f html/FontFun.java <RET>
Into the applet put the following code:
import java.applet.Applet;
import java.awt.*;
import java.awt.geom.*;
import java.awt.event.*;
import java.awt.font.*;

public class FontFun extends Applet implements AdjustmentListener
{

    public void adjustmentValueChanged(AdjustmentEvent e)
    {
	repaint();
    }

    public void paint(Graphics gnu)
    {
	centeredText("This is my text to be centered", gnu, 300);
    }

    public void centeredText(String text, Graphics g, int yloc)
    {
	FontMetrics fm = g.getFontMetrics();
	Rectangle2D r2d = fm.getStringBounds(text, g);
	g.drawString(text, (int)((getSize().getWidth()/2 -r2d.getWidth()/2)), yloc);
    }

}
Try just this applet. I.e., do the following:
  1. Save it. Hit the "save" icon in XEmacs
  2. Compile it.
    1. Start a terminal window
    2. cd html
    3. javac FontFun.java
  3. Run it. In the terminal window enter "appletviewer lab3.html". What does it do? Note that you created a brand new method named centeredText. The nice thing about creating such methods is that you can copy them and stick them into other programs later. Try changing the text and confirm that it is centered. What happens if you try to center a string that is too long to fit in the applet window?

Step 3: Center a Label

Add a class variable to FontFun by putting the following line into the class (outside any method):
        Label aLabel;
Now add this init function to FontFun:
 
       public void init()
       {
	  setLayout(new GridLayout(20,1));
          aLabel = new Label("This is a label");
          add(aLabel);
          aLabel.setAlignment(Label.CENTER);
       }
      
This should result in the label centering in the row in which it appears. Try changing CENTER to either RIGHT or LEFT. Are the results as you expect?

Step 4: Change font sizes

Add another class variable to FontFun by putting the following line into the class (outside any method):
        Scrollbar sizeScroller;
Now change the init function in FontFun to be the following:
 
       public void init()
       {
	  setLayout(new GridLayout(20,1));
          aLabel = new Label("This is a label");
          add(aLabel);
          aLabel.setAlignment(Label.CENTER);
          sizeScroller = new Scrollbar(Scrollbar.HORIZONTAL, 12, 1, 6, 40);
	  add(sizeScroller);
	  sizeScroller.addAdjustmentListener(this);
       }
      
Now add another new method to FontFun.
    public void changeFontSize(Graphics g, int textSize)
    {
	Font f = getFont();
	Font ff = new Font(f.getFontName(), Font.PLAIN, textSize);
	g.setFont(ff);
    }
Finally change the paint method to:
    public void paint(Graphics gnu)
    {
        changeFontSize(gnu, sizeScroller.getValue());
	centeredText("This is my text to be centered", g, 300);
    }
Save, compile and test. What happened? Did all of the text in the applet change size. If not, which text changed? Why?

Step 5: Change font sizes in Labels

Add yet another new method to FontFun.
    public void changeLabelFont(Label label, int textSize)
    {
	Font f = label.getFont();
	Font ff = new Font(f.getFontName(), Font.PLAIN, textSize);
	label.setFont(ff);
    }
And change the paint method to:
    public void paint(Graphics gnu)
    {
        changeFontSize(gnu, sizeScroller.getValue());
        changeLabelFont(aLabel, sizeScroller.getValue());
	centeredText("This is my text to be centered", g, 300);
    }
Save, compile and test. What happened? Try adding another label to the applet. Does its font change? If not, what do you need to do to get the font of the second label to change also.

Within changeLabelFont, try replacing PLAIN with BOLD or ITALIC. Are the results as you expect?

Step 6: Rotating Text

Add another class variable to FontFun by putting the following line into the class (outside any method):
        Scrollbar angleScroller;
Now change the init function in FontFun to be the following:
 
       public void init()
       {
	  setLayout(new GridLayout(20,1));
          aLabel = new Label("This is a label");
          add(aLabel);
          aLabel.setAlignment(Label.CENTER);
          sizeScroller = new Scrollbar(Scrollbar.HORIZONTAL, 12, 1, 6, 40);
	  add(sizeScroller);
	  sizeScroller.addAdjustmentListener(this);
  	  angleScroller = new Scrollbar(Scrollbar.HORIZONTAL, 0, 1, 0, 360);
	  add(angleScroller);
	  angleScroller.addAdjustmentListener(this);
       }
      
Now add another new method to FontFun.
    public void rotatedText(String text, int angle, int x, int y, Graphics g)
    {
        Graphics2D g2d = (Graphics2D)g;
        TextLayout layout = new TextLayout(text,
					   g2d.getFont(), 
					   g2d.getFontRenderContext());
        Dimension dim = getSize();
	g2d.translate(x,y);
        g2d.rotate(Math.toRadians(angle));
        layout.draw(g2d, -layout.getAdvance() / 2, 0);
    }

Finally change the paint method to:
    public void paint(Graphics gnu)
    {
        changeFontSize(gnu, sizeScroller.getValue());
	centeredText("This is my text to be centered", gnu, 300);
        changeLabelFont(aLabel, sizeScroller.getValue());
	rotatedText("This is rotated", angleScroller.getValue(), 200, 400, gnu);
    }
Save, compile and test. What happened? Does the text rotate? Could you use the rotatedText method to replace the centeredText method? If yes, how? Try to do it.