JAVA范例 十三)多线程编程(3)
????? 线程应用实例
实例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;elsereturn s2;} elsereturn 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; // 文件信息Beanlong[] 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;}} elsebreak;}} 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; // 子线程IDboolean 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));elsebreak;}}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 requestsif (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(// 创—imension对象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 throughx.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) {// 如果图象边框的长度大于30imgLength = 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 stubif(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 blocke.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;// 客户idprivate 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 blocke.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();}}
?