# Scroll TabStrip to active/selected tab - Vision

**URL:** <https://forum.inductiveautomation.com/t/scroll-tabstrip-to-active-selected-tab-vision/100853>\
**Category:** Ignition\
**Tags:** vision\
**Created:** [January 14, 2025, 11:48am UTC](https://forum.inductiveautomation.com/t/scroll-tabstrip-to-active-selected-tab-vision/100853 "2025-01-14T11:48:35Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![zxcslo](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/zxcslo/32/61610_2.png) [@zxcslo](https://forum.inductiveautomation.com/u/zxcslo)\
**Post date:** [January 14, 2025, 11:48am UTC](https://forum.inductiveautomation.com/t/scroll-tabstrip-to-active-selected-tab-vision/100853/1 "2025-01-14T11:48:35Z")

</div>

I have a TabStrip with 18 tabs.  
The popup, where the TabStrip is used is not big enough to show complete TabStrip, so the arrows are shown on the right side.  
If I set the active tab (when the popup is opened, via window parameter) to the tab, that is 'beyond' navigation arrows, is it possible somehow to 'auto scroll' to this selected/active tab, which is currently not visible?  
 ![Screenshot_tabstrip1](https://us1.discourse-cdn.com/inductiveautomation/original/3X/f/e/fe21dd8f3bd21a1d244aae6d6c92172100618755.png)

![Screenshot_tabstrip2](https://us1.discourse-cdn.com/inductiveautomation/original/3X/b/1/b15a0d6cafecbce0ef48307dd7daa8da604203b9.png)  
I'm/was playing with 'tabStrip.scrollRectToVisible' (like with the tables) but I had no success...

---

<div class="post-metadata">

**Author:** ![zxcslo](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/zxcslo/32/61610_2.png) [@zxcslo](https://forum.inductiveautomation.com/u/zxcslo)\
**Post date:** [January 15, 2025, 5:56am UTC](https://forum.inductiveautomation.com/t/scroll-tabstrip-to-active-selected-tab-vision/100853/2 "2025-01-15T05:56:46Z")

</div>

Nobody...?  
I was humbly hoped that at least @justinedwards.jle has some info... 🙏

---

<div class="post-metadata">

**Author:** ![justinedwards.jle](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/justinedwards.jle/32/37854_2.png) [@justinedwards.jle](https://forum.inductiveautomation.com/u/justinedwards.jle)\
**Post date:** [January 15, 2025, 9:06am UTC](https://forum.inductiveautomation.com/t/scroll-tabstrip-to-active-selected-tab-vision/100853/3 "2025-01-15T09:06:22Z")

</div>

I'm not sure the best way to approach this. That component doesn't use a scroll pane, so it's basically just a jpanel nested inside a jpanel. The outer panel will have a layout manager that dictates where the inner panel is positioned. My inclination is to leave that alone and manipulate the position of the inner panel the natural way with the buttons, albeit programmatically. I imagine this could be done with a loop that checks a given tab component's bounds against the tab holder panel's visible rectangle.

---

<div class="post-metadata">

**Author:** ![zxcslo](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/zxcslo/32/61610_2.png) [@zxcslo](https://forum.inductiveautomation.com/u/zxcslo)\
**Post date:** [January 15, 2025, 10:33am UTC](https://forum.inductiveautomation.com/t/scroll-tabstrip-to-active-selected-tab-vision/100853/4 "2025-01-15T10:33:14Z")

</div>

Thank you for your (always) valuable input...

> [@justinedwards.jle](#):
>
> ... **albeit programmatically**. I imagine this could be done with a loop that checks a given tab component's bounds against the tab holder panel's visible rectangle.

I guess that is a 'little' out of my league... 😇

---

<div class="post-metadata">

**Author:** ![justinedwards.jle](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/justinedwards.jle/32/37854_2.png) [@justinedwards.jle](https://forum.inductiveautomation.com/u/justinedwards.jle)\
**Post date:** [January 15, 2025, 4:01pm UTC](https://forum.inductiveautomation.com/t/scroll-tabstrip-to-active-selected-tab-vision/100853/5 "2025-01-15T16:01:20Z")

</div>

> [@zxcslo](#):
>
> 😇

haha, ...okay, this idea seems useful, so I'll develop the prototype

I've tested the following code, and it works:

```python
# Written for the propertyChange event handler of the tab strip
# Evaluates only when the selected tab changes
if event.propertyName == 'selectedTab':
	from java.awt.event import MouseEvent
	
	# Get the panels, the buttons, and the selected tab component
	arrowPanel, tabHolderPanel = event.source.components
	leftButton, rightButton = arrowPanel.components
	selectedTab = next(component for component in tabHolderPanel.components if component.selected)
	
	# Determine which if any button would need to be pressed to bring the selected tab view
	if not tabHolderPanel.visibleRect.contains(selectedTab.bounds):
		if tabHolderPanel.visibleRect.x < selectedTab.x:
			button = rightButton
		else:
			button = leftButton
	else:
		button = None
	
	# If needed, recursively schedule button clicks until the selected tab comes into view
	if button:
		def setPosition():
			releaseEvent = MouseEvent(button, MouseEvent.MOUSE_RELEASED, 0, 0, 0, 0, 1, False)
			button.dispatchEvent(releaseEvent)
			if not tabHolderPanel.visibleRect.contains(selectedTab.bounds):
				system.util.invokeLater(setPosition)
		setPosition()

```

Please share the final version when you're done golfing and streamlining it.

---

<div class="post-metadata">

**Author:** ![zxcslo](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/zxcslo/32/61610_2.png) [@zxcslo](https://forum.inductiveautomation.com/u/zxcslo)\
**Post date:** [January 16, 2025, 8:06am UTC](https://forum.inductiveautomation.com/t/scroll-tabstrip-to-active-selected-tab-vision/100853/6 "2025-01-16T08:06:16Z")

</div>

You did it again. Kudos to you.  
 ![giphy](https://us1.discourse-cdn.com/inductiveautomation/original/3X/4/8/48310f453c169abed61fb862f205842a88fd3b75.gif)  
I didn't need to change anything from your code. It just worked.  
I just moved the code to the project library, because I have a few tabStrips in my project.  
This is what I have on the tabStrip propertyChange event:

```python
if event.propertyName == "componentRunning" and event.newValue:
	tabStrip = system.gui.getParentWindow(event).getComponentForPath('Root Container.Tab Strip')
	various_functions.tab_strip.tabStripArrowEditor(tabStrip)

if event.propertyName == 'selectedTab':
	various_functions.tab_strip.moveToActiveTab(event)

```

And this is my project library script:

```python
#adjust arrow button size for touch screen
from com.inductiveautomation.factorypmi.application.components.util import HoldDownArrowButton
from com.inductiveautomation.factorypmi.application.components.tabstrip import LeftRightArrowPanel
from java.awt import Dimension
from java.awt.event import MouseEvent

arrowWidth = 50
arrowHeight = 50

def tabStripArrowEditor(tabStrip):
	if tabStrip.componentCount > 0:
		for component in tabStrip.getComponents():
			if isinstance(component, LeftRightArrowPanel):
				size = Dimension(arrowWidth*2,arrowHeight)
				component.setPreferredSize(size)
				component.setSize(size)
				component.background = system.gui.color(230,230,230)
				tabStripArrowEditor(component)
				return
			elif isinstance(component, HoldDownArrowButton):
				size = Dimension(arrowWidth,arrowHeight)
				component.setPreferredSize(size)
				component.setSize(size)
				component.background = system.gui.color(230,230,230)
			else:
				tabStripArrowEditor(component)

def moveToActiveTab(event):
	# Get the panels, the buttons, and the selected tab component
	arrowPanel, tabHolderPanel = event.source.components
	leftButton, rightButton = arrowPanel.components
	selectedTab = next(component for component in tabHolderPanel.components if component.selected)

	# Determine which if any button would need to be pressed to bring the selected tab view
	if not tabHolderPanel.visibleRect.contains(selectedTab.bounds):
		if tabHolderPanel.visibleRect.x < selectedTab.x:
			button = rightButton
		else:
			button = leftButton
	else:
		button = None
	
	# If needed, recursively schedule button clicks until the selected tab comes into view
	if button:
		def setPosition():
			releaseEvent = MouseEvent(button, MouseEvent.MOUSE_RELEASED, 0, 0, 0, 0, 1, False)
			button.dispatchEvent(releaseEvent)
			if not tabHolderPanel.visibleRect.contains(selectedTab.bounds):
				system.util.invokeLater(setPosition)
		setPosition()
		setPosition()	#because I'm using wider arrow keys, I need to call this twice more
		setPosition()

```

And this is the result:  
 ![tabStrip1](https://us1.discourse-cdn.com/inductiveautomation/original/3X/5/0/505e48cab00dac2945db7f48442c595dea28eb3a.gif)

Again, thank you very much for you help... 😃
