May 28, 2004

Simple NSTableView Example

Finally finally finally I've figured out a way to add data to a table via a simple add form.

I built upon the Expenses example I coded previously.

Here's a brief run-down:

In Interface Builder:

1. I created a window like the one above.
2. I created a class called MyDataSource. This class had:

two outlets: amountField and categoryField
one function: addExpense()

3. I instantiated MyDataSource
4. In the Instances Pane, I made the following connections

From MyDataSource to NSTextField below Account: accountField
From MyDataSource to NSTextField below Category: categoryField
From MyDataSource to NSTableView: expenseTable
From NSTableView to MyDataSource: dataSource
From "Add Expense" button to MyDataSource: addExpense()
From File's Owner to MyDataSource: delegate

5. Create files for MyDataSource

In XCode:

/* MyDataSource */

import com.apple.cocoa.foundation.*;
import com.apple.cocoa.application.*;

public class MyDataSource {

   public NSTextField categoryField;
   public NSTextField amountField;

   // expenseTable is the dataSource
   public NSTableView expenseTable;

   // holds expense values 
   NSMutableArray expenses;

   // default constructor
   public MyDataSource() {
        super();
        this.setExpenses(new NSMutableArray());
    }

   // METHOD:  addExpense(Object sender) 
   // this function is called when "Add Expense" is clicked
   public void addExpense(Object sender) {

      Expense exp = new Expense();
      String cat = categoryField.stringValue();
      Double amt = new Double(amountField.doubleValue());
      exp.setCategory(cat);
      exp.setAmount(amt);

      // add the newly created Expense object
      // to expenses
      expenses.addObject(exp);

      // reload the table data
      expenseTable.reloadData();
   }

   public NSArray getExpenses(){
      return expenses;
   }

   public void setExpenses(NSMutableArray value){
      this.expenses = value;
   }

   //implement abstract TableView methods

   public int numberOfRowsInTableView(NSTableView tableView){
      return expenses.count();
   }

   public Object tableViewObjectValueForLocation(
                   NSTableView tableView,
                   NSTableColumn tableColumn, int row){
      String identifier = (String)tableColumn.identifier();
      Expense expense = (Expense)expenses.objectAtIndex(row);
      return (Object)expense.valueForKey(identifier);

   }

   public void tableViewSetObjectValueForLocation(
                   NSTableView tableView, Object object,
                   NSTableColumn tableColumn, int row){
        String identifier = (String)tableColumn.identifier();
        Expense expense = (Expense)expenses.objectAtIndex(row);
      expense.takeValueForKey(object, identifier);
    }

}

//
//  Expense.java
//  Expenses
//
//  Created by Monica Shaw on Wed May 19 2004.
//  Copyright (c) 2004 Red Dinosaur Productions. All rights reserved.
//

import com.apple.cocoa.foundation.*;
import com.apple.cocoa.application.*;

//the class must extend NSObject so we can use
//the method valueForKey()
public class Expense extends NSObject {
   String date;
   String category;
   Double amount;  //we need Objects

   public Expense(){
      super();
      NSGregorianDate today = new NSGregorianDate();

      //Format the date output
      NSGregorianDateFormatter dateFormatter =
              new NSGregorianDateFormatter("%b %d, %Y",false);
      try{
         this.setDate(dateFormatter.stringForObjectValue(today));
         this.setCategory("Food");
         this.setAmount(new Double(0));
      }
      catch (NSFormatter.FormattingException e){
         System.err.println("Caught 
           NSFormatter.FormattingException: "+e.getMessage()); 
      }
   }

   // get and set methods
   public String getDate(){
      return this.date;
   }

   public void setDate(String value){
      this.date = value;
   }

   public String getCategory(){
      return this.category;
   }

   public void setCategory(String value){
      this.category = value;
   }

   public Double getAmount(){
      return this.amount;
   }

   public void setAmount(Double value){
      this.amount = value;
   }
}

Posted by monica at May 28, 2004 06:28 AM