FileDocCategorySizeDatePackage
Hypnosis.javaAPI DocExample5317Sat Jan 24 10:44:36 GMT 2004je3.graphics

Hypnosis

public class Hypnosis extends JComponent implements ActionListener
A Swing component that smoothly animates a spiral in a hypnotic way.

Fields Summary
double
x
double
y
double
r1
double
r2
double
a1
double
a2
double
deltaA
double
deltaX
double
deltaY
float
linewidth
Timer
timer
BufferedImage
buffer
Graphics2D
osg
Constructors Summary
public Hypnosis(double x, double y, double r1, double r2, double a1, double a2, float linewidth, int delay, double deltaA, double deltaX, double deltaY)

	this.x = x; this.y = y;
	this.r1 = r1; this.r2 = r2;
	this.a1 = a1; this.a2 = a2;
	this.linewidth = linewidth;
	this.deltaA = deltaA;
	this.deltaX = deltaX;
	this.deltaY = deltaY;

	// Set up a timer to call actionPerformed() every delay milliseconds
	timer = new Timer(delay, this);

	// Create a buffer for double-buffering
	buffer = new BufferedImage((int)(2*r2+linewidth),
				   (int)(2*r2+linewidth), 
				   BufferedImage.TYPE_INT_RGB);

	// Create a Graphics object for the buffer, and set the linewidth
	// and request antialiasing when drawing with it
	osg = buffer.createGraphics();
	osg.setStroke(new BasicStroke(linewidth, BasicStroke.CAP_ROUND,
				      BasicStroke.JOIN_ROUND));
	osg.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
			     RenderingHints.VALUE_ANTIALIAS_ON);
    
Methods Summary
public voidactionPerformed(java.awt.event.ActionEvent e)
This method implements the ActionListener interface. Our Timer object calls this method periodically. It updates the position and angles of the spiral and requests a redraw. Instead of redrawing the entire component, however, this method requests a redraw only for the area that has changed.

	// Ask to have the old bounding box of the spiral redrawn.
	// Nothing else has anything drawn in it, so it doesn't need a redraw
	repaint((int)(x-r2-linewidth), (int)(y-r2-linewidth),
		(int)(2*(r2+linewidth)), (int)(2*(r2+linewidth)));

	// Now animate: update the position and angles of the spiral

	// Bounce if we've hit an edge
	Rectangle bounds = getBounds();
	if ((x - r2 + deltaX < 0) || (x + r2 + deltaX > bounds.width))
	    deltaX = -deltaX;
	if ((y - r2 + deltaY < 0) || (y + r2 + deltaY > bounds.height))
	    deltaY = -deltaY;

	// Move the center of the spiral
	x += deltaX;
	y += deltaY;

	// Increment the start and end angles;
	a1 += deltaA;
	a2 += deltaA;
	if (a1 > 2*Math.PI) {  // Don't let them get too big
	    a1 -= 2*Math.PI;
	    a2 -= 2*Math.PI;
	}

	// Now ask to have the new bounding box of the spiral redrawn.  This
	// rectangle will be intersected with the redraw rectangle requested
	// above, and only the combined region will be redrawn
	repaint((int)(x-r2-linewidth), (int)(y-r2-linewidth),
		(int)(2*(r2+linewidth)), (int)(2*(r2+linewidth)));
    
public booleanisDoubleBuffered()
Tell Swing not to double-buffer for us, since we do our own

 return false; 
public static voidmain(java.lang.String[] args)
This is a main() method for testing the component

	JFrame f = new JFrame("Hypnosis");
	Hypnosis h = new Hypnosis(200, 200, 10, 100, 0, 5*Math.PI, 10, 100,
				  2*Math.PI/15, 3, 5);
	f.getContentPane().add(h, BorderLayout.CENTER);
	f.setSize(400, 400);
	f.show();
	h.start();
    
public voidpaintComponent(java.awt.Graphics g)
Swing calls this method to ask the component to redraw itself. This method uses double-buffering to make the animation smoother. Swing does double-buffering automatically, so this may not actually make much difference, but it is important to understand the technique.

	// Clear the background of the off-screen image
	osg.setColor(getBackground());
	osg.fillRect(0, 0, buffer.getWidth(), buffer.getHeight());

	// Now draw a black spiral into the off-screen image
	osg.setColor(Color.black);
	osg.draw(new Spiral(r2+linewidth/2, r2+linewidth/2, r1, a1, r2, a2));

	// Now copy that off-screen image onto the screen
	g.drawImage(buffer, (int)(x-r2), (int)(y-r2), this);
    
public voidstart()

 timer.start(); 
public voidstop()

 timer.stop();