Introduction to Graphics Programming: GImage, GPolygon, and GCompound, Study notes of Programming Methodologies

An introduction to using gimage, gpolygon, and gcompound in graphics programming. The instructor explains how to create empty polygons, add edges, and work with reference points. The document also covers the concept of gcompound and its relationship to gpolygon, as well as event-driven programming and the use of mouse and keyboard listeners.

Typology: Study notes

2010/2011

Uploaded on 10/04/2011

hollyb
hollyb 🇺🇸

4.8

(44)

431 documents

1 / 22

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
Programming Methodology-Lecture11
Instructor (Mehran Sahami):Hi, all. Welcome to CS106A. Let's go ahead and get
started. If you're on your way in, just feel free to come on in. You can always get the
handouts at the end.
A couple quick announcements before we dive into things. There's two handouts today.
There's a whole bunch of coding examples. There's coding examples up the wazoo.
They're sort of like – I gave you a bunch of code that might just be useful for you to look
out for Breakout, just because it's good times.
So also related to Breakout – no, I think we just change the way we say this. It's just
Breakout, and so any time you see people on campus – every quarter I come up with
some random thing that I wanted to try to get people on campus to say. And I've never
gotten one to take off seriously. Well, let's see if we can actually get Breakout to work.
So just practice that.
On the count of three: One, two, three. Students:
Breakout.
Instructor (Mehran Sahami):Yeah, good times. All right. See, sometimes you gotta
find these little [inaudible] of humor yourself.
Anyway, the note on Breakout is that first of all, there's actually a version of it that's
available on the Web site, so you can actually play around with. The other one is we've
talked a lot about classes so far. And with the initial project that we give you for
Breakout, there's one class in there, you don't actually need to write a whole bunch of
separate classes for Breakout. It's perfectly reasonable to write all your code in that one
class.
If you want to add additional classes and have additional files in the project, and do it like
we did in class, that's perfectly fine, and if it makes sense for you. But you shouldn't
necessarily feel obligated that, "Oh, we talked about classes, so we have to do that for
Breakout." For Breakout, you're actually fine. Classes can potentially provide some
[inaudible], but they're not a requirement for the assignment.
So just couple other quick questions. In class recently – so now that we've had a few
classes, you can sort of get the feel for – we do some stuff on slides. Occasionally, we do
some stuff on the board. And so I wanna get a preference. If you have a – if you get a
notion – if you have a preference for slide versus board.
How many people prefer slides?
How many people prefer the board?
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13
pf14
pf15
pf16

Partial preview of the text

Download Introduction to Graphics Programming: GImage, GPolygon, and GCompound and more Study notes Programming Methodologies in PDF only on Docsity!

Programming Methodology-Lecture

Instructor (Mehran Sahami): Hi, all. Welcome to CS106A. Let's go ahead and get started. If you're on your way in, just feel free to come on in. You can always get the handouts at the end.

A couple quick announcements before we dive into things. There's two handouts today. There's a whole bunch of coding examples. There's coding examples up the wazoo. They're sort of like – I gave you a bunch of code that might just be useful for you to look out for Breakout, just because it's good times.

So also related to Breakout – no, I think we just change the way we say this. It's just Breakout, and so any time you see people on campus – every quarter I come up with some random thing that I wanted to try to get people on campus to say. And I've never gotten one to take off seriously. Well, let's see if we can actually get Breakout to work. So just practice that.

On the count of three: One, two, three. Students:

Breakout.

Instructor (Mehran Sahami): Yeah, good times. All right. See, sometimes you gotta find these little [inaudible] of humor yourself.

Anyway, the note on Breakout is that first of all, there's actually a version of it that's available on the Web site, so you can actually play around with. The other one is we've talked a lot about classes so far. And with the initial project that we give you for Breakout, there's one class in there, you don't actually need to write a whole bunch of separate classes for Breakout. It's perfectly reasonable to write all your code in that one class.

If you want to add additional classes and have additional files in the project, and do it like we did in class, that's perfectly fine, and if it makes sense for you. But you shouldn't necessarily feel obligated that, "Oh, we talked about classes, so we have to do that for Breakout." For Breakout, you're actually fine. Classes can potentially provide some [inaudible], but they're not a requirement for the assignment.

