Cappuccino: zobrazujeme tabulku s daty

Minule jsme se naučili pracovat s uživatelským rozhraním a jeho základními prvky. Vytvořili jsme si jednoduchou aplikaci, která nám umožnila přidat položku z textového pole do pole CPArray. A v dnešním díle si naší aplikaci vylepšíme o možnost zobrazení záznamů v tabulce.

Seriál: Vývoj aplikací v Cappuccinu (4 díly)

  1. Cappuccino – webové aplikace snadno a rychle 4.10.2010
  2. Základy Objective-J: syntaxe a framework Foundation 18.10.2010
  3. Cappuccino: uživatelské rozhraní aplikace a AppKit 11.11.2010
  4. Cappuccino: zobrazujeme tabulku s daty 1.12.2010

Čeho chceme dosáhnout

V dnešním díle můžeme s naší jednoduchou aplikací, kterou jsme si vytvořili v minulém díle, pokračovat a rozvíjet ji.

Podstatnou částí většiny webových aplikací je rozumná forma výpisu dat, v našem případě se zaměříme na výpis úkolů do tabulky.

Naše aplikace bude vypadat v závěru takto:

Co k tomu budeme potřebovat

Začneme odděleným příkladem jednoduché tabulky, kterou následně na naší aplikaci napojíme.

CPTableView

Třída, která nám umožní pracovat s tabulkou se jmenuje CPTableView. Jak jsme si ale v prvním díle seriálu řekli, oficiální dokumentace nám toho příliš nepoví, proto doporučuji přečíst referenci k třídě NSTableView.

Příklad – tabulka

Začneme vygenerováním nového projektu pro oddělenou implementaci tabulky:

a pročištěním kódu:

@import
@implementation AppController : CPObject
{
}
- (void)applicationDidFinishLaunching:(CPNotification)aNotification
{
    var theWindow = [[CPWindow alloc] initWithContentRect:CGRectMakeZero() styleMask:CPBorderlessBridgeWindowMask],
        contentView = [theWindow contentView];

    //kód příkladu tabulky

    [theWindow orderFront:self];
}
@end

Náš příklad s tabulkou bude ve finále vypadat takto:

Třída CPTableView sama o sobě nezná způsob jak scrollovat, proto jí musíme umístit dovnitř další třídy CPScrollView, která ví, jak na to. Nové scrollView vytvoříme následovně:

var scrollView = [[CPScrollView alloc] initWithFrame: CGRectMake(50.0,50.0,150.0,200.0)];
[scrollView setAutoresizingMask: CPViewWidthSizable | CPViewHeightSizable];

Ve chvíli, kdy již máme prvek, uvnitř kterého se dá scrollovat, můžeme přejít k vytvoření samotné CPTableView, kterou nastavíme tak, aby rozměry přesně odpovídala  CPScrollView:

tableView = [[CPTableView alloc] initWithFrame: [scrollView bounds]];

Třída CPTableView, resp. naše tabulka bude mít zdroj dat. Tímto zdrojem bude pole definované jako instanční proměnná – stejně jako v minulém díle. Nastavíme tedy zdroj dat tabulky na self – odkaz na naší třídu AppController.

[tableView setDataSource:self];

Vytvoříme nový sloupeček tabulky a ten následně do tabulky přidáme:

var column = [[CPTableColumn alloc] initWithIdentifier:@"Browsers"];
[[column headerView] setStringValue:@"Browser"];
[column setWidth:140.0];
[tableView addTableColumn:column];

Důležitým krokem je nastavení potomka prvku pro CPScrollView. K samotnému uživatelskému rozhraní je to vše a můžeme tabulku přidat do View celé naší aplikace:

[scrollView setDocumentView:tableView];
[contentView addSubview:scrollView];

Bohužel to ještě není vše, co je potřeba udělat pro zprovoznění tableView, existují 2 metody, které musíme implementovat.

Metoda numberOfRowsInTableView nám vrací počet položek v tabulce.

A metoda tableView:objectValueForTableColumn:row: nám přesně určuje, který záznam se v řádku pro daný sloupec zobrazí.

Tyto dvě metody přidáme kamkoliv před ukončovací symbol  @end.

- (int)numberOfRowsInTableView:(CPTableView)aTableView
{
    return [browsers count];
}
- (id)tableView:(CPTableView)aTableView objectValueForTableColumn:(CPTableColumn)aTableColumn row:(int)aRow
{
    return [browsers[aRow]];
}

Poslední věcí, o kterou se v našem příkladu musíme postarat jsou samotná data. Vytvoříme si podobné pole jako v minulém díle, jen s tím rozdílem, že si do něj naházíme názvy prohlížečů:

browsers = [[CPArray alloc] init];
[browsers addObject:@"Google Chrome"];
[browsers addObject:@"Apple Safari"];
[browsers addObject:@"Mozilla FireFox"];
[browsers addObject:@"Internet Explorer"];

Stejně jako v minulém díle budeme pracovat s polem mimo metodu applicationDidFinishLaunching, takže jej musíme zpřístupnit pro jakoukoliv metodu dané třídy – udělat z něj instanční proměnnou.

@implementation AppController : CPObject
{
    CPArray browsers;
}

Funkční kód vypadá dohromady takto:

