=>AlarmClockApp.mxml
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600"
pageTitle="TheStudioOfCenyebao" xmlns:alarmClock="com.cen.programmingas3.alarmClock.*"
creationComplete="creationCompleteHandler(event)">
<fx:Script>
<![CDATA[
import com.cen.programmingas3.alarmClock.AlarmEvent;
import mx.events.FlexEvent;
protected function creationCompleteHandler(event:FlexEvent):void
{
clock.addEventListener(AlarmEvent.ALARM, onAlarm);
/**
* Adds 60 seconds to the current time and preloads the alarm fields*/
var alarmTime:Date = new Date();
alarmTime.setTime(alarmTime.time + 60000);
hourNs.value = alarmTime.hours;
minuteNs.value = alarmTime.minutes;
trace("=>alarmTime.hours:"+alarmTime.hours + "; alarmTime.minutes:" + alarmTime.minutes);
}
/**
* 闹钟闹时监听函数*/
private function onAlarm(event:AlarmEvent):void
{
alarmTimeTxt.text = event.message;
}
/**
* 处理分钟函数:有必要时添加零;*/
private function padZeroes(numStr:String, desiredLength:uint = 2):String
{
if(numStr.length < desiredLength) {
for(var i:int = 0; i<(desiredLength - numStr.length); i++) {
numStr = "0" + numStr;
}
}
return numStr;
}
protected function setAlarmBtn_clickHandler(event:MouseEvent):void
{
var alarmTime:Date = clock.setAlarm(hourNs.value, minuteNs.value, messageTxt.text);
alarmTimeTxt.text = "Alarm Time:" + alarmTime.hours + ":" + padZeroes(alarmTime.minutes.toString());
}
]]>
</fx:Script>
<!--闹钟DEMO-->
<s:VGroup width="650" height="100%" horizontalCenter="0" verticalCenter="0">
<s:HGroup width="100%" height="200">
<alarmClock:AlarmClock id="clock" creationComplete="clock.initClock()"/>
</s:HGroup>
<s:HGroup width="100%" verticalAlign="bottom">
<s:Label text="Message:"/>
<s:TextInput id="messageTxt" width="100%" text="Wake up!"/>
</s:HGroup>
<s:HGroup width="100%" verticalAlign="bottom">
<s:NumericStepper id="hourNs" stepSize="1" minimum="0" maximum="23" textAlign="right" width="50"/>
<s:Label text="时"/>
<s:NumericStepper id="minuteNs" stepSize="1" minimum="0" maximum="59" textAlign="right" width="50"/>
<s:Label text="分"/>
<s:Button id="setAlarmBtn" label="闹钟设置" click="setAlarmBtn_clickHandler(event)"/>
</s:HGroup>
<s:Label id="alarmTimeTxt" width="100%" text="Alarm Time: not set"/>
</s:VGroup>
</s:Application>
=>AnalogClockFace.as
package com.cen.programmingas3.alarmClock
{
import flash.display.Shape;
import flash.text.TextField;
import flash.text.TextFormat;
import mx.core.UIComponent;
/**
* 时钟界面组件类
* @author cen
*/
public class AnalogClockFace extends UIComponent
{
/**
* 属性*/
/*宽度*/
public var w:uint = 200;
/*长度*/
public var h:uint = 200;
/*半径*/
public var radius:uint;
/*圆点坐标*/
public var centerX:int;
public var centerY:int;
/*时针*/
public var hourHand:Shape;
public var hourHandColor:uint = 0x003366;
/*分针*/
public var minuteHand:Shape;
public var minuteHandColor:uint = 0x000099;
/*秒针*/
public var secondHand:Shape;
public var secondHandColor:uint = 0xCC0033;
/*背景颜色*/
public var bgColor:uint = 0xEEEEFF;
/*当前时间*/
public var currentTime:Date;
/**
* 构造函数
*/
public function AnalogClockFace(w:uint)
{
/*长度*/
this.w = w;
this.h = w;
/*半径*/
this.radius = Math.round(this.w/2);
/*圆点坐标*/
this.centerX = this.radius;
this.centerY = this.radius;
}
/**
* (手动调用)初始化函数:绘制轮廓;
* Creates the outline, hour labels, and clock hands.
*/
public function init():void {
// 绘制圆圈
drawBorder();
// 绘制文本标志
drawLabels();
// 绘制时、分、秒针
createHands();
}
/**
* 绘制圆圈
*/
private function drawBorder():void
{
graphics.lineStyle(0.5, 0x999999);
graphics.beginFill(bgColor);
graphics.drawCircle(centerX, centerY, radius);
graphics.endFill();
}
/**
* 绘制文本标志:绘制1-12的小时标志;
*/
private function drawLabels():void
{
for(var i:Number = 1; i<=12; i++) {
/*显示文本*/
var label:TextField = new TextField();
label.text = i.toString();
/*相对于12点方向来说,每个方向的弧度*/
var angleInRadians:Number = i * 30 * (Math.PI/180);
/*设置显示文本位置*/
label.x = centerX + (0.9 * radius*Math.sin(angleInRadians)) - 5;
label.y = centerY - (0.9 * radius*Math.cos(angleInRadians)) - 9;
/*设置文本样式*/
var tf:TextFormat = new TextFormat();
tf.font = "Arial";
tf.bold = "true";
tf.size = 12;
label.setTextFormat(tf);
/*添加到显示列表*/
addChild(label);
}
}
/**
* 绘制指针的通用方法
* Draws a clock hand with a given size, color, and thickness.
* @param hand
* @param distance
* @param color
* @param thickness
*/
private function drawHand(hand:Shape, distance:uint, color:uint, thickness:Number):void
{
hand.graphics.lineStyle(thickness, color);
hand.graphics.moveTo(0, distance);
hand.graphics.lineTo(0, 0);
}
/**
* 绘制时、分、秒针
* Creates hour, minute, and second hands using the 2D drawing API.
*/
private function createHands():void
{// 注意:刚开始的时候,指针都指向6点钟方向;
// 使用Shape控件是因为她是支持2D绘制API的最简单的组件;
/*时针*/
var hourHandShape:Shape = new Shape();
drawHand(hourHandShape, Math.round(radius*0.5), hourHandColor, 3.0);
this.hourHand = Shape(addChild(hourHandShape));// 添加进显示列表后,再进行位置的设置;
this.hourHand.x = centerX;
this.hourHand.y = centerY;
/*分针*/
var minuteHandShape:Shape = new Shape();
drawHand(minuteHandShape, Math.round(radius*0.8), minuteHandColor, 2.0);
this.minuteHand = Shape(addChild(minuteHandShape));
this.minuteHand.x = centerX;
this.minuteHand.y = centerY
/*秒针*/
var secondHandShape:Shape = new Shape();
drawHand(secondHandShape, Math.round(radius*0.9), secondHandColor, 0.5);
this.secondHand = Shape(addChild(secondHandShape));
this.secondHand.x = centerX;
this.secondHand.y = centerY;
}
/**
* (手动调用)渲染指针
*/
public function draw():void{
// 保存当前时间
currentTime = new Date();
showTime(currentTime);
}
/**
* 根据当前时间渲染指针
* @param time
*/
private function showTime(time:Date):void
{
// 提取时间各个部分值
var seconds:uint = time.getSeconds();
var minutes:uint = time.getMinutes();
var hours:uint = time.getHours();
/**
* 顺时针旋转角度(5秒钟30度,那1秒钟就旋转6度)*/
this.secondHand.rotation = 180 + (seconds * 6);
this.minuteHand.rotation = 180 + (minutes * 6);
/**
* 顺时针旋转角度(60分钟30度,那1分钟就旋转0.5度)*/
this.hourHand.rotation = 180 + (hours * 30) + (minutes * 0.5);
}
}
}
=>SimpleClock.as
package com.cen.programmingas3.alarmClock
{
import flash.events.TimerEvent;
import flash.utils.Timer;
import mx.core.UIComponent;
/**
* 时钟类:具有简单走时功能;
* @author cen
*/
public class SimpleClock extends UIComponent
{
/**
* 属性*/
/*钟面*/
public var face:AnalogClockFace;
/*计时器*/
public var ticker:Timer;
/*常量*/
public static const millisecondsPerMinute:int = 1000 * 60; //一分钟毫秒数;
public static const millisecondsPerHour:int = 1000 * 60 * 60; // 一个小时毫秒数;
public static const millisecondsPerDay:int = 1000 * 60 * 60 * 24; // 一天毫秒数;
/**
* 初始函数
* @param faceSize
*/
public function initClock(faceSize:Number = 200):void
{
/**
* 实例化钟面并添加到显示列表*/
face = new AnalogClockFace(Math.max(20, faceSize));
face.init(); // 手动调用init()方法进行初始渲染;
addChild(face);
/*绘制指针*/
face.draw();
/**
* 每秒触发一次计时器*/
ticker = new Timer(1000);
ticker.addEventListener(TimerEvent.TIMER, onTick);
/*开始计数*/
ticker.start();
}
/**
* 计数函数
* @param event
*/
private function onTick(event:TimerEvent):void
{
// 刷新钟面
face.draw();
}
}
}
=>AlarmEvent.as
package com.cen.programmingas3.alarmClock
{
import flash.events.Event;
/**
* 自定义闹钟事件:新添数据信息;
* @author cen
*/
public class AlarmEvent extends Event
{
/*事件类型*/
public static const ALARM:String = "alarm";
/**
* 信息属性
* A text message that can be passed to an event handler
* with this event object.*/
public var message:String;
/**
* 构造函数
* @param message
*/
public function AlarmEvent(message:String = "ALARM!")
{
super(ALARM);
this.message = message;
}
/**
* 克隆函数
* Creates and returns a copy of the current instance.
* @return
*/
public override function clone():Event
{
return new AlarmEvent(message);
}
/**
* Returns a String containing all the properties of the current instance.
* @return A string representation of the current instance.
*/
public override function toString():String
{
return formatToString("AlarmEvent", "type", "bubbles", "cancelable", "eventPhase", "message");
}
}
}
=>AlarmClock.as
package com.cen.programmingas3.alarmClock
{
import flash.events.TimerEvent;
import flash.utils.Timer;
/**
* 闹钟类
* @author cen
*/
public class AlarmClock extends SimpleClock
{
/**
*=>属性*/
/*闹钟时间*/
public var alarmTime:Date;
/*闹钟提示信息*/
public var alarmMessage:String;
/*闹钟计数器*/
public var alarmTimer:Timer;
/*1天毫秒数*/
public static var MILLISECONDS_PER_DAY:Number = 1000 * 60 * 60 * 24;
/**
* 初始化函数
* @param faceSize
*/
public override function initClock(faceSize:Number = 200):void{
super.initClock(faceSize);
alarmTimer = new Timer(0, 1);
alarmTimer.addEventListener(TimerEvent.TIMER, onAlarm);
}
/**
* 计数函数
* @param event
*/
private function onAlarm(event:TimerEvent):void
{
trace("=>Alarm!");
/**
* 调度事件_通知其他闹钟响咯*/
var alarm:AlarmEvent = new AlarmEvent(this.alarmMessage);
this.dispatchEvent(alarm);
}
/**
* 设置闹钟时间
* @param hour
* @param minutes
* @param message
* @return The time at which the alarm will go off.
*/
public function setAlarm(hour:Number = 0, minutes:Number = 0, message:String = "Alarm!"):Date
{
this.alarmMessage = message;
/*闹钟时间*/
var now:Date = new Date();
alarmTime = new Date(now.fullYear, now.month, now.date, hour, minutes);
/**
* determine(判断) if the specified time has already passed today*/
if(alarmTime <= now) {
alarmTime.setTime(alarmTime.time + MILLISECONDS_PER_DAY);
}
/*重置计数器*/
alarmTimer.reset();
/**
* 相当于当前,间隔多长触发*/
alarmTimer.delay = Math.max(1000, alarmTime.time - now.time);
alarmTimer.start();
return alarmTime;
}
}
}