如何使用Swing绘制动态时钟

这篇文章将为大家详细讲解有关如何使用Swing绘制动态时钟,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

我们提供的服务有:网站制作、做网站、微信公众号开发、网站优化、网站认证、君山ssl等。为1000多家企事业单位解决了网站和推广的问题。提供周到的售前咨询和贴心的售后服务,是有科学管理、有技术的君山网站制作公司

前言

编程实现一个时钟

利用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;  }  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方法  @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);    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);  }}

关于“如何使用Swing绘制动态时钟”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。


网页名称:如何使用Swing绘制动态时钟
URL分享:http://scyanting.com/article/ihehjs.html