使用Swing绘制动态时钟

网友投稿 548 2023-07-04

使用Swing绘制动态时钟

使用Swing绘制动态时钟

本文实例为大家分享了利用Swing绘制一个动态时钟的具体代码,供大家参考,具体内容如下

效果

代码在下面,可跳过解析

前言

编程实现一个时钟

利用Swing绘制一个时钟,只能是静态的。利用Calendar类获取当前的时分秒,然后根据数学公式绘制相应的时钟就可以了。

如果静态的时钟已经足够你使用,那么就无须用到线程的概念。

如何让时钟“动起来”

当然了,动起来肯定是不可能的,但是我们可以利用人眼的视觉,让时钟“好像动起来”,其实着很简单,只要让当前的图像每隔一秒种刷新一次就可以了。这样秒针在动,数字时间也在动,整个时钟就好像“动起来了”

线程

利用线程实现刷新,刷新间隔是1秒,每次刷新都先生成当前的时间,然后JVM又会自动调用paintComponent方法绘制图形,这样就好像时钟动起来了。

Thread thread = new Thread(){

public void run(){

while(true){

StillClock clock = new StillClock();

MessagePanel messagePanel1=new MessagePanel(clock.getHour()+":"+

clock.getMinute()+":"+clock.getSecond());

//设置显示居中

messagePanel1.setCentered(true);

//设置前景颜色

messagePanel1.setForeground(Color.black);

//设置字体

messagePanel1.setFont(new Font("Courier",Font.BOLD,16));

add(clock);

add(messagePanel1,BorderLayout.SOUTH);

clock.setVisible(true);

validate(); //接下来会每隔一秒重绘一次时钟——即(从frame中将clock组件删除),因此调用validate方法,使容器重新布置其子组件

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

clock.setVisible(false);

remove(clock); //在父容器中将其删除

clock.invalidate(); //使容器失效

}

}

};

thread.start();

线程代码解析

Thread thread = new Thread(){};

注意结尾使用了分号,既然使用了线程,那么需要重写它的run方法:

public void run(){}

既然想让时钟一直动起来,那么死循环是最好的选择

while(true){}

在while里面,每次都先生成当前的时间:

StillClock clock = new StillClock();

这里生成了一个无参构造的StillClock类,StillClock的无参构造方法里面会自动生成当前的时间。

注意:这里的StillClock是我自己定义的,代码贴在后面,但是如果不关心他是怎么实现的,可以直接忽略原理,直接使用,包括代码里面的messagePanel也是一样的自定义类。

时间生成完了之后,把时钟图形、当前时间的字符串、布局位置利用add()方法绘制到屏幕上

add(clock);

add(messagePanel1,BorderLayout.SOUTH);

接下来会每隔一秒重绘一次时钟——即(从frame中将clock组件删除),因此调用validate方法,使容器重新布置其子组件。

thread.start();

让线程开始工作把。

完整代码

DisplayClock.java:

package Test;

import javax.swing.*;

import javax.swing.border.Border;

import java.awt.*;

public class DisplayClock extends JFrame {

public DisplayClock(){

//创建一个现在的时间

StillClock clock=new StillClock();

//获取当前的时间

clock.setCurrentTime();

//设置时间的显示格式

Thread thread = new Thread(){

public void run(){

while(true){

StillClock clock = new StillClock();

MessagePanel messagePanel1=new MessagePanel(clock.getHour()+":"+

clock.getMinute()+":"+clock.getSecond());

//设置显示居中

messagePanel1.setCentered(true);

//设置前景颜色

messagePanel1.setForeground(Color.black);

//设置字体

messagePanel1.setFont(new Font("Courier",Font.BOLD,16));

add(clock);

add(messagePanel1,BorderLayout.SOUTH);

clock.setVisible(true);

validate(); //接下来会每隔一秒重绘一次时钟——即(从frame中将clock组件删除),因此调用validate方法,使容器重新布置其子组件

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

clock.setVisible(false);

remove(clock); //在父容器中将其删除

clock.invalidate(); //使容器失效

}

}

};

thread.start();

//布局默认为BorderLayout,让显示信息在底部(即南边)

}

public static void main(String[] args) {

DisplayClock frame=new DisplayClock();

frame.setTitle("DisplayClock");

frame.setSize(300,350);

frame.setLocationRelativeTo(null);

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

frame.setVisible(true);

}

}

StillClock.java:

package Test;

import sun.util.calendar.Gregorian;

import javax.swing.*;

import java.awt.*;

import java.util.Calendar;

import java.util.GregorianCalendar;

public class StillClock extends JPanel {

public int getHour() {

return hour;

}

public void setHour(int hour) {

this.hour = hour;

repaint();

}

public int getMinute() {

return minute;

}

public void setMinute(int minute) {

this.minute = minute;

repaint();

}

public int getSecond() {

return second;

dYLdxUsweB}

public void setSecond(int second) {

this.second = second;

repaint();

}

private int hour;

private int minute;

private int second;

public StillClock() {

setCurrentTime();

}

public StillClock(int hour, int minute, int second) {

this.hour = hour;

this.minute = minute;

this.second = second;

}

//使用Graphics类绘制图形,需要重写paintComponent方http://法

@Override

protected void paintComponent(Graphics g) {

super.paintComponent(g);

//绘制时钟参数

int clockRadius=(int)(Math.min(getWidth(),getHeight())*0.8*0.5);

int xCenter=getWidth()/2;

int yCenter=getHeight()/2;

//绘制一个圆

g.setColor(Color.BLACK);

g.drawOval(xCenter-clockRadius,yCenter-clockRadius,2*clockRadius

,2*clockRadius);

g.drawString("12",xCenter-5,yCenter-clockRadius+12);

g.drawString("9",xCenter-clockRadius+3,yCenter+5);

g.drawString("3",xCenter+clockRadius-10,yCenter

+3);

g.drawString("6",xCenter-3,yCenter+clockRadius-3);

//绘制秒针

int sLength=(int)(clockRadius*0.8);

int xSecond=(int)(xCenter+sLength*Math.sin(second*(2*Math.PI/60)));

int ySecond=(int)(xCenter-sLength*Math.cos(second*(2*Math.PI/60)));

g.setColor(Color.red);

g.drawLine(xCenter,yCenter,xSecond,ySecond);

//绘制分针

int mLength=(int)(clockRadius*0.65);

int xMinute=(int)(xCenter+mLength*Math.sin(minute*(2*Math.PI/60)));

int yMinute=(int)(xCenter-mLength*Math.cos(minute*(2*Math.PI/60)));

g.setColor(Color.blue)dYLdxUsweB;

g.drawLine(xCenter,yCenter,xMinute,yMinute);

//绘制时针

int hLength=(int)(clockRadius*0.5);

int xHour=(int)(xCenter+hLength*Math.sin((hour%12+minute/60.0)*(2*Math.PI/12)));

int yHour=(int)(xCenter-hLength*Math.cos((hour%12+minute/60.0)*(2*Math.PI/12)));

g.setColor(Color.green);

g.drawLine(xCenter,yCenter,xHour,yHour);

}

public void setCurrentTime(){

//构造一个日历类设定当前日期和时间

Calendar calendar=new GregorianCalendar();

//设定时分秒

this.hour=calendar.get(Calendar.HOUR_OF_DAY);

this.minute=calendar.get(Calendar.MINUTE);

this.second=calendar.get(Calendar.SECOND);

}

public Dimension getPreferredSize(){

return new Dimension(200,200);

}

}

messagePanel:

package Test;

import javax.swing.*;

import java.awt.*;

public class MessagePanel extends JPanel {

//显示的信息

private String message="Welcome to java";

//显示信息x的坐标

private int xCoordinate=20;

//显示信息y的坐标

private int yCoordinate=20;

//信息是否被显示在中心部位

private boolean centered;

//水平和垂直的移动显示信息

private int interval=10;

public int getXCoordinate() {

return xCoordinate;

}

public void setXCoordinate(int xCoordinate) {

this.xCoordinate = xCoordinate;

repaint();

}

//无参构造

public MessagePanel() {

}

//带参构造

public MessagePanel(String message) {

this.message = message;

repaint();

}

public int getYCoordinate() {

return yCoordinate;

}

public void setYCoordinate(int yCoordinate) {

this.yCoordinate = yCoordinate;

repaint();

}

public boolean isCentered() {

return centered;

}

public void setCentered(boolean centered) {

this.centered = centered;

repaint();

}

public int getInterval() {

return interval;

}

public void setInterval(int interval) {

this.interval = interval;

repaint();

}

@Override

protected void paintComponent(Graphics g) {

super.paintComponent(g);

if(centered){

//设定字体

FontMetrics fm=g.getFontMetrics();

//设置显示字体

int stringWidth=fm.stringWidth(message);

int stringAscent=fm.getAscent();

xCoordinate=getWidth()/2-stringWidth/2;

yCoordinate=getHeight()/2+stringAscent/2;

}

g.drawString(message,xCoordinate,yCoordinate);

}

//让信息往左边移动

public void moveLeft(){

xCoordinate-=interval;

repaint();

}

//让信息往右边移动

public void moveRight(){

xCoordinate+=interval;

repaint();

}

//让信息向上移动

public void moveUp(){

yCoordinate+=interval;

repaint();

}

public void moveDown(){

yCoordinate-=interval;

repaint();

}

//固定写法,不必探究

@Override

public Dimension getPreferredSize() {

return new Dimension(200,30);

}

}

结束

写的有些粗糙,有需要的可以根据自己的需求进行更改,比如如何更加稳定的实现动态时钟,让时钟刻度更加精细(根据数学公式增加刻度线即可),希望可以帮助到你。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Spring注解和同步锁不能同步问题解决
下一篇:Springboot中@Value的使用详解
相关文章

 发表评论

暂时没有评论,来抢沙发吧~