1

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?

Kirn Gill II
  • 90
  • 1
  • 6

1 Answers1

3

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);
Marek H
  • 5,173
  • 3
  • 31
  • 42
  • Thanks, this is perfect! – Kirn Gill II Sep 15 '15 at 18:06
  • Helpful, but deserves some supplemental information: the window will only appear when called from a JXA script _saved as a stay-open application_ in Script Editor. The window will have a a text field and a button, but you won't be able to interact with them. – mklement0 Oct 14 '15 at 04:06
  • Is there other way not to have Script Editor? Interaction - is it 10.10 or 10.11 you use? – Marek H Oct 14 '15 at 09:14
  • @MarekH: I tried on 10.11, but I would expect it work the same on 10.10. I don't think there's a way around using Script Editor, given that you need to create an _application_ that stays _open_ in order to receive events from the window. – mklement0 Oct 23 '15 at 12:26