So just couple other quick questions. In class recently – so now that we've had a few classes, you can sort of get the feel for – we do some stuff on slides. Occasionally, we do some stuff on the board. And so I wanna get a preference. If you have a – if you get a notion – if you have a preference for slide versus board.

How many people prefer slides?

How many people prefer the board?

Interesting. All right. How many people like some combination of the two? You can vote again if you want.

All right. So we'll try to do that. All righty. So today's gonna be a little slide-heavy day because we didn't have the vote so far. But we'll try to do some more board stuff as well.

So here are the class hierarchy you saw before. And we covered a lot of the class hierarchy last time. But there were still a few bits that we have left to cover, which is GImage, GPolygon, and GCompound. So you'll see those. And then you'll be ready to do all kinds of cool stuff today.

As a matter of fact, today we're gonna break out things you can do with a mouse and graphic – and more graphics kind of stuff with the mouse. And it's just a whole bunch fun [inaudible] doing Breakout.

So GImage: All the GImage is, and this is a funky way that you can put pictures inside your program, like pictures that you take with a camera or whatever or your phone. You can just stick them in your program. And the way you do this is there's a class called GImage. And so you can create an object of type GImage by saying, "new GImage." You give it the name of the file. That's the full file name that with a dot and whatever ending it has, and then the xy location for where you wanna display that image. The xy is the upper left-hand corner of the image.

So the file – image file is the name of the file containing the image, and x and y, as I just mentioned, are those coordinates. Now, where you have to stick this file – that's something to remember. So when it looks for the this file, what it will do is it will look in your current project folder, and if it does not find that file name in your current project folder, then it will look in a subdirectory named "Images."

So you can have the subfolder if you have a whole bunch of pictures called "Images" inside the folder for your project. Put all your images there. It will also look there as well.

If it's not in either one of these places, bad things happen. And if you wanna know what bad things happen, you can actually try it. But I wouldn't encourage you to try to do bad things. So just stick in the folder with your project, and you'll be fine. And you'll get the image.

So let me show you an example of what that actually looks like. Just so you know, both .gif or "jif" formats. Some people say "jif," even though the "g" stands for "graphics" over here, which is kind of a hard "g," and then .jpg, which is another graphics standard, and you'll see the files either in .jpg or .jpeg, which just another format. Both of them are supported, and so most cameras or phones or whatever actually end up taking pictures in one of these formats.

So here's a simple example. So if we had some program run, we can say I wanna have some image that's a GImage. So I create one, and let's say I have to have the Stanford

So the first thing you do is you say, "Create an empty polygon." So you create empty polygon object. And then what you're gonna do is you're gonna specify the vertices of that polygon one at a time using a method called addVertex. And addVertex can take an x and y coordinate. These x and y coordinates are relative to your reference point. So if you think of your reference point as being the center of the object, and you say, "Oh, my xy is 1,1," that's one pixel over and one pixel down from wherever you think of your reference point as being.

You never actually specify the reference point to the GPolygon. The reference point's just in your mind. All of the vertices are just relative to whatever reference point you happen to pick. And I'll show you an example of this to make it concrete in just a second.

After you set an initial vertex – so you need to set the first one with something called addVertex. After you set the initial vertex, you can set all the remaining vertices in one of two ways because we just give you options. We like you.

One way is just to keep adding vertices. And what – when you call a addVertex again, what it does is it adds a new vertex, again, relative to the reference point. And it essentially creates an imaginary line between the last vertex you just added and the first vertex you added. That's how you're getting edges of your polygon. You're sort of specifying the corner points.

Another way, instead of specifying corner points, is after you specify the first one, you can explicitly addEdge. And addEdge adds a new vertex relative to the preceding one. And here, it's going to do it with offsets of dx and dy.

So relative to where we were before, we actually specify sort of an offset in the x- direction, offset in the y-direction. It's kinda like you were almost creating a line, and it's gonna add an edge. This one here is using absolute coordinates relative to the reference point. That's kind of a – the key difference between these two things. And I'll show you an example of both of them.

