CSCI A201/A597

Lecture Notes Ten

Second Summer 2000


More fun with applets and instance variables. Changes of coordinates and the UnitConverter class.
Let's work some exercises today. OK, let's do that.

How could you describe this program?
class One {
    public static void main(String[] args) {
	A a = new A(); 
	a.fun(); 
	a.fun(); 
	a.fun(); 
	System.out.println(a.n); 
    } 
} 

class A {
    int n; 
    void fun() {
	n += 1; 
    } 
} 
Use the space above.

Didn't we say we should be using this when we refer to instance variables? Indeed. I should always use this for that.

The exmaple here relies on a default meaning. Can any class have a main?

Yes, and in fact we can shorten this example:
class A {
    int n; 
    void fun() {
	this.n += 1; 
    } 
    public static void main(String[] args) {
	A a = new A(); 
	a.fun(); 
	a.fun(); 
	a.fun(); 
	System.out.println(a.n); 
    } 
} 
So I only compile and run A.

Yes, that's called unit testing. I also noticed that you're using this now.

Yes, and we should get into the habit of using it that way always. Can we achieve the same effect with applets?

Yes, and as you shall see, even more. Let's see an example.

Here's a simple one. Can you explain how it works?
import java.applet.*; 
import java.awt.*;

public class Two extends Applet {
    int n;
    public void paint(Graphics g) {
	this.n = this.n + 1; 
	g.drawString("Paint called " + n + " times. ", 30, 30); 
	System.out.println("Paint called " + n + " times. "); 
    } 
}

Isn't it interesting? Don't forget that you need an HTML file with that.

Yes, but beyond that, isn't it intriguing? Yes it is, more precisely I don't quite understand how it relates to the previous example?

Who has the main? The appletviewer.

Can you describe that main?
I can try:
public static void main(String[] args) {
  Two a = new Two(); 
  a.start(); 
  a.paint(); 
  do the following while appletviewer is up and running {
  | watch for user actions... 
  | if the user leaves the page then 
  |   a.stop();
  | else if applet surface revealed then
  |   a.paint();
  | else if applet stopped and user came back then 
  |   a.start(); 
  |   a.paint(); 
  | else if user exits appletviewer 
  |   a.destroy();
  | resume watching user actions 
  }
  
}

Looks good. Can you take advantage of the loop that (as a user) you control? Yes, I can compute the sum of the first n numbers for any value of n.

Show it to me...
Here's what I was thinking of:
import java.applet.*; 
import java.awt.*;

public class Two extends Applet {
    int n;
    int sum; 
    public void start() {
	this.sum += this.n; // add this number 
	this.n = this.n + 1; // prepare next number
    }
    public void paint(Graphics g) {
	g.drawString("Sum of first " + 
                     (this.n - 1)    + // since n is already next number 
                     " numbers is: " + 
                     this.sum, 30, 30); 
    } 
} 

Nice, but you changed a few things... Yes, I wanted to be more in control of when the update will occur.

I can never be sure when paint is invoked... ... yes, paint is called every so often.

Also, I can see start and paint are actually communicating through instance variables n and sum. Yes, instance variables are global to the instance methods, unlike local variables, which are local to the methods they are defined in.

OK, let's move on. You said to me that instance variables and local variables are not alike from yet anotyher point of view.

Yes, instance variables are global to succesive invocations of instance methods. They are there with the object, while the object exists. Can you prove that to me?

Proof is the bottom line for everyone. If you say so.

What do you think of this?
public class Three {
    public static void main(String[] args) {
	Three a = new Three(); 
	a.fun(); 
	a.fun(); 
	a.fun(); 
    } 
    void fun() {
	int m = 0; 
	m = m + 1; 
	this.n = this.n + 1; 
	System.out.println("n is: " + this.n   + " and m is: " + m + " now."); 
    } 
    int n; // initialized to zero by default 
} 
Can I see an example with two functions?

How about this one:
public class Four {
    public static void main(String[] args) {
	Four a = new Four(); 
	a.fun1(); 
	a.fun2(); 
	a.fun1(); 
	a.fun2(); 
	a.fun1(); 
    } 
    void fun1() {
	int m = 0; 
	m = m + 1; 
	this.n = this.n + 1; 
	System.out.println("fun1 --> n is: " + this.n   + 
			   " and m is: " + m + " now.");
    } 
    void fun2() {
	int m = 0; 
	m = m + 1; 
	this.n = this.n + 1; 
	System.out.println("fun2 --> n is: " + this.n   + 
			   " and m is: " + m + " now.");
    } 
    int n; // initialized to zero by default 
} 
OK, I am convinced now.

Note how m is so local you can have a variable with this name in every function you define. OK. I do have a question though, maybe a bit unrelated.

What's that? What's a static variable?

Since you asked:
public class Five {
    int n; 
    static int m; 
    void fun() {
	this.n = this.n + 1; 
	this.m = this.m + 1; 
	System.out.println("n = " + this.n + ", m = " + this.m); 
    } 

} 

class Tester {
    public static void main(String[] args) {
	Five a = new Five(); 
	Five b = new Five(); 
	a.fun(); 
	a.fun(); 
	b.fun(); 
	a.fun(); 
	b.fun(); 
	b.fun();
	b.fun(); 
	a.fun();
    } 
} 
Oh, I see...

It's a factory variable. Global over all objects ever created by the factory. By the way, I suppose we could have kept everything in just one class, Five, no?

Yes, indeed. I made use of Tester to just make sure I don't clutter the main point of the example. I see. Of course, with Tester I need to compile the source code file first, ...

... and given the way I wrote the code the file must be called Five.java ... ... I can see that, ...

... and then run java on Tester, to see the results. Very good. What else are we going to look at today?

The UnitConverter Do we have to?

It will simplify a lot of things later. Can we put it off a little bit, though? I think I have another question.

Let's see the question. Can two instance methods call each other?

Of course they can. Can you show me an example?

Since you're asking:
import java.applet.*; 
import java.awt.*;

public class Six extends Applet {
    public void paint(Graphics g) {
	Graphics2D g2d = (Graphics2D) g; 
	Rectangle r = new Rectangle(3, 3, getWidth() - 7, getHeight() - 7); 
	g2d.draw(r); 
    } 
} 
To be honest, it looks good, but also a bit mysterious.

It should be mysterious. Did you mean to write this.getWidth() and this.getHeight() instead of just getWidth() and getHeight()?

Yes, and I'm glad you noticed that. But where are these methods defined?

Not in class Six for sure. I was going to say, because I can't see them...

They're in Applet which we extend. Oh, and objects of type Six inherit them!?...

Yes, do you remember the basic discussion about Points and Pixels from last time? I sure do now...


In terms of descriptions, or blueprints, does the blueprint of an object of type Pixel contain a feature called x? It does, because its description is extending that of Point's.

Well, the class that we are extending, java.applet.Applet, actually has the getHeight() and getWidth() methods. So we can use them, if we know about them, and I'd say we do now.

Note however that java.applet.Applet does not define these two methods. It inherits the getHeight() and getWidth() methods from Panel...

... which inherits them from Container ... which inherits them from Component,

... which is the one that defines them. It can get quite complicated.

Let's tackle the UnitConverter now. OK, let's do that, we're almost out of time.

Oh, well -- maybe we'll do it in lab. Sounds good to me.

Last updated: July 5, 2000 by Adrian German for A201