java.util.*
import
java.awt.*
import
java.applet.*
//impelements
Runnable
是线程程序的接口
public
class
Clock
extends
Applet
implements
Runnable
{
Thread
timer
=
null
//
定义线程实体timer
int
xcenter
=
400,
ycenter
=
50
int
Radius
=
ycenter
-
5
public
void
init()
{
resize(400,
125)//
设置时钟程序的窗口大小
setBackground(Color.white)//
设置小应用程序的背景色
}
public
void
paint(Graphics
g)
{
int
xh,
yh,
xm,
ym,
xs,
ys,
s,
m,
h
String
today
Date
dat
=
new
Date()
//
定义时间类dat
s
=
dat.getSeconds()
//
获得时间秒
m
=
dat.getMinutes()
//
获得时间分
h
=
dat.getHours()
today
=
dat.toLocaleString()
//
获得字符串时间格式
g.clearRect(0,
0,
size().width,
size().height)
//
消除小应用程序
xcenter
=
xcenter
-
1
//
向左移动一个像素点
if
(xcenter
<
-50)
xcenter
=
400
//
如果xcenter小于-50,则回到初始位置
//
计算秒的坐标
xs
=
(int)
(Math.cos(s
*
3.14f
/
30
-
3.14f
/
2)
*
(Radius
-
5)
+
xcenter)
ys
=
(int)
(Math.sin(s
*
3.14f
/
30
-
3.14f
/
2)
*
(Radius
-
5)
+
ycenter)
//
计算分钟的坐标
xm
=
(int)
(Math.cos(m
*
3.14f
/
30
-
3.14f
/
2)
*
(Radius
-
10)
+
xcenter)
ym
=
(int)
(Math.sin(m
*
3.14f
/
30
-
3.14f
/
2)
*
(Radius
-
10)
+
ycenter)
//
计算小时的坐标
xh
=
(int)
(Math.cos((h
*
30
+
m
/
2)
*
3.14f
/
180
-
3.14f
/
2)
*
(Radius
-
20)
+
xcenter)
yh
=
(int)
(Math.sin((h
*
30
+
m
/
2)
*
3.14f
/
180
-
3.14f
/
2)
*
(Radius
-
20)
+
ycenter)
g.setColor(Color.darkGray)
//
设置颜色
g.drawString("9",
xcenter
-
(Radius
-
5),
ycenter
+
3)
//
显示时钟上的数字‘9’
g.drawString("3",
xcenter
+
(Radius
-
10),
ycenter
+
3)
//
显示时钟上的数字‘3’
g.drawString("12",
xcenter
-
5,
ycenter
-
(Radius
-
13))
//
显示时钟上的数字'12'
g.drawString("6",
xcenter
-
3,
ycenter
+
(Radius
-
10))
//
显示时钟上的数字'6'
g.drawString(today,
0,
125)
//
显示字符串时钟
g.drawLine(xcenter,
ycenter,
xs,
ys)
//
画秒针
g.setColor(Color.blue)
//
设置颜色
g.drawArc(xcenter
-
Radius,
ycenter
-
Radius,
2
*
Radius,
2
*
Radius,
0,
360)
//
画钟
g.drawLine(xcenter,
ycenter
-
1,
xm,
ym)
//
画分针
g.drawLine(xcenter
-
1,
ycenter,
xm,
ym)
//
画分针
g.drawLine(xcenter,
ycenter
-
1,
xh,
yh)
//
画时针
g.drawLine(xcenter
-
1,
ycenter,
xh,
yh)
//
画时针
}
public
void
start()
{
if
(timer
==
null)
{
timer
=
new
Thread(this)
//
生成Thread(多线程程序)的对象实体
timer.start()
//
启动生成的线程
}
}
public
void
stop()
{
timer.stop()
//
停止线程的工作
timer
=
null
//
放掉Thread对象
}
public
void
run()
//
改方法用来定义线程体,一旦线程被启动执行,就开始执行这个方法
{
while
(timer
!=
null)
{
try
{
Thread.sleep(150)
//
使当前正在执行的线程进入睡眠时间由参数millis确定,
//
单位时间是毫秒,当这个时间过去,线程即可运行的
while
(timer
!=
null)
{
try
{
Thread.sleep(150)//
使用当前正在执行的线程进入睡眠时间由参数
//
millis确定,单位是毫秒,当这个时间过去,线程即为可运行的
}
catch
(InterruptedException
e)
{
}
repaint()
//
repaint所做的事其实是去调用方法uadate重画效应用程序
}
timer
=
null
}
catch
(InterruptedException
e)
{
}
}
}
//
所做的工作是先将整个效应用程序区域清除,再去调用paint,完成重画的动作
public
void
update(Graphics
g)
{
paint(g)
}
}
import java.awt.BasicStrokeimport java.awt.Color
import java.awt.Container
import java.awt.Font
import java.awt.Graphics
import java.awt.Graphics2D
import java.awt.Image
import java.awt.MediaTracker
import java.awt.Toolkit
import java.awt.geom.Ellipse2D
import java.awt.geom.Line2D
import java.awt.image.BufferedImage
import java.net.URL
import java.text.DateFormat
import java.util.Calendar
import java.util.Date
import java.util.GregorianCalendar
import javax.swing.JFrame
import javax.swing.JLabel
/**
* 时钟程序
*/
public class Clock extends JFrame
{
// 今天的日期对象
private GregorianCalendar now = new GregorianCalendar()
// 时钟标签,上面画的是圆形时钟
private ClockLabel clockLabel = new ClockLabel()
// 星期标签,指示星期
private JLabelweekLabel = new JLabel()
// 日期标签,指示日期
private JLabeldateLabel = new JLabel()
// 品牌标签
private JLabelremarkLabel = new JLabel()
// 时间标签,指示时间
private JLabeltimeLabel = new JLabel()
public Clock()
{
// 设置主界面属性
setTitle("时钟")
setSize(500, 480)
setLocation(100, 100)
init()
setResizable(false)
}
private void init()
{
// 初始化品牌标签
remarkLabel.setText("MyClock")
remarkLabel.setLocation(225, 80)
remarkLabel.setSize(100, 30)
remarkLabel.setFont(new Font("Bookman Old Style", Font.BOLD, 15))
remarkLabel.setForeground(Color.darkGray)
// 初始化星期标签
weekLabel.setSize(60, 20)
weekLabel.setLocation(315, 190)
weekLabel.setForeground(Color.darkGray)
weekLabel.setFont(new Font("Arial Narrow", Font.BOLD, 12))
// 为星期标签赋值
int week = now.get(Calendar.DAY_OF_WEEK)
switch (week)
{
case 1:
weekLabel.setText("SUNDAY")
break
case 2:
weekLabel.setText("MONDAY")
break
case 3:
weekLabel.setText("TUESDAY")
break
case 4:
weekLabel.setText("WEDNESDAY")
break
case 5:
weekLabel.setText("THURSDAY")
break
case 6:
weekLabel.setText("FRIDAY")
break
case 7:
weekLabel.setText("SATURDAY")
break
}
// 初始化日期标签
dateLabel.setSize(20, 20)
dateLabel.setLocation(370, 190)
dateLabel.setForeground(Color.darkGray)
dateLabel.setFont(new Font("Fixedsys", Font.BOLD, 12))
// 设置日期标签的值
dateLabel.setText("" + now.get(Calendar.DATE))
// 初始化时间标签
timeLabel.setSize(500, 30)
timeLabel.setLocation(100, 400)
timeLabel.setForeground(new Color(0, 64, 128))
timeLabel.setFont(new Font("Fixedsys", Font.PLAIN, 15))
// 将各组件加入到主窗口中
Container con = getContentPane()
con.setBackground(Color.white)
con.setLayout(null)
con.add(weekLabel)
con.add(dateLabel)
con.add(remarkLabel)
con.add(timeLabel)
con.add(clockLabel)
}
public static void main(String[] args)
{
Clock clock = new Clock()
clock.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
clock.setVisible(true)
}
// 自定义时钟标签,画一个圆形的时钟
class ClockLabel extends JLabel implements Runnable
{
// 时钟标签的宽度和高度
private final int WIDTH = 500
private final int HEIGHT = 440
// 圆形时钟的X半径和Y半径
private final int CIRCLE_X_RADIUS = 150
private final int CIRCLE_Y_RADIUS = 155
// 圆形时钟的原点
private final int CIRCLE_X= 250
private final int CIRCLE_Y= 200
// 圆形时钟指针的长度
private final int HOUR_LENGTH= 50
private final int MIN_LENGTH= 80
private final int SEC_LENGTH= 100
// 当前时针所处的角度
doublearcHour = 0
// 当前分针所处的角度
doublearcMin = 0
// 当前秒针所处的角度
doublearcSec = 0
// 颜色的透明度,
// 当颜色的alpha值为1或者255时,表示不透明,其他值时透明
int alpha = 50
// 标识颜色透明度变化的方向,
// 为true时表示越来越透明,为false时表示月来越不透明
booleanflag = false
// 背景图片的id,轮换显示背景图片时使用
int imageID = 0
// 背景图片对象数组
Imageimg[] = new Image[5]
// 背景图片URL
URL url[] = new URL[] { ClockLabel.class.getResource("image/1.jpg"), ClockLabel.class.getResource("image/2.jpg"), ClockLabel.class.getResource("image/3.jpg"), ClockLabel.class.getResource("image/4.jpg"), ClockLabel.class.getResource("image/5.jpg"), ClockLabel.class.getResource("image/6.jpg") }
// 一个具有缓冲区的图像对象
BufferedImage bufferedImage = null
int imageSize= 2 * Math.max(CIRCLE_X_RADIUS, CIRCLE_Y_RADIUS)
// 为bufferedImage创建的Graphics对象,用于在bufferedImage上画图
Graphics bufferedImageGraphics = null
// 时钟线程,因为时钟每秒钟都要动一次,所以用线程
ThreadclockThread= null
// 构造方法
public ClockLabel()
{
// 设置时钟标签的大小
this.setSize(WIDTH, HEIGHT)
// 获取时针、分针、秒针当前的角度
arcHour = now.get(Calendar.HOUR) * 30// 一格30度
arcMin = now.get(Calendar.MINUTE) * 6// 一格6度
arcSec = now.get(Calendar.SECOND) * 6// 一个6度
// 根据图片URL创建图片对象
Toolkit tk = this.getToolkit()
img[0] = tk.createImage(url[0])
img[1] = tk.createImage(url[1])
img[2] = tk.createImage(url[2])
img[3] = tk.createImage(url[3])
img[4] = tk.createImage(url[4])
try
{
// 使用MediaTracker加载图片对象
// MediaTracker 类是一个跟踪多种媒体对象状态的实用工具类,
// 媒体对象可以包括音频剪辑和图像,但目前仅支持图像.
MediaTracker mt = new MediaTracker(this)
mt.addImage(img[0], 0)
mt.addImage(img[1], 0)
mt.addImage(img[2], 0)
mt.addImage(img[3], 0)
mt.addImage(img[4], 0)
// 加载媒体跟踪器中所有的图像。
mt.waitForAll()
}
catch (Exception e)
{
e.printStackTrace()
}
// 创建一个有缓冲的Image对象
bufferedImage = new BufferedImage(imageSize, imageSize, BufferedImage.TYPE_INT_ARGB)
// 为BufferedImage创建Graphics2D对象,
// 以后用该Graphics2D对象画的图都会画在BufferedImage中
bufferedImageGraphics = bufferedImage.createGraphics()
// 启动线程
clockThread = new Thread(this)
clockThread.start()
}
public void paint(Graphics g1)
{
// Graphics2D继承Graphics,比Graphics提供更丰富的方法
Graphics2D g = (Graphics2D) g1
/** ***画圆形时钟的刻度,每6度便有一个刻度**** */
for (int i = 0i <360i = i + 6)
{
// 设置画笔的颜色为蓝色
g.setColor(Color.blue)
// 设置画笔的宽度为2
g.setStroke(new BasicStroke(2))
if (i % 90 == 0)
{
// 对于0,3,6,9点位置,使用一个大的蓝色刻度
g.setStroke(new BasicStroke(5))// 画笔宽度为5
// 当起点和终点一样时,画的就是点
g.drawLine(CIRCLE_X + (int) (Math.cos(i * Math.PI / 180) * CIRCLE_X_RADIUS), CIRCLE_Y + (int) (Math.sin(i * Math.PI / 180) * CIRCLE_Y_RADIUS), CIRCLE_X + (int) (Math.cos(i * Math.PI / 180) * CIRCLE_X_RADIUS), CIRCLE_Y + (int) (Math.sin(i * Math.PI / 180) * CIRCLE_Y_RADIUS))
}
else if (i % 30 == 0)
{
// 如果角度处于小时的位置,而且还不在0,3,6,9点时,画红色的小刻度
g.setColor(Color.red)
g.drawLine(CIRCLE_X + (int) (Math.cos(i * Math.PI / 180) * CIRCLE_X_RADIUS), CIRCLE_Y + (int) (Math.sin(i * Math.PI / 180) * CIRCLE_Y_RADIUS), CIRCLE_X + (int) (Math.cos(i * Math.PI / 180) * CIRCLE_X_RADIUS), CIRCLE_Y + (int) (Math.sin(i * Math.PI / 180) * CIRCLE_Y_RADIUS))
}
else
{
// 其他位置就画蓝色的小刻度
g.drawLine(CIRCLE_X + (int) (Math.cos(i * Math.PI / 180) * CIRCLE_X_RADIUS), CIRCLE_Y + (int) (Math.sin(i * Math.PI / 180) * CIRCLE_Y_RADIUS), CIRCLE_X + (int) (Math.cos(i * Math.PI / 180) * CIRCLE_X_RADIUS), CIRCLE_Y + (int) (Math.sin(i * Math.PI / 180) * CIRCLE_Y_RADIUS))
}
}
/** ****** 画时钟的指针 ******** */
// 画时针
Line2D.Double lh = new Line2D.Double(CIRCLE_X, CIRCLE_Y, CIRCLE_X + Math.cos((arcHour - 90) * Math.PI / 180) * HOUR_LENGTH, CIRCLE_Y + Math.sin((arcHour - 90) * Math.PI / 180) * HOUR_LENGTH)
// 设置画笔宽度和颜色
g.setStroke(new BasicStroke(6))
g.setColor(new Color(0, 128, 0))
// 利用Graphics2D的draw方法画线
g.draw(lh)
// 画分针
Line2D.Double lm = new Line2D.Double(CIRCLE_X, CIRCLE_Y, CIRCLE_X + Math.cos((arcMin - 90) * Math.PI / 180) * MIN_LENGTH, CIRCLE_Y + Math.sin((arcMin - 90) * Math.PI / 180) * MIN_LENGTH)
g.setStroke(new BasicStroke(3))
g.setColor(new Color(0, 128, 192))
g.draw(lm)
// 画秒针
Line2D.Double ls = new Line2D.Double(CIRCLE_X, CIRCLE_Y, CIRCLE_X + Math.cos((arcSec - 90) * Math.PI / 180) * SEC_LENGTH, CIRCLE_Y + Math.sin((arcSec - 90) * Math.PI / 180) * SEC_LENGTH)
g.setStroke(new BasicStroke(1))
// 秒针的颜色随机,使动画效果明显。
g.setColor(new Color((int) (Math.random() * 255), (int) (Math.random() * 255), (int) (Math.random() * 255)))
g.draw(ls)
/** **** 画时钟背景,并将其透明处理 ******* */
// 所有使用bufferedImageGraphics画的图像,都画在bufferedImage上,
// drawImage方法的参数含义分别是:背景图片对象、目标位置第一个角的X、Y坐标、目标位置第二个角的X、Y坐标、
// 源位置第一个角的X、Y坐标、源位置第二个角的X、Y坐标、图像对象改变时的通知接受者
bufferedImageGraphics.drawImage(img[imageID], 0, 0, imageSize, imageSize, 0, 0, imageSize + 10, imageSize + 10, this)
// 将背景图片透明化
for (int j = 0j <imageSizej++)
{
for (int i = 0i <imageSizei++)
{
// 获得背景图像中(i, j)坐标的颜色值
int pix = bufferedImage.getRGB(i, j)
Color c = new Color(pix)
int r = c.getRed()
int gr = c.getGreen()
int b = c.getBlue()
// 通过Color对象的alpha,使颜色透明。
int newpix = new Color(r, gr, b, alpha).getRGB()
// 重新设置背景图像该象素点的颜色
bufferedImage.setRGB(i, j, newpix)
}
}
/** 以上画背景 *** 作都是画在bufferedImage上的,这里要将bufferedImage画在ClockLabel **/
// 将当前用户剪贴区 Clip 与椭圆区域相交,并将 Clip 设置为所得的交集
g.clip(new Ellipse2D.Double(95, 45, imageSize, imageSize))
g.setColor(Color.white)
// 在用户剪贴区画bufferedImage
g.drawImage(bufferedImage, 95, 45, this)
}
public void run()
{
try
{
//
while (clockThread != null)
{
// 获得完整的日期格式
DateFormat df = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL)
// 格式化当前时间
String s = df.format(new Date())
timeLabel.setText(s)
// 每动一次对时钟指针的角度进行调整
arcSec += 6
arcMin += 0.1
arcHour += 0.1 / 60
// 当角度满一圈时,归0
if (arcSec >= 360)
{
arcSec = 0
}
if (arcMin >= 360)
{
arcMin = 0
}
if (arcHour >= 360)
{
arcHour = 0
}
// 实现背景透明度渐变
// 从浅入深,再由深入浅。
if (flag)
{
alpha += 10
if (alpha == 50)
{
flag = !flag
}
}
else
{
alpha -= 10
if (alpha == 0)
{
flag = !flag
// 当透明度变化一个轮回时,换一张背景图
imageID++
if (imageID == 4)
{
imageID = 0
}
}
}
// 重画时钟标签
repaint()
// 等待1秒钟
Thread.sleep(1000)
}
}
catch (Exception e)
{
e.printStackTrace()
}
}
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)