One final thing you should know is the polygon is, in some sense, closed for you. So if you were drawing a diamond, and – let's back up so I can show you the diamond. If you're drawing a diamond, you might specify that as the first vertex, then this is the second, then this is the third, and then this is the fourth.

How did that know what the fourth and first are what should be attached to each other? It just closes it for you. So after you've added the last vertex to the polygon, basically what it does is it just automatically sort of links up the first and last segments, or first and last vertices, to sort of close the polygon for you. That's how you actually specify. So you never actually need to go back to the first vertex again. It just does it.

So that's kinda a whole bunch of stuff in theory. What does it look like in practice.

So we're gonna create a diamond. We're actually gonna create it using some method that we'll see called createDiamond. And so when we call createDiamond, we're expected to give us back a GPolygon.

Here's where all the interesting stuff's going on. So here's the create-diamond method. CreateDiamond's gonna return a GPolygon. So it needs to create one because it's gonna return it back to us. And what it's getting is the width and height of what that diamond should look like. So the first thing it does is it says, "Create a new polygon." It creates a new, empty polygon, just like you sort of saw before.

Then what does it need to do? It needs to add the first vertex. So it adds the first vertex. And it's gonna do this relative to some imaginary reference point that I pick. The reference point that I'm gonna pick is going to be the center of the diamond, which means my first vertex in the x-direction is going to be minus width over two. So let me just show you where that vertex would be.

So if I think of the imaginary center, and I've just executed that line to add a vertex, I'll say relative to my imaginary center, my first vertex is at half the width of the diamond over in the negative x-direction, and on that same line, so 0 in the y-direction.

Then where do I go from there? Well, I'm gonna add the next vertex. The next vertex I'm gonna add, relative to my center, is going to be at the same x coordinate as the center, but it's going to be minus height divided by two upward. So what I get, essentially, is this is an x vertex, and it just kinda creates the segment in between them.

Where's my next vertex? It's gonna be over here. It's width divided by two for my imaginary center point and on the same line as the imaginary center point. So the y offset is 0.

And then last, but not least, the last vertex I'm gonna add is on the same x coordinate as the imaginary center. But the height is half the height of the diamond, downward. So I get that.

And now if I say, "Return diamond," it matches up the first and last vertex. So what I get back is a closed polygon. I actually get that diamond. And that's what's returned back to me in my "Run" function over here. So diamond is now this little polygon.

Question?

Student: Do you add [inaudible] you add the bottom to the top [inaudible]?

Instructor (Mehran Sahami): It depends on if you do something like addEdges versus addVertex. So again, I would try it. And especially if you try things like where your lines would've crossed, you'll see sort of funky things between addEdge and addVertex.

Uh-huh?

Instructor (Mehran Sahami): Yeah. There's a bunch of things we could do. Essentially, there's a bunch of stuff with polar coordinates that I should mention. We're not gonna deal – so if you read in the book about polar coordinates and fade and all that, we're actually not gonna do it in this class.

So if you're like, "Oh, polar coordinates." You're like, "Yeah, polar scares me," it scares me, too. Polar coordinates, you only need to worry about if you're a bear, or you're in the Antarctic.

We just not gonna worry about polar coordinates. We're just gonna do Cartesian coordinates. But there are – it's easier to do rotations if you think polar.

So in terms of adding an edge, we're gonna do the same thing for createDiamond using edges instead of vertices. So if we wanna create a diamond adding edges, we have to still specify the first vertex, just like we did before.

And now the edges – what I'm specifying for the values for the edge is an offset in the x and y direction. And my offset in the x-direction is width over two, so that would move here. And my height is negative height over two, so that would essentially move over here because it's relative to my last point. It's not relative to the imaginary reference point.

And so basically, if I sort of follow this all the way around, what I do is I addEdges. Again, after I add that last edge, the polygon is closed for me automatically. I get back the same diamond. I'm just now doing it with edges instead of with vertices, same sort of deal. I make it magenta because magenta's a fun color, and I write it out on the screen.

