在 Gorm 中也可以加入自訂的圖形元件, 而不使用 Gorm 內建的. 在這裡做一個顯示時間的圖形元件. 下圖中白色框線內即為自訂的圖形元件.
在 Gorm 中使用自訂元件時, 要先設計好其類別. 圖形元件可以繼承自 NSView 或 NSControl. NSView 要是是顯示, NSControl 則可以接受使用者的動作. NSControl 也是繼承自 NSView. 在這範列中, 要製做的元件稱為 TimeView, 繼承自 NSControl. 先選 NSResponder 旁的小圓鈕, 展開其子類別 (Subclass), 再展開 NSView 的字類別. 許多圖形元件都是繼承自 NSControl, 如 NSTextField.
選 NSControl, 選 "Classes->Create Subclass..." 產生新類別. 點兩下修改名稱為 "TimeView".
TimeView 同時也繼承了 NSControl 的三個 outlets 及七個 actions.
接著建立以下的圖形介面.
選其中的 CustomView, 選 Inspector 的 Attributes, 選 TimeView 類別. 如此便指定 CustomView 使用 TimeView 類別.
這時 CustomView 變成了 TimeView.
如同之前建立一個 Controller, 加入 timeView outlet 及 -showCurrentTime: action.
產生 Controller 物件, 連結 timeView outlet 至 TimeView 這個自訂元件. 連結按鈕到 -showCurrentTime 這個 action.
最後, 產生 TimeView 及 Controller 的程式碼, 並將圖形介面存檔成 TimeMachine.gorm. 這就是在 Gorm 中使用自訂元件的方法.
接下來就是要製做這個自訂元件, TimeView. 這個 TimeView 實際上是由 NSBox 及 NSTextView 所組成的. NSBox 即為其外框, NSTextField 則用來顯示字串. 做成自訂元件的好除了以後可以反複使用. 繼承自 NSView 的類別, 其啟始呼叫是 -initWithFrame: 因此要在 -initWithFrame 中加入要顯示的元件.
TimeView.h:
#import <AppKit/AppKit.h> @interface TimeView : NSControl { NSTextField *labelDate, *labelTime; NSTextField *localDate, *localTime; NSCalendarDate *date; } - (NSCalendarDate *) date; - (void) setDate: (NSCalendarDate *) date; @end
TimeView.m:
#import <AppKit/AppKit.h> #import "TimeView.h" @implementation TimeView - (id) initWithFrame: (NSRect) frame { NSBox *box; self = [super initWithFrame: frame]; box = [[NSBox alloc] initWithFrame: NSMakeRect(0, 0, frame.size.width, frame.size.height)]; [box setBorderType: NSGrooveBorder]; [box setTitlePosition: NSAtTop]; [box setTitle: @"Local Time"]; labelDate = [[NSTextField alloc] initWithFrame: NSMakeRect(10, 45, 35, 20)]; [labelDate setStringValue: @"Date: "]; [labelDate setBezeled: NO]; [labelDate setBackgroundColor: [NSColor windowBackgroundColor]]; [labelDate setEditable: NO]; labelTime = [[NSTextField alloc] initWithFrame: NSMakeRect(10, 15, 35, 20)]; [labelTime setStringValue: @"Time: "]; [labelTime setBezeled: NO]; [labelTime setBackgroundColor: [NSColor windowBackgroundColor]]; [labelTime setEditable: NO]; localDate = [[NSTextField alloc] initWithFrame: NSMakeRect(55, 45, 130, 20)]; localTime = [[NSTextField alloc] initWithFrame: NSMakeRect(55, 15, 130, 20)]; [box addSubview: labelDate]; [box addSubview: labelTime]; [box addSubview: localDate]; [box addSubview: localTime]; RELEASE(labelDate); RELEASE(labelTime); RELEASE(localDate); RELEASE(localTime); [self addSubview: box]; RELEASE(box); return self; } - (NSCalendarDate *) date { return date; } - (void) setDate: (NSCalendarDate *) aDate { ASSIGN(date, aDate); [date setCalendarFormat: @"%a, %b %e, %Y"]; [localDate setStringValue: [date description]]; [date setCalendarFormat: @"%H : %M : %S"]; [localTime setStringValue: [date description]]; } - (void) dealloc { RELEASE(date); [super dealloc]; } @end
有些 Gorm 產生的程式碼不一定會用到, 因此可以直接刪除. 在 TimeView.h, 宣告了四個 NSTextField 來顯示時間, 一個 NSCalendarDate 來記錄時間. 也增加兩個 methods 來更改時間. 這是典型的做法. 在 initWithFrame 中, 先設定好 NSBox, 再加入四個 NSTextField 到 NSBox. NSBox 便成為 NSTextField 的 Superview, 而 NSTextField 便成為 NSBox 的 Subview. Superview 會保留 (retain) subview, 所以在這裡可以將其釋放 (release). 最後再將 NSBox 加入 TimeView 中, 這時 NSBox 成為 TimeView 的 subview, 而 TimeView 成為 NSBox 的 superview.
其他部份就簡單許多了:
Controller.h:
#import <AppKit/AppKit.h> #import "TimeView.h" @interface Controller : NSObject { id timeView; } - (void) showCurrentTime: (id)sender; @end
Controller.m:
#import <AppKit/AppKit.h> #import "Controller.h" @implementation Controller - (void) showCurrentTime: (id)sender { /* insert your code here */ NSCalendarDate *date = [NSCalendarDate date]; [timeView setDate: date]; } @end
main.m:
#import <AppKit/AppKit.h> int main(int argc, const char *argv[]) { return NSApplicationMain (argc, argv); }
GNUmakefile:
include $(GNUSTEP_MAKEFILES)/common.make APP_NAME = TimeMachine TimeMachine_HEADERS = Controller.h TimeView.h TimeMachine_OBJC_FILES = main.m Controller.m TimeView.m TimeMachine_RESOURCE_FILES = TimeMachineInfo.plist TimeMachine.gorm TimeMachine_MAIN_MODEL_FILE = TimeMachine.gorm include $(GNUSTEP_MAKEFILES)/application.make
在 Gorm 中, 並沒有產生 TimeView 物件. 因為在圖形介面產生一個自訂元件, 並指定該自訂元件為 TimeView, 便等同產生一個 TimeView 物件. 而 Controller 因為不是圖形元件, 所以必需自行產生一個物件, 才能連結 outlet 及 action.