@import
@implementation AppController : CPObject
{
    CPArray browsers;
}
- (void)applicationDidFinishLaunching:(CPNotification)aNotification
{
    var theWindow = [[CPWindow alloc] initWithContentRect:CGRectMakeZero() styleMask:CPBorderlessBridgeWindowMask],
        contentView = [theWindow contentView];

    browsers = [[CPArray alloc] init];
    [browsers addObject:@"Google Chrome"];
    [browsers addObject:@"Apple Safari"];
    [browsers addObject:@"Mozilla FireFox"];
    [browsers addObject:@"Internet Explorer"];

    var scrollView = [[CPScrollView alloc] initWithFrame:CGRectMake(50.0,50.0,150.0,200.0)];
    [scrollView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];

    var tableView = [[CPTableView alloc] initWithFrame:[scrollView bounds]];

    [tableView setDataSource:self];

    var column = [[CPTableColumn alloc] initWithIdentifier:@"Browsers"];
    [[column headerView] setStringValue:@"Browser"];
    [column setWidth:140.0];
    [tableView addTableColumn:column];

    [scrollView setDocumentView:tableView];

    [contentView addSubview:scrollView];

    [theWindow orderFront:self];
}
- (int)numberOfRowsInTableView:(CPTableView)aTableView
{
    return [browsers count];
}
- (id)tableView:(CPTableView)aTableView objectValueForTableColumn:(CPTableColumn)aTableColumn row:(int)aRow
{
    return [browsers[aRow]];
}
@end

Napojení tabulky na ToDo aplikaci

Můžeme pokračovat s kódem, s kterým jsme skončili v minulém díle:

@import <Foundation/CPObject.j>
@implementation AppController : CPObject
{
    CPTextField textField;
    CPMutableArray todo;
}
- (void)applicationDidFinishLaunching:(CPNotification)aNotification
{
    var theWindow = [[CPWindow alloc] initWithContentRect:CGRectMakeZero() styleMask:CPBorderlessBridgeWindowMask],
        contentView = [theWindow contentView];

    todo = [[CPArray alloc] init];
        [todo addObject:@"Koupit rohlíky"];
        [todo addObject:@"Napsat článek pro zdroják"];

    var button = [[CPButton alloc] initWithFrame: CGRectMake(230.0,37.0,80.0,24.0)];
    [button setTitle:@"přidat"];
    [button setTarget:self];
    [button setAction:@selector(addItem:)];

    textField = [CPTextField textFieldWithStringValue:@"" placeholder:@"Úkol" width:200.0];
    [textField setFrameOrigin:CGPointMake(30.0, 35.0)];

    [contentView addSubview:textField];
    [contentView addSubview:button];

    [theWindow orderFront:self];
}
- (void)logIt:(id)sender
{
    console.log(@"-------");
    console.log(@"vypiš položky");

    for (var i = 0; i < todo.length; i++)
    {
        console.log([todo objectAtIndex: i]);
    }
}
- (void)addItem:(id)sender
{
    [todo addObject: [textField stringValue]];
    [self logIt:sender];
}
@end

Po drobnějších úpravách, aplikování metod a tříd, které jsme se dnes naučili používat, dosáhneme funkčního todo listu s výpisem položek do tabulky: 

@import
@implementation AppController : CPObject
{
    CPTextField textField;
    CPMutableArray todo;
    CPTableView tableView;
}
- (void)applicationDidFinishLaunching:(CPNotification)aNotification
{
    var theWindow = [[CPWindow alloc] initWithContentRect:CGRectMakeZero() styleMask:CPBorderlessBridgeWindowMask],
        contentView = [theWindow contentView];

    //data source - array
    todo = [[CPArray alloc] init];
    [todo addObject:@"Koupit rohlíky"];
    [todo addObject:@"Napsat článek pro zdroják"];

    var button = [[CPButton alloc] initWithFrame: CGRectMake(230.0,37.0,80.0,24.0)];

    [button setTitle:@"přidat"];
    [button setTarget:self];
    [button setAction:@selector(addItem:)];

    //textField
    textField = [CPTextField textFieldWithStringValue:@"" placeholder:@"Úkol" width:200.0];
    [textField setFrameOrigin:CGPointMake(30.0, 35.0)];

    //scrollView, tableView
    var scrollView = [[CPScrollView alloc] initWithFrame:CGRectMake(34.0,80.0,280.0,200.0)];

    tableView = [[CPTableView alloc] initWithFrame:[scrollView bounds]];

    [tableView setDataSource:self];
    var column = [[CPTableColumn alloc] initWithIdentifier:@"Tasks"];
    [[column headerView] setStringValue:@"Task"];
    [column setWidth:210.0];
    [tableView addTableColumn:column];

    [scrollView setDocumentView:tableView];

    //adding views - show
    [contentView addSubview:scrollView];
    [contentView addSubview:textField];
    [contentView addSubview:button];

    [theWindow orderFront:self];
}
- (void)addItem:(id)sender
{
    [todo addObject: [textField stringValue]];

    [tableView reloadData];
}
-(int)numberOfRowsInTableView:(CPTableView)aTableView
{
    return [todo count];
}
-(id)tableView:(CPTableView)aTableView objectValueForTableColumn:(CPTableColumn)aTableColumn row:(int)aRow
{
    return [todo[aRow]];
}
@end

Co jsme se naučili

Dnes jsme si rozšířili znalosti uživatelského rozhraní frameworku Cappuccino o výpis dat do tabulky a ukázali si praktické použití této tabulky v naší aplikaci.

Co bude příště

V příštím díle si ukážeme napojení na backend a komunikaci se serverem prostřednictvím JSO­Nu.

Zabývá se návrhem a vývojem webových aplikací. Své nápady s důrazem na jednoduchost a použitelnost realizuje spolu se členy týmu abdoc.

Věděli jste, že nám můžete zasílat zprávičky? (Jen pro přihlášené.)

Zdroj: https://www.zdrojak.cz/?p=3378