So that's GPolygon. Now, things get a little more funky. And the thing that gets the funkiest of all – it's kind of like the George Clinton of graphics class, is GCompound.

And so what GCompound's gonna do – anyone know George Clinton? All right, a couple, but at least it's not totally lost. GCompound basically is as you'd imagine. It's a compound shape. It allows you to take multiple other shapes that you've seen and put them all together and treat that one thing as one object, which is very convenient sometimes if you wanna draw something complicated and then move it all around the screen, for example, or rescale it.

So adding objects – the way a GCompound works is you add objects to a GCompound just like it was a canvas. So just like you've done before where you say, "I have some canvas, and I put these little objects on it, and it draws pictures," if I have some GCompound, and I add a bunch of objects to it, I now have this compound thing that encompasses all of those objects.

So you can now treat the whole compound as one object, though, which is the whole reason for having this, and I'll show you the example of this in just a second.

So similar to a GPolygon, a GCompound also has a reference point that when you add objects to the GCompound, you add all the objects relative to some imaginary reference point that the GCompound has.

And finally, how do you display this thing? So when you add things to a GCompound, they're not displaying on the screen. You need other take the GCompound and add it to the canvas just like all the other [inaudible] or ovals or whatever you did before. And when you place it, you place it relative to its reference points, and it will draw all the objects that it encompasses.

So let's actually just see what that looks like. So let's draw a little face. Oh, little face, and so you can see we're gonna use some different things here. We're gonna have an oval. We're gonna have a couple of other ovals as the eyes. Hey, triangle – what should we use for the triangle?

Student: [Inaudible]

Instructor (Mehran Sahami): Polygon, right. Some people are like, "Three lines." No, GPolygon. It's your friend, really. It's a fun time. And here's a little rectangle for the mouth.

So what we're gonna do with this is we're just gonna go ahead and take a look at a class GFace. So the GFace class that I'm creating is just a whole separate class. I'm going to create this class GFace as extending GCompound. So a GFace is going to be a GCompound. And what I'm gonna do is I'm gonna have a whole bunch of constants here that just specify the width of the eyes and height of the eyes and all the sort of features of the face. And I'm gonna have some objects that comprise my little GCompound.

So I'm gonna say, "Well, the head's an oval, and the left eye and the right eye are both oval, and the nose is gonna be a polygon. And the mouth is gonna be rectangle." These are all my private instance variables. They're just the variables I'm gonna use to keep track of the things I create and add to my GCompound.

So the compound has a constructor, which is just the same name of the class. It's GFace, and what it's gonna take is the width and the height because I wanna allow the face to automatically be resizable, which means all the stuff that I create that's part of the face needs to be in terms of the width and height that are past, and so it will resize itself depending on whatever width and height the user gives me.

So the first thing I do is I say, "Hey, the head's gonna be an oval." And the oval is basically just a circle that's off-size width, height. It's gonna be the size of the whole head, so whatever size you give me is the size of the head.

The left eye is gonna have the eye width times width, so it's gonna scale by whatever width you give me for the face. I'll scale it by eye width, and same thing for the height. I'll scale it by eye height. And I'm gonna create two eyes, left eye and right eye. Notice

So when I call add here, I'm not adding it to the graphics window. I'm adding it to the GCompound. So addHead and 0,0 – my imaginary reference point for this face is going to be this upper-left-hand corner of the bounding box.

So if I say add, head is 0,0. If I think of this as 0,0, and this is an oval, it's going to add the oval here because what I'm specifying is the upper-left-hand corner of the oval.

Now where am I gonna add other stuff? I'm gonna add the left eye to this kinda funky equation over here. But basically, all it's saying is I take a quarter of the width of the face and subtract from it the eye width scaled by the size of the face divided by two. So basically, what it's gonna do for the x coordinate is do something on sort of this part of the face. It's gonna bring it over a quarter from where it would've been relative to the center of the screen.

