Welcome to the MacNN Forums.

If this is your first visit, be sure to check out the FAQ by clicking the link above. You may have to register before you can post: click the register link above to proceed. To start viewing messages, select the forum that you want to visit from the selection below.

You are here: MacNN Forums > Software - Troubleshooting and Discussion > Developer Center > Answer me for once and all!

Answer me for once and all!
Thread Tools
Admin Emeritus
Join Date: Oct 2000
Location: Boston, MA
Status: Offline
Reply With Quote
Jan 26, 2001, 07:38 PM
 
How do I capture keyDown events in Cocoa?
"Against stupidity, the gods themselves contend in vain" (Schiller)
     
Fresh-Faced Recruit
Join Date: Jan 2001
Location: San Jose, CA USA
Status: Offline
Reply With Quote
Jan 27, 2001, 12:24 PM
 
Can you be just a wee bit more precise? I can't figure out what exactly you want to do. Do you just want to receive key events in an NSView subclass?
     
Mac Elite
Join Date: Jan 2001
Location: New York
Status: Offline
Reply With Quote
Jan 27, 2001, 02:32 PM
 
You have to use a NSView and inside of it create a method that receives key Down events.
     
Admin Emeritus
Join Date: Oct 2000
Location: Boston, MA
Status: Offline
Reply With Quote
Jan 27, 2001, 05:13 PM
 
Is there any way to do it sans NSView? Like in Carbon, where you could determine what happens to events *directly*
"Against stupidity, the gods themselves contend in vain" (Schiller)
     
Dedicated MacNNer
Join Date: Jan 2001
Location: Virginia, US
Status: Offline
Reply With Quote
Jan 27, 2001, 08:11 PM
 
Technically, any NSResponder subclass can receive events. This includes NSView, NSWindow, and NSApplication (and I guess NSWindowController these days). When an event gets passed to a window, it starts with the "active" view (known as the firstResponder), then walks through the responder chain (superview to superview when dealing with NSView classes) looking for an object that implements the particular event method. For key events, this typically won't go much farther than the active new.

Note that command-key events are handled a bit differently -- look at the -performKeyEquivalent: method on NSView.

If you have a situation where you don't want there to be an "active" view, meaning the responder chain starts at the window itself, then call [theWindow makeFirstResponder:nil]. This may not be the best approach though, as it will end any active text editing sessions and such.

While most situations can be dealt with nicely by hooking into the above mechanisms, if you really need to handle an event differently you could override -sendEvent: in a subclass of NSWindow and handle your particular event there (calling the super implementation for all other events of course).

If even that is too late, you could similarly override NSApplication's -sendEvent: in a subclass. NSApplication's implementation just picks the appropriate window for the event and sends the event to that window.

Look in the NSEvent, NSResponder, NSView, and NSWindow class documentation for further info.
     
Admin Emeritus
Join Date: Oct 2000
Location: Boston, MA
Status: Offline
Reply With Quote
Jan 28, 2001, 11:17 AM
 
Thanks all. I've can handle NSWindow's event, I'll just try now to subclass NSApplication and override the sendEvent.
"Against stupidity, the gods themselves contend in vain" (Schiller)
     
Mac Elite
Join Date: Sep 2000
Location: Edmond, OK USA
Status: Offline
Reply With Quote
Feb 1, 2001, 04:49 PM
 
Does all Cocoa event-handling involve subclassing? Is there any way to use JDK 1.1 style event listeners to listen for events? E.G.,

public class myFrame extends Frame
{
public myFrame()
{
addWindowListener(new CloseListener());
addWindowListener(new EditListener());
}
}

The advantage to this approach is that you don't have to subclass components just to be notified or events, and you can bundle common functionality into little bits that you attach where you want them. I was under the impression that Carbon's Event interface was like this.
     
Dedicated MacNNer
Join Date: Jan 2001
Location: Virginia, US
Status: Offline
Reply With Quote
Feb 2, 2001, 03:28 PM
 
Originally posted by absmiths:
Does all Cocoa event-handling involve subclassing? Is there any way to use JDK 1.1 style event listeners to listen for events?
If you're talking about very low-level events like mouse clicks and key presses, then yes you need a subclass. However, 99% of the times you need to handle these events you'll already have an NSView subclass and you'll be handling them there. I was mainly pointing out that the low-level events can be intercepted higher up in the process if the situation really does call for it.

For higher-level "events" (most of the stuff that Java listeners are used for), there are a couple of major schemes that are used.

The first is notifications, which are fairly similar to Java listeners. Many Cocoa objects are written to post notifications when various interesting things happen, like NSWindowWillCloseNotification, NSApplicationWillUnhideNotification, etc. To receive these notifications, simply register an object as an observer with the NSNotificationCenter and specify the name of the method you want called when the notification occurs. You can register to observer one particular object, or for all notifications of a given name no matter which posts it posts it.

Notifications are a bit easier to implement than Java listeners -- the posting class doesn't have to implement the listener list logic and provide an extra Java interface describing the methods that are called, and the observer doesn't need to implement a bunch of extra listener methods if they're only interested in one of them. What's more, you can register for the same notification on two (or more) objects, and have each one of those call a separate method.


The other major scheme is delegation. Many classes allow you to set a delegate for an instance of that class. When you do this, there are several methods you can implement to alter the default behavior of that class. For example, if you set a delegate to an NSWindow instance, you can implement the -windowShouldClose: method -- this gives you a chance to prevent the closing of the window in delicate circumstances. -windowShouldZoom:toFrame: allows you to prevent window zooming, windowWillResize:toSize: allows you to alter the user's proposed new size in any way you like before the window actually resizes, etc.

You only need to implement the ones you are interested in; if the delegate doesn't implement a particular delegate method then the default behavior is used. As you say, this scheme allows you to control lots of behavior without having to subclass all that much. The controller object for a window will typically be the window delegate, and likely also the delegate/notification observer for some of the GUI widgets in the window. The main application controller is generally the delegate for the NSApplication instance.

     
   
Thread Tools
Forum Links
Forum Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On
Top
Privacy Policy
All times are GMT -5. The time now is 12:12 PM.
All contents of these forums © 1995-2011 MacNN. All rights reserved.
Branding + Design: www.gesamtbild.com
vBulletin v.3.8.7 © 2000-2011, Jelsoft Enterprises Ltd., Content Relevant URLs by vBSEO 3.3.2