📄 hollywoodtext.java
字号:
/*
* HollywoodText.java - 30 May 1996 - Version 1.0
*
* Copyright 1997 by Bill Giel/Moondog Software
*
* E-mail: bgiel@ct2.nai.net
* WWW: http://w3.nai.net/~rvdi/bgiel/bill.htm
*
*
* A LICENSE to use, copy, modify, and distribute this software
* and its documentation for NON-COMMERCIAL purposes and without
* fee is hereby granted, provided that any use properly credits
* the author.
*
*
* THE AUTHOR 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. THE AUTHOR SHALL NOT BE LIABLE FOR ANY
* DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
* THIS SOFTWARE OR ITS DERIVATIVES.
*
*/
import java.awt.*;
import java.applet.*;
import java.net.*;
import java.util.*;
import java.io.*;
//An applet class to display text in a fashion similar to
//computer terminals that we see only in the movies :-)
public class HollywoodText extends Applet
implements Runnable
{
final String MOREMESSAGE = "More...";
Thread kicker;
Vector script = new Vector();
Image image;
boolean threadSuspended,
isRunning;
//Configurable stuff...
int width,
height;
Color bgcolor,
fgcolor;
AudioClip sound;
int cpause,
lpause,
spause,
lspace,
fontsize,
cursor,
indent,
initx,
inity,
maxy;
boolean loop;
Image bgimage;
MediaTracker tracker;
String file;
public String[][] getParameterInfo()
{
String[][] info = {
{"width", "int", "width of the applet, in pixels"},
{"height", "int", "height of the applet, in pixels"},
{"bgcolor", "String", "RGB hex triplet for 'screen' background <black>"},
{"fgcolor", "String", "RGB hex triplet for 'screen' foreground <green>"},
{"sound", "String", "Sound clip file, relative to codebase <none>"},
{"cpause", "int", "Delay between characters <25ms>"},
{"lpause", "int", "Delay between lines <250ms>"},
{"spause", "int", "Delay between repeats <500ms>"},
{"loop", "int", "Non-zero causes applet to loop <1>"},
{"script", "String", "Script file to display, relative to codebase <none>"},
{"lspace", "int", "Line spacing <15>"},
{"fontsize", "int", "Font size <12>"},
{"cursor", "int", "Width of \"Cursor\" <3>"},
{"indent", "int", "Indent value for text display in pixels <15>"},
{"initx","int", "X-coord of \"Screen\" origin in applet panel <0>"},
{"inity","int", "Y-coord of \"Screen\" origin in applet panel <0>"},
{"bgimage", "String", "Background image file, relative to codebase <none>"},
{"maxy","int","Lower limit of text display, zero uses applet height <0>"}
};
return info;
}
public String getAppletInfo()
{
return("HollywoodText Applet, Copyright 1997 by William Giel.");
}
public void init()
{
super.init();
width=size().width;
height=size().height;
String param = getParameter("bgcolor");
bgcolor = parseColorString(param, Color.black);
param = getParameter("fgcolor");
fgcolor = parseColorString(param, Color.green);
param = getParameter("sound");
sound = getClip(param);
param = getParameter("cpause");
cpause = getInt(param,25);
param = getParameter("lpause");
lpause = getInt(param,250);
param = getParameter("spause");
spause = getInt(param,500);
param = getParameter("loop");
loop = (getInt(param,1) > 0)? true : false;
param = getParameter("lspace");
lspace = getInt(param,15);
param = getParameter("fontsize");
fontsize = getInt(param,12);
param = getParameter("cursor");
cursor = getInt(param,3);
param = getParameter("indent");
indent = getInt(param,0);
param = getParameter("initx");
initx = getInt(param,0);
indent += initx;
param = getParameter("inity");
inity = getInt(param,0);
param = getParameter("maxy");
maxy = getInt(param,height);
param = getParameter("bgimage");
if(null != param){
try{
bgimage = getImage(getCodeBase(),param);
tracker = new MediaTracker(this);
tracker.addImage(bgimage,0);
}catch(Exception e){
bgimage = null;
}
}
file = getParameter("script");
if(null == file){
System.out.println("HollywoodText: No script was specified.");
return;
}
}
public void start()
{
if(null == kicker){
kicker=new Thread(this);
kicker.start();
}
}
public void stop()
{
if(null != kicker){
kicker.stop();
kicker=null;
}
}
private AudioClip getClip(String s)
{
AudioClip clip = null;
try{
URL url = new URL(getCodeBase(),s);
clip = getAudioClip(url);
}catch(Exception e){
System.out.println(e);
clip=null;
}
return clip;
}
private Color parseColorString(String colorString, Color dflt)
{
Color color;
try{
colorString = colorString.replace('#',' ').trim();
int R = Integer.valueOf(colorString.substring(0,2),16).intValue();
int G = Integer.valueOf(colorString.substring(2,4),16).intValue();
int B = Integer.valueOf(colorString.substring(4,6),16).intValue();
color = new Color(R,G,B);
}catch(Exception e){
color = dflt;
}
return color;
}
private int getInt(String s, int dflt)
{
int val;
try{
val = Integer.parseInt(s);
}catch(Exception e){
val = dflt;
}
return val;
}
private void getScript()
{
String textline;
try{
URLConnection urlConnection = new URL(getCodeBase(),file).openConnection();
//In JDK 1.1, this should be replaced with BufferedReader.readLine, however
//the following works with both 1.02 and 1.1...
DataInputStream in = new DataInputStream(urlConnection.getInputStream());
while(null != (textline = in.readLine())){
script.addElement(textline.trim());
}
}catch (Exception e){
script.removeAllElements();
script.addElement("Could not retrieve script.");
}
}
private void repaintScreen(Graphics g)
{
//We call this to refresh our buffered image
//prior to typing text onto it...
if(null == bgimage){
g.setColor(bgcolor);
g.fillRect(0, 0, width, height);
}
else{
g.drawImage(bgimage,0,0,this);
}
}
private int displayString(Graphics g, String string, int y, int w, int ascent)
{
//Step through the string, display each character with the sound effect
//Paint a cursor as we do, and sleep for the character pause interval
//in between each character.
//
//Return the Y coord for the next line of text.
for(int j = 0; j < string.length(); j++){
if(null != sound)
sound.play();
g.setColor(fgcolor);
g.drawString(string.substring(j,j+1),indent + (j)*w, y);
g.fillRect(indent + (j+1)*w, y-ascent, cursor, fontsize);
try{
kicker.sleep(cpause);
}catch(InterruptedException e){}
g.setColor(bgcolor);
g.fillRect(indent + (j+1)*w, y-ascent, cursor, fontsize);
repaint();
}
return y+lspace;
}
public void run()
{
//Wait for a background image, if any...
if(null != bgimage){
try{
tracker.waitForAll();
}catch(Exception e){
bgimage = null;
}
}
//Create our buffered image
image= createImage(width, height);
//Get the graphics context for the buffered image
Graphics g = image.getGraphics();
//Put it up...
repaint();
//Now, get the script (if necessary.)
if(script.isEmpty())
getScript();
//Set a teletype font, and get some font metrics
g.setFont(new Font("Courier", Font.PLAIN, fontsize));
FontMetrics fm = g.getFontMetrics();
int w = fm.stringWidth("A");
int ascent = fm.getMaxAscent();
//We've got our image and file, so we can now set isRunning to true.
//This is used to see if we are ready to respond to mouseDown events
//(see below)
isRunning=true;
while(kicker != null){
repaintScreen(g);
int Y = inity + lspace;
for(int i = 0; i < script.size(); i++){
String string = (String)script.elementAt(i);
//Handle a NEWLINE "tag"
if(string.toLowerCase().equals("<newline>")){
if(Y != inity + lspace)
Y += lspace;
}
//Handle a NEWPAGE "tag"
else if(string.toLowerCase().equals("<newpage>")){
repaintScreen(g);
Y = inity + lspace;
}
//Handle a PAUSE "tag" (parse out the value) and sleep
//for the requested duration
else if(string.toLowerCase().startsWith("<pause")){
int pause;
int start=string.indexOf(" ");
int end = string.indexOf(">");
start++;
try{
pause=Integer.parseInt(string.substring(start,end));
if(pause == 0){
threadSuspended=true;
kicker.suspend();
}
else{
kicker.sleep(pause);
}
}catch(Exception e){}
}
//Otherwise, handle a message line.
else{
if(string.toLowerCase().equals("<more>")){
string = MOREMESSAGE;
}
Y = displayString(g, string, Y, w, ascent);
//Are we near enough to the bottom of the display to
//show a "More..." (and is it appropriate, i.e. is
//there more text to display?)
if((Y + 2*lspace) > maxy && i+1 < script.size()){
Y+=lspace;
string=MOREMESSAGE;
displayString(g, string, Y, w, ascent);
}
//Did we just display "More..."?
if(string.equals(MOREMESSAGE)){
//This will force a new page after
//the thread resumes
Y += maxy;
threadSuspended=true;
kicker.suspend();
}
//Otherwise, if we simply displayed a text line,
//sleep for the line pause interval.
else{
try{
kicker.sleep(lpause);
}catch(InterruptedException e){}
}
}
//Do we need to start a new "Page?"
if(Y > maxy){
repaintScreen(g);
Y = inity + lspace;
}
}
//Is unattended looping enabled? If it is, sleep for
//a screen pause interval.
if(loop){
try{
kicker.sleep(spause);
}catch(InterruptedException e){}
}
//Otherwise, suspend until we get a mouseDown event
else{
threadSuspended=true;
kicker.suspend();
}
}
}
public synchronized boolean mouseDown(java.awt.Event evt, int x, int y)
{
//Only respond to mouseDown if the applet has its image and file
//and is running...
if(isRunning){
if (threadSuspended) {
kicker.resume();
}
else {
kicker.suspend();
}
threadSuspended = !threadSuspended;
}
return true;
}
public void paint(Graphics g)
{
//If we've got an image, draw it...
if(null != image)
g.drawImage(image,0,0,this);
//Otherwise, paint the applet panel the specified
//background color...
else{
g.setColor(bgcolor);
g.fillRect(0,0,size().width,size().height);
}
}
public void update(Graphics g)
{
//Override update to call our paint method
//to eliminate flickering.
paint(g);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -