Question about code example for system.util.invokeLater

I'm not quite clear on below example, how to duplicate this example in an actual vision window? any suggestion is appreciated.

This example is from the manual.

# The code in the update/refresh button uses the 'date' property on the two
# calendar components, which are bound to the current_timestamp property on their
# parent. We want to simulate a button press when the window opens, but only
# after the date properties' bindings have been evaluated.
  
if event.propertyName == 'current_timestamp':
   # Define a function to click the button
   def clickButton(button = event.source.parent.getComponent('Refresh')):
      import system
      button.doClick()
      system.gui.messageBox("Button has been clicked!")
  
   # Tell the system to invoke the function after
   # the current event has been processed
   system.util.invokeLater(clickButton)

What are you trying to accomplish?

I want to understand the purpose of this function through this example.

The function inserts the call to the function at the end of the current event call stack.

In this instance the assumption is that the example script will be called at window open. If you were to call the clickButton function immediately there would be invalid data because all of the bindings had not yet been processed.

Using invokeLater, means that the the function will be called following the binding processing events which are already on the GUI event dispatch thread.

The function is also commonly used to return data back to the GUI from a background thread in a thread safe way.

3 Likes

Which process is running first, the evaluation of property binding or the window property change event script? or they are simultaneously?

Vision is backed by Java Swing, which runs a single threaded event loop that processes all GUI events in a queue. All first party stuff is guaranteed to be correctly using that queue.

system.util.invokeLater simply appends some callable action to the end of that queue - no more, no less. If you use it from some script that's already running on the EDT, then you are guaranteed that your provided function will be called "later" - with no guarantee on when (though in practice it's likely less than a second).

Binding startup and evaluation happens, as much as possible, asynchronously, but actual property assignment once values are delivered must happen on the EDT. But that doesn't mean that simply putting your code into invokeLater is going to happen after all bindings are evaluated, because bindings can re-evaluate as many time as needed.

Are you actually trying to solve a specific problem here, or just curious about the details?

1 Like

So here if not use invokeLater, it may or may not have issue, but after use invokeLater, it can ensure this clickButton function is called just after the evaluate of current_timestamp property. this is much more safe style. This is why we need use it.