Search code examples
javascriptmacoscocoaosx-yosemitejavascript-automation

Programmatically creating and populating a NSWindow using JXA


I've recently learned about the existence of JavaScript for Automation. More interesting to me is the ability to call into Objective-C APIs, subclass Objective-C classes in JavaScript, and the ability to pass objects of JavaScript-implemented subclasses back to Objective-C APIs who use the parent class as an interface definition.

The biggest problem I have is that I don't exactly know Objective-C, and I know this. That's part of the reason I'm using JXA for this (the main reason being I find the fact you can even do this all with JavaScript for Automation to be quite intriguing.)

I also don't know the Cocoa API, but am attempting to learn it via JXA.

So, how would I go about creating and populating a JavaScript window using JXA?

The code I have so far is:

ObjC.import('Cocoa');

var frame = $.NSMakeRect(100, 100, 200, 200);
var styleMask = $.NSMiniaturizableWindowMask |
                $.NSClosableWindowMask | 
                $.NSTitledWindowMask;

var rect = $.NSWindow.contentRectForFrameRect = frame;
rect.styleMask = styleMask;

var window = $.NSWindow.alloc.initWithContentRect = rect;
window.styleMask = styleMask;
window.setBackgroundColor = $.NSColor.blueColor;

There's almost no examples out there, aside from the snipplets Apple provides with the JXA documentation on the Objective-C bindings.

So can someone show me how to come up with a basic window, and maybe a label, textbox, and button, with JXA?


Solution

  • A nice tutorial can be found here

    ObjC.import("Cocoa");
    
    var styleMask = $.NSTitledWindowMask | $.NSClosableWindowMask | $.NSMiniaturizableWindowMask;
    var windowHeight = 85;
    var windowWidth = 600;
    var ctrlsHeight = 80;
    var minWidth = 400;
    var minHeight = 340;
    var window = $.NSWindow.alloc.initWithContentRectStyleMaskBackingDefer(
      $.NSMakeRect(0, 0, windowWidth, windowHeight),
      styleMask,
      $.NSBackingStoreBuffered,
      false
    );
    
    var textFieldLabel = $.NSTextField.alloc.initWithFrame($.NSMakeRect(25, (windowHeight - 40), 200, 24));
    textFieldLabel.stringValue = "Image: (jpg, png, or gif)";
    textFieldLabel.drawsBackground = false;
    textFieldLabel.editable = false;
    textFieldLabel.bezeled = false;
    textFieldLabel.selectable = true;
    
    var textField = $.NSTextField.alloc.initWithFrame($.NSMakeRect(25, (windowHeight - 60), 205, 24));
    textField.editable = false;
    
    var btn = $.NSButton.alloc.initWithFrame($.NSMakeRect(230, (windowHeight - 62), 150, 25));
    btn.title = "Choose an Image...";
    btn.bezelStyle = $.NSRoundedBezelStyle;
    btn.buttonType = $.NSMomentaryLightButton;
    
    window.contentView.addSubview(textFieldLabel);
    window.contentView.addSubview(textField);
    window.contentView.addSubview(btn);
    
    window.center;
    window.title = "Choose and Display Image";
    window.makeKeyAndOrderFront(window);