Unable to make text field first responder

Hi there,

I have just started learning AppleScriptObjC and try to figure out how things are working. I went through most examples in Everyday AppleScriptObjC and AppleScriptObjC Explorer 5 but I have a hard time getting the following script to work.

I created a new project with two text fields and a button. The send action for leaving text field 1 is to call checkTextField1. If textfield1 is empty then I would like to place the cursor back into textfield1 so that the user can enter the value without clicking the field first.


script AppDelegate
	property parent : class "NSObject"
	
	-- IBOutlets
	property theWindow : missing value
    property textfield1 : ""
    property textfield2 : ""
	
    on checkTextField1:sender
        log "check textfield1"
        if textfield1 is equal to "" then
            log "textfield1 is empty"
            theWindow's makeFirstResponder_(textfield1)
        end if
    end checkTextField1
    
    on buttonPressed:sender
        log "button pressed"
        theWindow's makeFirstResponder:(missing value)
    end buttonPressed

    on applicationWillFinishLaunching:aNotification
        -- Insert code here to initialize your application before any files are opened
    end applicationWillFinishLaunching:
	
    on applicationShouldTerminate:sender
        -- Insert code here to do any housekeeping before your application quits
        return current application's NSTerminateNow
    end applicationShouldTerminate:
	
end script

When I run the script and press the tab key to get out of textfield1 I get the following error

2015-06-16 14:22:21.827 test3[71829:7123609] check textfield1
2015-06-16 14:22:21.827 test3[71829:7123609] textfield1 is empty
2015-06-16 14:22:21.827 test3[71829:7123609] -[__NSCFConstantString becomeFirstResponder]: unrecognized selector sent to instance 0x7fff78bf56e0
2015-06-16 14:22:21.830 test3[71829:7123609] *** -[AppDelegate checkTextField1:]: -[__NSCFConstantString becomeFirstResponder]: unrecognized selector sent to instance 0x7fff78bf56e0 (error -10000)

Pressing the button correctly focuses on the theWindow without any error. I just can’t get it to focus on a specific field.

Any hint on what I’m doing wrong would be appreciated.

Thanks,
Dirk

Hi,

you’re mixing up the textfield object and the string value of the textfield.
The error message reveals that you’re sending the makeFirstResponder message to a string instead of to an NSTextField instance.

Assign missing value to both textField1 and 2 properties
Connect the outlets in interface builder.

Then check


if textfield1's stringValue() as text is equal to "" then

Stefan,

Thanks for the quick reply, much appreciated!

I have changed the script to


script AppDelegate
	property parent : class "NSObject"
	
	-- IBOutlets
    property theWindow : missing value
    property textfield1 : missing value
    property textfield2 : missing value
    
    on checkTextField1:sender
        log "check textfield1"
        if textfield1's stringValue() as text is equal to "" then
            log "textfield1 is empty"
            theWindow's makeFirstResponder_(textfield1)
        end if
    end checkTextField1
    
    on buttonPressed:sender
        log "button pressed"
        theWindow's makeFirstResponder:(missing value)
    end buttonPressed
	
	on applicationWillFinishLaunching_(aNotification)
		-- Insert code here to initialize your application before any files are opened
        set textfield1's stringValue to ""
	end applicationWillFinishLaunching_
	
	on applicationShouldTerminate_(sender)
		-- Insert code here to do any housekeeping before your application quits 
		return current application's NSTerminateNow
	end applicationShouldTerminate_
	
end script

and I do no longer get an error message. I have also added a line set textfield1’s stringValue to “” which will later be used to add a default value.

However, pressing tab in textfield1 advances the cursor to textfield2 and it stays there even though textfield1 is empty. The log shows that is found textfield1 empty but then the cursor stays in textfield2.

2015-06-16 15:42:49.659 test3[12984:247811] check textfield1
2015-06-16 15:42:49.659 test3[12984:247811] textfield1 is empty

I feel I’m missing something obvious but I don’t see it yet.

Danke,
Dirk

is the property theWindow connected properly in Interface Builder?

Connection Inspector shows that theWindow has the Referencing Outlet AppDelegate (as it was by default when I created the project) and the Initial First Responder set to textfield1. No Bindings have been added.

Is that correct or am I missing a connection?

this is correct

Still playing, I managed to get the cursor in textfield3 and the focus on textfield1 allowing no input from keyboard until a textfield is clicked.

I suspect it’s a timing issue. In your handler, you’re setting the field to be first responder while it already is first responder – the first responder normally changes after the action handler has finished running.

Try using this:

theWindow's performSelector:"makeFirstResponder:" withObject:textfield1 afterDelay:0.1

Shane,

You are absolute right. I changed the code to include your line and the focus now go back to textfield1 if I tab out of textfield1 and it is empty.


script AppDelegate
	property parent : class "NSObject"
	
	-- IBOutlets
	property theWindow : missing value
    property textfield1 : missing value
    property textfield2 : missing value
    property textfield3 : missing value
    
    on checkTextField1:sender
        log "check textfield1"
        if textfield1's stringValue() as text is equal to "" then
            log "textfield1 is empty"
            theWindow's performSelector:"makeFirstResponder:" withObject:textfield1 afterDelay:0.1
        end if
    end checkTextField1
    
    on buttonPressed:sender
        log "button pressed"
        theWindow's makeFirstResponder:(missing value)
    end buttonPressed
	
	on applicationWillFinishLaunching_(aNotification)
		-- Insert code here to initialize your application before any files are opened 
        set textfield2's stringValue to "test"
	end applicationWillFinishLaunching_
	
	on applicationShouldTerminate_(sender)
		-- Insert code here to do any housekeeping before your application quits 
		return current application's NSTerminateNow
	end applicationShouldTerminate_
	
end script

Thank you both for helping,
Dirk