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 + -
显示快捷键?