NSTableView questions

  • Couple of questions-

    To prevent all entries from being edited in a NSTableView is it
    enough if I return NO to shouldEditTableColumn:row: ?
    Is there a better way to do this?

    I want to display a list of items stored in a file in a table. How do
    I initialize my dataSrc array when the application is launched? I can
    write a method in the dataSrc to open the file and read in the
    contents. But how do I ensure the method will be called when my
    application starts up?

    Thanks
    Hrishi

    ---
    www.greenwaysroad.com
  • >
    > To prevent all entries from being edited in a NSTableView is it
    > enough if I return NO to shouldEditTableColumn:row: ?
    > Is there a better way to do this?

    you can make a column un-editable in interface builder.  click on the column
    of your table and de-select "editable".

    I want to display a list of items stored in a file in a table. How do
    > I initialize my dataSrc array when the application is launched? I can
    > write a method in the dataSrc to open the file and read in the
    > contents. But how do I ensure the method will be called when my
    > application starts up?

    set up the data source array in the initialization of your controlling
    object.  so if you have AppController with an NSMutableArray property you
    would setup initialize / setup the data source array in AppControllers
    init.  i guess this assumes you have AppController instantiated in your nib
    file

    +Clint

    On 9/25/07, Hrishikesh Muruk <hrishim...> wrote:
    >
    > Couple of questions-
    >
    > To prevent all entries from being edited in a NSTableView is it
    > enough if I return NO to shouldEditTableColumn:row: ?
    > Is there a better way to do this?
    >
    > I want to display a list of items stored in a file in a table. How do
    > I initialize my dataSrc array when the application is launched? I can
    > write a method in the dataSrc to open the file and read in the
    > contents. But how do I ensure the method will be called when my
    > application starts up?
    >
    > Thanks
    > Hrishi
    >
    >
    > ---
    > www.greenwaysroad.com
    >
  • > set up the data source array in the initialization of your controlling
    > object.  so if you have AppController with an NSMutableArray property you
    > would setup initialize / setup the data source array in AppControllers
    > init.  i guess this assumes you have AppController instantiated in your nib
    > file

    -init is probably not where you'd want to load data from a file and
    force an update when the application finishes launching.

      1 - What if you want to throw a dialogue if there's a problem with the file?

      2 - What if the rest of the UI in the nib is not finished loading
    when you ask it to update?

      3 - What if other startup logic requires that the data is loaded in
    order to succeed?

      Consider using the -applicationDidFinishLaunching: delegate method
    (easily found by searching the documentation for "application launch",
    two words the OP used in his question). When this is called, you can
    rest assured that your application is ... well ... finished launching
    and that all the required parts are fully assembled and ready to go.

      From there you can (while checking for errors and handling them
    appropriately) try to load the file, then trigger any dependent UI
    updates. You can also make sure that, upon fatal error, you have the
    chance to notify the user and terminate before anything else can be
    done. All this is contained in one neat, easily-managed location.

    --
    I.S.
  • On 9/25/07, I. Savant <idiotsavant2005...> wrote:
    >> set up the data source array in the initialization of your controlling
    >> object.  so if you have AppController with an NSMutableArray property you
    >> would setup initialize / setup the data source array in AppControllers
    >> init.  i guess this assumes you have AppController instantiated in your nib
    >> file

      As a followup:

    http://developer.apple.com/documentation/Cocoa/Reference/ApplicationKit/Pro
    tocols/NSNibAwaking_Protocol/Reference/Reference.html


    "Because the order in which objects are instantiated from an archive
    is not guaranteed, your initialization methods should not send
    messages to other objects in the hierarchy. Messages to other objects
    can be sent safely from within awakeFromNib—by which time it's assured
    that all the objects are unarchived and initialized (though not
    necessarily awakened, of course)."

    --
    I.S.
  • I tried using the -applicationDidFinishLaunching: delegate but that
    does not work quite as I expected.

    Let me explain what I am trying to do again -
    I have a list of items that are created dynamically. This list
    (dataSrc) has to be displayed in an NSTableView. To show the list in
    the table view I have also implemented the following delegates
    1. - (int)numberOfRowsInTableView:(NSTableView *) aTable
    2. - (id)tableView:(NSTableView*) aTable objectValueForTableColumn:
    (NSTableColumn *)

    When the application is run -numberOfRowsInTableView: is called
    before -applicationDidFinishLaunching: . So initializing the array in
    -applicationDidFinishLaunching:  does not work because -
    numberOfRowsInTableView: returns zero (size of array) and the table
    does not get updated after that.

    I want to dynamically change the contents displayed in the
    NSTableView. I suppose sending a -reload: message (every time I
    update the contents o the dataSrc array) to the table will work. But
    in my program how do I get a reference to the NSTableView in my program?

    Thanks
    Hrishi

    On 25-Sep-07, at 11:29 PM, I. Savant wrote:

    > On 9/25/07, I. Savant <idiotsavant2005...> wrote:
    >>> set up the data source array in the initialization of your
    >>> controlling
    >>> object.  so if you have AppController with an NSMutableArray
    >>> property you
    >>> would setup initialize / setup the data source array in
    >>> AppControllers
    >>> init.  i guess this assumes you have AppController instantiated
    >>> in your nib
    >>> file
    >
    > As a followup:
    >
    > http://developer.apple.com/documentation/Cocoa/Reference/
    > ApplicationKit/Protocols/NSNibAwaking_Protocol/Reference/
    > Reference.html
    >
    > "Because the order in which objects are instantiated from an archive
    > is not guaranteed, your initialization methods should not send
    > messages to other objects in the hierarchy. Messages to other objects
    > can be sent safely from within awakeFromNib—by which time it's assured
    > that all the objects are unarchived and initialized (though not
    > necessarily awakened, of course)."
    >
    > --
    > I.S.

    ---
    www.greenwaysroad.com
  • You're missing a crucial point: The table view doesn't know squat about your
    data -- it asks your delegate.

    So, in answer to your queries:

    - it's OK that it returns zero at some point, because there's nothing there
    at that point.  It's only logical.

    - yes, applicationDidFinishLaunching is the appropriate place to do
    initialization many times because you can't predict when things will get
    pulled from the nib, and you, many times, need everything out of the nib to
    get the job done.  So awakeFromNib doesn't cut it.  You have to wait until
    later.

    - yes, every time you change your data storage underneath the NSTableView
    you have to do some form of reload to tell it that things are different.
    You don't have to reload the whole thing, look into reloadItem if you just
    change one (or a few things).

    - You get a reference to the NSTableView by declaring a variable as such:

        (IBOutlet) NSTableView *myTable;

    and connecting it in the Interface Builder.  It isn't unreasonable to
    declare this as an Extern even, and reference it from several code modules.

    HTH,
    Chris

    On 10/5/07 9:36 AM, "Hrishikesh Muruk" <hrishim...> wrote:

    > I tried using the -applicationDidFinishLaunching: delegate but that
    > does not work quite as I expected.
    >
    > Let me explain what I am trying to do again -
    > I have a list of items that are created dynamically. This list
    > (dataSrc) has to be displayed in an NSTableView. To show the list in
    > the table view I have also implemented the following delegates
    > 1. - (int)numberOfRowsInTableView:(NSTableView *) aTable
    > 2. - (id)tableView:(NSTableView*) aTable objectValueForTableColumn:
    > (NSTableColumn *)
    >
    >
    > When the application is run -numberOfRowsInTableView: is called
    > before -applicationDidFinishLaunching: . So initializing the array in
    > -applicationDidFinishLaunching:  does not work because -
    > numberOfRowsInTableView: returns zero (size of array) and the table
    > does not get updated after that.
    >
    > I want to dynamically change the contents displayed in the
    > NSTableView. I suppose sending a -reload: message (every time I
    > update the contents o the dataSrc array) to the table will work. But
    > in my program how do I get a reference to the NSTableView in my program?
    >
    > Thanks
    > Hrishi
    >
    > On 25-Sep-07, at 11:29 PM, I. Savant wrote:
    >
    >> On 9/25/07, I. Savant <idiotsavant2005...> wrote:
    >>>> set up the data source array in the initialization of your
    >>>> controlling
    >>>> object.  so if you have AppController with an NSMutableArray
    >>>> property you
    >>>> would setup initialize / setup the data source array in
    >>>> AppControllers
    >>>> init.  i guess this assumes you have AppController instantiated
    >>>> in your nib
    >>>> file
    >>
    >> As a followup:
    >>
    >> http://developer.apple.com/documentation/Cocoa/Reference/
    >> ApplicationKit/Protocols/NSNibAwaking_Protocol/Reference/
    >> Reference.html
    >>
    >> "Because the order in which objects are instantiated from an archive
    >> is not guaranteed, your initialization methods should not send
    >> messages to other objects in the hierarchy. Messages to other objects
    >> can be sent safely from within awakeFromNib‹by which time it's assured
    >> that all the objects are unarchived and initialized (though not
    >> necessarily awakened, of course)."
    >>
    >> --
    >> I.S.
    >
    > ---
    > www.greenwaysroad.com
  • Am 05.10.2007 um 18:58 schrieb Chris Williams:
    > - You get a reference to the NSTableView by declaring a variable as
    > such:
    >
    > (IBOutlet) NSTableView *myTable;
    >
    > and connecting it in the Interface Builder.  It isn't unreasonable to
    > declare this as an Extern even, and reference it from several code
    > modules.

      Are you sure this will compile? I never heard about being able to
    use "extern" with an outlet, and the brackets shouldn't work either.
    IBOutlet is only a marker that you put next to *instance* variables
    of objects (i.e. instances), so that when you drag the header onto
    one of Interface Builder's NIB windows to have it parsed, it'll know
    that this instance variable is supposed to be an outlet and that you
    want to be able to hook up another object in the NIB to it.

      So yes, IBOutlet is what Hrishikesh will want to use here. But
    extern and regular variables don't enter the picture here. ALso, an
    extern isn't really a good design anyway. Use an accessor method on
    the object here.

    Cheers,
    -- M. Uli Kusterer
    http://www.zathras.de
  • Excuse me, in the interest of brevity I trimmed.

    In the class definition:
        (IBOutlet) NSTableView *theTable;
    And connect in IB

    In various implementation module(s):
        extern NSTableView *mainTable;

    In the main implementation:
    - (void)awakeFromNib {
        mainTable = theTable;
    }

    As to the religious debate over externs... I'll leave that to zealots.  If
    you have two classes with no connection other than the fact that they reside
    in the same NIB, externs like this are an easy way (but admittedly not the
    only way) to connect them.

    From: Uli Kusterer <witness.of.teachtext...>
    Subject: Re: NSTableView questions

      Are you sure this will compile? I never heard about being able to
    use "extern" with an outlet, and the brackets shouldn't work either.
    IBOutlet is only a marker that you put next to *instance* variables
    of objects (i.e. instances), so that when you drag the header onto
    one of Interface Builder's NIB windows to have it parsed, it'll know
    that this instance variable is supposed to be an outlet and that you
    want to be able to hook up another object in the NIB to it.

      So yes, IBOutlet is what Hrishikesh will want to use here. But
    extern and regular variables don't enter the picture here. ALso, an
    extern isn't really a good design anyway. Use an accessor method on
    the object here.
  • I added a public member to my dataSrc class (edited the .h file)

    IBOutlet NSTablView *myTable;

    But I don't see that outlet when I open the .nib file.

    Is adding the outlet using Interface builder the only option? Then I
    would have to re-instantiate the c\object, redo all connections, and
    generate source files again. Is there an easier way?
    Thanks
    Hrishi

    On 06-Oct-07, at 6:00 PM, Uli Kusterer wrote:

    > Am 05.10.2007 um 18:58 schrieb Chris Williams:
    >> - You get a reference to the NSTableView by declaring a variable
    >> as such:
    >>
    >> (IBOutlet) NSTableView *myTable;
    >>
    >> and connecting it in the Interface Builder.  It isn't unreasonable to
    >> declare this as an Extern even, and reference it from several code
    >> modules.
    >
    > Are you sure this will compile? I never heard about being able to
    > use "extern" with an outlet, and the brackets shouldn't work
    > either. IBOutlet is only a marker that you put next to *instance*
    > variables of objects (i.e. instances), so that when you drag the
    > header onto one of Interface Builder's NIB windows to have it
    > parsed, it'll know that this instance variable is supposed to be an
    > outlet and that you want to be able to hook up another object in
    > the NIB to it.
    >
    > So yes, IBOutlet is what Hrishikesh will want to use here. But
    > extern and regular variables don't enter the picture here. ALso, an
    > extern isn't really a good design anyway. Use an accessor method on
    > the object here.
    >
    > Cheers,
    > -- M. Uli Kusterer
    > http://www.zathras.de
    >
    >
    >

    ---
    www.greenwaysroad.com
  • Drag the .h file into the Interface Builder.  It will be there.

    From: Hrishikesh Muruk <hrishim...>
    Subject: Re: NSTableView questions

    I added a public member to my dataSrc class (edited the .h file)

    IBOutlet NSTablView *myTable;

    But I don't see that outlet when I open the .nib file. 

    Is adding the outlet using Interface builder the only option? Then I would
    have to re-instantiate the c\object, redo all connections, and generate
    source files again. Is there an easier way?
    Thanks
    Hrishi
  • --As of October 7, 2007 10:54:01 PM +0530, Hrishikesh Muruk is alleged to
    have said:

    > I added a public member to my dataSrc class (edited the .h file)
    >
    > IBOutlet NSTablView *myTable;
    >
    > But I don't see that outlet when I open the .nib file.
    >
    > Is adding the outlet using Interface builder the only option? Then I
    > would have to re-instantiate the c\object, redo all connections, and
    > generate source files again. Is there an easier way?

    --As for the rest, it is mine.

    Reload the .h file.  IB doesn't automatically know that it needs to re-read
    it.

    Daniel T. Staal

    ---------------------------------------------------------------
    This email copyright the author.  Unless otherwise noted, you
    are expressly allowed to retransmit, quote, or otherwise use
    the contents for non-commercial purposes.  This copyright will
    expire 5 years after the author's death, or in 30 years,
    whichever is longer, unless such a period is in excess of
    local copyright law.
    ---------------------------------------------------------------
  • Am 07.10.2007 um 19:28 schrieb Chris Williams:
    > Drag the .h file into the Interface Builder.  It will be there.

      Or if you prefer, use the "Parse header file" menu item. Both will
    make IB read your header and add any outlets automatically.

    Cheers,
    -- M. Uli Kusterer
    http://www.zathras.de
  • On Oct 5, 2007, at 12:58 PM, Chris Williams wrote:

    > - yes, applicationDidFinishLaunching is the appropriate place to do
    > initialization many times because you can't predict when things
    > will get
    > pulled from the nib, and you, many times, need everything out of
    > the nib to
    > get the job done.  So awakeFromNib doesn't cut it.  You have to
    > wait until
    > later.

    I'm not sure the docs agree with you, they say

    > Messages to other objects can be sent safely from within
    > awakeFromNib—by which time it’s assured that all the objects are
    > unarchived and initialized (though not necessarily awakened, of
    > course).
  • This is true, that's what the doc says.  But, since you cannot predict the
    order in which "awakeFromNib" will be called among the various objects, you
    therefore cannot predict the state of all the objects.

    For example, if ObjA needs to do some stuff before it's ready to be called,
    and it does that stuff in its "awakeFromNib", having ObjB call it in its own
    "awakeFromNib" is dangerous.  It gets really ugly when ObjB itself needs to
    do some things in "awakeFromNib" before it can be safely called.

    You need a predictable and reliable call order to solve these initialization
    "race conditions".  And you don't have that predictable call order in
    "awakeFromNib" (see the parenthetical statement you quoted below).

    The only really good solution is to wait until even later -- in
    "applicationDidFinishLaunching".

    On 10/8/07 6:30 AM, "Paul Bruneau" <paul_bruneau...> wrote:

    > I'm not sure the docs agree with you, they say
    >
    >> Messages to other objects can be sent safely from within
    >> awakeFromNib‹by which time it¹s assured that all the objects are
    >> unarchived and initialized (though not necessarily awakened, of
    >> course).
  • On Oct 8, 2007, at 9:29 AM, Chris Williams wrote:
    > The only really good solution is to wait until even later -- in
    > "applicationDidFinishLaunching".

    (Sorry, missed the originally poster's question)

    Which works great for application launching.  You can also -
    performSelector:afterDelay: with a delay of 0.0 in -
    applicationDidFinishLaunching: to cause initialization to happen at
    the top of the first pass through the event loop.

    For any other nib, there are two situations:

    NSDocuments:  Provides methods that can be used to initialize a
    document as its nib(s) is(are) loaded.

    Everything else:  You wrote code to load the nib;  add your
    customization code immediately after the nib loading.

    Off the top of my head, I can't think of anything else that loads NIBs
    automatically that doesn't have a convenient spot for initialization.

    b.bum
  • ahh I see it now, thanks Chris.

    On Oct 8, 2007, at 10:29 AM, Chris Williams wrote:

    > This is true, that's what the doc says.  But, since you cannot
    > predict the
    > order in which "awakeFromNib" will be called among the various
    > objects, you
    > therefore cannot predict the state of all the objects.
    >
    > For example, if ObjA needs to do some stuff before it's ready to be
    > called,
    > and it does that stuff in its "awakeFromNib", having ObjB call it
    > in its own
    > "awakeFromNib" is dangerous.  It gets really ugly when ObjB itself
    > needs to
    > do some things in "awakeFromNib" before it can be safely called.
    >
    > You need a predictable and reliable call order to solve these
    > initialization
    > "race conditions".  And you don't have that predictable call order in
    > "awakeFromNib" (see the parenthetical statement you quoted below).
    >
    > The only really good solution is to wait until even later -- in
    > "applicationDidFinishLaunching".
    >
    > On 10/8/07 6:30 AM, "Paul Bruneau" <paul_bruneau...>
    > wrote:
    >
    >> I'm not sure the docs agree with you, they say
    >>
    >>> Messages to other objects can be sent safely from within
    >>> awakeFromNib—by which time it’s assured that all the objects are
    >>> unarchived and initialized (though not necessarily awakened, of
    >>> course).
    >
previous month september 2007 next month
MTWTFSS
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
Go to today