Swing时钟动画绘制

简介: 本文利用Java原生Swing技术绘制一个时钟动画。

核心结构是JFrame套一个JPanel。

效果:

image.png

Panel代码:

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.text.SimpleDateFormat;
import java.util.Calendar;

import javax.swing.JLabel;
import javax.swing.JPanel;

public class ClockPanel extends JPanel {

    private static final long serialVersionUID = 1L;

    private int hour, minute, second;

    private int secondX, secondY, minuteX, minuteY, hourX, hourY;

    private Calendar calendar;

    private final SimpleDateFormat sdf;

    private final JLabel timeLabel;

    public ClockPanel() {
        this.setBackground(Color.LIGHT_GRAY);
        this.sdf = new SimpleDateFormat("HH:mm:ss");
        this.timeLabel = new JLabel();
        this.timeLabel.setFont(new Font("黑体", Font.BOLD, 30));
        this.timeLabel.setBounds(250, 50, 100, 40);
        this.add(this.timeLabel);
        this.run();
    }

    public void paint(Graphics g) {
        super.paint(g);
        // 修改时间显示
        this.timeLabel.setText(this.sdf.format(calendar.getTime()));
        Graphics2D graphics2D = (Graphics2D) g;
        // 定义线条宽度为5
        graphics2D.setStroke(new BasicStroke(5));
        // 绿色线条绘制钟表刻度
        g.setColor(Color.pink);
        for (int i = 0; i < 60; i++) {
            int r = 160;
            if (i % 5 == 0) {
                if (i % 15 == 0) {
                    r = 120;
                } else {
                    r = 140;
                }
            }
            int x1 = (int) (300 + sin(i) * r);
            int y1 = (int) (300 - cos(i) * r);
            int x2 = (int) (300 + sin(i) * 180);
            int y2 = (int) (300 - cos(i) * 180);
            g.drawLine(x1, y1, x2, y2);
        }
        // 橙色线条绘制外环
        g.setColor(Color.orange);
        g.drawOval(120, 120, 360, 360);
        // 橙色线条绘制内环
        g.setColor(Color.orange);
        g.drawOval(205, 205, 190, 190);
        // 灰色线条绘制时针
        g.setColor(Color.gray);
        g.drawLine(300, 300, hourX, hourY);
        // 红色线条绘制分针
        g.setColor(Color.red);
        g.drawLine(300, 300, minuteX, minuteY);
        // 黄色线条绘制秒针
        g.setColor(Color.yellow);
        g.drawLine(300, 300, secondX, secondY);
        // 黑色线条绘制轴心
        g.setColor(Color.black);
        g.fillOval(292, 292, 15, 15);
    }

    private double sin(int num) {
        return Math.sin(Math.toRadians(6 * num));
    }

    private double cos(int num) {
        return Math.cos(Math.toRadians(6 * num));
    }

    public void run() {
        new Thread(() -> {
            while (true) {
                calendar = Calendar.getInstance();
                this.second = calendar.get(Calendar.SECOND);
                this.minute = calendar.get(Calendar.MINUTE);
                this.hour = calendar.get(Calendar.HOUR);
                this.secondX = (int) (300 + sin(second) * 150);
                this.secondY = (int) (300 - cos(second) * 150);
                this.minuteX = (int) (300 + sin(minute) * 120);
                this.minuteY = (int) (300 - cos(minute) * 120);
                this.hourX = (int) (300 + Math.sin(Math.toRadians(hour * 30 + minute * 0.5)) * 90);
                this.hourY = (int) (300 - Math.cos(Math.toRadians(hour * 30 + minute * 0.5)) * 90);
                this.repaint();
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

}

Frame代码:

import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Objects;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JOptionPane;

public class ClockFrame extends JFrame {

    private static final long serialVersionUID = 1L;

    public ClockFrame() {
        this.setTitle("Java时钟");
        this.setBounds(100, 200, 600, 700);
        ClockPanel clockPanel = new ClockPanel();
        this.add(clockPanel);
        this.setResizable(false);
        this.setLocationRelativeTo(null);
        ImageIcon imageIcon = new ImageIcon(Objects.requireNonNull(this.getClass().getResource("../../../clock.png")));
        this.setIconImage(imageIcon.getImage());
        this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
        this.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                int option = JOptionPane.showConfirmDialog(ClockFrame.this, "确定退出时钟?", "退出", JOptionPane.YES_NO_OPTION);
                if (option == JOptionPane.YES_OPTION && e.getWindow() == ClockFrame.this) {
                    ClockFrame.this.dispose();
                    System.exit(0);
                }
            }
        });
        this.setVisible(true);
    }

}
相关文章
|
1月前
ThreeJs的场景实现鼠标拖动旋转控制
这篇文章介绍了如何在Three.js中实现通过鼠标拖动来旋转场景中的模型,并提供了实现这一功能的代码示例。
84 0
|
4月前
|
前端开发 JavaScript
canvas系列教程07 ——捕获、拖拽、抛掷、缓动动画、弹性动画
canvas系列教程07 ——捕获、拖拽、抛掷、缓动动画、弹性动画
55 1
|
6月前
|
移动开发 前端开发 HTML5
使用canvas绘制超炫时钟
使用canvas绘制超炫时钟
34 3
使用canvas绘制超炫时钟
LabVIEW鼠标滚轮实现波形放大缩小(zoom)功能
实现功能:将鼠标放在波形图曲线上,滚轮可以实现波形放大缩小功能。 代码思想:注册鼠标滚轮事件,滚轮时改变波形图横纵坐标最大值和最小值。
147 0
An动画基础之元件的图形动画与按钮动画
An动画基础之元件的图形动画与按钮动画
335 0
An动画基础之元件的图形动画与按钮动画
|
前端开发
canvas炫酷转盘时钟
canvas炫酷转盘时钟,拿来即用
80 0
canvas炫酷转盘时钟
|
移动开发 前端开发 Shell
使用canvas绘制时钟
使用canvas绘制时钟
88 0
Core Animation - 发光的太阳(附高效设置图片圆角和变圆的方法)
Core Animation - 发光的太阳(附高效设置图片圆角和变圆的方法)
83 0
Core Animation - 发光的太阳(附高效设置图片圆角和变圆的方法)
鼠标控制物体旋转、移动、缩放(Unity3D)
Unity3D对于鼠标操作物体的旋转、移动、缩放的功能点使用的比较多。 今天就分享如何使用Unity实现鼠标对于物体的旋转、移动、缩放。
|
存储 图形学
动画系统中的基础动画
动画系统中的基础动画
175 0
动画系统中的基础动画