animator.java

来自「《移动Agent技术》一书的所有章节源代码。」· Java 代码 · 共 1,135 行 · 第 1/2 页

JAVA
1,135
字号
     */
    String doSubst(String inStr, String theInt) {
	String padStr = "0000000000";
	int length = inStr.length();
	StringBuffer result = new StringBuffer(length);
	
	for (int i = 0; i < length;) {
	    char ch = inStr.charAt(i);
	    if (ch == '%') {
		i++;
		if (i == length) {
		    result.append(ch);
		} else {
		    ch = inStr.charAt(i);
		    if (ch == 'N' || ch == 'n') {
			// just stick in the number, unmolested
			result.append(theInt);
			i++;
		    } else {
			int pad;
			if ((pad = Character.digit(ch, 10)) != -1) {
			    // we've got a width value
			    String numStr = theInt;
			    String scr = padStr+numStr;
			    result.append(scr.substring(scr.length() - pad));
			    i++;
			} else {
			    result.append(ch);
			    i++;
			}
		    }
		}
	    } else {
		result.append(ch);
		i++;
	    }
	}
	return result.toString();
    }	

    /**
     * Stuff a range of image names into a Vector.
     *
     * @return a Vector of image URLs.
     */
    Vector prepareImageRange(int startImage, int endImage, String pattern)
    throws MalformedURLException {
	Vector result = new Vector(Math.abs(endImage - startImage) + 1);
	if (pattern == null) {
	    pattern = "T%N.gif";
	}
	if (startImage > endImage) {
	    for (int i = startImage; i >= endImage; i--) {
		result.addElement(new URL(imageSource, doSubst(pattern, i+"")));
	    }
	} else {
	    for (int i = startImage; i <= endImage; i++) {
		result.addElement(new URL(imageSource, doSubst(pattern, i+"")));
	    }
	}

	return result;
    }

    
    /**
     * Initialize the applet.  Get parameters.
     */
    public void init() {


	tracker = new MediaTracker(this);

	appWidth = getSize().width;
	appHeight = getSize().height;

	try {
	    String param = getParam("IMAGESOURCE");	
	    imageSource = (param == null) ? getDocumentBase() : new URL(getDocumentBase(), param + "/");
	
	    String href = getParam("HREF");
	    if (href != null) {
		try {
		    hrefURL = new URL(getDocumentBase(), href);
		} catch (MalformedURLException e) {
		    showParseError(e);
		}
	    }

	    hrefTarget = getParam("TARGET");
	    if (hrefTarget == null) {
		hrefTarget = "_top";
	    }

	    param = getParam("PAUSE");
	    globalPause =
		(param != null) ? Integer.parseInt(param) : defaultPause;

	    param = getParam("REPEAT");
	    repeat = (param == null) ? true : (param.equalsIgnoreCase("yes") ||
					       param.equalsIgnoreCase("true"));

	    int startImage = 1;
	    int endImage = 1;
	    param = getParam("ENDIMAGE");
	    if (param != null) {
		endImage = Integer.parseInt(param);
		param = getParam("STARTIMAGE");
		if (param != null) {
		    startImage = Integer.parseInt(param);
		}
		param = getParam("NAMEPATTERN");
		images = prepareImageRange(startImage, endImage, param);
	    } else {
		param = getParam("STARTIMAGE");
		if (param != null) {
		    startImage = Integer.parseInt(param);
		    param = getParam("NAMEPATTERN");
		    images = prepareImageRange(startImage, endImage, param);
		} else {
		    param = getParam("IMAGES");
		    if (param == null) {
			showStatus("No legal IMAGES, STARTIMAGE, or ENDIMAGE "+
				   "specified.");
			error = true;
			return;
		    } else {
			images = parseImages(param, getParam("NAMEPATTERN"));
		    }
		}
	    }

	    param = getParam("BACKGROUND");
	    if (param != null) {
		backgroundImageURL = new URL(imageSource, param);
	    }

	    param = getParam("BACKGROUNDCOLOR");
	    if (param != null) {
		backgroundColor = decodeColor(param);
	    }

	    param = getParam("STARTUP");
	    if (param != null) {
		startUpImageURL = new URL(imageSource, param);
	    }

	    param = getParam("SOUNDSOURCE");
	    soundSource = (param == null) ? imageSource : new URL(getDocumentBase(), param + "/");
	
	    param = getParam("SOUNDS");
	    if (param != null) {
		sounds = parseSounds(param, images);
	    }

	    param = getParam("PAUSES");
	    if (param != null) {
		durations = parseDurations(param, images);
	    }

	    param = getParam("POSITIONS");
	    if (param != null) {
		positions = parsePositions(param, images);
	    }

	    param = getParam("SOUNDTRACK");
	    if (param != null) {
		soundtrackURL = new URL(soundSource, param);
	    }
	} catch (MalformedURLException e) {
	    showParseError(e);
	} catch (ParseException e) {
	    showParseError(e);
	}

	setFrameNum(0);
	addMouseListener(this);
    }

    Color decodeColor(String s) {
	int val = 0;
	try {
	    if (s.startsWith("0x")) {
		val = Integer.parseInt(s.substring(2), 16);
	    } else if (s.startsWith("#")) {
		val = Integer.parseInt(s.substring(1), 16);
	    } else if (s.startsWith("0") && s.length() > 1) {
		val = Integer.parseInt(s.substring(1), 8);
	    } else {
		val = Integer.parseInt(s, 10);
	    }
	    return new Color(val);
	} catch (NumberFormatException e) {
	    return null;
	}
    }

    void tellLoadingMsg(String file, String fileType) {
	showStatus("Animator: loading "+fileType+" "+file);
    }

    void tellLoadingMsg(URL url, String fileType) {
	tellLoadingMsg(url.toExternalForm(), fileType);
    }

    void clearLoadingMessage() {
	showStatus("");
    }
    
    void loadError(String fileName, String fileType) {
	String errorMsg = "Animator: Couldn't load "+fileType+" "+
	    fileName;
	showStatus(errorMsg);
	System.err.println(errorMsg);
	error = true;
	repaint();
    }

    void loadError(URL badURL, String fileType) {
	loadError(badURL.toExternalForm(), fileType);
    }

    void loadErrors(Object errors[], String fileType) {
	for (int i = 0; i < errors.length; i++) {
	    if (errors[i] instanceof Image) {
		URL url = (URL)imageNames.get((Image)errors[i]);
		if (url != null) {
		    loadError(url, fileType);
		}
	    }
	}
    }

    void showParseError(Exception e) {
	String errorMsg = "Animator: Parse error: "+e;
	showStatus(errorMsg);
	System.err.println(errorMsg);
	error = true;
	repaint();
    }

    void startPlaying() {
	if (soundtrack != null) {
	    soundtrack.loop();
	}
    }

    void stopPlaying() {
	if (soundtrack != null) {
	    soundtrack.stop();
	}
    }

    /**
     * Run the animation. This method is called by class Thread.
     * @see java.lang.Thread
     */
    public void run() {
	Thread me = Thread.currentThread();
	URL badURL;
	
	me.setPriority(Thread.MIN_PRIORITY);

	if (! loaded) {
	    try {
		// ... to do a bunch of loading.
		if (startUpImageURL != null) {
		    tellLoadingMsg(startUpImageURL, imageLabel);
		    startUpImage = fetchImageAndWait(startUpImageURL,
						     STARTUP_ID);
		    if (tracker.isErrorID(STARTUP_ID)) {
			loadError(startUpImageURL, "start-up image");
		    }
		    repaint();
		}
	    
		if (backgroundImageURL != null) {
		    tellLoadingMsg(backgroundImageURL, imageLabel);
		    backgroundImage = fetchImageAndWait(backgroundImageURL, 
							BACKGROUND_ID);
		    if (tracker.isErrorID(BACKGROUND_ID)) {
			loadError(backgroundImageURL, "background image");
		    }
		    repaint();
		}

		// Fetch the animation frames
		if (!fetchImages(images)) {
		    // get images in error, tell user about first of them
		    Object errors[] = tracker.getErrorsAny();
		    loadErrors(errors, imageLabel);
		    return;
		}

		if (soundtrackURL != null && soundtrack == null) {
		    tellLoadingMsg(soundtrackURL, imageLabel);
		    soundtrack = getAudioClip(soundtrackURL);
		    if (soundtrack == null) {
			loadError(soundtrackURL, "soundtrack");
			return;
		    }
		}

		if (sounds != null) {
		    badURL = fetchSounds(sounds);
		    if (badURL != null) {
			loadError(badURL, soundLabel);
			return;
		    }
		}

		clearLoadingMessage();

		offScrImage = createImage(appWidth, appHeight);
		offScrGC = offScrImage.getGraphics();
		offScrGC.setColor(Color.lightGray);

		loaded = true;
		error = false;
	    } catch (Exception e) {
		error = true;
		e.printStackTrace();
	    }
	}

	if (userPause) {
	    return;
	}

	if (repeat || frameNum < images.size()) {
	    startPlaying();
	}

	try {
	    if (images != null && images.size() > 1) {
		while (appWidth > 0 && appHeight > 0 && engine == me) {
		    if (frameNum >= images.size()) {
			if (!repeat) {
			    return;
			}
			setFrameNum(0);
		    }
		    repaint();

		    if (sounds != null) {
			AudioClip clip =
			    (AudioClip)sounds.get(frameNumKey);
			if (clip != null) {
			    clip.play();
			}
		    }

		    try {
			Integer pause = null;
			if (durations != null) {
			    pause = (Integer)durations.get(frameNumKey);
			}
			if (pause == null) {
			    Thread.sleep(globalPause);
			} else {
			    Thread.sleep(pause.intValue());
			}
		    } catch (InterruptedException e) {
			// Should we do anything?
		    }
		    setFrameNum(frameNum+1);
		}
	    }
	} finally {
	    stopPlaying();
	}
    }

    /**
     * No need to clear anything; just paint.
     */
    public void update(Graphics g) {
	paint(g);
    }

    /**
     * Paint the current frame.
     */
    public void paint(Graphics g) {
	if (error || !loaded) {
	    if (startUpImage != null) {
		if (tracker.checkID(STARTUP_ID)) {
		    if (backgroundColor != null) {
			g.setColor(backgroundColor);
			g.fillRect(0, 0, appWidth, appHeight);
		    }
		    g.drawImage(startUpImage, 0, 0, this);
		}
	    } else {
		if (backgroundImage != null) {
		    if (tracker.checkID(BACKGROUND_ID)) {
			g.drawImage(backgroundImage, 0, 0, this);
		    }
		} else {
		    g.clearRect(0, 0, appWidth, appHeight);
		}
	    }
	} else {
	    if ((images != null) && (images.size() > 0) &&
		tracker.checkID(ANIMATION_ID)) {
		if (frameNum < images.size()) {
		    if (backgroundImage == null) {
			offScrGC.clearRect(0, 0, appWidth, appHeight);
		    } else {
			offScrGC.drawImage(backgroundImage, 0, 0, this);
		    }

		    Image image = (Image)images.elementAt(frameNum);
		    
		    Point pos = null;
		    if (positions != null) {
			pos = (Point)positions.get(frameNumKey);
		    }
		    if (pos != null) {
			xPos = pos.x;
			yPos = pos.y;
		    }
		    if (backgroundColor != null) {
			offScrGC.setColor(backgroundColor);
			offScrGC.fillRect(0, 0, appWidth, appHeight);
			offScrGC.drawImage(image, xPos, yPos, backgroundColor,
					   this);
		    } else {
			offScrGC.drawImage(image, xPos, yPos, this);
		    }
		    g.drawImage(offScrImage, 0, 0, this);
		} else {
		    // no more animation, but need to draw something
		    dbg("No more animation; drawing last image.");
		    if (backgroundImage == null) {
			g.fillRect(0, 0, appWidth, appHeight);
		    } else {
			g.drawImage(backgroundImage, 0, 0, this);
		    }
		    g.drawImage((Image)images.lastElement(), 0, 0, this);
		}
	    }
	}
    }

    /**
     * Start the applet by forking an animation thread.
     */
    public void start() {
	if (engine == null) {
	    engine = new Thread(this);
	    engine.start();
	}
	showStatus(getAppletInfo());
    }

    /**
     * Stop the insanity, um, applet.
     */
    public void stop() {
	if (engine != null && engine.isAlive()) {
	    engine.stop();
	}
	engine = null;
    }

    /**
     * Pause the thread when the user clicks the mouse in the applet.
     * If the thread has stopped (as in a non-repeat performance),
     * restart it.
     */
    public void mousePressed(MouseEvent event) {
	if ((event.getModifiers() & InputEvent.SHIFT_MASK) != 0) {
	    showDescription();
	    return;
	} else if (hrefURL != null) {
	    //Let mouseClicked handle this.
	    return;
        } else if (loaded) {
	    if (engine != null && engine.isAlive()) {
		if (userPause) {
		    engine.resume();
		    startPlaying();
	        } else {
	    	    engine.suspend();
	    	    stopPlaying();
	        }
	        userPause = !userPause;
	    } else {
	        userPause = false;
	        setFrameNum(0);
	        engine = new Thread(this);
	        engine.start();
	    }
	}
    }

    public void mouseClicked(MouseEvent event) {
	if ((hrefURL != null) &&
	        ((event.getModifiers() & InputEvent.SHIFT_MASK) == 0)) {
	    getAppletContext().showDocument(hrefURL, hrefTarget);
	}
    }

    public void mouseReleased(MouseEvent event) {
    }

    public void mouseEntered(MouseEvent event) {
	showStatus(getAppletInfo()+" -- "+userInstructions);
    }

    public void mouseExited(MouseEvent event) {
        showStatus("");
    }
    
}


/**
 * ParseException: signals a parameter parsing problem.
 */
class ParseException extends Exception {
    ParseException(String s) {
	super(s);
    }
}


/**
 * DescriptionFrame: implements a pop-up "About" box.
 */
class DescriptionFrame extends Frame 
		       implements ActionListener {

    static final int rows = 27;
    static final int cols = 70;
    
    TextArea info;
    Button cancel;

    DescriptionFrame() {
	super("Animator v1.10");
	add("Center", info = new TextArea(rows, cols));
	info.setEditable(false);
	info.setBackground(Color.white);
	Panel buttons = new Panel();
	add("South", buttons);
	buttons.add(cancel = new Button("Cancel"));
	cancel.addActionListener(this);
	
	pack();
    }

    public void show() {
	info.select(0,0);
	super.show();
    }

    void tell(String s) {
	info.append(s);
    }

    public void actionPerformed(ActionEvent e) {
	setVisible(false);
    }
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?