George Aroush, instructor
- Re-write one of your bouncing ball/square/object applet so that the object moves towered the mouse as the mouse is moved on the screen.
- Re-write any of your 2D or 3D project so that the methods that deal with the rotation, movement, scaling, etc. are now part of a class (look at BounceClass.java for an example.)
Back to the top of this page. | Back to main Index |
Events
Every time we perform an action while running a Java application, such as clicking a mouse button or dragging a window, or pressing the keyboard, an event occurs. But, of course, events can also be triggered by internal actions that occur within a program. Many of the common events that occur in Java programs are handled by classes in the AWT package (java.awt.*)
Events in Java can be split into three main groups: mouse, keyboard, and system events. All of those events can be handled very similarly. For the goal of this lecture, we will focus on mouse events (we did look at keyboard event in a previous lecture.)
Mouse Event
By default, Java gives us predefined methods that are triggered when an event happens. To intercept those events we must provide (override really -- more on this in an upcoming lecture) one of the pre-defined mouse events. Java provides a number of mouse event for us to work with. In most programs we don't need them all. All of them are defined to return boolean true or false. If our applet handles the event it should then return true, otherwise it should return false. Each of those mouse event objects take three arguments. The first argument is an Event object that holds all the information about the event that has occurred. The second and third arguments are the x and y coordinates representing where the event took place.
The available methods for mouse events are:
public boolean mouseDown(Event e, int x, int y);
public boolean mouseUp(Event e, int x, int y);Clicking on a mouse button creates two distinct events, mouseDown() and mouseUp(). The mouseDown() event occurs when a button is initially pressed and the mouseUp() event occurs when a button is released.
public boolean mouseMove(Event e, int x, int y);
public boolean mouseDrag(Event e, int x, int y);The mouseMove() event method is used to constantly give feedback when the mouse pointer is over a component. The mouseDrag() event method tells us the same thing, but only while one of the mouse buttons is pressed.
public boolean mouseEnter(Event e, int x, int y);
public boolean mouseExit(Event e, int x, int y);These two events come in handy for certain situations. For example, if we want to provide feedback to the user when he or she moves the mouse pointer into or out of a button, we may want to display a message in the status bar. We can get basically the same effect by checking the mouseMove() method, but this method gets called many times while the mouse is over a button and the mouseEnter() and mouseExit() methods get called only once.
Back to the top of this page. | Back to main Index |
What are classes
Classes are the building blocks of a Java application. A class contains methods and variables; it serves as a blueprint for making class instances, which are run-time objects that implement the class structure. We declare a class with the class keyword. Methods and variables of the class appear inside the braces of the class declaration:
class Pendulum { float mass; float length = 1.0f; int cycles; // some variables in a class float Position(float time) // a method in the class { .... } .... }
The above class contains three variables and one method. Variable and method declarations can appear in any order, but variable initializes can't use forward references to uninitialized variables.
Now that we have defined the Pendulum class, we can create an actual Pendulum object as follows:
Pendulum p;
p = new Pendulum();The declaration of the variable p does not create a Pendulum object; it simply creates a variable that refers to an object of type Pendulum. We still have to create the object dynamically, using the new keyword. Now that we've created a Pendulum object, we can access its variables and methods:
p.mass = 5.0;
float pos = p.Position(1.0f);This should be familiar as it look similar to the way we created a Color object. Just like the color object we can create more then one Pendulum object:
Pendulum a, b;
a = new Pendulum();
b = new Pendulum();
a.mass = 10.0f;
float posA = a.Position(1.1f);
b.mass = 3.0f;
float posB = b.Position(2.0f);In this example we have two objects of type Pendulum: a and b which we can use for calculating the position independently.
Accessing Members
Inside of a class, we can access instance variables and call instance methods of the class directly by name. Here's an example that expands upon our Pendulum:
class Pendulum
{
float mass;
float length = 1.0f;
int cycles; // some variables in a class
float Position(float time) // a method in the class
{
....
}
// note how this method can access everything
// inside the class that it belongs to.
void ResetEverything()
{
cycles = 0;
mass = 1.0f;
float startingPosition = Position(0.0);
}
}Other classes access members of an object through a reference using the dot notation:
class TextBook
{
void Showendulum()
{
Pendulum bob;
int i;
bob = new Pendulum();
i = bob.cycles;
bob.ResetEverything();
bob.mass = 1.01f;
}
}Here we created a second class, TextBook (more about creating new class later) that uses a Pendulum object. It creates an instance in ShowPendulum() and then invokes methods and accesses variables of the object through the reference bob.
Class member access control
Several factors affect whether class members can be accessed from outside the class. We can use the visibility modifiers, public, private and protected to restrict access. The private modifier designates a variable or method for use only by other members inside the class itself. In the previous example, we could change the declaration of our variable cycles to private:
class Pendulum
{
....
private int cycles;
....
}Now we can't access cycles from TextBook:
class TextBook
{
....
void ShowPendulum()
{
....
i = bob.cycles; // ERROR: compile time error
....
}
}The same can be done to the method Position() in the class Pendulum. In a class we can mix and match between private and public as follows:
class Pendulum
{
// only 'cycles' can be accessed outside this class
private float mass;
private float length = 1.0f;
public int cycles;
// this method is accessible by outsiders
public float Position(float time)
{
....
}
// this method is not accessible by outsiders
private void ResetEverything()
{
cycles = 0;
mass = 1.0f;
float startingPosition = Position(0.0);
}
}In this example we used the keywords private and public to selectively define areas in the class Pendulum to be private or public. Regarding the protected keyword, we will look at it at a later lecture.
Local Variable Initialization
Unlike instance variables (variables declared at a class level) local variables must be initialized before they can be used. It's a compile-time error to try to access a local variable without first assigning it a value:
class Pendulum { float mass; // declare 'mass' and assign it 0.0f (the default) float length = 1.0f; // declare 'length' and assign it 1.0f int cycles; // declare 'cycles' and assign it 0 (the default) void ResetEverything() { int foo = 42; // declare and then assign 42 to 'foo' int bar; // just declare 'bar' bar += 1; // ERROR: compile time error bar = 99; bar += 1; // OK mass += 1.0; // OK, 'mass' by default was assigned 0.0f length += 0.1; // OK, 'length' was assigned 1.0f during declaration } }
Note that this doesn't imply local variables have to be initialized when declared, just that the first time they are referenced must be in an assignment.
Method Overloading
Method overloading is the ability to define multiple methods with the same name in the same class; when the method is invoked, the compiler picks the correct one based on the arguments passed to the method. This implies, of course, that overloaded methods must have different numbers or types of argument. The idea is to create methods that act in the same way on different types of arguments and have what appears to be a single method that operates on any of the types:
public class MyClass extends java.applet.Applet { void Test() { int i; float f; i = Random(10); // calls the int version f = Random(0.9f); // calls the float version i = Random(20, 30); // the the range version } // will give us back random ints int Random(int r) { .... } // will give us random floats float Random(flaot r) { .... } // will give us random numbers ranging from a to b int Random(int a, int b) { } }
In this example, we have the class MyClass that has in it three methods with the same name. What makes them different is the argument that they take. One takes float while the other takes int and a third takes two ints. Note that, if two that take one argument were taking an int argument (or a float) and they only differ in the return type (one returns float while the other returns int) then the compiler will give us an error as Java doesn't support return type overloading.
Back to the top of this page. | Back to main Index |
MouseOne.java
/* * Program: MouseOne.java * Purpose: Mouse example * Author: George Aroush * Date: 1/1/1998 * Change Log: None * * Full description of Program: * A very simple example of how to use the mouse to draw connect lines * as the user moves the mouse on the screen a clicks. */ import java.applet.*; import java.awt.*; public class MouseOne extends Applet { int mouseXPos, mouseYPos; int mouseXPosOld, mouseYPosOld; /* we will use the init() method to setup */ /* few thing for our program */ public void init() { mouseXPos = -1; mouseYPos = -1; } /* we can't use paint() because update() calls paint */ /* AFTER when it has erased the screen which is the */ /* default behavior of the update() method so here */ /* we will over-ride the update method to prevent it */ /* from cleaning the previous image */ public void update(Graphics g) { g.drawLine(mouseXPosOld, mouseYPosOld, mouseXPos, mouseYPos); } /* any time the mouse button is pressed down this */ /* method is called with the location of the mouse */ /* on the screen; the location of the mouse is */ /* stored inside 'x' and 'y' respectively */ public boolean mouseDown(Event evt, int x, int y) { /* for the first click we make the mouse */ /* click nothing but a pixel drawing */ if (mouseXPos == -1) mouseXPos = x; if (mouseYPos == -1) mouseYPos = y; /* remember the old location of the mouse */ mouseXPosOld = mouseXPos; mouseYPosOld = mouseYPos; /* record the new location of the mouse */ mouseXPos = x; mouseYPos = y; /* so that the update method gets called */ repaint(); return (true); } }MouseOne.htm
<html> <head> <title>
MouseOne</title> </head> <body> <hr> <applet code=
MouseOnewidth=640 height=480></applet> <hr> </body> </html>
MouseTwo.java
/* * Program: MouseTwo.java * Purpose: Mouse example * Author: George Aroush * Date: 1/1/1998 * Change Log: None * * Full description of Program: * Using the mouse to draw and then move objects on the screen. */ import java.applet.*; import java.awt.*; public class MouseTwo extends Applet { final int X_DONE = 550; /* define "Done" box: starting position */ final int Y_DONE = 410; final int B_WIDTH = 39; /* define "Done" box: size */ final int B_HEIGHT = 15; final int MAX_PTS = 1000; /* define how big the array will be */ final int X = 0; /* define the X part of 2D array */ final int Y = 1; /* define the Y part of 2D array */ int mouseXPos, mouseYPos; int mouseXPosOld, mouseYPosOld; int xy[][]; /* the array to hold our object */ int count; /* how many points are in the array */ boolean first; /* indicates that this is the very first pixel */ boolean done; /* set to true when the user clicks inside the 'done' box */ /* * void init() * * we will use the init() method to setup * few thing for our program */ public void init() { xy = new int[MAX_PTS][2]; count = 0; first = true; done = false; mouseXPos = -1; mouseYPos = -1; repaint(); } /* * void update() * * This is where our action will take place */ public void update(Graphics g) { int i, x1, y1, x2, y2; int xOffset, yOffset; if (first == true) { g.drawRect(X_DONE, Y_DONE, B_WIDTH, B_HEIGHT); g.drawString("DONE", X_DONE + 4, Y_DONE + 12); first = false; } else { /* if the mouse was not clicked inside the rectangle, */ /* do more drawings as long as we have room to store */ /* the new drawing in our array */ if (!InBox(mouseXPos, mouseYPos, X_DONE, Y_DONE, B_WIDTH, B_HEIGHT) && count < MAX_PTS && done == false) { /* save x and y from mouse_x and mouse_y */ xy[count][X] = mouseXPos; xy[count][Y] = mouseYPos; count++; /* increment the array index */ g.drawLine(mouseXPosOld, mouseYPosOld, mouseXPos, mouseYPos); g.fillOval(mouseXPos, mouseYPos, 2, 2); /* fatten point */ } else { /* we can make it follow the mouse */ done = true; g.clearRect(0, 0, 640, 480); xOffset = xy[0][X]; yOffset = xy[0][Y]; for (i = 1; i < count; i++) { x1 = xy[i - 1][X] - xOffset; y1 = xy[i - 1][Y] - yOffset; x2 = xy[i][X] - xOffset; y2 = xy[i][Y] - yOffset; x1 += mouseXPos; y1 += mouseYPos; x2 += mouseXPos; y2 += mouseYPos; g.drawLine(x1, y1, x2, y2); } } } } /* * boolean mouseDrag() * * Deals with mouse-drag event */ public boolean mouseDrag(Event evt, int x, int y) { /* for the first click we make the mouse */ /* click nothing but a pixel drawing */ if (mouseXPos == -1) mouseXPos = x; if (mouseYPos == -1) mouseYPos = y; /* remember the old location of the mouse */ mouseXPosOld = mouseXPos; mouseYPosOld = mouseYPos; /* record the new location of the mouse */ mouseXPos = x; mouseYPos = y; /* so that the update method gets called */ repaint(); return (true); } /* * boolean InBox() * * Makes a check and returns 1 if (x, y) are in box bounded by (bx, by) & (bx + w, by + h) */ boolean InBox(int x, int y, int bx, int by, int w, int h) { if ( x >= bx && x <= (bx + w) && y >= by && y <= (by + h) ) return (true); /* in the boundary */ else return (false); /* sorry, not in the boundary */ } }MouseTwo.htm
<html> <head> <title>
MouseTwo</title> </head> <body> <hr> <applet code=
MouseTwowidth=640 height=480></applet> <hr> </body> </html>
BounceClass.java
/* * Program: BounceClass.java * Purpose: Class creation * Author: George Aroush * Date: 1/1/1998 * Change Log: None * * Full description of Program: * Shows how to create our own class */ import java.applet.*; import java.awt.*; public class BounceClass extends Applet { final int NUM_OF_OBJECTS = 1000; Bounce a[]; public void init() { Randomizer rand = new Randomizer(); int i; /* creates 1000 empty objects of type */ /* 'Bounce' in the array 'a' */ a = new Bounce[NUM_OF_OBJECTS]; /* initialize each object in the array */ for (i = 0; i < NUM_OF_OBJECTS; i++) { a[i] = new Bounce(); /* makes each object */ a[i].init(rand.Random(10) - 5, rand.Random(10) - 5, rand.Random(10)); } } public void paint(Graphics g) { int i, j; /* move each object one at a time */ for (i = 0; i < 1000; i++) { g.clearRect(0, 0, 640, 480); for (j = 0; j < NUM_OF_OBJECTS; j++) a[j].paint(g); } } } /*--------------------------------------------------------------------------*/ /* This class will deal with all aspects of moving a square on the screen */ /* bouncing it off the four sides */ /*--------------------------------------------------------------------------*/ class Bounce { int x; int y; int xSpeed, ySpeed, side; int count = 0; /* * void init() * * Initializes the object and sets things up */ void init(int xs, int ys, int s) { Randomizer rand = new Randomizer(); xSpeed = xs; ySpeed = ys; side = s; x = rand.Random(640); y = rand.Random(480); } /* * void paint() * * Deals with the logic of moving, bouncing and drawing the object */ void paint(Graphics g) { /* draw the square only if it is on the screen */ /* if it is 'true' that x is to the right of */ /* the left AND is at least the square's size */ /* away from the right edge */ if (x < 0 || x > 639 - side) xSpeed = -xSpeed; /* reverse direction, without drawing yet */ if (y < 0 || y > 479 - side) /* same as above but now for y */ ySpeed = -ySpeed; g.fillRect(x, y, side, side); x = x + xSpeed; /* move the square */ y = y + ySpeed; /* move the square */ } } /*--------------------------------------------------------------------------*/ /* This class will deal random number generation. */ /*--------------------------------------------------------------------------*/ class Randomizer { /* * int Random() * * Gives us back random numbers */ int Random(int range) { return ((int) (Math.random() * range)); } }BounceClass.htm
<html> <head> <title>
BounceClass</title> </head> <body> <hr> <applet code=
BounceClasswidth=640 height=480></applet> <hr> </body> </html>
Back to the top of this page. | Back to main Index. |