7

I'm having some real difficulty with some initial Cocoa programming I am carrying out.

Essentially, I have an NSStatusBar item with an NSMenu attached as the menu. The menu has a single NMMenuItem. In IB I have connected the NSMenuItem to an NSObject which itself is set to the ApplicationDelegate's class; I have then set the Received Actions to an IBAction method in the ApplicationDelegate. Everything is hooked up correctly I think, except when I run the program and click the menu item the IBAction method is not called. I really can't seem to work it out. Here is the relevant code.

Application Delegate h file:

#import <Cocoa/Cocoa.h>

@interface sssAppDelegate : NSObject <NSApplicationDelegate> {
    IBOutlet NSMenu *statusMenu;
    NSStatusItem *statusItem;
}

- (IBAction)showPreferencePanel:(id)sender;

@end

Application Delegate m file:

#import "sssAppDelegate.h"
@implementation sssAppDelegate

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    // Insert code here to initialize your application 
}

-(void)awakeFromNib{
    statusItem = [[[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength] retain];
    [statusItem setMenu:statusMenu];
    [statusItem setTitle:@"Status"];
    [statusItem setHighlightMode:YES];
}


- (IBAction)showPreferencePanel:(id)sender {
    NSLog(@"Hello World!");
}

@end 

As I say, in IB I have connected the NSMenu to statusMenu in the Application Delegate (thus the menu all shows up under the NSStatusBar), and I have connected an NSMenuItem within the NSMenu to the NSObject with the Application Delegate class, and hooked it up to call showPreferencePanel, but nothing happens when I run it!!!

I tried it programatically as well but still can't get the IBAction method to be called.

Edit: I would attach some screen grabs to show the setup in IB but I'm not yet allowed.

The main nib which contains the menu that is added to the NSStatusBar, it looks like this:

  • FO NSApplication
  • FR FirstResponder
  • Application NSApplication
  • Font Manager NSFontManager
  • Main Menu NSMenu
    • Menu Item (Preferences) NSMenuItem
  • Sss App Delegate sssAppDelegate

NSMenuItem:

  • Sent Actions - showPreferencePanel--->Sss App Delegate

Sss App Delegate:

  • Outlets - statusMenu--->Main Menu
  • Received Actions - showPreferencePanel:--->Main Item (Preferences)
Edwardr
  • 2,906
  • 3
  • 27
  • 30
  • 1
    You mention that you created an object with the application delegate's class in the nib; is this nib the same one where you appointed the object as actually being the application delegate? If not, I'm wondering if you have created two application delegate objects by accident, which causes problems (not this one) because only one of them can really be the delegate at a time. – Peter Hosey Mar 06 '11 at 10:38
  • Have you tried logging the menu, its menu items, and the item in question's target and action? (Use `NSStringFromSelector` to convert the action selector to an NSString.) – Peter Hosey Mar 06 '11 at 10:41
  • Thanks for the comments, I've added some more to the question which will hopefully clarify things somewhat. – Edwardr Mar 06 '11 at 11:40
  • 1
    I've just made a sample project, set up as you described, and everything seems to work fine for me. The status bar item appears, it contains the entire main menu, and when I select AppName>Preferences, I get a message in the log. You should stick an `NSLog` call in `applicationDidFinishLaunching:` to make sure that this object really is the app's delegate. If so, the only suggestion I have is to make a sample project from scratch, containing just this functionality that you're having trouble with, to make sure that you don't miss anything and really truly do have everything hooked up properly. – jscs Mar 12 '11 at 05:43

1 Answers1

2

Programmatically, have you tried :

[statusItem setTarget:someTarget];
[statusItem setAction:@selector(someSelector)];

It should work.

Jean
  • 7,623
  • 6
  • 43
  • 58