home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 1998 November
/
Chip_1998-11_cd.bin
/
tema
/
Cafe
/
Source.bin
/
Plasma.java
< prev
next >
Wrap
Text File
|
1998-03-18
|
14KB
|
485 lines
package symantec.itools.multimedia;
import java.awt.Canvas;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.IndexColorModel;
import java.awt.image.MemoryImageSource;
import symantec.itools.lang.OS;
// 05/29/97 RKM Changed invalidate to repaint
// Changed symantec.beans references to java.beans
// No Bounding and constraining of the previewMode property (doesn't make sense)
// Deprecated getter for booleans, and added is
// 07/16/97 CAR marked fields transient as needed
// 07/16/97 CAR implemented readObject
// 10/17/97 LAB Added additional checking in removeNotify to avoid NullPointerExceptions
// (Addresses Mac Bug #9479).
/**
* Plasma component.
* Creates an animation of colored amorphous shapes, where colors gradually
* modulate as shapes merge and separate.
*
* @version 1.0, Nov 26, 1996
* @author Symantec
*/
public class Plasma
extends Canvas
implements Runnable
{
int xpoints[];
int ypoints[];
byte red[];
byte green[];
byte blue[];
byte buffer[];
byte costab[];
Dimension dim = null;
transient IndexColorModel cModel = null;
transient Image img = null;
byte x1;
byte x2;
byte y1;
byte y2;
byte x1mod = 6;
byte x2mod = 8;
byte y1mod = 6;
byte y2mod = 4;
boolean keepGoing = true;
boolean suspended = false;
boolean stopThread = false;
boolean Threadstopped = false;
transient Thread displayThread = null;
private boolean previewMode = false;
/**
* Create default plasma component.
*/
public Plasma()
{
super();
xpoints = new int[5];
ypoints = new int[5];
red = new byte[128];
green = new byte[128];
blue = new byte[128];
dopalette();
cModel = new IndexColorModel(7, 128, red, green, blue);
costab = new byte[256];
setupcos();
createBuffer();
}
void createBuffer()
{
dim = size();
buffer = new byte[dim.width * (dim.height + 100)];
img = null;
}
/**
* Tells this component that it has been added to a container.
* This is a standard Java AWT method which gets called by the AWT when
* this component is added to a container. Typically, it is used to
* create this component's peer.
*
* It has been overridden here to start the plasma thread.
*
* @see #removeNotify
*/
public synchronized void addNotify()
{
super.addNotify();
displayThread = new Thread(this);
displayThread.setPriority(Thread.MIN_PRIORITY);
displayThread.start();
}
/**
* Tells this component that it is being removed from a container.
* This is a standard Java AWT method which gets called by the AWT when
* this component is removed from a container. Typically, it is used to
* destroy the peers of this component and all its subcomponents.
*
* It has been overridden here to stop the plasma thread.
*
* @see #addNotify
*/
public synchronized void removeNotify()
{
keepGoing = false;
stopThread = false;
if (displayThread != null && displayThread.isAlive())
{
displayThread.setPriority(Thread.MAX_PRIORITY);
}
if (displayThread != null && displayThread.isAlive())
{
displayThread.resume();
}
while (displayThread != null && displayThread.isAlive())
{
try { Thread.sleep(40); } catch(Exception e) { };
}
super.removeNotify();
}
/**
* Resume plasma animation.
*/
public void startPlasma() {
suspended = false;
show();
}
/**
* Suspend plasma animation.
*/
public void stopPlasma() {
suspended = true;
}
/**
* Makes this component visible.
* This is a standard Java AWT method which gets called to show this
* component. If this component was invisible due to a previous hide()
* call it make this component visible again.
*
* @see #hide
*/
public synchronized void show() {
if (displayThread != null) {
if (stopThread) {
stopThread = false;
}
else {
displayThread.setPriority(Thread.MAX_PRIORITY);
displayThread.resume();
}
}
}
/**
* Makes this component invisible.
* This is a standard Java AWT method which gets called to hide
* this component. A hidden component cannot be seen by the user nor
* does it take up space in its container, but it does continue to
* exist.
*
* @see #show
*/
public synchronized void hide() {
if (!Threadstopped) {
stopThread = true;
displayThread.setPriority(Thread.MAX_PRIORITY);
}
}
/**
* Moves and/or resizes this component.
* This is a standard Java AWT method which gets called to move and/or
* resize this component. Components that are in containers with layout
* managers should not call this method, but rely on the layout manager
* instead.
*
* @param x horizontal position in the parent's coordinate space
* @param y vertical position in the parent's coordinate space
* @param width the new width
* @param height the new height
*/
public synchronized void reshape(int x,
int y,
int width,
int height)
{
super.reshape(x,y,width,height);
createBuffer();
}
/**
* Sets the preview mode flag. This flag is used by Visual Cafe to
* determine if this component should be run during design time.
* @param f new preview mode
* @see #getPreviewMode
*/
public void setPreviewMode(boolean f)
{
previewMode = f;
repaint();
}
/**
* @deprecated As of JDK version 1.1,
* replaced by isPreviewMode.
*/
public boolean getPreviewMode()
{
return previewMode;
}
/**
* Gets the preview mode flag. This flag is used by Visual Cafe to
* determine if this component should be run during design time.
* @see #setPreviewMode
*/
public boolean isPreviewMode()
{
return previewMode;
}
/**
* Plasma thread body. This method is called by the Java virtual
* machine to when this thread starts.
*/
public void run()
{
while (keepGoing) {
if ((!stopThread) && (!suspended) && (previewMode || !java.beans.Beans.isDesignTime()))
repaint();
if (stopThread) {
super.hide();
Threadstopped = true;
displayThread.setPriority(Thread.MIN_PRIORITY);
displayThread.suspend();
Threadstopped = false;
if (keepGoing) {
super.show();
displayThread.setPriority(Thread.MIN_PRIORITY);
}
}
else {
if (keepGoing)
try { Thread.sleep(100); } catch(Exception e) { };
}
}
displayThread = null;
}
transient private int iteration = 0;
transient private final int MAX_ITERATION_GC = 25;
/**
* Paints this component using the given graphics context.
* This is a standard Java AWT method which typically gets called
* by the AWT to handle painting this component. It paints this component
* using the given graphics context. The graphics context clipping region
* is set to the bounding rectangle of this component and its <0,0>
* coordinate is this component's top-left corner.
*
* @param g the graphics context used for painting
* @see java.awt.Component#repaint
* @see #update
*/
public void paint(Graphics g)
{
if (!suspended && (previewMode || !java.beans.Beans.isDesignTime()))
moveplasma();
//If img is null, we need to create one
if (img == null)
{
drawplasma();
try
{
img = createImage(new MemoryImageSource(dim.width,dim.height,cModel,buffer,0,dim.width));
}
catch(Exception e)
{
}
}
if (OS.isMacintosh())
{
//Clip the width of the component
g.clipRect(0, 0, dim.width, dim.height);
}
//Draw border
g.drawRect(0, 0, dim.width - 1, dim.height - 1);
//Inset clip 1,1
g.clipRect(1, 1, dim.width - 2, dim.height - 2);
//Draw plasma image
if (img != null)
{
if (symantec.itools.lang.OS.isMacintosh())
g.drawImage(img, 1, 1, null);
else
g.drawImage(img, 1, 1, this);
}
if (++iteration > MAX_ITERATION_GC) {
System.gc();
iteration = 0;
}
}
/**
* Handles redrawing of this component on the screen.
* This is a standard Java AWT method which gets called by the Java
* AWT (repaint()) to handle repainting this component on the screen.
* The graphics context clipping region is set to the bounding rectangle
* of this component and its <0,0> coordinate is this component's
* top-left corner.
* Typically this method paints the background color to clear the
* component's drawing space, sets graphics context to be the foreground
* color, and then calls paint() to draw the component.
*
* It is overridden here to reduce flicker by eliminating the uneeded
* clearing of the background.
*
* @param g the graphics context
* @see java.awt.Component#repaint
* @see #paint
*/
public void update(Graphics g)
{
paint(g);
}
/**
* Draws plasma data into an internal buffer. Not generally called directly.
*/
public void drawplasma()
{
int i;
int j;
char t1;
char t2;
char t3;
char t4;
t3 = (char) (y1);
t4 = (char) (y2);
for(j = 0; j < dim.height * dim.width; j += dim.width + dim.width + dim.width)
{
t1 = (char) (x1);
t2 = (char) (x2);
for(i = 0; i < dim.width; i += 4)
{
buffer[i + j] = (byte) ((costab[t1 & 255] +
costab[t2 & 255] +
costab[t3 & 255] +
costab[t4 & 255]));
buffer[i + j + 1] = buffer[i + j];
buffer[i + j + 2] = buffer[i + j];
buffer[i + j + 3] = buffer[i + j];
buffer[i + j + dim.width] = buffer[i + j];
buffer[i + j + dim.width + 1] = buffer[i + j];
buffer[i + j + dim.width + 2] = buffer[i + j];
buffer[i + j + dim.width + 3] = buffer[i + j];
buffer[i + j + dim.width + dim.width] = buffer[i + j];
buffer[i + j + dim.width + dim.width + 1] = buffer[i + j];
buffer[i + j + dim.width + dim.width + 2] = buffer[i + j];
buffer[i + j + dim.width + dim.width + 3] = buffer[i + j];
t1 += x1mod;
t2 += x2mod;
}
t3 += y1mod;
t4 += y2mod;
}
}
/**
* Moves Plasma occurance location at random within component. Not generally called directly.
*/
public void moveplasma()
{
x1 -= x1mod * 2;
y1 += y1mod * 2;
x1 += (byte) (Math.random() * 3);
x2 -= (byte) (Math.random() * 4);
y1 += (byte) (Math.random() * 3);
y2 -= (byte) (Math.random() * 5);
//Null the image, so we recreate it
if (img!=null) img.flush();
img = null;
}
/**
* Setup Plasma Palette. Not generally called directly.
*/
public void dopalette()
{
int i;
for(i = 0; i < 32; i++)
{
red[i] = (byte) 255;
green[i] = 0;
blue[i] = (byte) (i*8);
}
for(i = 32; i < 96; i++)
{
red[i] = (byte) (255-(i*8));
green[i] = (byte) (i*8);
blue[i] = (byte) 255;
}
for(i = 64; i < 96; i++)
{
red[i] = 0;
green[i] = (byte) 255;
blue[i] = (byte) (255-(i*8));
}
for(i = 96; i < 128; i++)
{
red[i] = (byte) (i*8);
green[i] = (byte) (255-(i*8));
blue[i] = 0;
}
}
/**
* Setup Plasma cosine table. Not generally called directly.
*/
public void setupcos()
{
int i;
for(i = 0; i < 256; i++)
{
costab[i]=(byte) (16 + Math.cos(((double)i * 360 / 255 / 180) *Math.PI) * 15);
}
}
private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
in.defaultReadObject();
cModel = new IndexColorModel(7, 128, red, green, blue);
}
}