⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 myclock.java

📁 一个applet的时钟程序,有删改,基本实现从本地读取时间并用小程序运行.
💻 JAVA
字号:
package clock;

import java.applet.Applet;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.MediaTracker;
import java.net.MalformedURLException;
import java.net.URL;

public class MyClock extends Applet implements Runnable {
	static final int BACKGROUND = 0; // 背景图片的序号,供数组使用

	static final int LOGO = 1; // LOGO图片的序号,供数组使用

	static final String JAVEX = "计时"; // 表盘上显示的文字

	static final double MINSEC = 0.104719755; // 分针和秒针在表盘上的刻度(60个)间的弧度

	static final double HOUR = 0.523598776; // 时针在表盘上的刻度(24个)间的弧度

	Thread clockThread = null; // 使用多线程机制,用另一个线程不断显示图片

	// 提供的默认参数,如果HTML文件里面没有给参数就使用
	int width = 100;

	int height = 100;

	Color bgColor = new Color(0, 0, 0);

	Color faceColor = new Color(0, 0, 0);

	Color sweepColor = new Color(255, 0, 0);

	Color minuteColor = new Color(192, 192, 192);

	Color hourColor = new Color(255, 255, 255);

	Color textColor = new Color(255, 255, 255);

	Color caseColor = new Color(0, 0, 0);

	Color trimColor = new Color(192, 192, 192);

	String logoString = null;

	Image images[] = new Image[2]; // 背景和LOGO的图片

	boolean isPainted = false; // 如果第一次载入时绘制背景及表盘,其他时候重绘则只绘制指针

	// 时钟圆心的位置
	int x1, y1;

	// 最上面那个三角形的刻度图形的坐标
	int xPoints[] = new int[3], yPoints[] = new int[3];

	// 保存当前时间,转换成(double)(hours + minutes/60)
	Hms cur_time;

	// 秒针、分针、时针
	SweepHand sweep;

	HmHand minuteHand, hourHand;

	// 用于绘制的时、分、秒
	double lastHour;

	int lastMinute, lastSecond;

	// 显示日期和表盘上的字母的字体
	Font font;

	// 图片显示使用了缓冲机制,offScrImage和offScrGC存放缓冲区内图片的信息
	Image offScrImage;

	Graphics offScrGC;

	// 用于测试背景图片和LOGO图片
	MediaTracker tracker;

	int minDimension; // 如果背景区域不是正方形的话,保证时钟在中间显示

	int originX; // 时钟图形所在正方形区域的左上角X坐标

	int originY; // 时钟图形所在正方形区域的左上角Y坐标

	double tzDifference = 0; // 时区间的差,向西为负数,向东为正数

	boolean localOnly = false; // 是否只使用本地时间,如果为FALSE则可以根据传入的时区显示该时区时间

	// 保存参数的类型说明
	public String[][] getParameterInfo() {
		String[][] info = { { "width", "int", "APPLET的长度,以象素为单位" },
				{ "height", "int", "APPLET的宽度,以象素为单位" },
				{ "bgColor", "string", "背景颜色,e.g FF0000" },
				{ "faceColor", "string", "表盘颜色" },
				{ "sweepColor", "string", "秒针颜色" },
				{ "minuteColor", "string", "分针颜色" },
				{ "hourColor", "string", "时针颜色" },
				{ "textColor", "string", "文本颜色" },
				{ "caseColor", "string", "框内颜色" },
				{ "trimColor", "string", "空白区颜色" },
				{ "bgImageURL", "string", "背景图片地址" },
				{ "logoString", "string", "LOGO字符" },
				{ "logoImageURL", "string", "LOGO图片地址" },
				{ "timezone", "real", "时区间的差" },
				{ "localonly", "int", "是否考虑到时区差别" } };
		return info;
	}

	// 显示信息
	public String getAppletInfo() {
		return "";
	}

	void showURLerror(Exception e) {
		String errorMsg = "URL错误:" + e;
		showStatus(errorMsg);
		System.err.println(errorMsg);
	}

