PDA

View Full Version : Trying to figure out Cocoa Multiple Windows... Help with Simple Problem




Soulstorm
Jun 30, 2006, 08:10 AM
I have a really hard time to make it happen.

I have a program that when a menu item will be pressed (it will be defined by me) a new window will appear with some options in it. And I don't know how to do it.

I have my application created in a Cocoa Application Xcode project. Apple's examples and documentation don't seem to work.

My program consists of a single window so far, which only contains some buttons and a tableView (not of importance).

To add a new window, I make a new window in the .nib file. I then make a subclass of NSWindowController, and I instantiate it. But after that, what do I do? I have made some experiments, but I can't seem to make it happen. Can anyone guide me to the solution of this? I know it's in front of my eyes, but I can't do it... :)

EDIT: Can anyone also tell me how can I pass a string value that the user gives on an NSTextField into the second window to a function that is a part of a class of the first window?



robbieduncan
Jun 30, 2006, 09:03 AM
Create a new nib file using the "Window" template. In XCode create a new file which is an NSWindowController subclass. Drag the .h file for this onto IB. Don't instanciate it! Double click on the File owner and set the Custom class to your new window controller subclass.

Ensure that the window outlet is connected.

In XCode you can now show you window via

MyWindowController *winC = [[MyWindowController alloc] initWithWindowNibName:@"MyWindowNib@]; // note without .nib
[winC showWindow:self];

Remember to release winC when you are done.

Obviously once this is working you can add other outlets, controls etc.

Note types straight into the web page: untested!

Soulstorm
Jun 30, 2006, 09:26 AM
Hm... I did that without having to create a different nib file.

Only that now I have another problem. The program that I am attaching, is a bank Account program that will handle multiple bank accounts. the problem is that I don't know exactly how am I going to implement the search function.

This is what I have done so far. I have managed to display the second window (which will show an NSTextField and by pressing a button it will search the array. My problem exactly is how can I pass the NSString contents from one window's window Controller, to another class' function inside my nib file.

The program is really simple, can anyone have a look at it?

caveman_uk
Jun 30, 2006, 09:44 AM
Hm... I did that without having to create a different nib file.

You don't have to create a separate nib file (in that case you don't have to load it either). You can shove everything in one nib file if you want but it makes the app quicker to launch if you break stuff up.

This is what I have done so far. I have managed to display the second window (which will show an NSTextField and by pressing a button it will search the array. My problem exactly is how can I pass the NSString contents from one window's window Controller, to another class' function inside my nib file.

Either set one as a delegate of the either and call a method from one to the other. Or use a notification. For classes that aren't really intimately related I think notifications are probably best.

robbieduncan
Jun 30, 2006, 10:23 AM
You don't have to create a separate nib file (in that case you don't have to load it either). You can shove everything in one nib file if you want but it makes the app quicker to launch if you break stuff up.

Either set one as a delegate of the either and call a method from one to the other. Or use a notification. For classes that aren't really intimately related I think notifications are probably best.

Or use a controller that has access to both of the other objects and bind the values to each other :D

Soulstorm
Jun 30, 2006, 11:48 AM
Hm... I should be more specific:
Here is an image from the nib file of my application.
http://img121.imageshack.us/img121/3159/picture10tc.jpg
The MyDataSource is meant to handle the class for the tableView in the image.

The MyWindowController class handles the second window (the little one). In the second window, I have connected the one and only button to an IBAction that exists in the MyDataSource class. In this function, I want to receive the text from the little window, and then do stuff with it.

But I don't know how to do it! The point is that I do not know how am I supposed to pass a reference of the class that handles the little Find window, so that I can extract the NSTextField's contents.

It is very simple, yet I cannot find how to do that anywhere....

You can view the full program here (http://att.macrumors.com/attachment.php?attachmentid=51682&d=1151677567)... (it is very small).

caveman_uk
Jun 30, 2006, 01:06 PM
Try the attached file which does it through notifications.

Note you need to register for a particular notification in the receiving object giving the selector of the method that should be called when that notification is received (I've added that code to MyDataSource's init method) and deregister when you don't want to get them any more (hence the new dealloc method). The actual posting is done by a new method in MyWindowController thats just the target of the button in the nib. The new method in MyDataSource then pulls the sent string out from the notification. (Strictly speaking the 'object' that's usually sent is the sending object (i.e self in the sending object). In that case you could use KVC to pull the value out but I've cheated and sent the actual search string as the object).

BTW, the extra release in the dealloc method of MyDataSource fixes a memory leak.

BTW2, you don't need that #ifndef ACCOUNT_H stuff. #import will only import files once. This isn't c++ you know ;-)

Soulstorm
Jul 1, 2006, 02:08 AM
Thanks alot for the answers, all of you (especially you, caveman), the problem has been rectified. Caveman, thanks a lot for your solution, you offered me an understanding on how notifications work (I hadn't figured that out at the start).

But there is another way to do it, by just connecting the MyDataSource to the second window's "Find" button, which in turn, when pressed, will trigger an action in the MyDataSource. I found that way simpler, but it seems that Notifications are a more elegant way to do it.

Thanks a lot!


EDIT: I read somewhere that the '#import' function is deprecated, and programmers are advised not to use it. But since Apple uses it everywhere, I imagine it won't be abandoned that easily...

caveman_uk
Jul 1, 2006, 03:51 AM
But there is another way to do it, by just connecting the MyDataSource to the second window's "Find" button, which in turn, when pressed, will trigger an action in the MyDataSource.

That works but it's a little inelegant and breaks the idea of one controller object handling the logic for each window. You're cross linking objects and starting to make spaghetti code.

Soulstorm
Jul 1, 2006, 10:38 AM
That works but it's a little inelegant and breaks the idea of one controller object handling the logic for each window. You're cross linking objects and starting to make spaghetti code.
I thought so... That's why I used your way at the end.