And then I'm also gonna do something relative to the height wherefore the left eye and the right eye – they're both gonna be at the same height, where I basically just look at a quarter of the height down the face is where those eyes are gonna show up. And I have to do some accounting for the eye height. So if my eyes – if my face were really big, my eyes still show up at the right place.

So it's just a little bit of math. You can sort of trace through it by hand if you're interested. And the exact coordinates for where these things are going is really not that important as long as we get a light – right layout that looks like a face. The important thing is all these things are relative to our little reference point at 0,0, which is the reference point for the face. We haven't put anything on the canvas yet.

The nose is just gonna be at the center, so nose is gonna be halfway over on the width and halfway over on the height. So if this is our reference point over here, we go halfway over on the width, halfway down on the height, that's the very center of the circle. And because when we created our GPolygon, the imaginary reference point of our triangle was the center, it places it relative to the imaginary center point of the triangle. So we get the triangle right in the middle of the face.

And last, but not least, we're gonna put in – we're gonna add the mouth. And the mouth is basically gonna go near the bottom of the face. It's actually gonna go in the center of the face. This is just basically finding the center point for the x shifted over by the sides of the rectangle, and then it's gonna be three quarters of the way down the circle, which is kinda how we get this.

So we add all these things relative to this reference point. And now, if we actually want to display this, we need to write some program that displays it. And so we'll have a program called DrawFace. And all DrawFace does is pretty simple. It says, "I'm gonna pop up a little pop-up in the middle of your screen."

I'm gonna have a graphics program that's gonna have some face width and face height. And what I'm gonna do is I'm gonna create a new face, giving it the width and height.

And where do I wanna place this face on the screen? I wanna center it on the screen. The reference point for the face, though, is not the center of the face. It's this upper-left-hand corner. So I need to figure out, relative to that upper-left-hand corner – I'm losing another piece of chalk – how to center the face.

So what do I do? I get the width of the screen. I subtract from it the face width, and I divide by two. That's kinda the classic thing you did when you were trying to center, say, a rectangle. You would take the width of the screen, subtract off the width of the rectangle, divide by two. What it will essentially do is figure out the coordinate to place this guy so this whole thing is centered in the screen. And we do essentially the same thing in the y-direction as well.

So we look at the height of the screen. We subtract off the height of the face and divide by two, and that gives us how much we should go down.

So again, when we finally place this on the canvas, we're placing it – when we specify the point on the canvas, that point is the reference point of the whole GCompound.

Instructor (Mehran Sahami):

Are there any questions about that?

Uh-huh?

Student: [Inaudible] the face [inaudible]?

Instructor (Mehran Sahami): I could've actually done it as just creating a GPolygon object and adding everything inside of another program. But I wanted you to actually see it as extending a class just because that's a common way of doing the decomposition. You say, "This thing that I'm gonna create really is a GCompound, so I'm gonna create it as a derived class of GCompound." It's the more common way of doing it.

Uh-huh?

Student: [Inaudible] –

Instructor (Mehran Sahami): Oh, sorry.

Uh-huh?

Student: [Inaudible] compound [inaudible] in the compound [inaudible]?

Instructor (Mehran Sahami): Yeah, so you can think of there's a z-ordering of the compound that's just like a canvas. So you actually have it – you can have layering of objects. And objects will include other objects in the compound. And it's the order in which they're added.

And that was an event, and there was cake and celebrating and the whole maybe – I don't know – maybe you were like, "Oh, I gotta go to Stanford. Bummer."

But it was an event. And in some sense, your life is a program, and it's driven by events. These little things happen, and it changes the course of your life. Hopefully coming to Stanford changed the course of your life in a good way.

In terms of actual programs you write, there will also be events that will change the course of your program. But these events are a little bit more minor than, say, getting into Stanford. There are things like when the user interacts with a computer, like clicking a mouse or pressing a key. Those are events that happen on a computer. And your program should be able to detect certain events that are going on and respond to them by doing various kinds of things, say when you're writing your Breakout program.

The way we be able to determine if an event has taken place is kinda a clandestine operation. It's kinda like we're in the CIA. And we gotta say, "Oh, did an event take place? Well, I don't know [inaudible] if an event took place. I need to send out my minions."

