📄 animator.java
字号:
} } } 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(""); } }/** * A class that represents an animation to be displayed by the applet */class Animation extends Object { static final int STARTUP_ID = 0; static final int BACKGROUND_ID = 1; static final int ANIMATION_ID = 2; static final String imageLabel = "image"; static final String soundLabel = "sound"; int globalPause = 1300; // global pause in milleseconds List frames = null; // List holding frames of animation int currentFrame; // Index into images for current position Image startUpImage = null; // The startup image if any Image backgroundImage = null; // The background image if any AudioClip soundTrack = null; // The soundtrack for this animation Color backgroundColor = null; // Background color if any URL backgroundImageURL = null; // URL of background image if any URL startUpImageURL = null; // URL of startup image if any URL soundTrackURL = null; // URL of soundtrack URL imageSource = null; // Directory or URL for images URL soundSource = null; // Directory or URL for sounds boolean repeat; // Repeat the animation if true Image offScrImage; // Offscreen image Graphics offScrGC; // Offscreen graphics context MediaTracker tracker; // MediaTracker used to load images Animator owner; // Applet that contains this animation Animation(Animator container) { super(); owner = container; } void init() { tracker = new MediaTracker(owner); currentFrame = 0; loadAnimationMedia(); startPlaying(); } void setGlobalPause(int pause) { globalPause = pause; } /** * Loads the images and sounds involved with this animation */ void loadAnimationMedia() { URL badURL; boolean error; try { if (startUpImageURL != null) { owner.tellLoadingMsg(startUpImageURL, imageLabel); startUpImage = fetchImageAndWait(startUpImageURL, STARTUP_ID); if (tracker.isErrorID(STARTUP_ID)) { owner.loadError(startUpImageURL, "start-up image"); } owner.repaint(); } if (backgroundImageURL != null) { owner.tellLoadingMsg(backgroundImageURL, imageLabel); backgroundImage = fetchImageAndWait(backgroundImageURL, BACKGROUND_ID); if (tracker.isErrorID(BACKGROUND_ID)) owner.loadError(backgroundImageURL, "background image"); owner.repaint(); } // Fetch the animation frame images Iterator iterator = frames.iterator(); while(iterator.hasNext()) { AnimationFrame frame = (AnimationFrame) iterator.next(); owner.tellLoadingMsg(frame.imageLocation, imageLabel); frame.image = owner.getImage(frame.imageLocation); tracker.addImage(frame.image, ANIMATION_ID); try { tracker.waitForID(ANIMATION_ID); } catch (InterruptedException e) {} } if (soundTrackURL != null && soundTrack == null) { owner.tellLoadingMsg(soundTrackURL, imageLabel); soundTrack = owner.getAudioClip(soundTrackURL); if (soundTrack == null) { owner.loadError(soundTrackURL, "soundtrack"); return; } } // Load the sounds into their frames iterator = frames.iterator(); while(iterator.hasNext()) { AnimationFrame frame = (AnimationFrame) iterator.next(); if (frame.soundLocation != null) { owner.tellLoadingMsg(frame.soundLocation, soundLabel); try { frame.sound = owner.getAudioClip(frame.soundLocation); } catch (Exception ex) { owner.loadError(frame.soundLocation, soundLabel); } } } owner.clearLoadingMessage(); offScrImage = owner.createImage(owner.appWidth, owner.appHeight); offScrGC = offScrImage.getGraphics(); offScrGC.setColor(Color.lightGray); owner.loaded = true; error = false; } catch (Exception e) { error = true; e.printStackTrace(); } } /** * Fetch an image and wait for it to come in. Used to enforce a load * order for background and startup images. */ Image fetchImageAndWait(URL imageURL, int trackerClass) throws InterruptedException { Image image = owner.getImage(imageURL); tracker.addImage(image, trackerClass); tracker.waitForID(trackerClass); return image; } /** * Stuff a range of image names into a List * @return a List of image URLs. */ void prepareImageRange(int startImage, int endImage, String pattern) throws MalformedURLException { frames = new ArrayList(Math.abs(endImage - startImage) + 1); if (pattern == null) pattern = "T%N.gif"; if (startImage > endImage) { for (int i = startImage; i >= endImage; i--) { AnimationFrame frame = new AnimationFrame(); frames.add(frame); frame.duration = globalPause; frame.imageLocation = new URL(imageSource, doSubst(pattern, i+"")); } } else { for (int i = startImage; i <= endImage; i++) { AnimationFrame frame = new AnimationFrame(); frames.add(frame); frame.duration = globalPause; frame.imageLocation = new URL(imageSource, doSubst(pattern, i+"")); } } } /** * Parse the SOUNDS parameter. It looks like * train.au||hello.au||stop.au, etc., where each item refers to a * source image. Empty items mean that the corresponding image * has no associated sound. */ void parseSounds(String attr) throws MalformedURLException { int frameIndex = 0; int numFrames = frames.size(); for (int i = 0; (i < attr.length()) && (frameIndex < numFrames); ) { int next = attr.indexOf('|', i); if (next == -1) next = attr.length(); String sound = attr.substring(i, next); if (sound.length() != 0) { AnimationFrame frame = (AnimationFrame) frames.get(frameIndex); frame.soundLocation = new URL(soundSource, sound); } i = next + 1; frameIndex++; } } /** * Parse the IMAGES parameter. It looks like * 1|2|3|4|5, etc., where each number (item) names a source image. */ void parseImages(String attr, String pattern) throws MalformedURLException { frames = new ArrayList(); if (pattern == null) pattern = "T%N.gif"; for (int i = 0; i < attr.length(); ) { int next = attr.indexOf('|', i); if (next == -1) next = attr.length(); String file = attr.substring(i, next); AnimationFrame frame = new AnimationFrame(); frames.add(frame); frame.imageLocation = new URL(imageSource, doSubst(pattern, file)); frame.duration = globalPause; i = next + 1; } } /** * Parse the PAUSES parameter. It looks like * 1000|500|||750, etc., where each item corresponds to a * source image. Empty items mean that the corresponding image * has no special duration, and should use the global one. * * @return a Hashtable of Integer pauses keyed to Integer * frame numbers. */ void parseDurations(String attr) { int imageNum = 0; int numImages = frames.size(); for (int i = 0; (i < attr.length()) && (imageNum < numImages); ) { int next = attr.indexOf('|', i); if (next == -1) next = attr.length(); AnimationFrame aFrame = (AnimationFrame) frames.get(imageNum); if (i != next) { int duration = Integer.parseInt(attr.substring(i, next)); aFrame.duration = duration; } i = next + 1; imageNum++; } } /** * Parse a String of form xxx@yyy and return a Point. */ Point parsePoint(String s) throws ParseException { int atPos = s.indexOf('@'); if (atPos == -1) throw new ParseException("Illegal position: "+s); return new Point(Integer.parseInt(s.substring(0, atPos)), Integer.parseInt(s.substring(atPos + 1))); } /** * Parse the POSITIONS parameter. It looks like * 10@30|11@31|||12@20, etc., where each item is an X@Y coordinate * corresponding to a source image. Empty items mean that the * corresponding image has the same position as the preceding one. * * @return a Hashtable of Points keyed to Integer frame numbers. */ void parsePositions(String param) throws ParseException { int imageNum = 0; int numImages = frames.size(); for (int i = 0; (i < param.length()) && (imageNum < numImages); ) { int next = param.indexOf('|', i); if (next == -1) next = param.length(); if (i != next) { AnimationFrame frame = (AnimationFrame) frames.get(imageNum); frame.position = parsePoint(param.substring(i, next)); } i = next + 1; imageNum++; } } /** * Substitute an integer some number of times in a string, subject to * parameter strings embedded in the string. * Parameter strings: * %N - substitute the integer as is, with no padding. * %<digit>, for example %5 - substitute the integer left-padded with * zeros to <digits> digits wide. * %% - substitute a '%' here. * @param inStr the String to substitute within * @param theInt the int to substitute, as a String. */ 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(); } void startPlaying() { if (soundTrack != null) soundTrack.loop(); } void stopPlaying() { if (soundTrack != null) soundTrack.stop(); } public void paint(Graphics g) { int xPos = 0; int yPos = 0; if ((frames.size() > 0) && tracker.checkID(ANIMATION_ID) && (offScrGC != null)) { AnimationFrame frame = (AnimationFrame) frames.get(currentFrame); Image image = frame.image; if (backgroundImage == null) { offScrGC.clearRect(0, 0, owner.appWidth, owner.appHeight); } else offScrGC.drawImage(backgroundImage, 0, 0, owner); Point pos = null; if (frame.position != null) { xPos = frame.position.x; yPos = frame.position.y; } if (backgroundColor != null) { offScrGC.setColor(backgroundColor); offScrGC.fillRect(0, 0, owner.appWidth, owner.appHeight); offScrGC.drawImage(image, xPos, yPos, backgroundColor, owner); } else { offScrGC.drawImage(image, xPos, yPos, owner); } if (offScrImage != null) g.drawImage(offScrImage, 0, 0, owner); } }}/** * Instances of this class represent a single frame of an animation * There can be an image, sound, and position associated with each frame */class AnimationFrame extends Object { static final String imageLabel = "image"; static final String soundLabel = "sound"; URL imageLocation = null; // Directory or URL of this frames image URL soundLocation = null; // Directory or URL of this frames sound int duration; // Duration time for this frame in milliseconds AudioClip sound; // Sound associated with this frame object Image image; // Image associated with this frame Point position; // Position of this frame}/** * 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 + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -