线程应用实例
实例244 下雪的村庄
package Chapter17;
import java.applet.Applet;
import java.awt.*;
import java.util.Random;
public class SnowVillage extends Applet implements Runnable {
Thread thread;// 声明主线程
Image off, images[];// 声明图片对象和图片数组
Random random;// 声明一个随机数对象
int flag, sonwNum, wind, thread_1, size;// 声明一些int型变量
int[] X, Y;// 声明两个int型数组,分别表示X和Y坐标点
long time = 0;// 表示时间
Dimension ds;// 声明一个Dimension对象
MediaTracker mt;// 声明一个MediaTracker对象
int getValue(String s1, int s2, int max, int min) {// 获取HTML标记中命名参数的值
String s = getParameter(s1);
if (s != null) {
if ((s2 = Integer.parseInt(s)) > max)
return max;
else if (s2 < min)
return min;
else
return s2;
} else
return s2;
}
public void init() {// Applet小程序初始化
this.setSize(300, 200);
random = new Random();
ds = getSize();
off = createImage(ds.width, ds.height);// 创建一个图象
sonwNum = getValue("sonwNum", 100, 500, 0);// 获取雪片的个数
size = getValue("size", 3, 10, 3);// 获取雪片的大小
thread_1 = getValue("threadsleep", 80, 1000, 10);// 获取休眠的时间
// 获取绘制雪片的XY坐标值
X = new int[sonwNum];
Y = new int[sonwNum];
for (int i = 0; i < sonwNum; i++) {
X[i] = random.nextInt() % (ds.width / 2) + ds.width / 2;
Y[i] = random.nextInt() % (ds.height / 2) + ds.height / 2;
}
mt = new MediaTracker(this);
images = new Image[1];
images[0] = getImage(getDocumentBase(), "xue.jpg");
mt.addImage(images[0], 0);
try {
mt.waitForID(0);
} catch (InterruptedException _ex) {
return;
}
flag = 0;
}
public void start() {// 启动小程序
if (thread == null) {
thread = new Thread(this);
thread.start();// 启动线程
}
}
public void stop() {// 停止运行小程序
thread = null;
}
public void run() {// 运行线程
while (thread != null) {
try {
Thread.sleep(thread_1);
} catch (InterruptedException _ex) {
return;
}
repaint();
}
}
public void snow(Graphics g) {// 绘制雪片
g.setColor(Color.white);
for (int i = 0; i < sonwNum; i++) {
g.fillOval(X[i], Y[i], size, size);
X[i] += random.nextInt() % 2 + wind;
Y[i] += (random.nextInt() % 6 + 5) / 5 + 1;
if (X[i] >= ds.width)
X[i] = 0;
if (X[i] < 0)
X[i] = ds.width - 1;
if (Y[i] >= ds.height || Y[i] < 0) {
X[i] = Math.abs(random.nextInt() % ds.width);
Y[i] = 0;
}
}
wind = random.nextInt() % 5 - 2;
}
public void paint(Graphics g) {// 绘制组件
off.getGraphics().setColor(Color.black);
off.getGraphics().fillRect(0, 0, ds.width, ds.height);
off.getGraphics().drawImage(images[0], 0, 0, this);
snow(off.getGraphics());
g.drawImage(off, 0, 0, null);
}
public void update(Graphics g) {// 重新绘制组件
paint(g);
}
}
实例245 小飞侠
package Chapter17.example;
import java.applet.Applet;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.MediaTracker;
public class SplitLine extends Applet implements Runnable {
private Image moveleft__1, moveright_1, moveleft_2, moveright_2, temp;// 声明Image对象
private Image image;//
private Graphics graphics;
private Thread thread = null;
private MediaTracker img_tracker;
private int height, width;
public void init() {// 初始化Applet小程序
// 创建Image对象
moveright_1 = getImage(getDocumentBase(), "3.jpg");
moveright_2 = getImage(getDocumentBase(), "4.jpg");
moveleft__1 = getImage(getDocumentBase(), "1.jpg");
moveleft_2 = getImage(getDocumentBase(), "2.jpg");
// 创建MediaTracker对象
img_tracker = new MediaTracker(this);
// 将图片对象加载到媒体跟踪器中
img_tracker.addImage(moveright_1, 0);
img_tracker.addImage(moveleft__1, 0);
img_tracker.addImage(moveright_2, 0);
img_tracker.addImage(moveleft_2, 0);
// 获取Applet的长和宽
width = this.size().width;
height = this.size().height;
try {
img_tracker.waitForID(0);// 跟踪指定ID的图象
} catch (InterruptedException e) {
}
// 创建图象区
image = createImage(width, height);
// 创建Graphics对象
graphics = image.getGraphics();
}
public void start() {// Applet小程序的start方法
if (thread == null) {
thread = new Thread(this);
thread.start();// 开始运行线程
}
}
public void run() {// 线程的run方法
Color fg = this.getForeground();
int imgWidth, imageHeight, x = 0, y = 0;
boolean forward = true;
imgWidth = moveright_1.getWidth(this);
imageHeight = moveright_1.getHeight(this);
y = (height - imageHeight) / 2;
fg = Color.blue;// 设置分割线的颜色
try {
while (thread != null) {
thread.sleep(200);
if (forward) {
x += 15;
if ((x % 2) == 1) {
temp = moveright_1;
} else {
temp = moveright_2;
}
if (x >= (width - imgWidth)) {
forward = false;
}
} else {
x -= 15;
if ((x % 2) == 1) {
temp = moveleft__1;
} else {
temp = moveleft_2;
}
if (x == 0) {
forward = true;
}
}
graphics.setColor(Color.white);// 设置小程序的背景颜色
graphics.fillRect(0, 0, width, height);
graphics.setColor(fg.brighter().darker());
graphics.drawLine(0, (height - imageHeight) / 2 + imageHeight,
width, (height - imageHeight) / 2 + imageHeight);
graphics.setColor(fg.darker().brighter());
graphics.drawLine(0, (height - imageHeight) / 2 + imageHeight,
width, (height - imageHeight) / 2 + imageHeight);
graphics.drawImage(temp, x, y, this);
repaint();
}
} catch (InterruptedException e) {
}
}
public void update(Graphics g) {
paint(g);
}
public void paint(Graphics g) {
g.drawImage(image, 0, 0, this);
}
}
实例246 飞流直下
package Chapter17.status;
import java.applet.Applet;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
public class Faucet extends Applet implements Runnable {
final int Max = 1000;// 水滴的最大个数
Drop d[];// 声明一个水滴对象
int width, height, X, Y;// 声明Applet小程序的宽和高,及以XY坐标中心
Image off;// 声明一个图片对象
Graphics graphics;// 声明一个Graphics对象
Thread thread;// 声明一个线程对象
public void init() {// Applet小程序初始化
this.setSize(300, 200);
setBackground(Color.gray);
width = getSize().width;
height = getSize().height;
d = new Drop[Max];
for (int i = 0; i < Max; i++)
d[i] = new Drop();
off = createImage(width, height);
graphics = off.getGraphics();
}
public void start() {// 开始执行小程序
thread = new Thread(this);
thread.start();
}
public void stop() {// 停止执行小程序
thread = null;
}
public void update(Graphics g) {// 重新绘制小程序
paint(g);
}
public void paint(Graphics g) {// 绘制组件
g.drawImage(off, 0, 0, this);
}
public void run() {// 运行线程
boolean reset = false;
int i, t = 0;
while (true) {
graphics.clearRect(0, 0, width, height);
graphics.setColor(Color.white);
graphics.drawLine(0, 15, 10, 15);
for (i = 0; i < Max; i++) {
graphics.fillOval((int) d[i].X, (int) d[i].Y, 3, 3);
d[i].X = d[i].X + d[i].newX;
if (d[i].X > 10) {
d[i].Y += d[i].newY * d[i].time / 1000;
d[i].newY = (int) 9.8 * d[i].time;
d[i].time++;
}
if (d[i].Y > height) {
d[i].reset();
}
}
repaint();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
}
}
}
class Drop {// 水滴类
double X, Y;
double newX, newY;
int time;
public Drop() {
reset();
}
public void reset() {// 重新设置绘制水滴的位置和大小
X = (int) (Math.random() * -40);
Y = (int) (Math.random() * 5 + 10);
newX = Math.random() * 3 + 1.0;
newY = 0;
time = 0;
}
}
实例247 多线程断点续传
package Chapter17.download;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.io.Serializable;
import java.net.HttpURLConnection;
import java.net.URL;
//Java实现网络文件传输,在客户端请求Web服务器传输指定文件,并将文件保存。
public class ResumeUpload {
private String downSource = "http://kent.dl.sourceforge.net/sourceforge/jamper/Sample.zip"; // 定义Web地址和文件名
private String savePath = "d:\\temp"; // 定义存文件路径
private String saveName = "汉仪YY字体.zip"; // 定义文件名
public ResumeUpload() {
try {
FileInfo bean = new FileInfo(downSource, savePath, saveName, 5);
FTPthread fileFetch = new FTPthread(bean);
fileFetch.start();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new ResumeUpload();
}
}
class FTPthread extends Thread { // 传输文件线程类
FileInfo siteInfoBean = null; // 文件信息Bean
long[] nPos;
long[] startPos; // 开始位置
long[] endPos; // 结束位置
FilePart[] fileSplitterFetch; // 子线程对象
long nFileLength; // 文件长度
boolean bFirst = true; // 是否第一次取文件
boolean bStop = false; // 停止标志
File tmpFile; // 文件传输临时信息
DataOutputStream output; // 输出到文件的输出流
public FTPthread(FileInfo bean) throws IOException {
siteInfoBean = bean;
tmpFile = new File(bean.getSFilePath() + File.separator
+ bean.getSFileName() + ".info");
if (tmpFile.exists()) {
bFirst = false;
readInform();
} else {
startPos = new long[bean.getNSplitter()];
endPos = new long[bean.getNSplitter()];
}
}
public void run() {
// 获得文件长度
// 分割文件
// 实例PartCacth
// 启动PartCacth线程
// 等待子线程返回
try {
if (bFirst) {
nFileLength = getFileSize();
if (nFileLength == -1) {
System.err.println("File Length is not known!");
} else if (nFileLength == -2) {
System.err.println("File is not access!");
} else {
for (int i = 0; i < startPos.length; i++) {
startPos[i] = (long) (i * (nFileLength / startPos.length));
}
for (int i = 0; i < endPos.length - 1; i++) {
endPos[i] = startPos[i + 1];
}
endPos[endPos.length - 1] = nFileLength;
}
}
// 启动子线程
fileSplitterFetch = new FilePart[startPos.length];
for (int i = 0; i < startPos.length; i++) {
fileSplitterFetch[i] = new FilePart(siteInfoBean.getSSiteURL(),
siteInfoBean.getSFilePath() + File.separator
+ siteInfoBean.getSFileName(), startPos[i],
endPos[i], i);
AddInform.log("Thread " + i + " , 开始位置 = " + startPos[i]
+ ", 结束位置 = " + endPos[i]);
fileSplitterFetch[i].start();
}
// 等待子线程结束
// int count = 0;
// 是否结束while循环
boolean breakWhile = false;
while (!bStop) {
writeInform();
AddInform.sleep(500);
breakWhile = true;
for (int i = 0; i < startPos.length; i++) {
if (!fileSplitterFetch[i].bDownOver) {
breakWhile = false;
break;
}
}
if (breakWhile)
break;
}
System.out.println("文件传输结束!");
} catch (Exception e) {
e.printStackTrace();
}
}
// 获得文件长度
public long getFileSize() {
int nFileLength = -1;
try {
URL url = new URL(siteInfoBean.getSSiteURL());
HttpURLConnection httpConnection = (HttpURLConnection) url
.openConnection();
httpConnection.setRequestProperty("User-Agent", "NetFox");
int responseCode = httpConnection.getResponseCode();
if (responseCode >= 400) {
processErrorCode(responseCode);
return -2; // -2 为Web服务器响应错误
}
String sHeader;
for (int i = 1;; i++) {
sHeader = httpConnection.getHeaderFieldKey(i);
if (sHeader != null) {
if (sHeader.equals("Content-Length")) {
nFileLength = Integer.parseInt(httpConnection
.getHeaderField(sHeader));
break;
}
} else
break;
}
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
AddInform.log(nFileLength);
return nFileLength;
}
// 保存传输信息(文件指针位置)
private void writeInform() {
try {
output = new DataOutputStream(new FileOutputStream(tmpFile));
output.writeInt(startPos.length);
for (int i = 0; i < startPos.length; i++) {
output.writeLong(fileSplitterFetch[i].startPos);
output.writeLong(fileSplitterFetch[i].endPos);
}
output.close();
} catch (Exception e) {
System.out.println("保存传输信息失败");
}
}
// 读取保存的下载信息(文件指针位置)
private void readInform() {
try {
DataInputStream input = new DataInputStream(new FileInputStream(
tmpFile));
int nCount = input.readInt();
startPos = new long[nCount];
endPos = new long[nCount];
for (int i = 0; i < startPos.length; i++) {
startPos[i] = input.readLong();
endPos[i] = input.readLong();
}
input.close();
// 判断每块的文件开始位置是否大于结束位置
for (int i = 0; i < startPos.length; i++) {
if (startPos[i] > endPos[i]) {
startPos[i] = endPos[i];
}
}
} catch (Exception e) {
System.out.println("读取保存的下载信息失败");
}
}
private void processErrorCode(int nErrorCode) {
System.err.println("Error Code : " + nErrorCode);
}
// 停止文件传输
public void doStop() {
bStop = true;
for (int i = 0; i < startPos.length; i++)
fileSplitterFetch[i].splitterStop();
}
}
class FileInfo { // 定义获取和设置相关文件信息类
private String sSiteURL; // 定义URL变量
private String sFilePath; // 定义存文件路径变量
private String sFileName; // 定义文件名变量
private int nSplitter; // 定义传输文件计数值
public FileInfo() {
this("", "", "", 5); // 设置传输文件计数值
}
public FileInfo(String sURL, String sPath, String sName, int nSpiltter) {
sSiteURL = sURL;
sFilePath = sPath;
sFileName = sName;
this.nSplitter = nSpiltter;
}
public String getSSiteURL() {
return sSiteURL;
}
public void setSSiteURL(String value) {
sSiteURL = value;
}
public String getSFilePath() {
return sFilePath;
}
public void setSFilePath(String value) {
sFilePath = value;
}
public String getSFileName() {
return sFileName;
}
public void setSFileName(String value) {
sFileName = value;
}
public int getNSplitter() {
return nSplitter;
}
public void setNSplitter(int nCount) {
nSplitter = nCount;
}
}
class FilePart extends Thread {
String sURL; // 定义文件传输时使用的变量
long startPos; // 分段文件传输开始位置
long endPos; // 分段文件传输结束位置
int nThreadID; // 子线程ID
boolean bDownOver = false; // 完成文件传输
boolean bStop = false; // 停止文件传输
SaveFile fileAccess = null;
public FilePart(String sURL, String sName, long nStart, long nEnd, int id)
throws IOException {
this.sURL = sURL;
this.startPos = nStart;
this.endPos = nEnd;
nThreadID = id;
fileAccess = new SaveFile(sName, startPos);
}
public void run() {
while (startPos < endPos && !bStop) {
try {
URL url = new URL(sURL);
HttpURLConnection httpConnection = (HttpURLConnection) url
.openConnection();
httpConnection.setRequestProperty("User-Agent", "NetFox");
String sProperty = "bytes=" + startPos + "-";
httpConnection.setRequestProperty("RANGE", sProperty);
AddInform.log(sProperty);
InputStream input = httpConnection.getInputStream();
byte[] b = new byte[1024];
int nRead;
while ((nRead = input.read(b, 0, 1024)) > 0
&& startPos < endPos && !bStop) {
startPos += fileAccess.write(b, 0, nRead);
}
AddInform.log("Thread " + nThreadID + " is over!");
bDownOver = true;
} catch (Exception e) {
System.out.println(getName() + " 线程运行异常");
}
}
bDownOver = true;
}
public void logResponseHead(HttpURLConnection con) {
for (int i = 1;; i++) {
String header = con.getHeaderFieldKey(i);
if (header != null)
AddInform.log(header + " : " + con.getHeaderField(header));
else
break;
}
}
public void splitterStop() {
bStop = true;
}
}
class SaveFile implements Serializable { // 定义访问文件类
RandomAccessFile oSavedFile;
long nPos;
public SaveFile() throws IOException {
this("", 0);
}
public SaveFile(String sName, long nPos) throws IOException {
oSavedFile = new RandomAccessFile(sName, "rw");
this.nPos = nPos;
oSavedFile.seek(nPos);
}
public synchronized int write(byte[] b, int nStart, int nLen) {
int n = -1;
try {
oSavedFile.write(b, nStart, nLen);
n = nLen;
} catch (IOException e) {
System.out.println("同步存储信息异常");
}
return n;
}
}
class AddInform { // 定义输出提示信息及线程sleep类
public AddInform() {
}
public static void sleep(int nSecond) {
try {
Thread.sleep(nSecond);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void log(String sMsg) {
System.out.println(sMsg);
}
public static void log(int sMsg) {
System.out.println(sMsg);
}
}
实例248 滚动的珠子
package Chapter17;
import java.awt.Button;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class MoveBall extends Frame implements ActionListener {
// 创建3个按扭组件,分别代表开始、停止和退出
private Button quit = new Button("退出");
private Button start = new Button("开始");
private Button stop = new Button("停止");
private DrawBall balls[] = new DrawBall[20];
// 构造方法,对各组件进行初始化
public MoveBall() {
super();
setLayout(new FlowLayout());
add(quit);
quit.addActionListener(this);
add(start);
start.addActionListener(this);
add(stop);
stop.addActionListener(this);
validate();
this.setBackground(Color.black);
this.setSize(300, 300);
this.setVisible(true);
for (int i = 0; i < balls.length; i++) {
int x = (int) (getSize().width * Math.random());
int y = (int) (getSize().height * Math.random());
balls[i] = new DrawBall(this, x, y);
}
}
public void actionPerformed(ActionEvent e) {// 为Button添加事件处理
if (e.getSource() == stop) {// 单击停止按扭
for (int i = 0; i < balls.length; i++) {
balls[i].setRun();
}
}
if (e.getSource() == start) {// 单击开始按扭
for (int i = 0; i < balls.length; i++) {
balls[i].setRun();
balls[i] = new DrawBall(this, balls[i].x, balls[i].y);
}
}
if (e.getSource() == quit) {// 单击退出按扭
System.exit(0);
}
}
public void paint(Graphics g) {// 绘制组件
for (int i = 0; i < balls.length; i++)
if (balls[i] != null)
balls[i].paintBall(g);
}
public static void main(String[] args) {// 程序的入口处
MoveBall t = new MoveBall();
}
}
class DrawBall extends Thread {// 绘画珠子
// 利用随机数获取绘制珠子的位置
private int a = 2 * (1 - 2 * (int) Math.round(Math.random()));
private int b = 2 * (1 - 2 * (int) Math.round(Math.random()));
private boolean running = false;// 控制是否绘制珠子的标志
private MoveBall table = null;// 声明一个MoveBall对象
protected int x, y;// 定义XY坐标点
public DrawBall(MoveBall _table, int _x, int _y) {// 构造方法,给其成员变量赋初值
table = _table;
x = _x;
y = _y;
start();
}
public void start() {
running = true;
super.start();// 启动线程
}
public void setRun() {
running = false;
}
public void run() {// 重写Thread类的run方法
while (running) {
move();
try {
sleep(50);
} catch (InterruptedException e) {
System.out.println(e.getMessage());
}
table.repaint();
}
}
public void paintBall(Graphics g) {// 自定义绘制珠子的方法
g.setColor(Color.red);
g.fillOval(x, y, 20, 20);
}
private void move() {// 珠子在滚动
x += a;
y += b;
if ((x > table.getSize().width) || (x < 0)) {
a *= (-1);
}
if ((y > table.getSize().height) || (y < 0)) {
b *= (-1);
}
}
}
实例249 余额查询
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class QueryBalance extends JPanel {
private JTextField acctext;// 声明一个录入帐号的输入框
private JTextField pass;// 声明一个录入帐号密码的输入框
private JButton button1;// 声明一个查询按扭
private JButton button2;// 声明一个取消按扭
private JLabel balanceL;// 声明一个录入帐号的输入框
private volatile Thread lookupThread;// 创建一个线程
public QueryBalance() {// 构造方法
mainFrame();
searchEvents();
}
private void mainFrame() {
// 创建组件
JLabel Lacct = new JLabel("账户编号:");
JLabel Lpass = new JLabel("密码:");
acctext = new JTextField(12);
pass = new JTextField(4);
JPanel mainPanel = new JPanel();// 创建一个面板对象
mainPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
// 将组件添加到面板中
mainPanel.add(Lacct);
mainPanel.add(acctext);
mainPanel.add(Lpass);
mainPanel.add(pass);
// 创建Button按扭
button1 = new JButton("查询");
button2 = new JButton("取消查询");
button2.setEnabled(false);
// 创建装载Button组件的面板
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new GridLayout(1, -1, 5, 5));
// 将Button组件添加到buttonPanel面板中
buttonPanel.add(button1);
buttonPanel.add(button2);
JPanel addPanel = new JPanel();
addPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
addPanel.add(buttonPanel);// 将buttonPanel面板添加到addPanel面板中
JLabel balancePrefixL = new JLabel("账户余额:");
balanceL = new JLabel("查询未知");
// 将用于显示查询结果的组件放到searchPanel面板中
JPanel searchPanel = new JPanel();
searchPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
searchPanel.add(balancePrefixL);
searchPanel.add(balanceL);
JPanel showPanel = new JPanel();
showPanel.setLayout(new GridLayout(-1, 1, 5, 5));
showPanel.add(mainPanel);
showPanel.add(addPanel);
showPanel.add(searchPanel);
setLayout(new BorderLayout());
add(showPanel, BorderLayout.NORTH);
}
private void searchEvents() {// 为查询按扭和取消按扭
button1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
searchING();
}
});
button2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
cancelSearch();
}
});
}
private void searchING() {// 正在查询的过程中
ensureEventThread();
button1.setEnabled(false);
button2.setEnabled(true);
balanceL.setText("正在查询 请稍候 ...");
// 获取录入的账号和密码
String acct = acctext.getText();
String pin = pass.getText();
lookupMessage(acct, pin);
}
private void lookupMessage(String acct, String pin) {// 设置查询信息
final String acctNum = acct;
final String pinNum = pin;
Runnable lookupRun = new Runnable() {
public void run() {
String bal = searchAndCheck(acctNum, pinNum);
setSafe(bal);
}
};
lookupThread = new Thread(lookupRun, "lookupThread");
lookupThread.start();
}
private String searchAndCheck(String acct, String pin) {// 检查账号和密码是否输入正确
try {
Thread.sleep(5000);
if (!acct.equals("220302113325") && pin.equals("198713")) {
return "您输入的账号错误!";
} else if (acct.equals("220302113325") && !pin.equals("198713")) {
return "您输入的密码错误!";
}
return "1,234.56";
} catch (InterruptedException x) {
return "取消查询";
}
}
private void setSafe(String newBal) {// 进行安全设置
final String newBalance = newBal;
Runnable r = new Runnable() {
public void run() {
try {
setValue(newBalance);
} catch (Exception x) {
x.printStackTrace();
}
}
};
SwingUtilities.invokeLater(r);
}
private void setValue(String newBalance) {// 获取查询结果
ensureEventThread();
balanceL.setText(newBalance);
button2.setEnabled(false);// 正在查询的过程中,取消查询按扭是不用的
button1.setEnabled(true);
}
private void cancelSearch() {// 取消查询
ensureEventThread();
button2.setEnabled(false); // prevent additional requests
if (lookupThread != null) {
lookupThread.interrupt();
}
}
private void ensureEventThread() {
if (SwingUtilities.isEventDispatchThread()) {
return;
}
throw new RuntimeException("只有线程可以调用此方法");
}
public static void main(String[] args) {
QueryBalance qb = new QueryBalance();
JFrame f = new JFrame("Balance Lookup");
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
f.setContentPane(qb);
f.setSize(400, 150);
f.setVisible(true);
}
}
实例250 滚动的文字
package Chapter17.status;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.font.FontRenderContext;
import java.awt.font.TextLayout;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class CryptoService extends JComponent {
private BufferedImage image;// 声明一个BufferedImage类对象
private Dimension imageOfSize;// 声明一个Dimension类对象
private volatile int currOffset;// 声明一个用于表示偏移量的变量
private Thread thread;// 声明一个线程
private volatile boolean flag;
public CryptoService(String text) {
currOffset = 0;
buildImage(text);
setMinimumSize(imageOfSize);
setPreferredSize(imageOfSize);
setMaximumSize(imageOfSize);
setSize(imageOfSize);
flag = true;
Runnable r = new Runnable() {
public void run() {
try {
ScrollING();
} catch (Exception x) {
x.printStackTrace();
}
}
};
thread = new Thread(r, "ScrollText");
thread.start();
}
private void buildImage(String text) {
RenderingHints renderHints = new RenderingHints(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);// 根据抗锯齿提示键和抗锯齿提示值来创建一个RenderingHints类对象
renderHints.put(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY);// 将指定的呈现提示键映射到此RenderingHints对象中的指定呈现指示值。
BufferedImage scratchImage = new BufferedImage(1, 1,
BufferedImage.TYPE_INT_RGB);// 构造一个类型为预定义的图像
Graphics2D scratchG2 = scratchImage.createGraphics();// 创建一个Graphics2D类对象
scratchG2.setRenderingHints(renderHints);// 设置呈现算法
Font font = new Font("Serif", Font.BOLD | Font.ITALIC, 24);// 创建一个Font字体对象
FontRenderContext frc = scratchG2.getFontRenderContext();// 创建一个FontRenderContext对象
TextLayout tl = new TextLayout(text, font, frc);// 创建一个TextLayout对象
Rectangle2D textBounds = tl.getBounds();// 创建一个Rectangle2D对象
int textWidth = (int) Math.ceil(textBounds.getWidth());// 设置文字的显示宽度
int textHeight = (int) Math.ceil(textBounds.getHeight());// 设置文字的显示长度
int horizontalPad = 10;// 设置水平间距为10象素
int verticalPad = 6;// 设置垂直间距为6象素
imageOfSize = new Dimension(// 创建Dimension对象
textWidth + horizontalPad, textHeight + verticalPad);
image = new BufferedImage(
// 创建BufferedImage对象
imageOfSize.width, imageOfSize.height,
BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = image.createGraphics();
g2.setRenderingHints(renderHints);
int baselineOffset = (verticalPad / 2) - ((int) textBounds.getY());// 基线的偏移量
g2.setColor(Color.black);// 设为黑色背影
g2.fillRect(0, 0, imageOfSize.width, imageOfSize.height);
g2.setColor(Color.WHITE);// 白色字体
tl.draw(g2, 0, baselineOffset);
scratchG2.dispose();
scratchImage.flush();
g2.dispose();
}
public void paint(Graphics g) {
// 将当前的剪贴区设置为由给定坐标指定的矩形。
g.setClip(0, 0, imageOfSize.width, imageOfSize.height);
int localOffset = currOffset; // 本地偏移量是不断的变化的
g.drawImage(image, -localOffset, 0, this);
g.drawImage(image, imageOfSize.width - localOffset, 0, this);
// 绘画出边框
g.setColor(Color.red);
g.drawRect(0, 0, imageOfSize.width - 1, imageOfSize.height - 1);
}
private void ScrollING() {// 执行滚动操作
while (flag) {
try {
Thread.sleep(100);
currOffset = (currOffset + 1) % imageOfSize.width;
repaint();
} catch (InterruptedException x) {
Thread.currentThread().interrupt();
}
}
}
public static void main(String[] args) {
CryptoService st = new CryptoService("教师节快乐");
JPanel p = new JPanel(new FlowLayout());
p.add(st);
JFrame f = new JFrame("滚动的文字");
f.setContentPane(p);
f.setSize(400, 100);
f.setVisible(true);
}
}
实例251 漂浮效果
package Chapter17;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import Chapter17.status.CryptoService;
public class FloatingEffect extends Object {
private Component comp;// 创建一个Component对象
// 定义显示位置的X、Y坐标点
private int initX;
private int initY;
// 定义偏移位置的X、Y坐标点
private int offsetX;
private int offsetY;
// 标志是否是第一次执行
private boolean firstTime;
// 声明一个实现Runnable接口的匿名内部类对象
private Runnable runable;
// 声明一个线程对象
private Thread thread;
// 标识是否停止浮动
private volatile boolean flag;
// 构造方法,为其成员变量初始化
public FloatingEffect(Component comp, int initX, int initY, int offsetX,
int offsetY) {
this.comp = comp;
this.initX = initX;
this.initY = initY;
this.offsetX = offsetX;
this.offsetY = offsetY;
firstTime = true;
runable = new Runnable() {
public void run() {
newPosition();
}
};
flag = true;
Runnable r = new Runnable() {// 实现Runnable接口的匿名内部类
public void run() {
try {
floatING();
} catch (Exception x) {
// in case ANY exception slips through
x.printStackTrace();
}
}
};
thread = new Thread(r);// 线程实例化
thread.start();// 启动线程
}
private void floatING() {// 执行漂浮
while (flag) {
try {
Thread.sleep(200);
SwingUtilities.invokeAndWait(runable);
} catch (InterruptedException ix) {
// ignore
} catch (Exception x) {
x.printStackTrace();
}
}
}
private void newPosition() {// 更新新的坐标值
if (!comp.isVisible()) {// 判断此组件在其父容器内是否可见
return;
}
Component parent = comp.getParent();// 获得此组件的父级
if (parent == null) {
return;
}
Dimension parentSize = parent.getSize();
if ((parentSize == null) && (parentSize.width < 1)
&& (parentSize.height < 1)) {
return;
}
int newX = 0;
int newY = 0;
if (firstTime) {
firstTime = false;
newX = initX;
newY = initY;
} else {
Point loc = comp.getLocation();
newX = loc.x + offsetX;
newY = loc.y + offsetY;
}
newX = newX % parentSize.width;
newY = newY % parentSize.height;
if (newX < 0) {
// 绕到另一侧
newX += parentSize.width;
}
if (newY < 0) {
newY += parentSize.height;
}
comp.setLocation(newX, newY);
parent.repaint();
}
public static void main(String[] args) {// 执行该程序的主入中
Component[] comp = new Component[6];// 创建一个Component组件数组
comp[0] = new CryptoService("幸福");
comp[1] = new CryptoService("快乐");
comp[2] = new ImageShow("E:\\tupian\\1.jpg", 30);
comp[3] = new ImageShow("E:\\tupian\\1.jpg", 30);
comp[4] = new ImageShow("E:\\tupian\\2.jpg", 100);
comp[5] = new ImageShow("E:\\tupian\\2.jpg", 100);
JPanel p = new JPanel();
p.setBackground(Color.white);
p.setLayout(null);
for (int i = 0; i < comp.length; i++) {
p.add(comp[i]);
int x = (int) (300 * Math.random());
int y = (int) (200 * Math.random());
int xOff = 2 - (int) (5 * Math.random());
int yOff = 2 - (int) (5 * Math.random());
new FloatingEffect(comp[i], x, y, xOff, yOff);
}
JFrame f = new JFrame("漂浮效果");
f.setContentPane(p);
f.setSize(400, 300);
f.setVisible(true);
}
}
class ImageShow extends JComponent {// 其类的主
private Dimension size;// 显示图像的尺寸
private volatile int imgLength;// 绘制图像的大小
private Thread thread;// 声明一个线程对象
private Image im;// 声明一个图像对象
private static String imgUrl = "";// 表示图片所示磁盘的位置
public ImageShow(String image, int n) {
imgUrl = image;
imgLength = 0;
size = new Dimension(n, n);
creatImage();
setMinimumSize(size);// 设置此组件的最小尺寸
setPreferredSize(size);// 设置此组件的首先尺寸
setMaximumSize(size);// 设置此组件的最大尺寸
setSize(size);// 调整组件的大小
Runnable r = new Runnable() {
public void run() {
try {
showING();
} catch (Exception x) {
x.printStackTrace();
}
}
};
thread = new Thread(r, "ImageShow");
thread.start();
}
private void creatImage() {// 获取图片对象
ImageIcon ic = new ImageIcon(imgUrl);
im = ic.getImage();
}
public void paint(Graphics g) {// 绘制图像
g.drawImage(im, imgLength, imgLength + 2, this);
}
private void showING() {// 显示图象
while (true) {
try {
Thread.sleep(300); // 休眠3毫秒
imgLength = imgLength + 1;
if (imgLength > 30) {// 如果图象边框的长度大于30
imgLength = 0;// 边框设为0
}
repaint();// 重新绘制图像
} catch (InterruptedException x) {
Thread.currentThread().interrupt();
}
}
}
}
实例252 监视内存的使用情况
package Chapter17;
import java.awt.BorderLayout;
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingConstants;
//监控内存
public class Memory extends JFrame {
private JPanel panel;
private BorderLayout layout = new BorderLayout();
// 创建JProgressBar对象并实例化
private JProgressBar bar_1 = new JProgressBar();
private JLabel label_1 = new JLabel();
private JLabel label_2 = new JLabel();
private void Initial() throws Exception {
panel = (JPanel) this.getContentPane();
panel.setLayout(layout);
this.setSize(new Dimension(305, 215));
this.setTitle("内存的使用情况");
label_1.setFont(new java.awt.Font("Dialog", 0, 14));
label_1.setHorizontalAlignment(SwingConstants.CENTER);
label_1.setText("自定义任务管理器");
bar_1.setOrientation(JProgressBar.VERTICAL);
bar_1.setFont(new java.awt.Font("Dialog", 0, 14));
bar_1.setToolTipText("");
bar_1.setStringPainted(true);
label_2.setFont(new java.awt.Font("Dialog", 0, 14));
label_2.setText("");
panel.add(bar_1, BorderLayout.CENTER);
panel.add(label_1, BorderLayout.NORTH);
panel.add(label_2, BorderLayout.SOUTH);
ProgressThread pt = new ProgressThread(this.bar_1, this.label_2);
pt.start();
this.setVisible(true);
}
public static void main(String[] args) {
try {
new Memory().Initial();
} catch (Exception e) {
e.printStackTrace();
}
}
}
class ProgressThread extends Thread {
JProgressBar jpb;
JLabel jl;
public ProgressThread(JProgressBar jpb, JLabel jl) {
this.jpb = jpb;
this.jl = jl;
}
public void run() {
int min = 0;
int max = 100;
int free = 0;
int totle = 0;
int status = 0;
jpb.setMinimum(min);
jpb.setMaximum(max);
jpb.setValue(status);
while (true) {
totle = (int) (Runtime.getRuntime().totalMemory() / 1024);
free = (int) (Runtime.getRuntime().freeMemory() / 1024);
jl.setText("可用内存"
+ (int) (Runtime.getRuntime().freeMemory() / 1024) + "K"
+ " 总共分配的内存:"
+ (int) (Runtime.getRuntime().totalMemory() / 1024) + "K");
status = (int) (free * 100 / totle);
jpb.setValue(status);
jpb.setString("可用内存:" + status + "%");
try {
this.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
实例253 璀璨的星空
package Chapter17.example;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
public class Universe extends java.applet.Applet implements Runnable {
int Width, Height;// 定义小程序的长和宽
Thread thread = null;// 声明一个线程对象
boolean suspend = false;// 是否暂停
Image im;// 声明一个图象对象
Graphics graphics;// 声明一个Graphics对象
double rot, dx, ddx;// 声明double型变量
int speed, stars, type;// 声明int型变量
double defddx, max;// 声明double型变量
Star pol[]; // 星光
public void init() {// 初始化Applet小程序
rot = 0;
dx = 0;
ddx = 0;
Width = 300;
Height = 300;
String theSpeed = "25";
Show("speed", theSpeed);
speed = (theSpeed == null) ? 50 : Integer.valueOf(theSpeed).intValue();
String theStars = "250";
Show("stars", theStars);
stars = (theStars == null) ? 30 : Integer.valueOf(theStars).intValue();
try {
im = createImage(Width, Height);
graphics = im.getGraphics();
} catch (Exception e) {
graphics = null;
}
pol = new Star[stars];
for (int i = 0; i < stars; i++)
pol[i] = new Star(Width, Height, 150, type);
System.out.println(Width + "," + Height);
}
public void paint(Graphics g) {// 绘制组件
if (graphics != null) {
paintStart(graphics);
g.drawImage(im, 0, 0, this);
} else {
paintStart(g);
}
}
public void paintStart(Graphics g) {
g.setColor(Color.black);
g.fillRect(0, 0, Width, Height);
for (int i = 0; i < stars; i++)
pol[i].DrawSelf(g, rot);
}
public void start() {// 启动Applet小程序
if (thread == null) {
thread = new Thread(this);
thread.start();// 启动线程
}
}
public void stop() {// 停止运行Applet小程序
if (thread != null) {
thread.stop();
thread = null;
}
}
public void run() {// 运行线程
while (thread != null) {
rot += dx;
dx += ddx;
if (dx > max)
ddx = -defddx;
if (dx < -max)
ddx = defddx;
try {
Thread.sleep(speed);
} catch (InterruptedException e) {
}
repaint();
}
}
public void update(Graphics g) {// 重新绘制组伯
paint(g);
}
public void Show(String theString, String theValue) {
if (theValue == null) {
System.out.println(theString + " : null");
} else {
System.out.println(theString + " : " + theValue);
}
}
}
class Star {// 代表星星类
int H, V;
int x, y, z;
int type;
Star(int width, int height, int depth, int type) {// 构造函数为各变量初始化
this.type = type;
H = width / 2;
V = height / 2;
x = (int) (Math.random() * width) - H;
y = (int) (Math.random() * height) - V;
if ((x == 0) && (y == 0))
x = 10;
z = (int) (Math.random() * depth);
}
public void DrawSelf(Graphics g, double rot) {// 根据坐标绘制星星
double X, Y;
int h, v, hh, vv;
int d;
z -= 2;
if (z < -63)
z = 100;
hh = (x * 64) / (64 + z);
vv = (y * 64) / (64 + z);
X = (hh * Math.cos(rot)) - (vv * Math.sin(rot));
Y = (hh * Math.sin(rot)) + (vv * Math.cos(rot));
h = (int) X + H;
v = (int) Y + V;
if ((h < 0) || (h > (2 * H)))
z = 100;
if ((v < 0) || (v > (2 * H)))
z = 100;
setColor(g);
if (type == 0) {
d = (100 - z) / 50;
if (d == 0)
d = 1;
g.fillRect(h, v, d, d);
} else {
d = (100 - z) / 20;
g.drawLine(h - d, v, h + d, v);
g.drawLine(h, v - d, h, v + d);
if (z < 50) {
d /= 2;
g.drawLine(h - d, v - d, h + d, v + d);
g.drawLine(h + d, v - d, h - d, v + d);
}
}
}
public void setColor(Graphics g) {// 给绘制的对象设置颜色
if (z > 50) {
g.setColor(Color.gray);
} else if (z > 25) {
g.setColor(Color.lightGray);
} else {
g.setColor(Color.white);
}
}
}
实例254 银行和超市业务的模拟
package Chapter17.bank;
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.Label;
import java.awt.Panel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class SimulationSite extends Frame implements ActionListener {//模拟现场场景
//定义全局成员常量
protected static final int num_agents=10;
protected static final int num_initial_agents=6;
protected static final int max_customer_delay=9000;
protected static final int max_teller_break=1000;
protected static final int max_no_customers=2000;
//创建Button组件
private Button open = new Button("开门");
private Button close = new Button("关门");
private Button add = new Button("欢迎光临");
private Button del = new Button("请慢走");
private Bank bank = new Bank();
private Finance supermarket = new Finance("");
//添加窗口关闭事件
private class WindowCloser extends WindowAdapter{
public void windowClosing(WindowEvent e){
bank.stop();
supermarket.stop();
System.exit(0);
}
}
public SimulationSite(){//构造方法,进行组件初始化和布局
super("SimulationSite");
Panel buttons = new Panel();
buttons.setLayout(new FlowLayout());
buttons.add(open);
open.addActionListener(this);
buttons.add(close);
close.addActionListener(this);
buttons.add(add);
add.addActionListener(this);
buttons.add(del);
del.addActionListener(this);
this.addWindowListener(new WindowCloser());
this.setLayout(new BorderLayout());
add("West",bank);
add("East",supermarket);
add("South",buttons);
validate();
pack();
show();
bank.start();
supermarket.start();
}
public void actionPerformed(ActionEvent e) {//为单击按扭做事件监听
// TODO Auto-generated method stub
if(e.getSource()==open){
bank.openDoor();
supermarket.openDoor();
}else if(e.getSource()==close){
bank.closeDoor();
supermarket.closeDoor();
}else if(e.getSource()==add){
bank.addAgent();
supermarket.addAgent();
}else if(e.getSource()==del){
bank.retireAgent();
supermarket.retireAgent();
}
}
public static void main(String[] args){//本程序的入口处
SimulationSite sl = new SimulationSite();
}
}
class Finance extends Panel implements Runnable {
protected Penson[] person = new Penson[SimulationSite.num_agents];
protected Label[] labelAgent = new Label[SimulationSite.num_agents];
protected Label labelQueue = new Label("已服务的顾客数:0");
protected Label labelServed = new Label("Customers servers:0");
protected Label labelWait = new Label("Customers wait:0");
protected int numAgents = SimulationSite.num_initial_agents;
protected int numCustomer = 0;// 顾客数
protected long totalWait = 0L;// 等待顾客数
private Thread thread = null;
private boolean doorIsOpen = false;
public Finance(String title) {
super();
setup(title);
}
public void updateDisplay() {
}
public void generateCustomer() {
}
public Customer requestCustomerFor(int id) {
return null;
}
public void checkoutCustomer(int handled, long waitTime) {// 更新顾客的数量,和正在等待的总人数
numCustomer++;
totalWait += waitTime;
}
public void addAgent() {// 增加人员
if (numAgents < SimulationSite.num_agents) {
person[numAgents] = new Penson(this, numAgents);
person[numAgents].start();
numAgents++;
}
}
public void retireAgent() {// 减少人员
if (numAgents > 1) {
person[numAgents - 1].setRunING();
numAgents--;
}
}
public void start() {
if (thread == null) {
thread = new Thread(this);
doorIsOpen = true;
thread.start();// 启动当前线程
for (int i = 0; i < numAgents; i++) {
person[i].start();// 启动Person类中的线程
}
}
}
public void stop() {
doorIsOpen = false;
thread = null;
for (int i = 0; i < numAgents; i++) {
person[i].setRunING();
}
}
public void openDoor() {// 营业
doorIsOpen = true;
}
public void closeDoor() {// 打烊
doorIsOpen = false;
}
public void run() {// 重写Runnable的run方法
while (thread == Thread.currentThread()) {
try {
thread.sleep((int) Math.random()
* SimulationSite.max_no_customers);
if (doorIsOpen) {
generateCustomer();
updateDisplay();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private void setup(String title) {// 设置状态
Panel agentPanel = new Panel();
agentPanel.setLayout(new GridLayout(SimulationSite.num_agents + 3, 1));
for (int i = 0; i < SimulationSite.num_agents; i++) {
labelAgent[i] = new Label("Penson" + i + ":served 0");
agentPanel.add(labelAgent[i]);
person[i] = new Penson(this, i);
}
for (int i = numAgents; i < SimulationSite.num_agents; i++) {
labelAgent[i].setText("Penson" + i + ":inactive");
}
agentPanel.add(labelQueue);
agentPanel.add(labelServed);
agentPanel.add(labelWait);
setLayout(new BorderLayout());
add("Center", agentPanel);
add("North", new Label(title));
}
}
class Penson extends Thread {// 创建一个Thread类的子类Penson类
private boolean running = false;// 是否停止运行的标志
private Finance bn = null;
private int id = -1;// 客户id
private int numCustomers = 0;// 顾客数量
public Penson(Finance _bn, int _id) {
this.bn = _bn;
this.id = _id;
}
public void start() {
running = true;
super.start();// 启动线程
}
public void setRunING() {// 设置执行状态
running = false;
}
public int getNum() {// 获取顾客数量
return numCustomers;
}
private void releaseCustomer(Customer customer) {// 释放顾客对象
numCustomers++;
bn.checkoutCustomer(numCustomers, customer.getWaitTime(new Date()));
}
public void run() {// 重写Thread的run方法
while (running) {
try {
sleep((int) (Math.random() * SimulationSite.max_teller_break) + 1000);// 随面休眠
Customer customer = bn.requestCustomerFor(id);
if (customer != null) {
sleep(customer.getDelayTime());
releaseCustomer(customer);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Bank extends Finance implements Runnable {
private ObjectQueue queue = null;
public Bank() {
super("中国北京银行");// 调用父类的带参构造方法
queue = new ObjectQueue();// 创建ObjectQueue对象
}
public void updateDisplay() {// 更新显示
labelServed.setText("已服务的顾客数:" + numCustomer);// 设置标签的显示内容
if (numCustomer != 0) {
labelWait.setText("平均等待:" + (totalWait / numCustomer));
for (int i = 0; i < numAgents; i++) {
labelAgent[i].setText("顾客:" + i + ": 已服务" + person[i].getNum());
}
for (int i = numAgents; i < SimulationSite.num_agents; i++) {
labelAgent[i].setText("顾客:" + i + ": 未服务");
labelQueue.setText("正在等待的顾客数:" + queue.getSize());
}
}
}
public void generateCustomer() {// 增加新的顾客,表示又有新的顾客光临
queue.insert(new Customer());
}
public Customer requestCustomerFor(int id) {// 表示有顾客发出想进行服务的需求
return queue.requestCustomer();
}
}
//class SimulationSite extends Frame implements ActionListener {// 模拟现场场景
// // 定义全局成员常量
// protected static final int num_agents = 10;
// protected static final int num_initial_agents = 6;
// protected static final int max_customer_delay = 9000;
// protected static final int max_teller_break = 1000;
// protected static final int max_no_customers = 2000;
// // 创建Button组件
// private Button open = new Button("开门");
// private Button close = new Button("关门");
// private Button add = new Button("欢迎光临");
// private Button del = new Button("请慢走");
// private Bank bank = new Bank();
// private Hypermarket supermarket = new Hypermarket();
// // 添加窗口关闭事件
// private class WindowCloser extends WindowAdapter {
// public void windowClosing(WindowEvent e) {
// bank.stop();
// supermarket.stop();
// System.exit(0);
// }
// }
// public SimulationSite() {// 构造方法,进行组件初始化和布局
// super("SimulationSite");
// Panel buttons = new Panel();
// buttons.setLayout(new FlowLayout());
// buttons.add(open);
// open.addActionListener(this);
// buttons.add(close);
// close.addActionListener(this);
// buttons.add(add);
// add.addActionListener(this);
// buttons.add(del);
// del.addActionListener(this);
// this.addWindowListener(new WindowCloser());
// this.setLayout(new BorderLayout());
// add("West", bank);
// add("East", supermarket);
// add("South", buttons);
// validate();
// pack();
// show();
// bank.start();
// supermarket.start();
// }
// public void actionPerformed(ActionEvent e) {// 为单击按扭做事件监听
// // TODO Auto-generated method stub
// if (e.getSource() == open) {
// bank.openDoor();
// supermarket.openDoor();
// } else if (e.getSource() == close) {
// bank.closeDoor();
// supermarket.closeDoor();
// } else if (e.getSource() == add) {
// bank.addAgent();
// supermarket.addAgent();
// } else if (e.getSource() == del) {
// bank.retireAgent();
// supermarket.retireAgent();
// }
// }
// public static void main(String[] args) {// 本程序的入口处
// SimulationSite sl = new SimulationSite();
// }
//}
class ObjectQueue {// 线程队列
private List customers = new ArrayList();
private synchronized Object performAction(String cmd, Object obj) {// 获取对象
if (cmd.equals("insert")) {// 增加方法的操作流程
if (customers.isEmpty())
customers.add(obj);
notify();
return null;
} else if (cmd.equals("size")) {// 获取容量
return new Integer(customers.size());
} else if (cmd.equals("retrieve")) {
while (customers.size() == 0) {
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Customer c = (Customer) customers.get(0);
customers.remove(0);
return c;
}
return null;
}
public void insert(Customer c) {// 增加操作
performAction("insert", c);
}
public int getSize() {// 获取容量
return (((Integer) performAction("size", null)).intValue());
}
public Customer requestCustomer() {// 请求服务
return (Customer) performAction("retrieve", null);
}
}
class Customer {// 顾客类
private Date date;// 声明一个日期类的对象
public Customer() {// 构造方法,为date对象初始化
date = new Date();
}
public int getDelayTime() {// 获取超时的时间
return (int) (Math.random() * SimulationSite.max_customer_delay);
}
public long getWaitTime(Date now) {// 获取等待的时间
return now.getTime() - date.getTime();
}
}