And your minions are called your listeners. Your listeners are something you put out there that says, "I'm here. I'm listening for events. Is anything going on?"

And unless you put out your listeners, you're deaf to what's going on in the world. It's kind of like you weren't listening. You weren't watching the mail for that Stanford packet, and the Stanford packet came, and you just never checked the mail, and you never knew. And no one was gonna tell you because you didn't put out your listener for the Stanford packet.

Well, on the computer, there are two different kinds of listeners we think about. There's a mouse listener and a key listener, which gets events from the mouse and events from the keyboard. And so the way we create our listeners is in our program very early on, we either say addMouseListeners or addKeyListeners. We can actually say "both" – listen for both things. And these are methods that are supported by graphics programs, for example.

Now, in order to use these listeners, you need to have a library added in your program that deals with events, and that's the Java awt.event.*. So on your programs that use events like listeners, and we'll look at events in just a second, you'll need to have this little import line in there. And this is all in the book. You don't have to hurriedly copy it down.

A bunch of people have asked for slides. And I was hesitant to post slides on the Web because I think if slides are up there, people will not come to class.

So first of all, how many people would like me to post the slides on the Web?

How many people would continue to come to class if I post the slides on the Web?

Yeah, it should be all those same hands. Good times. All right. I'll probably post them on the Web, then.

All right. So there are certain methods of a listener that get called when an event happens, and this is the funky thing. Up until this time, all of your programs have be – have been what we refer to as synchronous. There are some series of events that happen, and you know the next event is gonna happen, or the next method's gonna get called after the last method got called. You're now entering the world called the asynchronous world, which means you don't know when things are gonna happen.

Events happen. You might've been waiting for weeks for that Stanford little acceptance letter to come. You didn't know when it was gonna come. Eventually, it came, but you didn't know. And there were some sad people who we won't talk about right now, but if you're out there watching on video, it's fine. It's perfectly okay. You were waiting for the Stanford acceptance letter, and it never came. That happens. It's not a bad thing. You're still listening. You were active. You took a participatory role in life. That's what you should do. It's a good thing. But you didn't know when or if it was gonna happen.

And that's what an asynchronous event is. It happens, and you don't know when it's gonna happen. You just gotta be prepared when it happens. You're like, "I'm gung ho. When it happens, it's gonna happen, and I'm gonna be there because I'm listening for it." That's what you wanna think about.

So let's look at a simple example of a event-driven program called ClickForFace. You're like, "What does that mean?" But it probably involves the face. Yes, in fact, it does.

So click can mean anything. ClickForFace. Here's an example of an event-driven program. What this is gonna do is it's gonna bring up a blank screen, and every place we click on the screen, it's gonna put a little face there. That's why it's ClickForFace, all right?

So how does this work? Well, first of all, ClickForFace is a graphics program. It's gonna drawFace wherever the user clicks the mouse. Now, here's the funky thing. There's a couple funky things that happen in this program. This program has no run method because there is nothing we need to do in terms of a bunch of sequential steps in this program. All we're doing is we're waiting for events. We're waiting for someone to click the mouse. Until they click the mouse, we got nothing to do except for we gotta be listening for that mouse to get clicked.

So there's a method called a init(), and init() automatically gets called when a program starts. And you might say, "Well, that sounds a lot like run. What's the difference between run and init()?" The way you wanna think about the difference between these is run is when you're actually doing some real work.

Init() is generally when you're just saying, "There's a few things I need to initialize. I need to put my little ear out there to be listening for things. But there's not any real work

Question?

Student: Do you have to [inaudible] click to [inaudible]?

Instructor (Mehran Sahami): If you have two programs running simultaneously?

Student: [Inaudible] if you have [inaudible].

Instructor (Mehran Sahami): Uh-huh?

Student: [Inaudible]?

Instructor (Mehran Sahami): Yeah, so while your program's running, if you get these asynchronous mouse clicks, your – the mouse-click method will get called for you, yeah.

Student: [Inaudible] will it stop [inaudible] method [inaudible]?

Instructor (Mehran Sahami): It will stop momentarily for you to deal with that method called mouseClicked(), and then it will continue execution.

Student: [Inaudible]

Instructor (Mehran Sahami): Yeah. So here we have – there's nothing in the program yet because we haven't clicked yet. Ah, ClickForFace. So you can hit it, and you can spend weeks. You're like, "Yeah, there's a click here. I'm gonna put some face on top of each other. It's like a party over here." Yeah, ClickForFace. That's it.

If I click out here, I don't get any faces. I [inaudible] into some other application because it only listens for events inside here. So that's ClickForFace. There we go.

Uh-huh?

Student: [Inaudible] a [inaudible]?

Instructor (Mehran Sahami): No, because you don't know where it would return it to. You're not the one that called it. Someone else called you, so you're like, "Hey, you called me. Here's a good time. Have a candy bar." And it's like, "I don't wanna candy bar." And it gets really upset, so – but I hope you wanted the candy bar.

So yeah, you don't return anything. But that's a good thing to think about.

So that's ClickForFace. Now, there's a whole bunch of things you can actually listen for. It's not just clicks. The general idea is first, you add your mouseListeners. That's critical. Common thing people do is they forget their listeners. And they're like, "Hey, I'm clicking for face. And I'm not getting any face."

And it's not because the face doesn't love you. The face loves you. I know. I've was writing the face at 3:00 a.m. last night. It loves you. And then what you need to do after you have your mouse listener in there, and then you add definitions for any listeners you wanna have.

So here are the common set of listeners for mouses. There's mouse-click, which you just saw. That's called whenever the user clicks the mouse. There's mouse-pressed. What's the difference between a click and a press? The press is that the mouse button has been pressed down. It has not yet been released. So if you wanna do something like a drag where you hit a button, and you move the mouse around, and then you release it, you can check for press and released. So a press and a release together is a click.

So you can actually kinda do multiple things. You can do something when the mouse is pressed. You can do something when the mouse is released, and that'll also count as a click. So mouseClicked(), mousePressed(), mouse released. MouseMoved() – every single pixel that the mouse moves, it's like, "Oh, mouse move, mouse move, mouse move." Yeah, I can't even do it fast enough. That's how fast it goes. It's how quickly the mouse moved.

And mouseDragged() is when someone actually clicks on something and then moves the mouse while holding down the button. In fact, we'll say that the mouse has been dragged, which is like mouseMoved() except that this is only happening when the button's down, and someone's moving the mouse.

But all these take the same kind of mouse events, and so you can get the xy location for where that click happened, or where the mouse recently moved to. And that's gonna provide you the data about the event.

So let's look at another one. Let's actually track the mouse. And you're like, "Oh, that wily mouse. It has gotten away from me. How do I track the mouse?" MouseTracker might be real useful for Breakout, just in case it wasn't clear.

What the MouseTracker's gonna do is basically, I'm gonna have a run method here because there's actually some work I wanna do other than just having listeners. What am I gonna do? I'm gonna create some empty label. I'm gonna make a font for that label real big so that you can see it. I'm gonna add that label at a particular location on the screen because it's an empty label. When I start out, nothing will show up. And then I listen. I set out my mouseListeners, and I'm like, "Woo, mouse? Mouse?" And what I'm checking for is mouseMoved(). That's the only listener that I'm setting up here.

If mouse moves, I get some events. I'm going to change the text for that label to be a mouse with the xy location it moved to. And I need to keep track of my label, both here and here, so I need to keep track of the label in between method calls so I actually have my label be a private-instance variable.

So you can actually do funky things what – when you press something, like the screen goes black, and then your roommate leaves and doesn't know what you're doing, and then you lift up the key, and it comes back. You can actually do that.

KeyTyped() is basically a click. It's press and release together. So when you press and release a key, that generates a keyTyped() event. What you get in this E that you're getting is an event. It's not a mouse event. It's a key event. And key event is an object which has information about, for example, which key was pressed. And the book goes into details of which key was pressed.

But I wanna show you some simple example of this where we don't even care what key was pressed. All we care is that a key was pressed. So yet another example. Woo-hoo. And I can actually just close PowerPoint.

