Beginners Question: on clicked theObject

Hi Folks,

this is maybe a stupid question, but is it possible to have more than 1 on clicked theObject handler in XCode?

Background: my onclicked theObject handler is pretty large, therefore it takes a long time after pressing a button until the result will be displayed or until the process starts…

Has anybody an idea on what I shall do?

Below is the current onClicked theObject handler…

on clicked theObject
	-- Löschen des SMS Textes
	if name of theObject is "sms_delete" then
		set contents of text view "text" of scroll view "text" of tab view item "Outbox" of tab view "tab" of window "main" to ""
	end if
	
	-- dieser block muss immer gleich sein mit dem obersten block
	set modem_check to serialport list
	if modem_check contains "/dev/cu.HUAWEIMobile-Modem" then
		set modem to "/dev/cu.HUAWEIMobile-Modem"
		set modem_display to "Web'n'walk Box compact"
	else if modem_check contains "/dev/cu.Icon Modem" then
		set modem to "/dev/cu.Icon Modem"
		set modem_display to "Web'n'walk Box"
	end if
	--serialport close modem_check
	
	--	set idle of theObject to false
	--display dialog modem_display
	
	if name of theObject is "Connect" then
		tell window "main"
			set PopupButtonItem to modem_display
		end tell
		
		set theMatrixItem to title of current cell of matrix "theMatrix" of tab view item "Setting" of tab view "tab" of window "main"
		
		if modem_display is "Web'n'walk Box compact" then
			-- Check Huawei E220 gprsinternet
			if (PopupButtonItem is "Web'n'walk Box compact") and (theMatrixItem is "HSDPA Internet") then
				tell application "Internet Connect"
					set configName to "HUAWEI Mobile"
					set currentStatus to status of configuration configName
					connect PPP configuration configName to telephone number "gprsinternet"
					quit
				end tell
				set enabled of button "Connect" of tab view item "Connection" of tab view "tab" of window "main" to false
				set enabled of button "Disconnect" of tab view item "Connection" of tab view "tab" of window "main" to true
				
			end if
			-- Check Huawei E220 business.gprsinternet
			if (PopupButtonItem is "Web'n'walk Box compact") and (theMatrixItem is "HSDPA Business") then
				tell application "Internet Connect"
					set configName to "HUAWEI Mobile"
					set currentStatus to status of configuration configName
					connect PPP configuration configName to telephone number "business-gprsinternet"
					quit
				end tell
				set enabled of button "Connect" of tab view item "Connection" of tab view "tab" of window "main" to false
				set enabled of button "Disconnect" of tab view item "Connection" of tab view "tab" of window "main" to true
				
			end if
		else if modem_display is "Web'n'walk Box" then
			
			-- web'n'walk box - gprsinternet
			if (PopupButtonItem is "Web'n'walk Box") and (theMatrixItem is "HSDPA Internet") then
				tell application "Internet Connect"
					set configName to "Icon Modem"
					set currentStatus to status of configuration configName
					connect PPP configuration configName to telephone number "gprsinternet"
					quit
				end tell
				set enabled of button "Connect" of tab view item "Connection" of tab view "tab" of window "main" to false
				set enabled of button "Disconnect" of tab view item "Connection" of tab view "tab" of window "main" to true
				
			end if
			-- web'n'walk box - business.gprsinternet
			if (PopupButtonItem is "Web'n'walk Box") and (theMatrixItem is "HSDPA Business") then
				tell application "Internet Connect"
					set configName to "Icon Modem"
					set currentStatus to status of configuration configName
					connect PPP configuration configName to telephone number "business.gprsinternet"
					quit
				end tell
				set enabled of button "Connect" of tab view item "Connection" of tab view "tab" of window "main" to false
				set enabled of button "Disconnect" of tab view item "Connection" of tab view "tab" of window "main" to true
				
			end if
		end if
	end if
	
	if name of theObject is "Disconnect" then
		tell application "Internet Connect"
			if modem_display is "Web'n'walk Box compact" then
				set configName to "HUAWEI Mobile"
			end if
			if modem_display is "Web'n'walk Box" then
				set configName to "Icon Modem"
			end if
			set currentStatus to status of configuration configName
			disconnect configuration configName
		end tell
		set enabled of button "Connect" of tab view item "Connection" of tab view "tab" of window "main" to true
		set enabled of button "Disconnect" of tab view item "Connection" of tab view "tab" of window "main" to false
	end if
	delay 5
	set init_run to false
	idle
	
	if name of theObject is "sms_button" then
		set contents of text field "sms_report" of tab view item "Outbox" of tab view "tab" of window "main" to "Nachricht wird gesendet"
		
		set portRef to serialport open modem
		-- SMS senden
		---- Speicherart der SMS setzen 1 - Text
		set xstr to "at+cmgf=1" & return
		serialport write xstr to portRef
		set content of control "pegel_send" of tab view item "Outbox" of tab view "tab" of window "main" to 2
		delay 1
		-- SMS Center setzen
		set sms_center to "\"+43676021\""
		set xstr to "at+csca=" & sms_center & return
		serialport write xstr to portRef
		set content of control "pegel_send" of tab view item "Outbox" of tab view "tab" of window "main" to 3
		delay 1
		-- Telefonnummer holen:
		set theNumber to contents of text field "sms_nummer" of tab view item "Outbox" of tab view "tab" of window "main"
		set quota to "\""
		set sms to quota & theNumber & quota
		set content of control "pegel_send" of tab view item "Outbox" of tab view "tab" of window "main" to 4
		delay 1
		-- Text holen
		set text_sms to contents of text view "text" of scroll view "text" of tab view item "Outbox" of tab view "tab" of window "main"
		set ctrl to ASCII character 26
		set xstr to "at+cmgs=" & sms & return
		serialport write xstr to portRef
		serialport write text_sms to portRef
		serialport write ctrl to portRef
		set report to "SMS gesendet!"
		set contents of text field "sms_report" of tab view item "Outbox" of tab view "tab" of window "main" to report
		serialport close portRef
		set content of control "pegel_send" of tab view item "Outbox" of tab view "tab" of window "main" to 5
		delay 2
	end if
	
