1,主控制臺
2.計劃任務設置界面。
3.控制臺輸出結果。
二、程序開發環境:
它由Java(JDK 1.4)開發,圖形界面由Eclipse的SWT(版本2.1.3)開發。運行主機:P4 2.6+1G內存windowsXP操作系統。
第三,準備。
開發這樣的程序,最好不要用JAVA線程直接編程,這樣會增加不必要的復雜性和難度。JAVA中有壹個包java.util.Timer這個包封裝了線程上的操作,我們可以稱之為Timer類。讓我們先看壹個簡單的例子:
導入Java . util . timer;
導入Java . util . timertask;
公開課提醒{
定時器timer;
公共提醒(整數秒){
timer =新計時器();
timer.schedule(new RemindTask(),秒* 1000);//參數要求轉換為毫秒。
}
公共靜態void main(String args[]) {
新提醒(5);//5秒後運行。
}
/* *封裝要運行的任務的內部類*/
類提醒任務擴展TimerTask {
公共無效運行(){
System.out.println("任務正在運行。。。。");
timer . cancel();//結束計時器中的所有任務
}
}
}
這裏涉及到兩個JAVA類Timer和TimerTask。在繼承了TimerTask類之後,我們將要運行的任務封裝在它的run方法中。Timer可以管理數千個任務(TimerTask)。請註意,同壹個任務對象不能兩次添加到Timer中執行。
對(雖然兩個任務相同,但是兩個任務對象):
timer.schedule(new RemindTask(),秒* 1000);
timer.schedule(new RemindTask(),秒* 1000);
錯誤的
remind task task = new remind task();
timer.schedule(任務,秒* 1000);
timer.schedule(任務,秒* 2000);
四、設計方案。
主類圖
描述:
任務類的設計。我們先創建壹個抽象類AbstractTimerTask,它直接繼承自TimerTask類,為TimerTask提供封裝。那麽所有具體的任務類(比如TimerTask_1)都繼承自AbstractTimerTask。
導入Java . util . timertask;
公共抽象類AbstractTimerTask擴展了TimerTask {
TaskEntry任務條目;//任務記錄
公共抽象TimerTask(TaskEntry taskEntry) {
this . task entry = task entry;
}
/*
*生成壹個新實例等同於克隆自身;原因是同壹個任務對象不能兩次添加到Timer中。
*在TaskEntry類中,您將看到如何使用它。
*/
abstract timertask getCloneObject();
}
下面是壹個實現類的源代碼。我們可以在這個類中編寫要運行的任務的代碼。
導入Java . util . calendar;
公共類TimerTask_1擴展了AbstractTimerTask {
public time task _ 1(task entry task entry){//構造函數
超級(task entry);
}
公共抽象TimerTask getCloneObject() {
返回新的TimerTask _ 1(task entry);
}
公共無效運行(){
/*在這裏寫下妳要執行的程序。。。。。*/
System.out.println("?Time: "+taskEntry.getName()+"運行壹次");
this . task entry . task start();//運行下壹個時間點任務
}
}
AbstractTimerTask類中有壹個TaskEntry字段,是這個設計的核心類。它代表壹個完整的任務記錄,每個任務類及其運行計劃都封裝在這個類中。源代碼如下。Timer和AbstractTimerTask之前都說過,那麽TimePlan是幹什麽用的呢?
導入Java . util . calendar;
導入Java . util . date;
導入Java . util . timer;
導入my timer . util . util;
/* *任務記錄類*/
公共類TaskEntry {
public static final int TASK _ START = 0;//定義兩個代表任務記錄狀態的常量。
public static final int TASK _ STOP = 1;
私有Long oid//任務ID號,唯壹
私有字符串名稱;//任務名稱
private int state = TASK _ STOP//任務狀態(開始/停止)
私人定時器Timer;//JAVA定時器
私人時間計劃時間計劃;//時間計劃的類型
私有抽象timerTask timerTask;//任務類的種子對象,會不斷克隆。
私有抽象AbstractTimerTask runTimerTask//運行計劃的當前任務。
/**
* itaskentry . taskstart()-& gt;timertask . run()-& gt;ITaskEntry.taskStart()
*形成壹個循環。這個方法負責啟動這個類代表的任務。
*/
公共void taskStart() {
if (timePlan.haveNext()) {
date date = time plan . next date();//獲取任務計劃時間
runTimerTask = timertask . getcloneobject();//獲取任務(復制)
timer.schedule(runTimerTask,date);//加入計劃隊列
//打印要運行的計劃任務的信息。
calendar c = calendar . getinstance();
c . settimeinmillis(runtimertask . scheduledexecutiontime());
系統。out . println(util . datetolongstr(c . gettime())+“將運行”+name);
}否則{
狀態=任務_停止;
system . out . println(name+" end ");
}
}
/* *停止任務*/
公共void taskStop() {
if (runTimerTask!= null) {
//打印信息
calendar c = calendar . getinstance();
c . settimeinmillis(runtimertask . scheduledexecutiontime());
System.out.println("預定於:"+util。datetolongstr (c.gettime ())+“正在運行”+name+“已終止”);
//終止這個任務,調用Timer.cancel()就是終止Timer的所有任務。
runtimertask . cancel();
}否則{
System.out.println(name+"不在執行計劃中");
}
}
…………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………
/* *聽力班(內班)*/
公共靜態類DateBeforeTodayException擴展了NullPointerException {
私人約會日期;
public datebbeforetodayexception(Date Date){ this . Date = Date;}
公共字符串toString() {
返回“計劃時間("+Util.dateToLongStr(date)+")早於當前時間”;
}
}
}
1,TimePlan是壹個接口,意思是“計劃運行”。該程序提供了三種運行的計劃方案(見上圖:計劃任務設置界面):
壹次性操作
每隔壹段時間運行壹次。
選擇壹周中的哪幾天運行。
它被設計成壹個接口,便於將來的擴展。如果要添加新的時間方案,只需要繼承這個接口,寫壹個新的實現即可。三種時間方案的類圖如下:
描述:
A) TimePlan封裝了五個方法,其中haveNext()和nextDate()是最重要的。這兩種方法模仿了Java中集合叠代器的設計形式,代碼如下:
導入Java . util . date;
//時間規劃方案界面
公共接口時間計劃{
布爾型haven ext();//判斷是否有下壹個計劃時間。
date next date();//獲取下壹個計劃時間
date getCurrentDate();//獲取開始時間
void setCurrentDate(日期日期);//設計開始時間
string getTimePlanString();//顯示工序計劃方案的文本描述。
}
B) AbstractTimePlan是壹個抽象類,主要用途是在這裏寫壹些子類的公共方法。代碼如下:
導入Java . util . date;
公共抽象類AbstractTimePlan實現TimePlan {
//記錄計劃的第壹個時間點,除非設置新的開始時間,否則不會更改。
受保護日期currentDate
/*
每次替換計劃時,當前計劃的時間點都會更新。
好像這個應該叫cureentDate,抱歉不想再改了。
*/
受保護日期計劃日期;
public boolean haveNext() {
return (planDate!= null);
}
公共日期getCurrentDate() {
返回當前日期;
}
public void setCurrentDate(Date Date){
currentDate =日期;
計劃日期=日期;//當賦給currentDate值時,也賦給planDate。
}
}
c)然後我們來看三個規劃方案的實現類的源代碼:
//計劃方案類“壹次性操作”
導入Java . util . date;
公共類TimePlanOnce擴展AbstractTimePlan {
公共日期nextDate() {
//將當前計劃時間保存在中間變量中。
date return date = this . plan date;
//制定出下壹個計劃時間。如果沒有下壹個,將其設置為null
this.planDate = null
//判斷計劃時間是否符合要求。
if (returnDate == null)
拋出new NullPointerException("沒有下壹個計劃日期");
返回returnDate
}
公共字符串getTimePlanString() {
返回“壹次性操作,運行時間:(print this . current date)”;
}
}
//時間計劃方案類“周期區間”
導入Java . util . date;
公共類TimePlanPeriod擴展AbstractTimePlan {
公共靜態最終int HOUR = 0;
public static final int DAY = 1;
私有int時空;//間隔,以毫秒為單位
private int timeType
公共日期nextDate() {
//將當前計劃時間保存在中間變量中。
date return date = this . plan date;
//制定出下壹個計劃時間。如果沒有下壹個,將其設置為null
int毫秒= 0;
if(time type = =小時)毫秒=時空* 1000;//小時* 60 * 60 * 1000;
if (timeType ==DAY)毫秒=時空* 24 * 60 * 60 * 1000;//天
planDate = Util。DateAddSpaceMilliSecond(計劃日期,毫秒);
//判斷計劃時間是否符合要求。
if (returnDate == null)
拋出new NullPointerException("沒有下壹個計劃日期");
返回returnDate
}
公共字符串getTimePlanString() {
if(時間類型==小時)
Return "第壹次運行時間:當前日期。並在每個時空小時運行”;
if(時間類型==天)
Return "第壹次運行時間:當前日期。並在每個時空日運行”;
返回“”;
}
public int getspace time(){ return space time;}
public int gettime type(){ return time type;}
public void set space time(int I){ space time = I;}
public void setTimeType(int I){ time type = I;}
}
/* *選擇壹周中的某壹天在同壹時間運行任務。必須選擇壹周中的某壹天*/
導入Java . util . calendar;
導入Java . util . date;
公共類TimePlanSelectWeek擴展AbstractTimePlan {
私有靜態日歷c = Calendar . getinstance();//獲取日歷實例
private static int毫秒= 0;//間隔,以毫秒為單位
private boolean[]select week = new boolean[7];//0是星期天,1是星期壹。
公共日期nextDate() {
Date returnDate = null
如果(!出庫周(計劃日期))//如果該日不是所選周內的某壹天,
planDate = getNextDate(計劃日期);
returnDate = planDate
planDate = getNextDate(計劃日期);
//判斷計劃時間是否符合要求。
if (returnDate == null)
拋出new NullPointerException("沒有下壹個計劃日期");
返回returnDate
}
//制定出下壹個計劃時間。如果沒有下壹個,將其設置為null
私人約會getNextDate(Date date) {
Date tempDate =日期;
Date returnDate = null
for(int I = 0;我& lt7;i++) {
tempDate = Util。dateaddspace millisecond(tempDate,space millisecond);
if (isSelectWeek(tempDate)) {
returnDate = tempDate
打破;
}
}
返回returnDate
}
/* *設置是否選擇星期,0是星期天,1是星期壹...6號是星期六*/
public void setSelectWeek(int i,boolean b){ select week[I]= b;}
/* *判斷是否選擇了壹周*/
public boolean is select week(int I){ return select week[I];}
/* *判斷星期幾是否屬於某壹天被選中*/
public boolean is select week(Date Date){
if (date == null)返回false
c .設置時間(日期);
//日歷。星期幾:星期日=1,星期六=7 c.get(日歷。星期幾)
return is selectweek(c . get(Calendar。星期幾)-1);
}
公共字符串getTimePlanString() {
string buffer sb = new string buffer(" ");
If (select week [1]) sb。Append("星期壹,");
if(select week[2])sb . append(" Tuesday,");
If (selectWeek[3]) sb.append("星期三",);
if(select week[4])sb . append(" Thursday,");
if(select week[5])sb . append(" Friday,");
if(select week[6])sb . append(" Saturday,");
if(select week[0])sb . append(" Sunday,");
返回“每周”+sb.toString()+“運行”;
}
}
TimerTask的工廠類。將生成TimerTask的代碼放在另壹個類中的好處是,代碼的層次結構更清晰,更易於管理。因為TimerTask包含幾個字段,所以生成TimerTask對象仍然很復雜。建立壹個工廠類來生成TimerTask,這樣我們在生成TimerTask對象的時候就可以省去很多麻煩的代碼。當然因為我的工作任務,只需要壹個TimerTask對象就夠了,所以在開始之前直接寫在了圖形界面的代碼裏。
這裏建立了壹個TimerTask對象池tasks,它是壹個靜態變量,因此在獲取getInstance時並不總是需要生成壹個新的TimerTask。還有,Timer是壹個靜態變量,是壹個全局的singleton(最簡單的singleton模式)。如前所述,Timer可以管理數千個任務,因此壹個Timer對象就足夠了。
導入Java . util . hashmap;
導入Java . util . timer;
公共類TaskEntryFactory {
私有靜態final HashMap tasks = new HashMap();
私有靜態最終定時器Timer = new Timer();
公共靜態TaskEntry getInstance(長oid,字符串名稱){
if (tasks.containsKey(oid)) {
return(task entry)tasks . get(oid);
}否則{
task entry entry = new task entry();
entry . setoid(oid);
entry.setName(名稱);
entry.setTimer(定時器);
entry . settimertask(new TimerTask _ 1(entry));
tasks.put(oid,entry);
返回條目;
}
}
}
啟動和停止任務,在任務設置界面(TaskListDialog.java)點擊確定後進行處理。界面的編寫超出了本文的範圍。
//在任務設置界面點擊“確定”按鈕後的處理
if (dialog.open() ==窗口。好){
if(task entry . getstate()= = task entry。TASK_START) {
task entry . task stop();//停止舊的。
task entry . task start();//啟動新設置的
}
if(task entry . getstate()= = task entry。任務_停止)
task entry . task stop();
TV . refresh(task entry);
}