# Synchronize multiple tables scroll position

**URL:** <https://forum.inductiveautomation.com/t/synchronize-multiple-tables-scroll-position/98052>\
**Category:** Ignition\
**Tags:** ignition81, vision\
**Created:** [November 1, 2024, 4:59pm UTC](https://forum.inductiveautomation.com/t/synchronize-multiple-tables-scroll-position/98052 "2024-11-01T16:59:31Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![David\_Anderson1](https://avatars.discourse-cdn.com/v4/letter/d/71c47a/32.png) [@David\_Anderson1](https://forum.inductiveautomation.com/u/David_Anderson1)\
**Post date:** [November 1, 2024, 4:59pm UTC](https://forum.inductiveautomation.com/t/synchronize-multiple-tables-scroll-position/98052/1 "2024-11-01T16:59:31Z")

</div>

Need a little help. I have a table I'm trying to display in a Vision window. The data is coming from a named query, the table has more rows that would fit well on a screen, I would like to show all rows. I was going to break the query into two tables. I would like to synchronize the scrolling of both tables, is that possible? I asked ChatGPT and this is what it came up with:  
An event script on one of the tables

if event.propertyName == 'verticalScrollPosition':  
# Get the new scroll position of Table 1  
newScrollPos = event.newValue

```
# Find Table 2
table2 = event.source.parent.getComponent('Table 2')

# Update Table 2's scroll position to match Table 1
table2.setVerticalScrollPosition(newScrollPos)

```

':  
# Get the new scroll position of Table 1  
newScrollPos = event.newValue

```
# Find Table 2
table2 = event.source.parent.getComponent('Table 2')

# Update Table 2's scroll position to match Table 1
table2.setVerticalScrollPosition(newScrollPos)

```

Look good to me however, it did not work. I did I print out the property event in the script (at the top of course), yet it never said the 'verticalScrollPosition' event when I scroll the scrollbar and of course, nothing happens. Needless to say, the synchronization of the scrolling bars did not work.

I look forward to your ideas and comments,  
David

---

<div class="post-metadata">

**Author:** ![dkhayes117](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/dkhayes117/32/68344_2.png) [@dkhayes117](https://forum.inductiveautomation.com/u/dkhayes117)\
**Post date:** [November 1, 2024, 7:35pm UTC](https://forum.inductiveautomation.com/t/synchronize-multiple-tables-scroll-position/98052/2 "2024-11-01T19:35:04Z")

</div>

This will get you started. You should add a `ChangeListener` to sync the scrollbar positions.

In the `initialize` extension function on the first table add this script

```python
	from javax.swing.event import ChangeListener

	tableMain = self.parent.getComponent('Power Table')
	table2 = self.parent.getComponent('Power Table 1')
	
	class myListener(ChangeListener):
		def stateChanged(self, e):
			scrollBarMain = tableMain.getVerticalScrollBar()
			scrollBar2 = table2.getVerticalScrollBar()
			scrollBar2.setValue(scrollBarMain.getValue())
			
	#to remove ChangeListener
	listeners = tableMain.viewport.getChangeListeners()
	for listener in listeners:
		tableMain.viewport.removeChangeListener(listener)
		
	#to add ChangeListener
	tableMain.viewport.addChangeListener(myListener())

```

You may want to consider this comment from a similar thread.

> [@Scroll two (or more ) tables with one scroolbar](https://forum.inductiveautomation.com/t/scroll-two-or-more-tables-with-one-scroolbar/20125/3):
>
> I would add a ChangeListener to each table’s Viewport that would relay any desired operations to the other tables. And use mouseenter, mouseexit, and mousemove events to ensure only one table’s event are relayed at any given moment. The ChangeListener will get an event even if the scroll happens as a result of a non-mouse operation.

---

<div class="post-metadata">

**Author:** ![David\_Anderson1](https://avatars.discourse-cdn.com/v4/letter/d/71c47a/32.png) [@David\_Anderson1](https://forum.inductiveautomation.com/u/David_Anderson1)\
**Post date:** [November 1, 2024, 8:05pm UTC](https://forum.inductiveautomation.com/t/synchronize-multiple-tables-scroll-position/98052/3 "2024-11-01T20:05:54Z")

</div>

> [@dkhayes117](#):
>
> ```python
> 			
> 
> ```

WOW, thank you so much for responding. You mentioned ' In the `initialize` extension function on the first table add this script', there is no _initialize_ extension function from within the table's scripting.

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/1/a/1ab22b39cff6d61484b7f4187717ba2a48b19e85.png)

---

<div class="post-metadata">

**Author:** ![dkhayes117](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/dkhayes117/32/68344_2.png) [@dkhayes117](https://forum.inductiveautomation.com/u/dkhayes117)\
**Post date:** [November 4, 2024, 1:34pm UTC](https://forum.inductiveautomation.com/t/synchronize-multiple-tables-scroll-position/98052/4 "2024-11-04T13:34:42Z")

</div>

The power table component has the initialize function, which I tend to use for its configuration flexibility over the regular table component. In a regular table you would move this script to the `propertyChange` event handler with a filter clause since you don't want to run the script on _every_ property change.

```python
if event.propertyName == 'componentRunning':
	from javax.swing.event import ChangeListener
	
	# put your initialization code here
	tableMain = event.source.parent.getComponent('Table')
	table2 = event.source.parent.getComponent('Table 1')
	
	class myListener(ChangeListener):
		def stateChanged(self, e):
			scrollBarMain = tableMain.getVerticalScrollBar()
			scrollBar2 = table2.getVerticalScrollBar()
			scrollBar2.setValue(scrollBarMain.getValue())
			
	#to remove ChangeListener
	listeners = tableMain.viewport.getChangeListeners()
	for listener in listeners:
		tableMain.viewport.removeChangeListener(listener)
		
	#to add ChangeListener
	tableMain.viewport.addChangeListener(myListener())

```

This will only work in the _ **designer** _ if you enable preview mode before opening the window with the associated components.
