本文的案例學習提供了一個例子,說明如何將UML用在現實中。一個處理圖書館借閱和預定圖書和雜志的應用程序,可以大到足夠檢驗UML解決現實問題能力的程度。但是如果太大的話,則不適合在雜志上發表。 在分析模型中,用用例和域分析描述了應用程序。我們進一步把它擴展成設計模型。在設計模型中,我們描述了典型的技術解決方案細節。最后,我們編寫了一段Java代碼(代碼連同完整的分析和設計模型放在網上,以一種包括評估版在內的Rational Rose能夠識別的格式在線提供。)
必須注意,這里只是一個可行的解決方案。可能會有許多其他的解決方案。沒有絕對正確的方案。當然,有的方案更好一些,但只有不斷的實踐和努力的工作才能掌握相應的技能。 1.需求(Requirements)
典型地,由系統最終用戶的代表寫出文本形式的需求規范文檔。對于該圖書館應用程序來說,需求規范文檔應該類似于這樣:
1. 這是一個圖書館支持系統;
2. 圖書館將圖書和雜志借給借書者。借書者已經預先注冊,圖書和雜志也預先注冊;
3. 圖書館負責新書的購買。每一本圖書都購進多本書。當舊書超期或破舊不堪時,從圖書館中去掉。
4. 圖書管理員是圖書館的員工。他們的工作就是和讀者打交道并在軟件系統的支持下工作。
5. 借閱人可以預定當前沒有的圖書和雜志。這樣,當他所預定的圖書和雜志歸還回來或購進時,就通知預定人。當預定了某書的借書者借閱了該書后,預定就取消。或者通過顯式的取消過程強行取消預定。
6. 圖書館能夠容易地建立、修改和刪除標題、借書者、借閱信息和預定信息。
7. 系統能夠運行在所有流行的技術環境中,包括Unix, Windows和OS/2,并應有一個現代的圖形用戶界面 (GUI)。
8. 系統容易擴展新功能。
系統的第一版不必考慮預定的圖書到達后通知預定人的功能,也不必檢查借書過期的情況。 2.分析(Analysis)
系統分析的目的是捕獲和描述所有的系統需求,并且建立一個模型來定義系統中主要的域類。通過系統分析達到開發者和需求者的理解和溝通。因此,分析一般都是分析員和用戶協作的產物。
在這個階段,程序開發者不應該考慮代碼或程序的問題;它只是理解需求和實現系統的第一步。
2.1需求分析(Requirements Analysis)
分析的第一步是確定系統能夠做什么?誰來使用這個系統?這些分別叫角色(actors)和用例(use cases)。用例描述了系統提供什么樣的功能。通過閱讀和分析文檔,以及和潛在的用戶討論系統來分析用例。
圖書館的角色定為圖書管理員和借書人。圖書管理員是軟件系統的用戶;而借書者則是來借閱或預定圖書雜志的客戶。偶爾,圖書管理員或圖書館的其他工作人員也可能是一個借書者。借書者不直接和系統交互,借書人的功能由圖書管理員代為執行。
圖書館系統中的用例有:
1. 借書
2. 還書
3. 預定
4. 取消預定
5. 增加標題
6. 修改或刪除標題
7. 增加書目
8. 刪除書目
9. 增加借書者
10. 修改或刪除借書者
由于一本書通常有多個備份,因此系統必須將書的標題和書目的概念區分開。
圖書館系統分析的結果寫在UML 用例圖中,如圖1所示。每一個用例都附帶有文本文檔,描述用例和客戶交互的細節。文本是通過與客戶討論得到的。用例“借書”描述如下:
1.如果借閱者沒有預定:
h 確定標題
h 確定該標題下有效的書目
h 確定借書者
h 圖書館將書借出
h 登記一個新的借閱
2.如果借閱者有預定:
h 確定借書人
h 確定標題
h 確定該標題下有效的書目
h 圖書館將相應的書目借出
h 登記一個新的借閱
h 取消預定
除了定義系統的功能需求之外,在分析過程中用例用于檢查是否有相應的域類已經被定義,然后他們可以被用在設計階段,確保解決方案可以有效地處理系統功能。可以在順序圖中可視化實現細節。
圖1:角色和用例。分析中的第一步就是指出系統能被用來做什么,誰將去使用它。它們分別就是用例和角色。所有的用例必須始于角色,而且有些用例也結束于角色。角色是位于你所工作的系統外部的人或其他系統。一臺打印機或一個數據庫都可能是一個角色。本系統有兩個角色:借閱者和圖書管理員。通過與用戶或客戶的討論,可以將每一個用例用文字進行說明。
2.2域分析(Domain Analysis)
系統分析也詳細地列出了域(系統中的關鍵類)。為了導出一個域分析,可以閱讀規范文檔(specifications)和用例,查找哪一些概念應該被系統處理。或者組織一個集體討論,在用戶及領域專家共同的參與下指出系統中必須處理的關鍵概念,以及它們之間的關系。
圖書館系統中的域類如下:borrowerinformation(如此命名是為了與用例圖中的角色borrower區分開來),title,book title, magazine title, item, reservation和loan。這些類以及它們之間的關系記錄在類圖文檔中,如圖2所示。域類定義為Business object版型,Business object版型是一個用戶自定義的版型,指定該類的對象是關鍵域的一部分,并且應該在系統中持久存儲。
其中有些類有UML狀態圖,用來顯示這些類的對象可能具有的不同狀態,以及觸發他們的狀態發生改變的事件。該例子中有狀態圖的類是item 和title類。
用例lend item(借閱者沒有預定的情況)的順序圖顯示在圖3中。所有用例的順序圖都可從在線模型中查到。
圖2:域類結構。
域分析詳細說明了系統中的關鍵類。對每一個對象而言,如果它調用了其他對象的方法,那么在他們之間就用一條直線連結起來,以顯示他們之間的關系。每一個代表類的四邊形被分成了三部分,最頂層包括類的名稱,中間一層是類的屬性,最底層是類的方法。類之間的直線是關聯,用來指出一個對象調用另一個對象的方法。如果再仔細看,將會發現在Loan和Item之間的關聯關系中靠近Loan的一端有“0..1”,這代表關聯的重數。重數“0..1表示Item可以感知0個到1個loan。其他可能出現的重數還有:“0..*”表示0或多;“1”表示就是1;“0”表示就是0,“1..*”表示1或多。
當對順序圖建模時,必須提供窗體和對話框作為人機交互的界面。在本分析當中,只要知道借書、預定和還書需要窗體就可以了。在此,詳細的界面不必考慮。
為了把系統中的窗體類和域類分開,所有的窗體類組織在一起放在GUI Package包中。域類組織在一起放在Business Package包中。
 圖3:Lend item場景的順序圖。