end clicked

Thanks a lot for your help and support…

Best Regards,

Stefan

stefanl,
Short answer… NO, it’s not possible to have more than one of each handler. If you try to put more than 1 in, xcode will give you an error telling that it’s declared more than once.

After looking at your code, I do have a few recommendations…

  1. Use if/else statements instead of multiple if statements. Rather than having many separate if statements, put all of your testing into one set of if/else statements. This, in my opinion, is much cleaner and predictable than having a whole bunch of separate tests. While there are certainly occasions where having multiple tests occurring in your handler are appropriate, it’s usually best to avoid using anything but one if/else series.

  2. Clarify what needs to be in your if/else blocks and what doesn’t. While I admit I haven’t looked very carefully at everything your code does, I think that the following two blocks of code look like they are out of place…

   set modem_check to serialport list
   if modem_check contains "/dev/cu.HUAWEIMobile-Modem" then
       set modem to "/dev/cu.HUAWEIMobile-Modem"
       set modem_display to "Web'n'walk Box compact"
   else if modem_check contains "/dev/cu.Icon Modem" then
       set modem to "/dev/cu.Icon Modem"
       set modem_display to "Web'n'walk Box"
   end if

   delay 5
   set init_run to false
   idle

Since they are not in any if/else statement , they execute EVERY TIME you click ANYTHING connected to the handler. As I said, this may be what you want to happen, but the ‘delay 5’ command is especially questionable. No matter what button you press, it always will delay for 5 seconds before evaluating the final if statement in the handler. Since there can be only one handler, you typically want to put everything inside of one of your if/else blocks, and have no code outside of them… as this code will get executed every time the handler is called. If you DO want these to execute every time ANY button or object calls the clicked handler, then you should at least put them in a subroutine (see below).

  1. Use subroutines. Just for your information, your on clicked handler is not “pretty large”. I have apps with dozens of objects connected to one clicked handler, that have way more lines of code in my clicked handler. The only difference, is that mine are probably just simply cleaner and more organized than yours, because I use only subroutines called from the handler. Try separating your code into subroutines… blocks of code that accomplish one particular purpose… and call them from your clicked handler rather than putting all of your code into the handler itself.

The following simple example below illustrates all of the points I’ve made above…

on clicked theObject
	set theAction to (name of theObject) as string

	if theAction is "doSomeThing" then
		doSomeThing()
	else if theAction is "doSomeThingElse" then
		doSomeThingElse(true)
	else if theAction is "manipulateData" then
		setDataTo({data:"someValue"})
	else if theAction is "changeVariableX" then
		changeVariableXTo("Y")
	end if
end clicked

(* Subroutines *)
to doSomeThing()
	--> Do Something Here
end doSomeThing

to doSomeThingElse(true)
	--> Do Something Else Here
end doSomeThingElse

to setDataTo(inputList)
	--> Manipulate Your Data Here
end setDataTo

to changeVariableXTo(newValue)
	--> Change Your Variable Here
end changeVariableXTo

Using subroutines is a really easy way to clean up your code, and make it more modular. While the code has to live somewhere, it’s cleaner to have it hidden off in a subroutine somewhere, and leave the clicked handler nice and clean. This also enables you to call a particular block of code from multiple places, such as from a button, a menu item, or an application event… without having to completely re-write the code in 3 separate places. Another advantage to this, is that when you look in the dropdown menu in the editor, it lists all of your subroutines along with your handlers. If you name them efficiently, you can easily access them quickly by choosing them in the list and jumping right to them.

Hope that helps,
j

Hi Jobu,

thanks for your suggestions! I have done it as you have told me, and now everything is working faster…!

Best regards,

Stefan