使用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;
  }

  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);
  }
}

结束

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Java编程小实例—数字时钟的实现代码示例

    本文的实例是Java编程实现一个数字时钟,代码测试可用,练练手吧.代码如下: package me.socketthread; import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.util.Calendar; import java.util.GregorianCalenda

  • Java实现的动态数字时钟功能示例【显示世界时间】

    本文实例讲述了Java实现的动态数字时钟功能.分享给大家供大家参考,具体如下: 构建: 1. Clock继承 JFrame 为运行页面 2. ClockText 测试类 创建 Clock 对象 运行效果: 具体实现: 一.Clock类  四个JPnal 三个放时间 最后一个放日期 放时间的三个JPnal 分别加入 地点 时间 按钮 最后一个按钮添加日期 具体实现如下: public class Clock extends JFrame { private JPanel jPanelBeijing

  • Java实现的简单数字时钟功能示例

    本文实例讲述了Java实现的简单数字时钟功能.分享给大家供大家参考,具体如下: 应用名称:Java数字时钟 用到的知识:Java GUI编程,线程 开发环境:win8+eclipse+jdk1.8 功能说明:可以显示当前系统的年月日.星期以及准确时间,并实时更新显示. 效果图: 源代码: import javax.swing.JFrame; import javax.swing.JPanel; import java.awt.BorderLayout; import javax.swing.JL

  • java实现的小时钟示例分享

    复制代码 代码如下: //package com.clock; import java.awt.BasicStroke;import java.awt.Color;import java.awt.Font;import java.awt.Graphics;import java.awt.Graphics2D;import java.awt.Insets;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;i

  • java实现动态时钟并设置闹钟功能

    本文实例为大家分享了java实现动态时钟设置闹钟功能,供大家参考,具体内容如下 显示如上图所示的动态时钟,并且可以设置闹钟,播放mp3. 首先用到的是时钟(Timer)和日历(Calendar)得到系统的当前时间. 代码如下: import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.geom.Ellipse2D; import java.awt.geom.Line2D; import java.io.Buffer

  • Java实现动态数字时钟

    本文实例为大家分享了Java实现动态数字时钟的具体代码,供大家参考,具体内容如下 构建: Clock继承 JFrame 为运行页面 ClockText 测试类 创建 Clock 对象 运行效果: 具体实现: 一.Clock类 四个JPnal 三个放时间 最后一个放日期 放时间的三个JPnal 分别加入 地点 时间 按钮 最后一个按钮添加日期 具体实现如下: public class Clock extends JFrame { private JPanel jPanelBeijing; priv

  • java多线程编程制作电子时钟

    模拟一个电子时钟,它可以在任何时候被启动或者停止,并可以独立的运行. 1.定义一个Clock类.它继承Label类,并实现Runnable接口.这个类中有一个Thread类型的clocker域,以及start()和run()方法.在run()方法中,每隔一秒就把系统时间显示为label的文本. class Clock extends Label implements Runnable { //定义Thread类型的clocker域 public Thread clocker=null; publ

  • Java实现动态模拟时钟

    本文实例为大家分享了java动态模拟时钟的具体代码,供大家参考,具体内容如下 应用名称:java动态模拟时钟 用到的知识:javaGUI,java 绘图 开发环境:win10+eclipse+jdk1.8 功能说明:通过java绘图画出一个虚拟的动态时钟 效果图: 源代码: import javax.swing.*; import java.awt.*; import java.util.*; import java.lang.Thread; import java.text.DecimalFo

  • 使用Swing绘制动态时钟

    本文实例为大家分享了利用Swing绘制一个动态时钟的具体代码,供大家参考,具体内容如下 效果 代码在下面,可跳过解析. 前言 编程实现一个时钟 利用Swing绘制一个时钟,只能是静态的.利用Calendar类获取当前的时分秒,然后根据数学公式绘制相应的时钟就可以了. 如果静态的时钟已经足够你使用,那么就无须用到线程的概念. 如何让时钟"动起来" 当然了,动起来肯定是不可能的,但是我们可以利用人眼的视觉,让时钟"好像动起来",其实着很简单,只要让当前的图像每隔一秒种刷

  • JS+Canvas绘制动态时钟效果

    本文实例为大家分享了Canvas绘制动态时钟效果展示的具体代码,供大家参考,具体内容如下 <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> <style> #mycanvas{ position: absolute; left:50%; margin-left:-250px; border:5px solid #

  • javascript canvas封装动态时钟

    本文实例为大家分享了canvas封装动态时钟的具体代码,供大家参考,具体内容如下 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title&

  • js+SVG实现动态时钟效果

    本文实例为大家分享了js+SVG实现动态时钟效果展示的具体代码,供大家参考,具体内容如下 <!DOCTYPE HTML> <html> <meta charset="utf-8"> <head> <title>Analog Clock</title> <script> function updateTime() { var now = new Date(); // 当前时间 var min = now.

  • Android动态时钟壁纸开发

    本文实例为大家分享了Android动态时钟壁纸展示的具体代码,供大家参考,具体内容如下 先看效果 上图是动态壁纸钟的一个时钟. 我们先来看看 Livewallpaper(即动态墙纸)的实现,Android的动态墙纸并不是GIF图片,而是一个标准的Android应用程序,也就是APK.既然是应用程序,当然意味着天生具有GIF图片不具备的功能--能与用户发生交互,而且动态的背景变化绝不仅仅局限于GIF图片那般只能是固定的几张图片的循环播放.但是我们在这里没有加入与用户交互的动作,只是加入一个时钟(当

  • python实现简易动态时钟

    本文实例为大家分享了python实现简易动态时钟的具体代码,供大家参考,具体内容如下 from turtle import * from datetime import * #移动到指定位置 def skip(step): penup() forward(step) pendown() #画指针 def drawpointer(name, length): reset() skip(-length*0.1) begin_poly() forward(length*1.1) end_poly()

  • QT实现动态时钟

    本文实例为大家分享了QT实现动态时钟的具体代码,供大家参考,具体内容如下 首次学习QT,这次用QT实现了动态图的制作,并成功制作了一个简易的时钟,效果如图: 加快100倍效果 所用背景图,如下(素材来源于百度图片): 代码,原理如下: mainwindow.h #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; }

  • Qt实现指针式时钟 Qt实现动态时钟

    本文实例为大家分享了Qt实现指针式时钟.动态时钟的具体代码,供大家参考,具体内容如下 先上图: 点击运行后首先是一个指针式时钟窗口,点击Digital Clock->可以跳转到数字时钟窗口,再点击Move Clock->可以还原为指针式时钟窗口 关于整个程序的讲解都在代码注释中给出,很详细~ 概要: 我设计两个窗口,一个主窗口一个子窗口,利用按钮+信号与槽机制,实现两个窗口的互相切换,其中主窗口用来显示指针时钟,完成三个基本要求: 1.正确显示系统时钟: 2.能准确定位时钟刻度和时分秒针的位置

  • Qt实现简单动态时钟

    本文实例为大家分享了Qt实现简单动态时钟的具体代码,供大家参考,具体内容如下 任务实现: 通过Qt语言使用计时器实现一个简单的动态时钟: 实现效果: 实现过程: 整体过程主要分为两个部分: 1.绘制一个表盘所需的元素:时分秒针,刻度,还可以插入钟面背景图片: 2.让所绘制的指针动起来(使用计时器并关联系统时间): 整体代码: dialog.h #ifndef DIALOG_H #define DIALOG_H #include <QDialog> QT_BEGIN_NAMESPACE name

随机推荐