|
場景是從頭到尾實現一個用例的一次特定的過程。場景總是始于角色,而角色是屬于系統外部的。場景描繪了從所有角色的觀點出發,完成一次系統動作的完整過程。UML在用順序圖來圖示場景。本用例圖顯示了在借閱者沒有預定圖書的情況下的Lend用例。橫在圖的頂部的是參與交互的對象。自上而下表示時間的流逝。首先,圖書管理員嘗試去查找標題。標有“Lending Window”的是用戶界面,在分析階段作為一個粗略的對象。橫在順序圖中的每一個箭頭都是一次方法的調用,箭頭的首端是調用的對象,箭頭的末端是被調用的對象。
3.設計(Design)
設計階段對分析模型進行擴展并將模型進一步細化,并考慮技術細節和限制條件。設計的目的是指定一個可行的解決方案,以便能很容易地轉變成為編程代碼。
設計可以分成兩個階段:
體系結構設計階段(Architecture Design)。這是一個從較高層次的進行的設計,用來定義包(子系統),描述包之間的依賴性及通信機制。很自然,目的是要設計一個清晰簡單的體系結構,有很少的依賴性,而且盡可能避免雙向依賴。詳細設計階段(Detailed Design)。在此階段,所有的類都詳盡地進行描述,給編寫代碼的程序員一個清晰的規范說明。UML中的動態模型用來說明類的對象如何在特定的情況下做出相應的表現。
3.1體系結構設計
一個良好的體系結構設計是一個可擴展的和可改變的系統的基礎。包可能關注特定的功能領域或關注特定的技術領域。把應用程序邏輯(域類)和技術邏輯分開是至關重要的,這樣不管哪一部分的改變都不會影響其他的部分。
本案例的包或叫子系統如下:
User-Interface Package包。該包中的類基于Java AWT包,java AWT是一個用來書寫用戶界面應用程序的Java的標準庫。該包和Business-objects Package包協作。Business-objects Package包包含那些實際存儲數據的類。UI包調用Business 對象的操作,對他們進行取出或插入數據操作。
Business-object Package。該包包括域類,這些域類(如borrowerinformation,title,item,loan等)來自于分析模型。設計階段完整地定義了這些類的操作,并增加了一些其他細節來支持持續存儲。Business-object包與Database Package進行協作。所有的Business-object類必須繼承Database Package中的persistent類。
Database Package。Database Package向Business-object包中的類提供服務,以便他們能夠持續地存儲。在當前版本中,persistent類將把它的子類的對象存儲到文件系統的文件中。
Utility Package。Utility Package包含了一些服務,用來被系統中其他包調用。當前,ObjId類是該包中的唯一的類。用來被整個系統包括User-Interface,Business-Object和Database package使用。
這些包的內部設計如圖4所示.
 圖4:圖書館應用程序體系結構設計總覽。
