© 2000-2001 A-Square, Inc. Reston Virginia
>
/*
* Banner2b applet Version 2.0
*
* Jan Aminoff , September 2000
* © A-Square 1997-2000.
*
*/
import java.awt.*;
import java.applet.Applet;
/**
* This Applet demonstrates object oriented programming.
* Compared to the Banner1 example, we have broken out the
* code relating to a specific logo and how it moves. As a result
* we have a much simpler applet that with minimum modifications
* may be used for the display of other logos.
*
* author Jan Aminoff/ © A-Square 1997
* version 2.0, modified September 2000, for use at IEEE/A-Square
* Introduction to Java, tutorial.
*
* This version should compile and run under JDK 1.0.2
*/
public class Banner2b extends Applet implements Runnable {
///////////////////////////////////////////////////////////////////////////
// The Banner1 class declares the following public methods and no public
// variables: init, start, run, stop, mouseDown.
///////////////////////////////////////////////////////////////////////////
/*
* The init() method is prescribed by the Applet class, or more
* precisely, the init() method here overrides a method in the
* Applet class that Banner2 extends.
*/
public void init() {
// Actually all initial processing has been moved to the manageScreen
// method which takes care of a modified screen/window/applet size.
manageScreen();
}
private void manageScreen(){
/* In this case we will add a modification to the Banner2 applet.
* We will handle the case when the size of the applet has changed.
* This will never happen in a browser where the size is given in
* the Applet tag. In the AppletWiever, however, you may change the
* size of the window. The manageScreen method is called when such a
* change is detected and adjusts the processing by getting a new
* appropriately sizedbuffer, Since maxx and maxy are initilized to 0,
* the first use of the manageScreen is in init saving some typing.
*/
int mx1 = size().width; // Get the width of the screen/window
int my1 = size().height; // Get the height of the window
// Get the doublebuffer if you can
// but first get rid of the old one if there is one
if (imagebuffer != null){
imagebuffer = null;
}
try {
// allocate an offscreen graphics
imagebuffer = createImage(mx1, my1);
gc = imagebuffer.getGraphics();
}
catch (Exception e) { gc = null; }
// Since we have new values for the screensize we had better
// get a new version of the logo to ensure it is inside the new screen.
logo = new IEEELogo(mx1, my1, size); //IEEE specific
// and set the maximum speed for the new logo.
logo.setMaxSpeed(maxv);
// Finally we have to make sure that maxx and maxy gets the right values
maxx = mx1;
maxy = my1;
} // End of manageScreen
/* Normally private variables would be placed at the end of the class
* source. We are giving them here to allow them to be considered in the
* textual context where they are set initially.
*/
private Graphics gc; // used for drawing
private Image imagebuffer; // Used for drawing when double buffering
// The applet appears as a rectangle with upper left coordinates (0, 0)
// and lower right coordinates (maxx, maxy),.
private int maxx = 0; // The right edge of the applet
private int maxy = 0; // The lower edge of the applet
private int maxv = 8; // Max speed of logo
private int size = 35; // Size of logo
private IEEELogo logo; // IEEE specific
// End of init and declarations of private variables initiated in init.
/*
* The following three public methods: start, stop and run implement
* the Runnable Interface. It is useful to allow programs outside the Applet
* control the animation.
*/
public void start() {
if (clock == null) {
clock = new Thread(this, "Banner");
clock.start();
}
}
/*
* The run method interupts execution for stime milliseconds between repaints.
* This is a crude way to get the applet to execute frames at a rate which is
* relatively independent of processor speed.
*/
public void run() {
while (clock != null) {
try {
clock.sleep(stime); //wait for stime milliseconds.
}
catch (InterruptedException e) {} //resume
repaint();
}
clock = null;
}
public void stop() {
if (clock != null) {
clock.stop();
clock = null;
}
}
private Thread clock = null; //A thread is a thread of execution
/* If dtime is 1000 milliseconds then stime is about 25 milliseconds which
* means there are about 40 frames in a second if the time to do the
* actual animation is ignored. This should give a smooth animation.
*/
private int dtime=1000;
private int stime=dtime/40;
// End of Runnable related methods and variables
/*
* mouseDown, Library method called when the user presses the mouse.
*
* The mouseDown method is now depreciated and replaced with more general
* but also more complex methods for event handling. The Java virtual
* machine automatically invokes the mouseDown method when the user
* presses the mouse button. In this case we are not intersted in
* xd and yd, which would give the coordinates for the mouse click.
*/
public boolean mouseDown(java.awt.Event evt, int xd, int yd) {
if (move){
logo.stopMove();
}else{
logo.resumeMove();
}
move=!move;
return true;
}
private boolean move=true; // This variable says that the logo is moving
// End of mousDown method and related private variables
/*
* The update method is prescribed by the Applet.
*
* The update method is called periodically. It has two branches depending
* on wether or not we were succesfull in securing us a buffer for double
* buffering.
* If the imagebuffer is null we have to paint this applet directly
* on the graphichs context g.
*
* This is also where we will track if the size of the window has changed.
* If it has, we call the manageChange metod again.
*/
public void update(Graphics g){
int xm1 = size().width;
int ym1 = size().height;
if ((xm1 != maxx)||(ym1 != maxy)){ //Has the size changed?
manageScreen();
}
if (imagebuffer != null) {
paintBanner(gc);
g.drawImage(imagebuffer, 0, 0, this);
}
else {
g.clearRect(0, 0, maxx, maxy);
paintBanner(g);
}
}
///////////////////////////////////////////////////////////////////////////
// Following the declarations of public methods and variables, the Java
// coding conventions require the positioning of private methods and
// variables. The Banner2 class has the following private methods:
// paintBanner, manageScreen, and printString which may be considered .
// a utility method.
///////////////////////////////////////////////////////////////////////////
/*
* The paintBanner method paints the whole rectangle (0, 0, maxx, maxy)
* using the graphics context g. It starts by painting it all light gray.
* It then draws and moves the logo. Compare to Banner2a with ASquareLogo!
* It then draws the three strings s1, s2 and s3.
* Note that all information of the movements is in the Logo class
*/
private void paintBanner(Graphics g){
// This method paints the whole rectangle (0,0, maxx, maxy)
g.setColor(Color.white); // Looks better with IEEE logo
g.fillRect(0, 0, maxx, maxy); // Paint the screen white
//For IEEE it looks better to have the Logo under the strings
logo.drawLogo(g); // Draw the logo
logo.moveLogo(); // Move the logo
printString(g, s1, maxx,45 ,24);// Draw the three strings
printString(g, s2, maxx,70 ,12);
printString(g, s3,maxx,maxy-5,9);
}
private String s1="Welcome to Introductory Java";
private String s2="Jan Aminoff, Instructor";
private String s3="Also inventor of RARTª, Random Art for the Internet";
// End of paintBanner and declarations of strings
/*
* Standard methods
*/
// The following prints the String st using the color blue and the font
// Helvetica at pointsize s according to coordinates x and y.
private static void printString(Graphics g, String st, int x, int y, int s)
{//Decided to fancy it up so the text is centered between 0 and x May 8, 1998
Font Hel = new Font("Helvetica", Font.BOLD, s);
g.setFont(Hel);
FontMetrics fm = g.getFontMetrics(Hel);
int cx=fm.stringWidth(st);
cx=(x-cx)/2;
g.setColor(Color.blue);
g.drawString( st, cx, y );
} // End of standard methods
} // End of Banner2b
>
>
/* IEEELogo.java Version 2.0 030105
*
* This class is used to provide a floating IEEE logo.
* It is in particular used in the Banner2b applet,
*
* Copyright (c) A-Square Inc.,
* 175 Richdale Ave, Cambridge MA 02140
* All Rights Reserved.
*/
import java.awt.*;
public class IEEELogo extends Logo{
/** In this class we only need to define the two methods
* declared abstract in Logo:
* drawLogo(Graphics g)which draws the object of size s centered at point p
* eraseLogo(Graphics g, Color c) which erases the object by drawing a
* rectangle of size s and the color c centered at point p
*
*/
// The following constructor invokes the super constructor, that is the
// constructor of the class this class extends
public IEEELogo(int xmax, int ymax, int size){
super(xmax,ymax,size);
// Import a gif image. This works only because Logo extends Component
// and precludes the use of this applet in a JDK 1.0.2 environment.
// It also causes a security exception when executed in a browser.
// See Exercise 3d for how the picture or any resource may be imported
// in a Rart universe also when executing in an applet environment.
Image logo1 = getRartImage("num3blu.gif");
logo = logo1.getScaledInstance(2*size, 2*size, Image.SCALE_FAST);
}
public void drawLogo(Graphics g){
int w=s; //half width
int h=s; //half height
g.drawImage(logo, p.x-w, p.y-h, this);
}
public void eraseLogo(Graphics g, Color c){
// Erases the IEEE logo by drawing a rectangle of size
// 2*s by 2*s centered at p
int w=s;
int h=s;
g.setColor(c);
g.fillRect(p.x-w,p.y-h,2*w,2*h);
}
private Image logo;
}
>
Note: Identical to class with same name in the source for Banner2a
>
/**
* Logo.java version 1.0 000910
*
* This is an example of an abstract class. We prescribe a behavior common to
* all concrete implementations of this class, which prescribe the way Logo
* objects float on the screen. We leave the specifics on how an actual Logo
* looks to the programmer who uses the class.
*
* Copyright (c) A-Square Inc.,
* 1648 Waters Edge Lane, Reston, VA 20190
* All Rights Reserved.
*
*/
import java.awt.*;
public abstract class Logo extends Component{
/* In an abstract class some items are left for the extending classes to
* define. In this case the extending classes will define the look of the
* floating objects.
* Movement is defined in the moveLogo() method and can be influenced by the
* MouseDown() method.
* Jan Aminoff, A-Square, September 2000.
*/
public Logo(int xm, int ym, int size){
/**
* This constructor initiates a Logo of size size floating within
* the rectangle with (0.0) as the upper right and (xm, ym) at lower left.
*/
maxx = xm;
maxy = ym;
p= new Point( RND(maxx), RND(maxy));
// d.dbg("Point : "+p.x+ ", "+p.y);
s = size;
maxv = 2+(maxx+maxy)/100;
dx=setSpeed(maxv);
dy=setSpeed(maxv);
}
public abstract void drawLogo(Graphics g);
/* Abstract method draw
* Draws a Logo of size s pixels at Point p (Coordinates p.x and p.y)
* using the Graphics Context g
*/
public abstract void eraseLogo(Graphics g, Color c);
/* Abstract method erase
* erases a Logo of size s pixels centered at p by drawing
* it using the Color c, for example the background color, using g
*/
public void moveLogo(){
/* This is NOT an abstract method! It encapsulates the moving of a
* point bouncing as we have seen a number of times.
*/
int x = p.x;
int y = p.y;
x += dx;
y += dy;
// check to see if point hit the edge
if (x < 0 || x > maxx ){ // Check to see if the point hit the edge in x-direction
dx = (x < 0)? ABS(dx) : - ABS(dx); //Ensure point always moving toward center
x += 2*dx; //Double back
dy = setSpeed(maxv); //change speed in y-direction
}
if (y < 0 || y > maxy ){
dy = (y < 0)? ABS(dy) : - ABS(dy);
y += 2*dy;
dx = setSpeed(maxv); //change speed in x-direction
}
p = new Point(x,y);
}
public void setMaxSpeed( int vmax){
maxv = vmax;
}
public void stopMove(){
dx1=dx;
dx=0;
dy1=dy;
dy=0;
}
public void resumeMove(){
dx=dx1;
dy=dy1;
}
private int setSpeed(int mv){
// We will also define a method to generate a change of speed based on
// a maximum speed mv
int v;
do v = mv/2- RND(mv);
while (v ==0);
return v;
}
// The following methods are protected. This means the methods are available
// to methods extending the Logo class but not elsewhere.
protected Image getRartImage(String s){
// This method is identical to one provided in the Universe class
// The point here is to allow the extensions of the Logo class to
// import and display their own pictures.
// However, while this works fine in the appletviewer, it causes an
// security exception when run in a browser.
return Toolkit.getDefaultToolkit().getImage(s);
}
// RND generates any of the integers in the interval 0 to max - 1.
protected static int RND(int max)
{
return (int)(java.lang.Math.random() * max);
}
// ABS(x) returns the absolute value of the integer x
protected static int ABS(int x){
return ((x>0)? x: -x);
}
// The following two variables are protected, that is their values are
// at any time available to any class extending the Logo class.
// In particular the values are used to draw the object in the draw
// method
protected Point p; // The center of the object.
// A point with coordinates p.x and p.y
protected int s; // A measure of the size of the object
//Here we list the private variables used by the class
private int maxx; //Windowsize in x-direction
private int maxy; //Windowsize in y-direction
private int maxv; //Maximum sped in any direction, pixels per frame
private int dx; //Current speed in x-direction
private int dy; //Current speed in y-direction
private int dx1; //Keeper for speed in x-direction
private int dy1; //Keeper for speed in y-direction
}
>