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

📄 clockpanel.java

📁 实现了一个由时间服务器
💻 JAVA
字号:
package client.ds;

import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;

import javax.swing.*;

/**
 * 绘制时钟面板
 * 
 * @author elegate
 * @since 2007-10-22
 * @version 0.1
 */
public class ClockPanel extends JPanel implements ClockI {
	/**
	 * 
	 */
	private static final long serialVersionUID = -8540617832921070650L;

	/**
	 * 背景色
	 */
	public static final Color BACKGROUND_COLOR = Color.PINK;

	/**
	 * 表盘颜色
	 */
	public static final Color DIAL_COLOR = Color.BLACK;

	/**
	 * 指针颜色
	 */
	public static final Color HAND_COLOR = Color.DARK_GRAY;

	/**
	 * 时间
	 */
	private Calendar c = null;

	/**
	 * 中心坐标
	 */
	private int x, y;

	/**
	 * 表盘半径
	 */
	private int radius;

	/**
	 * 面板高度
	 */
	private int height;

	/**
	 * 面板宽度
	 */
	private int width;

	private SimpleDateFormat dateFormat;

	public ClockPanel() {
		dateFormat = new SimpleDateFormat("hh:mm:ss");
	}

	/**
	 * 重写绘制函数
	 */
	public void paintComponent(Graphics g) {
		// 如果时间未设置,则不绘制
		if (c == null)
			return;

		Graphics2D g2D = (Graphics2D) g;
		// 消除锯齿
		g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
				RenderingHints.VALUE_ANTIALIAS_ON);
		// 绘制背景
		Rectangle r = g2D.getClipBounds();
		g2D.setColor(BACKGROUND_COLOR);
		g2D.fill(r);

		// 计算相关参数
		height = r.height;
		width = r.width;
		radius = (int) (Math.min(r.height, r.width) * 0.6) / 2;
		x = (width - 2 * radius) / 2 + radius;
		y = (height - 2 * radius) / 2 + radius;
		// 绘制表盘
		drawDial(g2D);
		// 绘制指针
		drawHands(g2D);

		// 绘制数字时钟
		Font f = g2D.getFont();
		f = f.deriveFont(30.0f);
		f = f.deriveFont(Font.BOLD);
		g2D.setFont(f);
		FontRenderContext frc = g2D.getFontRenderContext();
		String time = dateFormat.format(c.getTime());
		Rectangle2D bound = f.getStringBounds(time, frc);
		double startX = x - bound.getWidth() / 2;
		double startY = ((height - 2 * radius) / 2 - bound.getHeight()) / 2
				+ bound.getHeight();
		g2D.drawString(time, (float) startX, (float) startY);
	}

	/**
	 * @param g
	 *            绘图环境
	 */
	public void drawDial(Graphics2D g) {
		// 绘制外层表盘
		Stroke s = new BasicStroke(8.0f);
		g.setStroke(s);
		g.setColor(DIAL_COLOR);
		double outRadius = radius * 1.05;
		Ellipse2D.Double ellipse = new Ellipse2D.Double(x - outRadius, y
				- outRadius, 2 * outRadius, 2 * outRadius);
		g.draw(ellipse);

		// 绘制表盘中心
		s = new BasicStroke(3.0f);
		g.setStroke(s);
		g.setColor(HAND_COLOR);
		Ellipse2D.Double dot = new Ellipse2D.Double(x - 5, y - 5, 10, 10);
		g.draw(dot);

		// 绘制表盘分割线
		g.setColor(DIAL_COLOR);
		// 绘制长分隔线
		s = new BasicStroke(3.0f);
		g.setStroke(s);
		int r1 = radius, r2 = (int) (radius - radius * 0.1);
		drawDelimiter(0, 360, 30, r1, r2, g);
		// 绘制短分隔线
		s = new BasicStroke(1.0f);
		g.setStroke(s);
		r2 = (int) (radius - radius * 0.05);
		drawDelimiter(0, 360, 6, r1, r2, g);
	}

	/**
	 * 绘制分割线
	 * 
	 * @param start
	 *            起始绘制位置
	 * @param end
	 *            终止绘制位置
	 * @param step
	 *            步长
	 * @param r1
	 *            半径1
	 * @param r2
	 *            半径2
	 * @param g
	 *            绘图环境
	 */
	private void drawDelimiter(int start, int end, int step, double r1,
			double r2, Graphics2D g) {
		for (int theta = start; theta < end; theta += step) {
			double a = theta / 180.0 * Math.PI;
			// System.out.println("sin:"+Math.sin(a)+",cos:"+Math.cos(a));
			double x1 = x + Math.cos(a) * r1;
			double y1 = y - Math.sin(a) * r1;

			double x2 = x + Math.cos(a) * r2;
			double y2 = y - Math.sin(a) * r2;

			Line2D.Double line = new Line2D.Double(x1, y1, x2, y2);
			g.draw(line);
		}
	}

	/**
	 * 绘制指针,通过调用<code>drawHand(double, double, double, Graphics2D)</code>完成三种指针的绘制
	 * 
	 * @param g
	 *            绘图环境
	 * @see #drawHand(double, double, double, Graphics2D)
	 */
	public void drawHands(Graphics2D g) {
		int hour = c.get(Calendar.HOUR);
		int minute = c.get(Calendar.MINUTE);
		int second = c.get(Calendar.SECOND);
		double h = hour % 12 + minute / 60.0 + second / 60.0 / 60.0;
		double theta = 360 - h / 12 * 360 + 90;
		theta = theta * Math.PI / 180;
		g.setColor(HAND_COLOR);

		// 时针
		Stroke s = new BasicStroke(3.0f);
		g.setStroke(s);
		drawHand(theta, 0.6, 0.08, g);
		// 分针
		theta = 360 - minute / 60.0 * 360 + 90;
		theta *= Math.PI / 180;
		s = new BasicStroke(2.0f);
		g.setStroke(s);
		drawHand(theta, 0.8, 0.05, g);
		// 秒针
		theta = 360 - second / 60.0 * 360 + 90;
		theta *= Math.PI / 180;
		s = new BasicStroke(1.0f);
		g.setStroke(s);
		drawHand(theta, 1.0, 0.03, g);
	}

	/**
	 * 绘制单个指针,如分针,时针等,由<code>drawHands(Graphics2D g)</code>调用
	 * 
	 * @param theta
	 *            角度,弧度制
	 * @param factor
	 *            控制指针长度
	 * @param deltaTheta
	 *            控制箭头和指针的夹角
	 * @param g
	 *            绘图参数
	 * @see #drawHands(Graphics2D)
	 */
	private void drawHand(double theta, double factor, double deltaTheta,
			Graphics2D g) {
		int r2 = (int) (radius * factor);

		// 计算指针头部位置
		double x1 = x + Math.cos(theta) * r2;
		double y1 = y - Math.sin(theta) * r2;

		// 计算指针的箭头位置
		// 右侧
		double x2 = x + Math.cos(theta - deltaTheta) * r2 * 0.9;
		double y2 = y - Math.sin(theta - deltaTheta) * r2 * 0.9;
		// 左侧
		double x3 = x + Math.cos(theta + deltaTheta) * r2 * 0.9;
		double y3 = y - Math.sin(theta + deltaTheta) * r2 * 0.9;

		Line2D.Double line = new Line2D.Double(x1, y1, x, y);
		g.draw(line);
		line = new Line2D.Double(x2, y2, x1, y1);
		g.draw(line);
		line = new Line2D.Double(x3, y3, x1, y1);
		g.draw(line);
		line = new Line2D.Double(x2, y2, x3, y3);
		g.draw(line);
	}

	/**
	 * 
	 */
	public void update(Calendar c) {
		this.c = c;
		repaint();

	}

	/**
	 * 
	 */
	public void update(int hour, int minute, int second) {
		if (c == null)
			c = Calendar.getInstance();
		c.set(Calendar.HOUR_OF_DAY, hour);
		c.set(Calendar.MINUTE, minute);
		c.set(Calendar.SECOND, second);
		repaint();

	}

	/**
	 * 
	 */
	public void update(long time) {
		if (c == null)
			c = Calendar.getInstance();
		c.setTimeInMillis(time);
		repaint();
	}

	public static void main(String[] args) {
		JFrame frame = new JFrame();
		frame.setSize(500, 500);
		final ClockPanel p = new ClockPanel();
		new Thread() {
			public void run() {
				while (true) {
					Calendar c = Calendar.getInstance();
					p.update(c);
					try {
						sleep(100);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}

		}.start();
		frame.getContentPane().add(p, BorderLayout.CENTER);
		frame.setVisible(true);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}
}

⌨️ 快捷键说明

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