首页 > 代码库 > (原创 by 徐剑生)《Java Swing之利用简单的多线程实现动态时钟》

(原创 by 徐剑生)《Java Swing之利用简单的多线程实现动态时钟》

注:本文仅供学习和交流

以上是截图,下面上代码

第一个类是Circle

package org.xt.util;import java.awt.Point;public class Circle {    private Point centre;    private int radius;    public Circle(Point centre, int radius) {        this.centre = centre;        this.radius = radius;    }    public Point getCentre() {        return centre;    }    public void setCentre(Point centre) {        this.centre = centre;    }    public int getRadius() {        return this.radius;    }    public void setRadius(int radius) {        this.radius = radius;    }}

 

第二个类是Clock

package org.xt.clock;import java.awt.BasicStroke;import java.awt.BorderLayout;import java.awt.Color;import java.awt.Graphics;import java.awt.Graphics2D;import java.awt.RenderingHints;import java.util.Calendar;import javax.swing.JComponent;import javax.swing.JFrame;import javax.swing.JPanel;@SuppressWarnings("serial")public class Clock extends JComponent implements Runnable {    private int radius;    public Clock(int radius) {        this.radius = radius;    }    public void paint(Graphics g) {        Graphics2D g2d = (Graphics2D) g;     //这两句话是去除线条锯齿的关键,至于原理笔者也不清楚,这两句是笔者从网络上找来的(就这两句不是自己写的,呵呵)        g2d.setStroke(new BasicStroke(1.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL));        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);     //钟盘所在的矩形的左上角的坐标        int clockPlateX = 0;        int clockPlateY = 0;        g2d.setColor(Color.GRAY);     //画两个同心圆盘,作为时钟的边框        g2d.drawOval(clockPlateX, clockPlateY, this.radius * 2, this.radius * 2);        g2d.drawOval(clockPlateX + 5, clockPlateY + 5, this.radius * 2 - 10, this.radius * 2 - 10);     //圆心坐标        int centreX = this.radius;        int centreY = centreX;        g2d.setStroke(new BasicStroke(0.8f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL));     //这是钟盘中心的那个点        g2d.fillOval(centreX - 3, centreY - 3, 6, 6);        g2d.setStroke(new BasicStroke(2.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL));     //以下开始画大刻度,共有12个,表示有12个小时,基准是9时所指的刻度        double degree = 0;        double radian = Math.toRadians(degree);        for (int i = 0; i < 12; ++i) {       //计算刻度线相对位置位于左边的点            int leftX = (int) ((double) centreX - (this.radius - 15) * Math.cos(radian));            int leftY = (int) ((double) centreY - (this.radius - 15) * Math.sin(radian));       //计算刻度线相对位置位于右边的点            int rightX = (int) ((double) centreX - (this.radius - 25) * Math.cos(radian));            int rightY = (int) ((double) centreY - (this.radius - 25) * Math.sin(radian));                  g2d.drawLine(leftX, leftY, rightX, rightY);            degree += 30;       //将角度转换为弧度            radian = Math.toRadians(degree);        }        g2d.setStroke(new BasicStroke(1.5f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL));             //以下开始画小刻度,共有60-12=48个,基准是0时所指的刻度        degree = 0;        radian = Math.toRadians(degree);        for (int i = 0; i < 60; ++i) {         //此条件在于避免小刻度和大刻度重复            if (i != 0 && degree % 30 != 0) {                int leftX = (int) ((double) centreX - (this.radius - 15) * Math.cos(radian));                int leftY = (int) ((double) centreY - (this.radius - 15) * Math.sin(radian));                int rightX = (int) ((double) centreX - (this.radius - 17) * Math.cos(radian));                int rightY = (int) ((double) centreY - (this.radius - 17) * Math.sin(radian));                g2d.drawLine(leftX, leftY, rightX, rightY);            }        //每次增加6度            degree += 360 / 60;            //将角度转换为弧度            radian = Math.toRadians(degree);        }     //获取当前的时,分,秒(Date类已经被淘汰,这里使用Calendar)        Calendar cal = Calendar.getInstance();        int second = cal.get(Calendar.SECOND);        int minute = cal.get(Calendar.MINUTE);        int hour = cal.get(Calendar.HOUR_OF_DAY);        if (hour > 12) {            hour = hour % 12;        }     //计算秒针当前距离开始位置的弧度,其余两句分别是分针和时针        double secondProp = Math.toRadians(second * (360 / 60));        double minuteProp = Math.toRadians(minute * (360 / 60));        double hourProp = Math.toRadians((hour + minuteProp / (2 * Math.PI)) * (360 / 12));        int leftX = (int) (centreX + (this.radius - 25) * Math.sin(secondProp));        int leftY = (int) (centreY - (this.radius - 25) * Math.cos(secondProp));        g2d.setStroke(new BasicStroke(1.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL));        g.drawLine(leftX, leftY, centreX, centreY);        leftX = (int) (centreX + (this.radius - 45) * Math.sin(minuteProp));        leftY = (int) (centreY - (this.radius - 45) * Math.cos(minuteProp));        g2d.setStroke(new BasicStroke(1.5f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL));        g.drawLine(leftX, leftY, centreX, centreY);        leftX = (int) (centreX + (this.radius - 70) * Math.sin(hourProp));        leftY = (int) (centreY - (this.radius - 70) * Math.cos(hourProp));        g2d.setStroke(new BasicStroke(2.5f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL));        g.drawLine(leftX, leftY, centreX, centreY);    }    public void run() {        while (true) {            try {                Thread.sleep(1000);            } catch (InterruptedException e) {                e.printStackTrace();            }            this.repaint();        }    }    public static void main(String[] args) {        JFrame frame = new JFrame();        JPanel panel = new JPanel(new BorderLayout());        frame.setContentPane(panel);        Clock clock = new Clock(150);        new Thread(clock).start();        panel.add(clock, BorderLayout.CENTER);        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);        frame.setSize(600, 400);        frame.setVisible(true);    }}

 

呵呵,水平有限,代码写的比较乱

 

——写于2014-09-08 20:30:00上下

(原创 by 徐剑生)《Java Swing之利用简单的多线程实现动态时钟》