|
本類圖顯示了應用程序包以及它們之間的依賴性。Database包提供了persistence類。Utility包提供了Object ID類。Business-Object包包含了域類(詳細情況參見圖5)最后,UI包(在本例中它是基于標準Jaa AWT庫)調用business對象中的操作來實現對他們的數據存取操作。,
3.2詳細設計
細節設計描述了新的技術性的類,如User-Interface和Database 包中的類,并且豐富了分析階段所形成的Business-Object類。類圖、狀態圖和動態圖用的還是分析階段所形成的圖,但對他們定義的更加詳細,具有了更高的技術水平。在分析階段對用例進行的文字性描述在此用來證明用例在設計階段也能被處理。順序圖就是用來說明用例如何在系統中被實現的。
Database Package。應用程序必須有持續存儲的對象。因此,必須增加數據層來提供這樣的服務。為簡單起見,我們將對象以文件的形式保存在磁盤上。存儲的細節被應用程序隱藏起來,只需調用諸如store(), update(),delete()和find()這樣的公共操作即可。這些都是persistent類的一部分,所有需要持續對象的類必須繼承它。
對類進行持續處理的一個重要因子就是ObjId類。它的對象用來引用系統中的任何持續對象(不管這個對象是在磁盤上還是已經被讀進了應用程序之中)。ObjId是Object Identity的簡寫,它是一個廣為應用的技術,用來有效地處理應用程序中的對象引用。通過使用object identifiers,一個對象ID能被傳遞到普通的persistent.getobject()操作中,進而該對象將被從持續的存儲體中取出或存儲。通常情況下,這些都是通過每個持續類的一個getobject操作完成的。當然,持續類同時也作一些檢查或格式轉換的操作。一個對象標識符也能作為一個參數很容易地在兩個操作之間傳遞(例如,一個查找特定對象的查詢窗口可以將它的查詢結果通過object id傳遞給另一個窗口 )。
ObjId是一個系統中所有的包(User Interface , Business Object和Database)都能使用的通用類,所以在設計階段它被放置在Utility包中,而不是放在Database包中。
當前對persistent類的實現還能改進。為此,定義persistent類的接口,方便持續存儲的改變。一些備選的方案可能是:將對象存儲在一個關系數據庫中或存儲在面向對象的數據庫中,或使用Java 1.1所支持的持續對象來存儲他們。
Business-Object Package。設計階段的Business-Object包基于相應的分析階段的放置域類的包。類和類之間的關系以及他們的行為繼續保留,只是被描述的更為詳細,包括他們的關系和行為如何被實現。
分析模型中的一些操作中被翻譯成設計模型的操作,另一些改了名字。這是很正常的事,因為分析階段得到的是每一個類的草圖,而設計階段是對系統的詳細描述。因此,設計模型的操作必須有設計良好的特征值和返回值(由于空間限制,圖5沒有顯示,但他們在在線模型中都有)。注意以下所列的設計和分析階段的變化:
1. 系統的當前版本不要求檢查書目是否按時歸還,也不要求處理預定的次序。因此沒有在loan 和reservation類中設置日期屬性。
2. 除了最長借閱期外,對雜志和書標題的處理方式是一樣的。因此分析階段的子類magazine title和book title被認為在設計階段是不必要的,而是在title類中增加type屬性來指出該標題引用的是一本書還是一本雜志。在面向對象的設計中不存在設計不能簡化分析的說法。
如果認為有必要的話,在將來的版本中這些簡化都可以很容易地被取消。
分析階段的狀態圖也在設計階段細化了。狀態圖顯示了如何表示狀態及如何在系統中處理狀態。設計階段的title 類的狀態圖如圖6所示。其他的對象可以通過調用如圖所示的操作addreservation()和removereservation()來改變title對象的狀態。
User-Interface Package。User-Interface Package位于其他包的“上面”。在系統中它為用戶提供輸出信息和服務。正如上面曾經提到的,該包是基于標準Java AWT(abstract windows toolkit)類的。
設計模型中的動態模型放置在GUI包中,因為所有和用戶的交互都從用戶界面開始。在此聲明,順序圖用來顯示動態模型。用例在設計模型中的實現通過順序圖被詳細地顯示出來,包括類中的實際操作。
順序圖由一系列的交互構成。在實現階段(編碼),考慮到具體情況,可能會有更多的交互。圖7顯示了add title用例的順序圖。實際的操作和特征值從在線模型代碼中可以看到。

