/* * MarqueeLights.java * A java program to attach blinking lights around an image * Usage: * * * * The modes can be selected through * : Forward, reverse, blink * The value string can contain * f=forward chase, r=reverse chase, F,R use multicolors * c,C=clear sequence, s,S=set sequence, C,S are random * y=yes (all on), n=no (all off) * b=blink, 1=one, +=additive * * Ken Shirriff ken.shirriff@eng.sun.com * * Copyright (c) 1996 Sun Microsystems, Inc. All Rights Reserved. * * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. * * Please refer to the file "license.txt" * for further important copyright and licensing information. */ import java.awt.*; import java.awt.image.*; import java.io.*; import java.net.*; import java.applet.Applet; // A class to hold an image and an "ok" flag. For the chase lights, stride // images are used, with the appropriate lights lit in each one. If the // image is still being loaded, ok will be set to false. imgs[stride] // is a general image buffer. class Img { Image image; Graphics graphics; boolean ok; }; public class MarqueeLights extends java.applet.Applet implements Runnable, ImageObserver { Thread marquee = null; Image outbuf; Img imgs[]; Image gif; final int ON=1; final int OFF=5; int width = 100; int height = 40; int border = 10; // The total width of the image border int stride = 3; // Number of bulbs in the chase sequence int delay = 150; // Delay between steps int newdelay = 150; // Fudged delay int bulb = 3; // Pixel size of a bulb boolean stale = true; // Image has been updated String status = ""; // For mouse entry URL url = null; // For mouse click String mode = "frbF"; // Default mode sequence int mg = 0; // Margin int gap = 1; // Gap between bulbs int wb, hb, nb; // width in bulbs, height in bulbs, number of bulbs boolean error = false; Point bulbs[]; boolean statusflag = false; // Asynchronous update of image size. Print error if size is wrong. // Set the stale flag so images are updated. public boolean imageUpdate(Image img, int infoflags, int x, int y, int inwidth, int inheight) { if ((infoflags & (WIDTH|HEIGHT)) != 0) { if (width != inwidth+2*border || height != inheight+2*border) { System.out.println("MarqueeLights: dimensions should be width="+(inwidth+2*border)+" height="+(inheight+2*border)); } } stale = true; return true; } // Compute the size of everything // wb = width in bulbs, hb = height in bulbs, nb = number of bulbs public void sizeit() { wb = (width-2*mg+gap)/(bulb+gap); hb = (height-2*bulb-2*gap+gap)/(bulb+gap); nb = 2*wb+2*hb; bulbs = new Point[nb]; int i; for (i=0;i=mode.length()) { idx=0; } n=0; initMode(modec); } if (stale) { // Redraw the images int i; for (i=0;i=stride) { rval=0; } } else { rval = n-1; if (rval<0) { rval=stride-1; } } cnt--; if (cnt<=0 && (rval%2)==0) { rval = -1; } } else if (mode == '+') { n++; rval = n; if (n < tot) { light(imgs[stride].graphics,n-1,OFF); light(imgs[stride].graphics,n-1+nb/2,OFF); } else { tot--; n=0; rval = 0; if (tot==0) { rval = -1; } } light(imgs[stride].graphics,n,ON); light(imgs[stride].graphics,n+nb/2,ON); } else if (mode == '1') { light(imgs[stride].graphics,n,OFF); rval = n+1; if (rval>=nb) { rval = -1; } else { light(imgs[stride].graphics,rval,ON); } } else if (mode == 'S' || mode=='C') { light(imgs[stride].graphics,randseq[n],mode=='S'?ON:OFF); rval = n+1; if (rval>=nb) { rval = -1; } } else if (mode == 's' || mode=='c') { light(imgs[stride].graphics,n,mode=='s'?ON:OFF); rval = n+1; if (rval>=nb) { rval = -1; } } else if (mode=='b') { for (i=0;i=6) { rval = -1; } } else if (mode=='y' || mode=='n') { rval = -1; } if (imgs[bnum].ok == false) { imgs[bnum].ok = true; imgs[bnum].image.getGraphics().drawImage(gif,border,border,width-2*border, height-2*border,this); } return rval; } public String getAppletInfo() { return "MarqueeLights by Ken Shirriff shirriff@eng.sun.com"; } public String[][] getParameterInfo() { String [][] info = { {"image ","URL ", "image (Required)"}, {"width ","int ", "image width"}, {"height ","int ", "image height"}, {"delay ","int ", "delay, default=50"}, {"bulb ","int ", "bulb size, default=10"}, {"gap ","int ", "bulb gap, default=1"}, {"border ","int ", "border width, default=10"}, {"stride ","int ", "chase stride"}, {"url ","URL ", "click url"}, {"mode ","string ", "flash mode"} }; return info; } public void start() { if (marquee == null) { marquee = new Thread(this); marquee.start(); } } public boolean mouseDown(java.awt.Event evt, int x, int y) { if (url !=null) { getAppletContext().showDocument(url); } return true; } public boolean mouseEnter(java.awt.Event evt, int x, int y) { statusflag = !statusflag; if (statusflag) { showStatus(status); } else { showStatus("MarqueeLights by Ken Shirriff"); } return true; } public boolean mouseExit(java.awt.Event evt, int x, int y) { showStatus(" "); return true; } // Compute the position of bulb n public void pos(int n, Point p) { int x=0,y=0; int excess; if (nwidth) { x=width-bulb; } y = (bulb+gap)*(n-wb)+excess/2; } else if (n-wb-hbheight) { y=height-bulb; } } else if (n-2*wb-hb=5) { g.fillOval(bulbs[n].x, bulbs[n].y,bulb,bulb); } else { g.fillRect(bulbs[n].x, bulbs[n].y,bulb,bulb); } } // Clear the image to have no bulbs on public void resetImg(Graphics g) { g.setColor(Color.black); g.fillRect(0,0,width,height); g.drawImage(gif,border,border,width-2*border, height-2*border,this); } } // MarqueeLights