Swing-定时任务(模拟时钟)

女生的网名这么多〃 提交于 2019-11-26 19:23:14

 设计思路:

1、‘开始’监听器的设计

定义一个swing 下的Timer对象,每隔一段时间,触发一次timer的监听器(重新绘制钟表面板),即令钟表可以走动

2、钟表的设计

难点在于钟表角度的绘制,

在这里为钟表加上了一个辐射渐变背景图

详情见代码注释:

3、‘停止’按钮的设计

即timer.stop();

 

三个类:

1、钟表面板设计类

2、注面板设计类

3、main类

package my3;

import java.awt.Container;
import java.awt.FlowLayout;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;

public class Swing2
{
	private static void createGUI()
	{
		// JFrame指一个窗口,构造方法的参数为窗口标题
		// 语法:因为MyFrame是JFrame的子类,所以可以这么写
		JFrame frame = new MyFrame("Js钟表");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		
		// 设置窗口的其他参数,如窗口大小
		frame.setSize(700, 450);
		
		// 显示窗口
		frame.setVisible(true);
		
		
	}
	
	public static void main(String[] args)
	{
		// 此段代码间接地调用了 createGUI()
		javax.swing.SwingUtilities.invokeLater(new Runnable() {
			public void run()
			{
				createGUI();
			}
		});

	}
}
package my3;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

public class MyFrame extends JFrame
{
	CustomClock clock=new CustomClock();
	
	Timer timer;
	
	public MyFrame(String title)
	{
		super(title);
		
		// Content Pane
		JPanel root = new JPanel();
		this.setContentPane(root);
		root.setLayout(new BorderLayout());	
		
		root.add(clock, BorderLayout.CENTER);
		
		// 工具栏
		Box toolbar = Box.createHorizontalBox();
		JButton startButton = new JButton("开始");
		JButton stopButton = new JButton("停止");
		toolbar.add(startButton);
		toolbar.add(Box.createHorizontalStrut(10));
		toolbar.add(stopButton);
		root.add(toolbar, BorderLayout.PAGE_START);
				
		startButton.addActionListener( (e)->{
				startClock();
			});
		stopButton.addActionListener( (e)->{
				stopClock();
			});
	}
	
	private void startClock()
	{
		if(timer!=null) return;
		
		//创建定时器,每隔1000毫秒执行一次
		//第一个参数是delay
		//第二个参数为ActionListener,可以用匿名类或者Lamada表达式
//		timer=new Timer(1000,(e)-> {
//			clock.repaint(); //重置时钟
//		});
		
		//匿名类
		timer=new Timer(1000,new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				
				clock.repaint();
			}
			
		});
		timer.start();
	}
	
	private void stopClock()
	{
		if(timer != null)
		{
			timer.stop();
			timer = null;
		}
	}
}
package my3;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RadialGradientPaint;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.util.Calendar;

import javax.swing.JPanel;

public class CustomClock extends JPanel
{

	@Override
	protected void paintComponent(Graphics g) 
	{
		int width=this.getWidth();
		int height=this.getHeight();
		Graphics2D g2d=(Graphics2D)g;
		
		
		// 平滑绘制 ( 反锯齿 )
		g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
		g2d.setPaint(Color.white);
		g2d.fillRect(0, 0, width, height);
		
		// 取得一个最大的正文形
		//Rectangle rect = new Rectangle(0,0,200,200);
		int w = width;
		int h = width;
		if( h > height)
		{
			h = height;
			w = height;
		}
		Rectangle rect = new Rectangle((width-w)/2, (height-h)/2, w, h);		
		rect.grow(-4,-4); // 往里缩一点
		
		//中心点以及半径
		int centerX=(int)rect.getCenterX();
		int centerY=(int)rect.getCenterY();
		int radius=(int)rect.width/2;
	
	
		//////////////表盘的圆框 /////////////
		if(true)
		{			
			// 背景填充白色
//			g2d.setPaint(new Color(0xFFFFFF));
//			g2d.fillOval(rect.x, rect.y, rect.width, rect.height);
			
			// 边框
			g2d.setStroke(new BasicStroke(4));
			g2d.setPaint(Color.RED);
			g2d.drawOval(rect.x, rect.y, rect.width, rect.height);
		}
		
		
		/////////////// 刻度 /////////////////
		if(true)
		{
			g2d.setStroke(new BasicStroke(4));
			for(double angle=0;angle<360;angle+=30)
			{
				drawRadialLine(g2d, centerX, centerY, radius, angle);
			}
			//截断辐条得到刻度
			radius-=5;
//			g2d.setPaint(Color.WHITE);
//			g2d.fillOval(centerX-radius, centerY-radius, radius*2, radius*2);
			//中心画一个小圆点
			int r=4;
			g2d.setPaint(Color.RED);
			g2d.fillOval(centerX-r, centerY-r, r*2, r*2);
		}
		
		//辐射渐变填充
		if(true)	
		{
			Point2D center=new Point2D.Double(centerX,centerY);
			float[] dist= {0.0f,0.2f,1.0f};  //距离
			Color[] colors = { Color.RED, Color.WHITE, Color.BLUE };  //颜色
			//Gradient  梯度
			RadialGradientPaint paint=new RadialGradientPaint(center,radius,dist,colors);
			g2d.setPaint(paint);
			g2d.fillOval(centerX-radius, centerY-radius, radius*2, radius*2);

		}
			
			//////////////秒针,分针,时针 ///////////
			
			//得到时分秒值
			Calendar cal=Calendar.getInstance();
			int hour=cal.get(Calendar.HOUR);
			int minute=cal.get(Calendar.MINUTE);
			int second=cal.get(Calendar.SECOND);
			
			//时针
			if(true)
			{
				double radius2=radius*0.5;
				g2d.setPaint(Color.ORANGE);
				g2d.setStroke(new BasicStroke(6));
				
				//计算角度
				double vv=hour+minute/60.0;
				drawRadialLine(g2d,centerX,centerY,radius2,vv/12.0*360-90);
			}
			
			// 分针
			if(true)
			{
				double radius2 = radius *0.7;
				g2d.setPaint(Color.GREEN);
				g2d.setStroke(new BasicStroke(3));
				
				double vv = minute + second/60.0; // 角度计算有一点点复杂
				drawRadialLine(g2d, centerX, centerY, radius2, minute/60.0 * 360 - 90);
			}
			
			// 秒针
			if(true)
			{
				double radius2 = radius *0.9;
				g2d.setPaint(Color.RED);
				g2d.setStroke(new BasicStroke(1));			
				drawRadialLine(g2d, centerX, centerY, radius2, second/60.0 * 360 - 90 );
			}	
		
	}

	
	
	// 绘制从圆心发散出的辐条线条,中心centerX, centerY, 半径radius, 角度angle
	private void drawRadialLine(Graphics2D g2d,
			double centerX, double centerY,
			double radius, double angle)
	{
		double radian=angle/180*Math.PI; //角度转化为弧度
		
		double x = centerX + radius * Math.cos( radian );
		double y = centerY + radius * Math.sin( radian );	
		
		Line2D line=new Line2D.Double(x, y, centerX, centerY);
		g2d.draw(line);
	}
	
}

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!