Set focus on any input control

The requestFocusInWindow() method only works for simple input controls like a Text Field (single line). When used on more complicated controls such as a Text Area (which can have scrollbars) or a Popup Calendar the focus will end up on the control’s container, rather than the component the user interacts with. From the user’s perspective no component will have focus.

Here is a function to set focus on any input control with a minimum of effort, including compound components. It can be used from any event script.

def focus(event, path):
	import system
	def requestFocus(event=event):
		import system
		c = system.gui.getParentWindow(event).getComponentForPath(path)
		# Drill down to find a component without any children
		while len(c.components) > 0:
			# Just grab the first child
			c = c.components[0]
		c.requestFocusInWindow()
	system.util.invokeLater(requestFocus)

Example usage:

  1. Place the code inside a file called ‘util’ in the script module editor.
  2. Add a PopupCalendar component called ‘calendarSelect’ to your window
  3. Add the following to the visionWindowOpened event for the window:
app.util.focus(event, 'Root Container.calendarSelect')

Cool. Instead of drilling down to the “deepest” component (component without any children) you might look for children that return true from isFocusable()

I was originally hoping to do something like that. Unfortunately isFocusable() returns true for many things that we don’t want to focus on. Actually, I can’t remember ever seeing it return false.

JScrollPane components are focusable, so it would end up focusing the scrollbars of a textarea instead of the input underneath, although this can be overcome by using viewport.view if available.

Confusingly, JPanel and JInternalFrame components are focusable too, even though they’re just containers and focusing on them makes no sense. This is probably why PMIDateTimePopupSelector, etc are also focusable, since they inherit from swing components.

Yeah, any component can claim focusability in Swing, even if they don’t end up doing anything with their focus.

What about setting the container to focus (requestFocusInWindow()) and then using nextFocus()? this works for a List comoponent, haven’t tested with anything else.

Whoops, didn’t realise this was such an old post… better late than never I guess