圖5:商業對象設計(Business-Object design)。
本圖描述了在Business-Object包中的不同類的設計。設計包括定型模型,更完全地定制界面,給屬性選擇數據類型等等。
6:Title的狀態圖。Title具有預定和非預定狀態,在設計中,通過稱為“reservations”的矢量來實現。
7:Add Title的順序圖。本圖中所涉及到的用戶界面問題的詳細情況已經超出了本文的討論范圍。
協作圖可以作為順序圖的替代,如圖8所示:
圖8:Add Title的協作圖。本圖中涉及到的用戶界面問題的詳細情況已經超出了本文討論的范圍
3.3 用戶界面 設計(User-lnterface Design)
設計階段的一個特定的活動是創建用戶界面。
圖書館系統的用戶界面基于用例,分為以下幾部分,每一部分都在主窗體菜單上給出一個單獨的菜單項。
Functions:實現系統基本功能的窗體,通過它可以實現借閱、歸還和對圖書的預定。
Information:查看系統信息的窗體,收集了借閱者和圖書的信息。
Maintenance:維護系統的窗體,添加、修改和刪除標題、借閱者和書目。
圖9顯示了一個User-Interface Package中類圖的例子。其中包含了典型的AWT事件句柄。按鈕(button)、標簽(label)和編輯(edit)等的屬性沒有顯示。
典型地,每一個窗體都給出了系統的一個服務,并且映射一個最初的用例(盡管并非所有的用戶界面都必須從用例中映射)。創建成功的用戶界面已經超出了本文所討論的范圍。在此邀請讀者來考慮用symantec visual cafe 環境開發的本應用程序的UI代碼(已經放在網上)。

