On 06/06/2009, at 2:03 AM, Martin Batholdy wrote:

I have a problem, getting a window in front by clicking a menu item;

In my xcode project I have a menuHandler, which has methods to create a menu, add items to that menu, delete items and so on.

Since you're new to Cocoa and to OO programming in general, it might be useful to take a step back from the immediate problem and talk about more useful ways of tackling things in general.

First, the above approach to managing menus is very rare and hardly ever done. Menus are not typically very dynamic, even in large apps. Instead, you lay out all of your menus in the MainMenu.xib file and let your program manage the *state* of them as the context changes. Even that is largely automatic for many common situations.

My AppController knows about the menuHandler and creates an instance of it in the awakeFromNib function. There it tells the menuHandler to create a menu and add items to that menu.

Or just lay out your menus in IB and let the standard default mechanism handle that. Win to you: much less code you have to write, debug and maintain.

One of that items has the title "open window x".
The method that generates this item in the menuHandler refers to the function "showWindow" inside itself
(setTarget:self).

I have created a window in the Interface Builder and have connected it with an IBOutlet NSWindow variable in the MenuHandler.

This is OK, except that typically objects that respond to menu commands are called controllers, and they are usually focused on what they control, not on what they "handle" or respond to. So what you have or appear to want here is a window controller (NSWindowController!). It's certainly fine to connect the action of a menu item directly to a controller if that makes sense and you are able to.

The controller could live in the MainMenu.xib file, in which case hooking up the action to the menu is no problem. This might be appropriate for a simple app with only one window, but typically the window + its controller and the menus would be in separate nibs. In that case you have to resort to a little bit of indirection to make your menu do what you want. To open the window, typically your menu command would target either a generic object such as the application delegate, or a central controller that does this job, or nil, allowing the command to propagate through the responder chain. When the command arrives at the object responsible, it loads the appropriate nib and invokes the controller methods that open the window.

But the problem is, that the menu item does not do what it should do (invoke the window).

I know that it gets called, when I click on the item "open window x".
But all calls to the window are just ignored without a message in the log (like [myWindow makeKeyAndOrderFront:self]; [myWindow orderBack:self]; etc.)


Can someone help me on this?

I have also tried several options for the window in the IB ... no improvement ...

Windows should generally be managed by window controllers (NSWindowController), which are often subclassed. For most ordinary cases, the controller will be the nib's "File's Owner", meaning that the app instantiates the controller when necessary, which loads the nib and becomes its owner. From then on you interact with the window via its controller.

One common error is to forget to connect the controller's 'window' outlet to the actual window. Also, turn OFF the window's "visible at launch" flag.

So, to sum up, the pathway that is *typically* followed to open a window from a menu command is:

"Open My Window" menu command, target = nil, action -openMyWindow: --> responder chain --> [application delegate openMyWindow:] --> instantiate MyWindowController (NSWindowController) --> loads "MyWindow.nib", owner = self --> then calls [MyWindowController showWindow:]

In code, this is simply:

- (void)        openMyWindow:(id) sender
{
    if( myWindowController == nil )
myWindowController = [[NSWindowController alloc] initWithWindowNibName:@"MyWindow"];

    [myWindowController showWindow:sender];
}

which is a method of the application delegate object (which is automatically able to respond to actions sent up the responder chain). Everything else is set up in IB, both the menu and the window. The controller is instantiated the first time it is used, and stored in an instance variable. On subsequent invocations of "Open My Window", the message is simply forwarded to the existing controller.

Note that because an object in the responder chain is able to respond to the action "-openMyWindow:", your menu item will be automatically enabled with no further work required on your part.

The nib "MyWindow.nib" is set up so that the class of File's Owner is set to NSWindowController (or a subclass of it) and the window outlet is connected to the window.

--Graham






_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to