Re: get a window in front by clicking on a menu item
Re: get a window in front by clicking on a menu item
- Subject: Re: get a window in front by clicking on a menu item
- From: Graham Cox <email@hidden>
- Date: Sat, 6 Jun 2009 11:58:38 +1000
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 (email@hidden)
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:
This email sent to email@hidden