圖9:功能類圖模型。功能菜單中的用戶界面類一般都有1對1的關聯關系,表示需要建立關聯的窗口類,或者需要訪問關聯的商業對象類。
4.實現(Implementation)
在構造或稱實現階段進行程序編寫。該應用程序要求能運行在幾個不同的處理器和不同的操作系統上,因此選擇Java來實現系統。Java可以輕松地將邏輯類映射為代碼組件,因為在類和Java代碼文件之間有1對1的映射。
圖10:組件圖顯示了依賴性。源代碼組件實現了域類,他們之間的關聯顯示為雙向依賴性
圖10顯示,設計模型的組件視圖簡單地將邏輯視圖中的類映射為組件視圖中的組件。每個邏輯視圖包含了一個指向邏輯視圖中類的連接,因此可以很容易地在不同的視圖之間導航(即便象本例只是簡單地使用了文件名)。由于依賴性可以從邏輯視圖的類圖中得到,因此組件圖中沒有顯示組件之間的依賴性。
編寫代碼時,從下面的設計模型的圖中取出規范說明:
1.類規范:每一個類的規范詳細地顯示了必要的屬性和操作。
2.類圖:類圖由類構成,顯示了類的結構以及類之間的關系。
3.狀態圖:類的狀態圖顯示了類可能具有的狀態以及需要處理的狀態轉移(以及觸發轉移的操作)。
4.動態圖(順序圖、協作圖和活動圖):涉及到類的對象,顯示了類中的特定方法如何實現,或對象之間如何使用其它類的對象進行交互。
5.用例圖和規范:當開發者需要了解更多的關于系統如何被使用的信息時(當開發者感到他或她已經迷失在一片細節中),他們顯示了系統被使用的結果。
很自然,設計中的某些缺陷可以在編碼階段發現。可能需要一些新的操作或修改某些操作,這意味著開發者必須改變設計模型。這在所有的工程中都會發生。重要的是將設計模型和代碼同步,以便使模型能夠成為系統的最終文檔。
這里給出了loan 類和部分titleframe類的Java代碼。整個應用程序的Java代碼可以從網上查到。當學習這些代碼時,注意結合UML模型,考慮UML結構是如何被轉變為代碼的。注意以下幾點:
1.Java包規范是與類所屬的邏輯視圖或組件視圖中相應的包等值的代碼。
2.私有屬性對應于模型中指定的屬性;并且,很自然Java 方法對應于模型中的操作。
3.ObjId類(對象標識符)被調用來實現關聯。也就是說,關聯通常和類一起保存(因為ObjId類是持續的)。
程序清單1的代碼示例來自于loan類,loan類是一個Business-Object類,用來存放借閱信息。由于該類主要是信息的存放處,因此程序的實現是直接的,代碼也簡單。大多數的功能繼承了Database 包中的Persistent類。該類的唯一屬性是對象標識符,將item和borrowerinformation類關聯起來。并且這些關聯屬性也在Write()和Read()操作中被保存。
試著在Add Title順序圖(圖7)上下文中檢驗一下程序清單2中顯示的Addbutton_Clicked()操作。結合順序圖閱讀代碼,可以看出:它就是另一個對順序圖所表達的協作關系的更為詳細的描述。
所有設計模型中的順序圖的編碼都包含在源代碼當中(操作名和類名顯示在順序圖中)
5.測試和部署(Test and Deployment)
編碼結束后,UML的使用還沒有停止。例如,可以檢驗用例能否在已完成的應用程序中得到很好的支持。對于系統的部署來說,利用模型和本文可以做一份得心應手的文檔。
6.總結
本學習案例的不同部分由一組人分別來設計完成。他們以做實際工程的方式努力完成該工作。盡管不同的階段和活動似乎是獨立的,而且以嚴格的順序來管理,但在實際工作中仍然有很多反復。設計中的經驗和教訓反饋到分析模型,實現階段所發現的新情況在設計模型中更改或更新。這就是建立面向對象系統的一般方法。
本文摘錄自UML Toolkit,New York:Wiley & Sons,1998. Hans-Erik Erikkson是一個有名的C++和OO技術方面的作者。Magnus Penker是Astrakan培訓副主席,Astrankan是一個瑞典專攻OO建模和設計的公司。
原文鏈接:http://www.umlchina.com/Indepth/DesignJava.htm
模型及源碼:http://www.umlchina.com/zippdf/libraryjava.zip
附:主要術語中英文對照
actor:角色
use case:用例
domain:域
domain analysis:域分析
specification:規范文檔
sequence diagram:順序圖
collaboration diagram:協作圖
component diagram:組件圖
state diagram:狀態圖
dependency:依賴性
attribute:屬性
method:方法
operation:操作
association:關聯
multiplicity:重數
class:類
object:對象
package:包
implementation:實現
deployment:部署
附:源代碼
Listing 1. Loan class. Loan is a Business-object class used for storing information about a loan. Most of the functionality is inherited from the Persistent class in the Database Package.
// Loan.java: represents a loan. The loan refer to one
// title and one borrower.
//
Package bo;
import util.ObjId;
import db.*;
import java.io.*;
import java.util.*;
public class Loan extends Persistent
{
private ObjId item;
private ObjId borrower;
public Loan()
{
}
public Loan(ObjId it, ObjId b)
{
item = it;
borrower = b;
}
public BorrowerInformation getBorrower()
{
BorrowerInformation ret =
(BorrowerInformation) Persistent.getObject(borrower);
return ret;
}
public String getTitleName()
{
Item it = (Item) Persistent.getObject(item);
return it.getTitleName();
}
public Item getItem()
{
Item it =
(Item) Persistent.getObject(item);
return it;
}
public int getItemId()
{
Item it = (Item) Persistent.getObject(item);
return it.getId();
}
public void write(RandomAccessFile out)
throws IOException
{
item.write(out);
borrower.write(out);
}
public void read(RandomAccessFile in)
throws IOException
{
item = new ObjId();
item.read(in);
borrower = new ObjId();
borrower.read(in);
}
}
Listing 2. TitleFrame Class. This is another, more detailed description of the collaboration described by the diagram in Figure 7.
// TitleFrame.java
//
Package ui;
import bo.*;
import util.*;
import java.awt.*;
public class TitleFrame extends Frame {
private Title current;
void addButton_Clicked(Event event) {
if (Title.findOnName(titleField.getText()) != null)
{
new MessageBox(
this,"A Title with that name already exists!");
return;
}
if (Title.findOnISBN(isbnField.getText()) != null)
{
new MessageBox(
this,"A title with the
same isbn/nr field already exists!");
return;
}
int type = 0;
if (bookButton.getState() == true)
type = Title.TYPE_BOOK;
else if (magazineButton.getState() == true)
type = Title.TYPE_MAGAZINE;
else
{
new MessageBox(this,"Please give type of title!");
return;
}
current =
new Title(
titleField.getText(),
authorField.getText(),
isbnField.getText(),
type);
int itemno;
if (itemsField.getText().equals(""))
itemno = 0;
else
itemno = Integer.valueOf(
itemsField.getText()).intValue();
if (itemno > 25)
{
new MessageBox(this, "Maximum number of items is 25!");
return;
}
for (int i = 0; i <\<> itemno; i++)
{
Item it = new Item(current.getObjId(),i+1);
it.store();
current.addItem(it.getObjId());
}
current.store();
titleField.setText("");
authorField.setText("");
isbnField.setText("");
itemsField.setText("");
bookButton.setState(false);
magazineButton.setState(false);
}
void cancelButton_Clicked(Event event) {
dispose();
}
public TitleFrame() {
//{{INIT_CONTROLS
setLayout(null);
addNotify();
resize(
insets().left + insets().right + 430,insets().top +
insets().bottom + 229);
titleLabel = new java.awt.Label("Title Name");
titleLabel.reshape(
insets().left + 12,insets().top + 24,84,24);
add(titleLabel);
titleField = new java.awt.TextField();
titleField.reshape(
insets().left + 132,insets().top + 24,183,24);
add(titleField);
authorField = new java.awt.TextField();
authorField.reshape(
insets().left + 132,insets().top + 60,183,24);
add(authorField);
isbnField = new java.awt.TextField();
isbnField.reshape(
insets().left + 132,insets().top + 96,183,24);
add(isbnField);
label1 = new java.awt.Label("ISBN / Nr");
label1.reshape(
insets().left + 12,insets().top + 96,84,24);
add(label1);
label2 = new java.awt.Label("Author");
label2.reshape(
insets().left + 12,insets().top + 60,84,24);
add(label2);
addButton = new java.awt.Button("Insert");
addButton.reshape(
insets().left + 348,insets().top + 24,60,24);
add(addButton);
cancelButton = new java.awt.Button("Close");
cancelButton.reshape(
insets().left + 348,insets().top + 192,60,24);
add(cancelButton);
label3 = new java.awt.Label("Items available");
label3.reshape(
insets().left + 12,insets().top + 192,108,24);
add(label3);
itemsField = new java.awt.TextField();
itemsField.reshape(
insets().left + 132,insets().top + 192,36,23);
add(itemsField);
Group1 = new CheckboxGroup();
bookButton =
new java.awt.Checkbox("Book", Group1, false);
bookButton.reshape(
insets().left + 132,insets().top + 132,108,24);
add(bookButton);
magazineButton =
new java.awt.Checkbox("Magazine", Group1, false);
magazineButton.reshape(
insets().left + 132,insets().top + 156,108,24);
add(magazineButton);
label4 = new java.awt.Label("Type");
label4.reshape(
insets().left + 12,insets().top + 132,108,24);
add(label4);
setTitle("Insert Title Window");
//}}
bookButton.setState(true);
titleField.requestFocus();
//{{INIT_MENUS
//}}
}
public TitleFrame(String title) {
this();
setTitle(title);
}
public synchronized void show() {
move(50, 50);
super.show();
}
public boolean handleEvent(Event event) {
if (event.id == Event.WINDOW_DESTROY) {
dispose();
return true;
}
if (event.target == addButton && event.id ==
Event.ACTION_EVENT) {
addButton_Clicked(event);
return true;
}
if (event.target == cancelButton && event.id ==
Event.ACTION_EVENT) {
cancelButton_Clicked(event);
return true;
}
return super.handleEvent(event);
}
//{{DECLARE_CONTROLS
java.awt.Label titleLabel;
java.awt.TextField titleField;
java.awt.TextField authorField;
java.awt.TextField isbnField;
java.awt.Label label1;
java.awt.Label label2;
java.awt.Button addButton;
java.awt.Button cancelButton;
java.awt.Label label3;
java.awt.TextField itemsField;
java.awt.Checkbox bookButton;
CheckboxGroup Group1;
java.awt.Checkbox magazineButton;
java.awt.Label label4;
//}}
//{{DECLARE_MENUS
//}}
}