	// 相当于把时钟变成100×100的大小,percent即相对坐标
	private int size(int percent) {
		return (int) ((double) percent / 100.0 * (double) minDimension);
	}

	public void init() {
		URL imagesURL[] = new URL[2];
		String szImagesURL[] = new String[2];
		tracker = new MediaTracker(this);

		// 得到HTML页面提供的参数,并把它转换相应的格式
		String paramString = getParameter("WIDTH");
		if (paramString != null)
			width = Integer.valueOf(paramString).intValue();

		paramString = getParameter("HEIGHT");
		if (paramString != null)
			height = Integer.valueOf(paramString).intValue();

		paramString = getParameter("TIMEZONE");
		if (paramString != null)
			tzDifference = Double.valueOf(paramString).doubleValue();

		paramString = getParameter("LOCALONLY");
		if (paramString != null && Integer.valueOf(paramString).intValue() != 0) {
			localOnly = true;
			tzDifference = 0.;
		}

		paramString = getParameter("BGCOLOR");
		if (paramString != null)
			bgColor = parseColorString(paramString);

		paramString = getParameter("FACECOLOR");
		if (paramString != null)
			faceColor = parseColorString(paramString);

		paramString = getParameter("SWEEPCOLOR");
		if (paramString != null)
			sweepColor = parseColorString(paramString);

		paramString = getParameter("MINUTECOLOR");
		if (paramString != null)
			minuteColor = parseColorString(paramString);

		paramString = getParameter("HOURCOLOR");
		if (paramString != null)
			hourColor = parseColorString(paramString);

		paramString = getParameter("TEXTCOLOR");
		if (paramString != null)
			textColor = parseColorString(paramString);

		paramString = getParameter("CASECOLOR");
		if (paramString != null)
			caseColor = parseColorString(paramString);

		paramString = getParameter("TRIMCOLOR");
		if (paramString != null)
			trimColor = parseColorString(paramString);

		logoString = getParameter("LOGOSTRING");
		if (logoString == null)
			logoString = JAVEX;
		else if (logoString.length() > 8)
			logoString = logoString.substring(0, 8); // 限制8个字母,否则显示不下!

		// szImagesURL数组根据HTML传入参数存放图片的文件名
		szImagesURL[BACKGROUND] = getParameter("BGIMAGEURL");
		szImagesURL[LOGO] = getParameter("LOGOIMAGEURL");

		// 测试图片
		for (int i = 0; i < 2; i++) {
			if (szImagesURL[i] != null) {
				// 根据CodeBase参数与Image文件名得到image的路径,测试是否存在,如果不存在就不用图片
				try {
					imagesURL[i] = new URL(getCodeBase(), szImagesURL[i]);
				} catch (MalformedURLException e) {
					showURLerror(e);
					imagesURL[i] = null;
					images[i] = null;
				}
				if (imagesURL[i] != null) {
					showStatus("加载图片: " + imagesURL[i].toString());
					images[i] = getImage(imagesURL[i]);
					if (images[i] != null)
						tracker.addImage(images[i], i);
					showStatus("");
				}
				try {
					tracker.waitForAll(i);
				} catch (InterruptedException e) {
				}
			} else
				images[i] = null;
		}

		// 得到相应时区的时间
		cur_time = (localOnly) ? new Hms() : new Hms(tzDifference);
		lastHour = -1.0;
		lastMinute = -1;
		lastSecond = -1;

		x1 = width / 2;
		y1 = height / 2;

		// 换算出圆形时钟在背景里的左上角坐标
		minDimension = Math.min(width, height);
		originX = (width - minDimension) / 2;
		originY = (height - minDimension) / 2;

		// 计算出上面三角形的三个点的坐标
		xPoints[1] = x1 - size(3);
		xPoints[2] = x1 + size(3);
		xPoints[0] = x1;
		yPoints[1] = y1 - size(38);
		yPoints[2] = y1 - size(38);
		yPoints[0] = y1 - size(27);

		// 计算出秒针、分针、时针图形的各个点坐标
		sweep = new SweepHand(x1, y1, size(40), 3);
		minuteHand = new HmHand(x1, y1, size(40), size(6), 6);
		hourHand = new HmHand(x1, y1, size(25), size(8), 6);

		// 构造字体
		font = new Font("TXT", Font.BOLD, size(10));

		// 构造缓冲区内图形
		offScrImage = createImage(width, height);
		offScrGC = offScrImage.getGraphics();

		System.out.println(getAppletInfo());
	}

