Thread View: comp.sys.next.programmer
6 messages
6 total messages
Started by Tim McClarren
Wed, 30 Sep 1992 03:30
NXBrowser problem...
Author: Tim McClarren
Date: Wed, 30 Sep 1992 03:30
Date: Wed, 30 Sep 1992 03:30
17 lines
1150 bytes
1150 bytes
I am experiencing a problem with the NXBrowser class under 3.0. In effect, the manual page says to use the method "setCellClass:" to set the class of the cells that the Browser is to create inside the new columns it makes. I then use the "addRow" method of class Matrix and it seems that the new cells are in fact NOT of the class I had specified. I am subclassing NXBrowserCell, so that isn't the problem I don't think. How do I get NXBrowser to behave properly without going around it's back and setting the cell prototype in the Matrix like the documentation specifically warns against doing? Tim -- Tim McClarren | "...a bajillion brilliant Jobsian lithium licks." timm@ncsa.uiuc.edu| (217)244-0015 |
Re: NXBrowser problem...
Author: Brian Willoughby
Date: Mon, 05 Oct 1992 01:15
Date: Mon, 05 Oct 1992 01:15
43 lines
2587 bytes
2587 bytes
Tim McClarren writes
| I am experiencing a problem with the NXBrowser class under
| 3.0. In effect, the manual page says to use the method "setCellClass:" to
| set the class of the cells that the Browser is to create inside the
| new columns it makes. I then use the "addRow" method of class Matrix
| and it seems that the new cells are in fact NOT of the class I had
| specified. I am subclassing NXBrowserCell, so that isn't the problem
| I don't think. How do I get NXBrowser to behave properly without going
| around it's back and setting the cell prototype in the Matrix like the
| documentation specifically warns against doing?
I posted the answer to this on Sep 14, but it was perhaps obscured among some
other answers - here is a short recap:
After MUCH experimentation under 2.1, I found that -appDidInit: and
-setBrowserOutlet: were not reliable places to make the -setCellClass: call. I
subclassed NXBrowser and included the following class method:
+ initialize
{
[super initialize];
[NXBrowserSub setCellClass:[NXBrowserTextFieldCell class]]; // bogus?
[self setCellClass:[NXBrowserTextFieldCell class]];
return self;
}
This code looks redundant, but that is because I never went back to look at it
until today. I guess the old adage: "don't fix it if it ain't broke" applies
here. I would assume that either line would suffice, but I haven't tested
anything but what appears above.
#mount _soap_box
This is a prime example of how NeXTanswers is nearly useless. appkit.827 says
to -setCellClass inside -initFrame:, appkit.816 says to -setCellClass in
-appDidInit:, appkit.761 says that you must -setCellClass in +initialize
because -init is too late, implying that -appDidInit would be far too late. It
took a great deal of experimentation and searching to figure out what worked.
Of course the simpler approaches didn't work and they were what I tried first.
#dismount _soap_box
--
Brian Willoughby Software Design Engineer, BSEE NCSU
BrianW@SoundS.WA.com Sound Signal Processing Software and Consulting
NeXTmail welcome - NO EMAIL SOLICITATION without prior permission
Re: NXBrowser problem...
Author: Tim McClarren
Date: Mon, 05 Oct 1992 17:28
Date: Mon, 05 Oct 1992 17:28
32 lines
1692 bytes
1692 bytes
BrianW@SoundS.WA.com (Brian Willoughby) writes:
>I posted the answer to this on Sep 14, but it was perhaps obscured among some
>other answers - here is a short recap:
>After MUCH experimentation under 2.1, I found that -appDidInit: and
>-setBrowserOutlet: were not reliable places to make the -setCellClass: call. I
>subclassed NXBrowser and included the following class method:
>+ initialize
>{
> [super initialize];
> [NXBrowserSub setCellClass:[NXBrowserTextFieldCell class]]; // bogus?
> [self setCellClass:[NXBrowserTextFieldCell class]];
> return self;
>}
>This code looks redundant, but that is because I never went back to look at it
>until today. I guess the old adage: "don't fix it if it ain't broke" applies
>here. I would assume that either line would suffice, but I haven't tested
>anything but what appears above.
Well, it is with deep regret that I inform you that I wasn't able to
get the above to work under 3.0. It seems to work okay if I do the
setCellClass in initFrame of the NXBrowser. Are you still using the
above code under 3.0?
Tim
--
Tim McClarren | "...a bajillion brilliant Jobsian lithium licks."
timm@ncsa.uiuc.edu|
(217)244-0015 |
Re: NXBrowser problem...
Author: Sharon Zakhour
Date: Wed, 07 Oct 1992 00:17
Date: Wed, 07 Oct 1992 00:17
97 lines
5094 bytes
5094 bytes
Tim McClarren writes
| I am experiencing a problem with the NXBrowser class under
| 3.0. In effect, the manual page says to use the method "setCellClass:" to
| set the class of the cells that the Browser is to create inside the
| new columns it makes. I then use the "addRow" method of class Matrix
| and it seems that the new cells are in fact NOT of the class I had
| specified. I am subclassing NXBrowserCell, so that isn't the problem
| I don't think. How do I get NXBrowser to behave properly without going
| around it's back and setting the cell prototype in the Matrix like the
| documentation specifically warns against doing?
First of all, it's important to note that there are two setCellClass mechanisms
in the AppKit's control classes. The Control class itself offers a
+setCellClass: factory method. This method must be called before any Cell
instances are created -- typically in the +initialize method as described in
NeXTanswer appkit.761.
However, NXBrowser is a special beast and offers an instance method of
-setCellClass:. The 3.0 documentation specifically states that you should use
the instance -setCellClass: method for NXBrowser and NOT the factory method
inherited from Control. [See the -setCellClass: method description in the
NXBrowser spec sheet.] The obvious advantage to this implementation is that
you can change the cell class for a specific instance of NXBrowser without
changing it for ALL browsers.
You need to call -setCellClass: before loadColumnZero is called. If you create
an NXBrowser instance programmatically -initFrame: would be a good place.
However, when you are trying to change the cell class for an NXBrowser that was
instantiated in a nib file -initFrame: will not get called (and therefore the
cell class will not get set). In this case, you might want to do it in an
outlet initialization. If you wait to make the call until AFTER the
loadNibSection, then you will need to reload column zero. (Between the outlet
initialization call and the completion of the loadNibSection, the first column
has already been loaded with the default prototype Cell.) So if you set the
cell class in -appDidInit:, you would need to do this:
- appDidInit:sender
{
[browser setCellClass:[myCustomCell class]];
[browser loadColumnZero];
return self;
}
Whereas you wouldn't need the loadColumnZero in the outlet initialization:
- setMyBrowser:anOutlet
{
myBrowser = anOutlet;
[myBrowser setCellClass: [myCustomCell class]];
return self;
}
So, based on Tim's symptoms above, it looks like he might be trying to set the
cell class either:
- inside of -initFrame: or
- after -loadNibSection: and is not re-loading the first column
Brian Willoughby writes:
| After MUCH experimentation under 2.1, I found that -appDidInit: and
| -setBrowserOutlet: were not reliable places to make the -setCellClass:
| call. I subclassed NXBrowser and included the following class method:
| #mount _soap_box
| This is a prime example of how NeXTanswers is nearly useless. appkit.827
| says to -setCellClass inside -initFrame:, appkit.816 says to -setCellClass
| in -appDidInit:, appkit.761 says that you must -setCellClass in +initialize
| because -init is too late, implying that -appDidInit would be far too late.
| It took a great deal of experimentation and searching to figure out what
| worked. Of course the simpler approaches didn't work and they were what I
| tried first.
| #dismount _soap_box
I'm sorry to hear that you find NeXTanswers "nearly useless". We write these
in our spare time and it's disappointing to hear that they are not being well
received. We try to police them for accuracy and content but sometimes errors
do creep in. We are interested in keeping them as accurate and up to date as
possible and we hope that when you find errors or inconsistencies that you will
send them to nextanswers@next.com. Help us to help the community.
The information I gave above for the 3.0 case is also true in the 2.x case
although there were a couple of bugs that complicated matters. For example,
under 2.x no matter WHERE you called -setCellClass: for NXBrowser, you always
needed to call loadColumnZero (unless you didn't care if the first column used
the default cell). Also, this approach didn't work at all if you set
reuseColumns:YES on the browser -- this would crash the application. These
bugs have all been cleaned up for 3.0.
Sharon Zakhour
Developer Support
P.S. I do plan to update appkit.761 to include more of this information. It is
accurate but could stand some fleshing out.
Re: NXBrowser problem...
Author: Sharon Zakhour
Date: Wed, 07 Oct 1992 00:23
Date: Wed, 07 Oct 1992 00:23
48 lines
2227 bytes
2227 bytes
I wanted to also post some information which explains more fully some of the
nuances of the factory +setCellClass: method...
First of all, it's important to note that there are two setCellClass mechanisms
in the AppKit's control classes. The Control class itself offers a
+setCellClass: factory method. This method must be called before any Cell
instances are created -- typically in the +initialize method as described in
NeXTanswer appkit.761.
The disadvantage of setting the cell class using the factory method
+setCellClass, is that it will change the cell for EVERY instance of that class
-- including subclasses. For example, if you subclass Button and add a
+initialize method to look like:
+initialize
{
[super initialize];
[MyButton setCellClass: [MyButtonCell class]];
return self;
}
@end
Then not only will all instances of MyButton have MyButtonCell as a cell class,
but so will all instances of Button! This is probably non-desirable behavior
for most applications, so for this case we recommend using this approach:
- initFrame:(const NXRect *)frameRect
{
id newTextField;
[[self class] setCellClass: [TurboTFCell class]];
newTextField = [super initFrame:frameRect];
[[self class] setCellClass: [TextFieldCell class]];
return newTextField;
}
Note that this code is excerpted from the 2.0/3.0 MiniExample TextORama
[TurboTextField.m] and the README explains why it is implemented this way [in
change history -- 4/27/92]. Basically the cell prototype is created inside of
the call to [super initFrame:frameRect] so we are still setting the class PRIOR
to the creation of the cell.
See my other followup to this thread for more information in the instance
method of setCellClass available only to NXBrowser and it's subclasses.
Sharon Zakhour
Developer Support
Re: NXBrowser problem...<long>
Author: Tim McClarren
Date: Wed, 07 Oct 1992 16:55
Date: Wed, 07 Oct 1992 16:55
97 lines
5108 bytes
5108 bytes
szakhour@next.com (Sharon Zakhour) writes:
<let's see, what do I rip out and what do I leave in>
>Tim McClarren writes
>| I am experiencing a problem with the NXBrowser class under
>| 3.0. In effect, the manual page says to use the method "setCellClass:" to
>| set the class of the cells that the Browser is to create inside the
>| new columns it makes. I then use the "addRow" method of class Matrix
>| and it seems that the new cells are in fact NOT of the class I had
>| specified. I am subclassing NXBrowserCell, so that isn't the problem
>| I don't think. How do I get NXBrowser to behave properly without going
>| around it's back and setting the cell prototype in the Matrix like the
>| documentation specifically warns against doing?
>First of all, it's important to note that there are two setCellClass mechanisms
>in the AppKit's control classes. The Control class itself offers a
>+setCellClass: factory method. This method must be called before any Cell
>instances are created -- typically in the +initialize method as described in
>NeXTanswer appkit.761.
Okay...I can't beleive this is going around yet again. Anyways, I got
mail after posting the original problem from Rick Maurer and Scott Hess,
both of which identified the problem I was experiencing properly and
offered me a solution which did work, albeit cumbersome. It involved
using "loadColumnZero" and having either your outlet-setting routine do it
or doing it in appDidInit, although the latter involves also adding a kludge
Boolean so that you don't actually load any cells in the "load" routine
the first time through. According to Rick the Boolean wasn't necessary
under 2.1 because "loadColumnZero" wasn't called until he had already
set the cell prototype.
The Control's +setCellClass method wasn't part of the problem and I was in fact
calling the right routine.
>You need to call -setCellClass: before loadColumnZero is called. If you create
>an NXBrowser instance programmatically -initFrame: would be a good place.
>However, when you are trying to change the cell class for an NXBrowser that was
>instantiated in a nib file -initFrame: will not get called (and therefore the
>cell class will not get set). In this case, you might want to do it in an
>outlet initialization. If you wait to make the call until AFTER the
>loadNibSection, then you will need to reload column zero. (Between the outlet
>initialization call and the completion of the loadNibSection, the first column
>has already been loaded with the default prototype Cell.) So if you set the
>cell class in -appDidInit:, you would need to do this:
>- appDidInit:sender
>{
> [browser setCellClass:[myCustomCell class]];
> [browser loadColumnZero];
> return self;
>}
>Whereas you wouldn't need the loadColumnZero in the outlet initialization:
>- setMyBrowser:anOutlet
>{
> myBrowser = anOutlet;
> [myBrowser setCellClass: [myCustomCell class]];
> return self;
>}
These are in fact the two "fixes" that Rick and Scott suggested, except
Scott's code snippet did in fact have a "loadColumnZero" call in it
and he was using the outlet init as his place to set the browser.
He didn't say whether it was 2.1 or 3.0 though.
But guess what? I'm instantiating a subclass of NXBrowser from a .nib
file and have initFrame overriden and that works fine! I was not
successful in doing it inside -init or inside +initialize, and it's now
pretty obvious that +initialize was bad place to try anyways.
I suspect that the only reason I'm getting "initFrame" is because I'm
a Custom View object, but it seems to work fine and doesn't involve
an additional call to "loadColumnZero" which seemed a major kludge to
me, so I'm going to stick with it for now...here's a stack crawl:
#0 -[HDFObjectBrowser initFrame:] (self=0x1db6e8, _cmd=0x618694b,
frameRect=0x1da418) at HDFObjectBrowser.m:11
#1 0x6049af0 in -[CustomView nibInstantiate] ()
#2 0x6029c3a in -[IBObjectData nibInstantiateIn:owner:] ()
#3 0x6026bf2 in loadObjectData ()
#4 0x602643a in -[Application loadNibFile:owner:withNames:fromZone:] ()
#5 0x6040092 in -[Application _loadNibSegment:section:owner:withNames:
fromShlib:fromHeader:fromZone:] ()
#6 0x605d8ac in -[Application loadNibSection:owner:withNames:fromZone:] ()
#7 0x473e in -[HDFDoc initFromFile:] (self=0x17b194, _cmd=0x6187a03,
file=0x3ffed76 "/LocalLibrary/hdf/coil.hdf") at HDFDoc.m:46
Any comments?
--
Tim McClarren | "...a bajillion brilliant Jobsian lithium licks."
timm@ncsa.uiuc.edu|
(217)244-0015 |
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads