[comp.sys.next] Help, please, on making connections in IB

mcdonald@fornax.UUCP (Ken Mcdonald) (04/18/91)

I'm having a few problems defining and sending action messages in
Interface Builder, and hope that some kind soul might be able to give
me some advice.

First, I'd like to use a subclass of the "TextField" class, which I call
"EntryField"; an EntryField object is defined to respond to one additional
action message (besides those defined by a standard text field), called
"update".  The idea is that the user enters data into this text field,
then presses a button to tell the application that the data in said
text field is what they want; the button sends an "update" message to the
EntryField object, which in turn sends an action message to the application
informing it of the presence of new data in the field.  This may be a bit
klugey, but that's OK--this is just a prototype.

The first problem is that I can't even create an object of class EntryField
in Interface Builder.  The class definition is no problem, but I can find
no way to specify that a normal TextField should actually be of type
EntryField, and when I try to Instantiate an EntryField object from the
Classes window, the Instantiate pulldown menu entry is disabled whenever
EntryField is the selected class.  So, having defined an EntryField class,
how do I create an object of this class in Interface Builder, so as to 
make connections to and from it?

My other question is very similar.  The application itself will be an
object of type "MyApp", which is a subclass of the Application class, with
some extra action messages and so forth.  Again, I can find no way to create
or refer to this object in Interface Builder; so there is no way, for
example, that I can tell my EntryField object that it should send a
"newData:" message to the application, in response to  the "update:" message
it just received.

This seems so simple that I'm sure I must be missing something.  Any advice
is most welcome, as without it, I can't even get started on this project.

Thanks in advance,
Ken McDonald
{mcdonald@cs.sfu.ca}
.

jjfeiler@nntp-server.caltech.edu (John Jay Feiler) (04/20/91)

This fouled me up for a few days, and may be of some interest to others, 
so I decided to post this...

mcdonald@fornax.UUCP (Ken Mcdonald) writes:

>I'm having a few problems defining and sending action messages in
>Interface Builder, and hope that some kind soul might be able to give
>me some advice.

>First, I'd like to use a subclass of the "TextField" class, which I call
>"EntryField"; an EntryField object is defined to respond to one additional
>action message (besides those defined by a standard text field), called
>"update".  The idea is that the user enters data into this text field,
>then presses a button to tell the application that the data in said
>text field is what they want; the button sends an "update" message to the
>EntryField object, which in turn sends an action message to the application
>informing it of the presence of new data in the field.  This may be a bit
>klugey, but that's OK--this is just a prototype.

>The first problem is that I can't even create an object of class EntryField
>in Interface Builder.  The class definition is no problem, but I can find
>no way to specify that a normal TextField should actually be of type
>EntryField, and when I try to Instantiate an EntryField object from the
>Classes window, the Instantiate pulldown menu entry is disabled whenever
>EntryField is the selected class.  So, having defined an EntryField class,
>how do I create an object of this class in Interface Builder, so as to 
>make connections to and from it?
You need to drag a customview object to the palette with all the buttons
onto your window, then tell IB that it is of class EntryField.  As far as
I've been able to tell, this is the easiest (and perhaps the only) way
to instantiate a subclass of View.  (it actually makes a lot of sense in
retrospect, but I couldn't figure this out for days....)


>My other question is very similar.  The application itself will be an
>object of type "MyApp", which is a subclass of the Application class, with
>some extra action messages and so forth.  Again, I can find no way to create
>or refer to this object in Interface Builder; so there is no way, for
>example, that I can tell my EntryField object that it should send a
>"newData:" message to the application, in response to  the "update:" message
>it just received.
After you've created the class description and parsed it, go to the instantiate
menu item on the popup list in the class inspector window.  This will create
and object in the window where the sound suitcase and stuff is, and it will be
called MyAppInstance.  Rename it if you wish, and you can now drag connections 
from the icon representing this instancce of the class to anything else in the
App.

>This seems so simple that I'm sure I must be missing something.  Any advice
>is most welcome, as without it, I can't even get started on this project.

>Thanks in advance,
>Ken McDonald
>{mcdonald@cs.sfu.ca}
>.

	John Feiler

liberte@ncsa.uiuc.edu (Daniel LaLiberte) (04/20/91)

In article <2524@fornax.UUCP> mcdonald@fornax.UUCP (Ken Mcdonald) writes:
>  The first problem is that I can't even create an object of class EntryField
>  in Interface Builder.  

You're right, you can't instantiate your subclass, unless it is a
subclass of Object.  I dont know why this restriction exists, but
there it is.  It would also be useful to set the class of any IB object
to a subclass of its default class, but you can't - not that I can see.

But there is one way to get an instance of a class that is not a subclass
of Object.  You can specify the class of the File Owner, which is normally
Application.  I dont know if it makes sense to say it is anything other
than a subclass of Application.  You might be able to do the same for
other objects in the .nib file.

Dan LaLiberte
National Center for Supercomputing Applications
liberte@ncsa.uiuc.edu

cnh5730@maraba.tamu.edu (04/20/91)

In article <LIBERTE.91Apr19145552@babbage.ncsa.uiuc.edu> liberte@ncsa.uiuc.edu (Daniel LaLiberte) writes:
   In article <2524@fornax.UUCP> mcdonald@fornax.UUCP (Ken Mcdonald) writes:
   >  The first problem is that I can't even create an object of 
   >  class EntryField
   >  in Interface Builder.  

   You're right, you can't instantiate your subclass, unless it is a
   subclass of Object.  I dont know why this restriction exists, but
   there it is.  

Here are the classes which I can determine that IB will allow you to
instantiate:
1) Object
2) UserCreatedSubclassesOf:Object
3) List:Object
4) HashTable:Object
5) Sound:Object
6) Storage:Object
7) NXStringTable:HashTable:Object

so clearly IB knows how to instantiate some of its (sub)classes but not others.

adonis1@nwnexus.WA.COM (Adonis Corporation ) (04/21/91)

In article <2524@fornax.UUCP> mcdonald@fornax.UUCP (Ken Mcdonald) writes:

[stuff deleted so I can mail this]

>First, I'd like to use a subclass of the "TextField" class, which I call
>"EntryField"; an EntryField object is defined to respond to one additional
>action message (besides those defined by a standard text field), called
[stuff deleted]
>"update".  The idea is that the user enters data into this text field,
>informing it of the presence of new data in the field.  This may be a bit
>klugey, but that's OK--this is just a prototype.

You could have the button send a message to the application telling it that
there is new data in the TextField.  Then you have no need to subclass
the TextField object.

>
>The first problem is that I can't even create an object of class EntryField
>in Interface Builder.  The class definition is no problem, but I can find
[stuff deleted]
>how do I create an object of this class in Interface Builder, so as to 
>make connections to and from it?

If you really want to subclass it you do it by dragging a CustomView
object from the IB pallete to where your TextField goes.  In the attributes
section of the Inspector (Command-1), select EntryField as the class
you wish you CustomView to have (press OK).  Do a File.TestInterface
to see what it'll look like when you run.

>
>My other question is very similar.  The application itself will be an
>object of type "MyApp", which is a subclass of the Application class, with
>some extra action messages and so forth.  Again, I can find no way to create
>or refer to this object in Interface Builder; so there is no way, for
>example, that I can tell my EntryField object that it should send a
>"newData:" message to the application, in response to  the "update:" message
>it just received.
>

You could try this: 

Click on File's Owner in your suitcase panel and do command-1.  Select
MyApp for its class (press OK).  Now you can create connections between 
the owner (subclass MyAPP) and your interface objects by dragging around
in IB.

in your appname_main.m file you might have to replace
	NXApp = [Application new];
with
	NXApp = [MyApp new];

(I think this'll get wiped out when you resave in IB)(?).

The above steps may not work.  I don't really understand the relation between
the File Owner (of class Application) and NXApp, also of class Application.
Anybody have a contribution to this?

Doug Kent
Independent NeXT Developer
adonis1@nwnexus.wa.com

martin@edison.seas.ucla.edu (Kenneth Martin) (04/23/91)

>   >  The first problem is that I can't even create an object of 
>   >  class EntryField
>   >  in Interface Builder.  
>
>   You're right, you can't instantiate your subclass, unless it is a
>   subclass of Object.  I dont know why this restriction exists, but
>   there it is.  
>
>Here are the classes which I can determine that IB will allow you to
>instantiate:
>1) Object
>2) UserCreatedSubclassesOf:Object
>3) List:Object
>4) HashTable:Object
>5) Sound:Object
>6) Storage:Object
>7) NXStringTable:HashTable:Object
>
>so clearly IB knows how to instantiate some of its (sub)classes but not others.

Somewhere in the Next documentation, it states that subclasses of View can't
be instantiated.  You might try the following in using subclasses of View in
IB.  (I hope I get all the steps right).

1) Prepare the subclass.m and subclass.h files (i.e. MyTextField.m and
MyTextField.h for this example)
2) Add them to the project using the project inspector
3) Double click the classes.h icon in the files window to get the classes
browser
4) In the classes browser click the superclass (for example TextField in
the directory under Control)
5) Using the 'Operations' pull-down menu in the classes browser, first
select subclass, then name the new subclass, (for example MyTextField)
and then using the pull-down menu again, parse the new class.
6) Prepare another subclass but this time of application.  It might be
called Coordinator.m and Coordinator.h.  In this class, define some objects
that will be your new View classes (eg. 'id mytextField' in Coordinator.h). 
Also include these files and tell the IB about them using the classes
browser to subclass, name, and parse them.  This class can and should be
instantiated.
7) Drag in a CustomView from the Palettes window.
8) Using the Inspector and the Attributes submenu, rename the CustomView
MyTextField.
9) Using the Inspector and the Miscellaneous submenu, rename the new view
the same name used for the defined objects in Coordinator.m (i.e. mytextField).
10) Any special initialization code should be put in the initFrame method
of your subclass or in the AppDidInit delegate method of Coordinator.m.
If you use the former, make sure you call [super initFrame] in thennew
initFrame method in MyTextField.m.  If you use the latter, then a connection
between File's Owner (in the files window) and Coordinator.m (with delegate
selected as the outlet) is necessary.
11) Drag a connection between Coordinator.m and the renamed MyTextField view
in the IB window (i.e. the view that used to be the CustomView).  Make sure
mytextField is selected as the outlet and then connect the View.

If I haven't forgotten anything this should be it.  I haven't tried this
for TextField's but have used it for ScrollViews and Text objects.
Good Luck.
-Ken Martin (martin@icsl.ucla.edu)