	public void start() // 开始启动显示线程
	{
		if (clockThread == null) {
			clockThread = new Thread(this);
		}
		clockThread.start();
	}

	public void stop() // 停止显示
	{
		clockThread = null;
	}

	private void drawHands(Graphics g) {

		double angle;
		int i, j;
		int x, y;

		angle = MINSEC * lastSecond; // 根据lastSecond算出秒针相对于12点刻度的角度
		sweep.draw(faceColor, angle, g);// 画出秒针

		// 如果时与分改变则重绘时针分针
//		if (cur_time.getMinutes() != lastMinute) {
//			minuteHand.draw(faceColor, MINSEC * lastMinute, g);
//			if (cur_time.get_hours() != lastHour)
//				hourHand.draw(faceColor, HOUR * lastHour, g);
//		}
//
		g.setColor(textColor);
		g.fillRect(originX + size(12), y1 - size(2), size(10), size(4)); // 绘制左侧横条
		g.fillRect(x1 - size(2), originY + minDimension - size(22), size(4),
				size(10)); // 绘制下面的横条
		g.fillPolygon(xPoints, yPoints, 3); // 绘制顶部的三角形
		for (i = 1; i < 12; i += 3)
			// 在表盘的2、3、5、6、8、9、11时针刻度区绘制圆
			for (j = i; j < i + 2; j++) {
				x = (int) (x1 + Math.sin(HOUR * j) * size(35));
				y = (int) (y1 - Math.cos(HOUR * j) * size(35));
				g.fillOval(x - size(3), y - size(3), size(6), size(6));
			}

		// 设置字体
		g.setFont(font);
		FontMetrics fm = g.getFontMetrics();

		// 画顶部的LOGO字符串
		g.drawString(logoString, x1 - fm.stringWidth(logoString) / 2, y1
				- size(12));

		// 得到日期
		String day = Integer.toString(cur_time.getDate(), 10);

		// 将日期绘制在表盘右侧
		g.drawString(day, originX + minDimension - size(14)
				- fm.stringWidth(day), y1 + size(5));
//
//		// 外面画上框子
		g.drawRect(originX + minDimension - size(14) - fm.stringWidth(day)
				- size(2), y1 - size(5) - size(2), fm.stringWidth(day)
				+ size(4), size(10) + size(4));

		if (images[LOGO] != null) { // 如果LOGO图片存在,在底部画出来
			x = originX + (minDimension - images[LOGO].getWidth(this)) / 2;
			y = y1
					+ (minDimension / 2 - size(22) - images[LOGO]
							.getHeight(this)) / 2;
			if (x > 0 && y > 0)
				offScrGC.drawImage(images[LOGO], x, y, this);
		}

//		lastHour = cur_time.get_hours();
//		hourHand.draw(hourColor, HOUR * lastHour, g); // 画时针

//		lastMinute = cur_time.getMinutes();
//		minuteHand.draw(minuteColor, MINSEC * lastMinute, g); // 画分针

//		g.setColor(minuteColor); // 绘制分针尾部的圆形
//		g.fillOval(x1 - size(4), y1 - size(4), size(8), size(8));
		g.setColor(sweepColor); // 绘制秒针尾部的圆形
		g.fillOval(x1 - size(3), y1 - size(3), size(6), size(6));

		lastSecond = cur_time.getSeconds(); // 得到新的秒数,重画
		angle = MINSEC * lastSecond;
		sweep.draw(sweepColor, angle, g);

		g.setColor(trimColor);
		g.fillOval(x1 - size(1), y1 - size(1), size(2), size(2)); // 秒针尾部圆心部分应该是螺丝,挖空处理^_^
	}

	private Color parseColorString(String colorString) // 参数传入为字符串形(规定为16进制6位字符串)
	{
		if (colorString.length() == 6) {
			int R = Integer.valueOf(colorString.substring(0, 2), 16).intValue(); // 前两位为R值
			int G = Integer.valueOf(colorString.substring(2, 4), 16).intValue(); // 中间为G值
			int B = Integer.valueOf(colorString.substring(4, 6), 16).intValue(); // 最后为B值
			return new Color(R, G, B); // 得到COLOR
		} else
			return Color.lightGray; // 字符串不符合规范,默认为灰色
	}

	public void run() {
		repaint(); // 每次启动时首先重绘一次
		// 每隔500ms获得现在时间并重绘一次
		while (null != clockThread) {
			cur_time = (localOnly) ? new Hms() : new Hms(tzDifference);
			repaint();

			try {
				Thread.sleep(500);
			} catch (InterruptedException e) {
			}
		}
	}

	public void paint(Graphics g) // 首先绘制缓冲区内图片,再显示出来
	{
		int i, x0, y0, x2, y2;

		// 如果没有提供背景图片,则用bgColor绘制背景
		if (images[BACKGROUND] == null) {
			offScrGC.setColor(bgColor);
			offScrGC.fillRect(0, 0, width, height);
		} else
			// 否则直接使用背景图片
			offScrGC.drawImage(images[BACKGROUND], 0, 0, this);

		// 绘制外框到表盘间的部分
		offScrGC.setColor(caseColor);

		// 将园形的范围适量缩减(不充满整个区域),防止有些地方被截取
		offScrGC.fillOval(originX + 1, originY + 1, minDimension - 2,
				minDimension - 2);

		// 绘制表盘
		offScrGC.setColor(faceColor);
		offScrGC.fillOval(originX + size(5), originY + size(5), minDimension
				- size(10), minDimension - size(10));

		// 绘制外框线
		offScrGC.setColor(trimColor);
		offScrGC.drawOval(originX + 1, originY + 1, minDimension - 2,
				minDimension - 2);

		// 绘制内框线
		offScrGC.drawOval(originX + size(5), originY + size(5), minDimension
				- size(10), minDimension - size(10));

		offScrGC.setColor(textColor);

		// 画刻度,一共有60个刻度,x0、y0为刻度起始的位置,x1、y1圆心位置,x2、y2为刻度终止位置(x0<x2,y0<y2)
		for (i = 0; i < 60; i++) {
			if (i == 0 || (i >= 5 && i % 5 == 0)) { // 每5格绘制一条长线(相对圆心)
				x0 = (int) (x1 + size(40) * Math.sin(MINSEC * i));
				y0 = (int) (y1 + size(40) * Math.cos(MINSEC * i));
			} else { // 其他部分绘制短线
				x0 = (int) (x1 + size(42) * Math.sin(MINSEC * i));
				y0 = (int) (y1 + size(42) * Math.cos(MINSEC * i));
			}
			x2 = (int) (x1 + size(44) * Math.sin(MINSEC * i));
			y2 = (int) (y1 + size(44) * Math.cos(MINSEC * i));
			offScrGC.drawLine(x0, y0, x2, y2);
		}

		drawHands(offScrGC); // 绘制指针
		g.drawImage(offScrImage, 0, 0, this); // 把生成的缓冲区图形绘制到页面上

		isPainted = true; // 使下次UPDATE时不绘制表盘
	}

	public synchronized void update(Graphics g) {
		if (!isPainted) // 绘制表盘
			paint(g);
		else { // 已经绘制了表盘,只用绘制指针,首先在缓冲区内绘制,然后显示出来
			drawHands(offScrGC);
			g.drawImage(offScrImage, 0, 0, this);
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -