NJUPT JAVA语言 多线程 时钟

一、 实验目的和要求

    本实验旨在通过实验,培养学生将JAVA 线程的相关知识点(包括线程调度,线程同步等)有机结合并加以综合应用,在实验中设计多线程程序的能力。

实验内容:设计和编写一个编写一个指针式时钟程序,应用线程实现时钟的走动。


二、实验代码

package think;
import java.util.*;
import java.awt.*;
import javax.swing.*;
public class java_exp_04clock
{	public static void main(String args[])
	{	
	    JFrame frame = new JFrame();
		ClockPaint panel = new ClockPaint();
		frame.add(panel);
		frame.setTitle("时钟");
		frame.setBounds(200,200,400,400); 
		frame.setBackground(Color.white);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);	
		frame.setVisible(true); 
	}
}
class ClockPaint extends JPanel implements Runnable   //
{							//小时,分钟,秒
	ClockPaint() 
	{	Thread t = new Thread(this);	//创建线程
		t.start();						//启动线程
	}
	private int h, m, s;
	public void paintComponent(Graphics g) 
	{
		int r, l, x1, y1;
		int x = getWidth();				//根据面板大小画时钟
		int y = getHeight();
		r = (int) (Math.min(x, y) * 0.4); 	//时钟半径
		x = x / 2;				      		//圆心坐标
		y = y / 2;
		g.setColor(Color.WHITE);
		
		g.fillOval(x - r, y - r, r * 2, r * 2);	//画钟面圆
		l = (int) (r * 0.9);
		g.setColor(Color.BLACK);
		
		for(int i = 0; i<60; i++) 			//画刻度
		{	
			x1 = (int) (x + l * Math.sin(i * (2 * Math.PI / 60)));
			y1 = (int) (y - l * Math.cos(i * (2 * Math.PI / 60)));
			if(i%5 == 0)
				g.fillOval(x1 - 3, y1 - 3, 6, 6);
			else
				g.fillOval(x1 - 1, y1 - 1, 2, 2);
		}
		
		l = (int) (r * 0.5); 				//时针长度
		x1 = (int) (x + l * Math.sin((h % 12 + m / 60.0) * (2 * Math.PI / 12)));
		y1 = (int) (y - l * Math.cos((h % 12 + m / 60.0) * (2 * Math.PI / 12)));
		g.setColor(Color.BLUE);
		g.drawLine(x, y, x1, y1);			//画时针
		
		l = (int) (r * 0.7);				//分针长度
		x1 = (int) (x + l * Math.sin(m * (2 * Math.PI / 60)));
		y1 = (int) (y - l * Math.cos(m * (2 * Math.PI / 60)));
		g.setColor(Color.GREEN);
		g.drawLine(x, y, x1, y1);			//画分针
		
		l = (int) (r * 0.9);				//秒针长度
		x1 = (int) (x + l * Math.sin(s * (2 * Math.PI / 60)));
		y1 = (int) (y - l * Math.cos(s * (2 * Math.PI / 60)));
		g.setColor(Color.RED);
		g.drawLine(x, y, x1, y1); 	     	//画秒针
	}
	public void run() 
	{	while(true) 
		{	
			try 
			{	
				Thread.sleep(1000);	                //线程休眠 1000ms 也就是 1s 运行一次
			}
			catch (Exception ex) {}
			Calendar cal = new GregorianCalendar();
			h = cal.get(Calendar.HOUR); 	        //获取当前时
			m = cal.get(Calendar.MINUTE);     		//获取当前分
			s = cal.get(Calendar.SECOND);     		//获取当前秒
			this.repaint();							//重绘图形
		}
	}
}

三、界面



四、实验小结

整体的思路:

 *顶层框架里放入一个时钟布局,根据线程的调度,每隔1s获取当前的时间来改变时针分针秒针的长度来更新布局。

遇到的问题和解决的方法:

 * 一开始思路不清晰,搜索了几个例子看了感觉有了点思路。所以,没有思路的时候,记得搜索!

 * 布局:时针分针秒针的位置可以根据当前的时间转换成角度,再显示。

 * 图形设置的优化:由于界面是可以调整的,所以时钟的圆心和半径是一个难点。解决的方案是寻找长宽里小的那一个,再设置为一半即可获得圆心,半径设置为其0.9倍即可。

 * 优化:线程睡眠的时间程序里设置的是1000ms,其实可以改成比1000ms更小的数字。即表示,每隔多少ms更新一次。设置成1000ms正好,不浪费资源也正好满足了需求。


  • 5
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值