So what we're gonna do is we're going to DragObjects around. What does DragObjects do? So DragObjects is a graphics program, and what I'm gonna do is create a rectangle on the screen and add it, create an oval on the screen and add it, and add mouseListeners and keyListeners.

And you might see this and go, "Marilyn, why is it a init() method as opposed to a run method? Shouldn’t that really be a run method because you're doing some work?" Yeah, probably. You can – it's [inaudible] the other. The book actually has a similar program for this. It's not the same program but a similar program that they call it init() over there. So I just made it init() just kinda to match the book so you're not like, "Oh, Marilyn, slides in the book are just completely wrong," and again, this death struggle.

No, it just – it doesn't really matter that much. But we create the rectangle. We create the oval. We add them both to the screen. We add the listeners, both the mouse listener and the key listener. And now here's what we're gonna do that's funky. We're going to allow objects to be dragged on the screen.

What does that mean? That means when you click on a rectangle on the screen, and you move your mouse holding down the button – that's called a drag – we're gonna have the rectangle move with you. Woo-hoo. Rock on. So mouse drag. Mouse drag is gonna get some mouse events.

Now, there's a little bit of funkiness in here with this little GObject thing. What does that mean? So I'll get back to that in just a second by first showing you what this GObject actually is. So what I'm gonna keep track of in my program is a generic GObject. And you might say, "But Marilyn, we don't create generic GObjects." Yeah, that's because its variable GObject is either gonna be the rectangle or the oval. It can be either one. They're both GObjects. So the common denominator is that they're GObjects.

So this object – this variable is gonna keep track of what object is currently being dragged on the screen – what object I clicked on so I know what I'm actually dragging, whether it's the oval or rectangle or that I haven't clicked on any object at all.

GPoint is basically just something that holds the x and y location. It's a very simple object that we haven't talked about till right now. But basically, all the GPoint is is it's a little tiny object, and it has an x and a y location in it. And so I can set the x and y location in the point, and I can say, "Give me both getters and setters." Get the x and y location. It's just a little convenient encapsulation. I could've actually had this be a separate variable x and a separate variable y. I just created the GPoint so you could see a GPoint.

And I'm gonna have little randomness in my program, too. So the random generator will once again rear its ugly head. And so I have – I get an instance of the random generator. You'll see we're gonna generate some random colors in just a second.

So with that said, how did this mouse press and mouse drag thing work? MousePressed() is when someone clicked the button. They have not yet released the button. It is not a full click. It's just the mouse was pressed. The mouse was pushed down. I get this event. And that event, E, basically has an x and y location associated with it.

As you saw in the previous example, I can get the x and y location separately. There is a way I can just say e.get point(), and it gets the x and y location together in a little point object and gives that back to you, which is why I created this thing called the GPoint, so you could see it. It's just a nice [inaudible] that gives you x and y at the same time.

And when I say, "Hey, get that point, and what I wanna do is get the elements at that point." So wherever you clicked, call getElement() at. That will return to me the topmost object at the point you clicked. If it's the rectangle, it will give me back the rectangle. If it's the oval, it will give me back the oval.

If there is no object at the point I clicked, I get back something called null, N-U-L-L, and that gets assigned to GObject, which means your GObject – there is no thing. There is no object there. Null is just a way of referring essentially to no object. But you can assign any object the value null to say, "There's not really an object here."

And so getElement() will either give you the oval, the rectangle, or null. Get element – that's something you're gonna use for Breakout. Pay close attention.

So what happens after the user clicks? If I get an object at the place they clicked, I now see are they moving the mouse? If they're dragging the mouse – after they click, if they move the mouse at all, that generates events that are mouse-dragged events. So gets called the position of the mouse that the mouse has been dragged to.

First thing I checked, are you dragging a natural object? When you click the mouse, did you click it on top of an object? If you did, then the object is not null. If you didn't click it on an object, then it is null, so hey, nothing to see here. You didn't click on an object, and now you're trying to drag around. You've got nothing to drag, buddy. Sorry. Thanks for playing. I'm not gonna do anything.