#import "MyDocument.h"
#import "Person.h"
/**
* 表每行的元素放在一個(gè)對(duì)象中, 所有行存放在一個(gè)NSMutableArray中, 這樣好管理, 當(dāng)然每列的內(nèi)容可以分開(kāi)存放, 但不方便.
* 當(dāng)表有多列時(shí), (在IB中選中列)要為每個(gè)列指定一個(gè)identifier, 其值為存儲(chǔ)的對(duì)象的屬性名稱, 當(dāng)使用
* [aTableColumn identifier]時(shí), 就可以取得這一列存儲(chǔ)的內(nèi)容是這個(gè)對(duì)象的哪一個(gè)屬性,
* 然后使用key-value-coding([obj setValue:value forKey:@"name"], [obj valueForKey:@"name"])
* 來(lái)取得與修改這個(gè)對(duì)象的屬性.
*
* 表的內(nèi)容是存儲(chǔ)在NSTableDataSource中, 只要一個(gè)類實(shí)現(xiàn)了下面兩個(gè)方法, 然后在界面中直接右擊表, 把其中的
* dataSource拖動(dòng)指到doc window中的這個(gè)類(文檔的直接是File's Owner, 非文檔的先建立一個(gè)NSObject的Controller)
* - (int)numberOfRowsInTableView:(NSTableView*)tv 返回列的行.
* - (id)tableView:(NSTableView*)tv objectValueForTableColumn:(NSTableColumn*)tc row:(int)rowIndex
*
* 如果想使一個(gè)表是可以修改的, 再實(shí)現(xiàn)下面的這個(gè)方法即可
* - (void)tableView:(NSTableView*)tc setObjectValue:(id)anObject
* forTableColumn:(NSTableColumn*)tc row:(int)rowIndex
*
*
* IBOutlet是一個(gè)宏, 給Interface Builder提供信息(即在其中可以看到IBOutlet修飾的變量).
* 當(dāng)你想使用一個(gè)界面元素的方法(如NSTextField)時(shí), 就聲明一個(gè)相關(guān)的變量為IBOutlet,
* 這樣, 在你的程序中就可以直接操作那個(gè)界面元素的一切.
*
* IBAction實(shí)際上就是void, 但是也是為了給IB提供信息, 讓IBActon定義的方法在IB中顯示出來(lái).
* 事件處理函數(shù)用IBAction來(lái)定義, 如作為NSButton的action selector.
*
* getter的名字為屬性的名字, setter的名字為set加上屬性的名字(此時(shí)屬性的名字的第一個(gè)字母要大寫(xiě)).
*/
@implementation MyDocument
- (IBAction)addEmployee:(id)sender {
Person* newEmployee = [[Person alloc] init];
[employees addObject:newEmployee];
[newEmployee release];
[tableView reloadData];
}
- (IBAction)removeEmployee:(id)sender {
NSIndexSet* rows = [tableView selectedRowIndexes];
if ([rows count] == 0) {
NSBeep();
return;
}
[employees removeObjectsAtIndexes:rows];
[tableView reloadData];
}
////////////////////////////////////////////////////////////////////////////////////
// Methods for NSTableDataSource
////////////////////////////////////////////////////////////////////////////////////
- (int)numberOfRowsInTableView:(NSTableView*)tv {
return [employees count];
}
- (id)tableView:(NSTableView*)tv objectValueForTableColumn:(NSTableColumn*)tc
row:(int)rowIndex {
NSString* columnIdentifier = [tc identifier];
NSLog(@"%@", columnIdentifier);
Person* person = [employees objectAtIndex:rowIndex];
return [person valueForKey:columnIdentifier];
//return nil;
}
- (void)tableView:(NSTableView*)tv setObjectValue:(id)anObject
forTableColumn:(NSTableColumn*)tc row:(int)rowIndex {
NSString* identifier = [tc identifier];
Person* employee = [employees objectAtIndex:rowIndex];
[employee setValue:anObject forKey:identifier];
}
////////////////////////////////////////////////////////////////////////////////////
// Overrieded Methods.
////////////////////////////////////////////////////////////////////////////////////
- (id)init
{
self = [super init];
if (self) {
// Add your subclass-specific initialization here.
// If an error occurs here, send a [self release] message and return nil.
employees = [[NSMutableArray alloc] init];
}
return self;
}
- (void)dealloc {
[employees release];
[super dealloc];
}
- (NSString *)windowNibName
{
// Override returning the nib file name of the document
// If you need to use a subclass of NSWindowController or if your document supports multiple NSWindowControllers, you should remove this method and override -makeWindowControllers instead.
return @"MyDocument";
}
- (void)windowControllerDidLoadNib:(NSWindowController *) aController
{
[super windowControllerDidLoadNib:aController];
// Add any code here that needs to be executed once the windowController has loaded the document's window.
}
- (NSData *)dataOfType:(NSString *)typeName error:(NSError **)outError
{
// Insert code here to write your document to data of the specified type. If the given outError != NULL, ensure that you set *outError when returning nil.
// You can also choose to override -fileWrapperOfType:error:, -writeToURL:ofType:error:, or -writeToURL:ofType:forSaveOperation:originalContentsURL:error: instead.
// For applications targeted for Panther or earlier systems, you should use the deprecated API -dataRepresentationOfType:. In this case you can also choose to override -fileWrapperRepresentationOfType: or -writeToFile:ofType: instead.
if ( outError != NULL ) {
*outError = [NSError errorWithDomain:NSOSStatusErrorDomain code:unimpErr userInfo:NULL];
}
return nil;
}
- (BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName error:(NSError **)outError
{
// Insert code here to read your document from the given data of the specified type. If the given outError != NULL, ensure that you set *outError when returning NO.
// You can also choose to override -readFromFileWrapper:ofType:error: or -readFromURL:ofType:error: instead.
// For applications targeted for Panther or earlier systems, you should use the deprecated API -loadDataRepresentation:ofType. In this case you can also choose to override -readFromFile:ofType: or -loadFileWrapperRepresentation:ofType: instead.
if ( outError != NULL ) {
*outError = [NSError errorWithDomain:NSOSStatusErrorDomain code:unimpErr userInfo:NULL];
}
return YES;
}
@end