Remove Scrollbar from Template Repeater

Hi,

I am currently working with template repeaters and I have to make the component a bit smaller than what it would like creating a scroll bar.

Is there a way to remove the scroll bar just for this Template repeater?

In propertyChange for the repeater, add this script:

if event.propertyName == "componentRunning":
	event.source.getComponent(1).verticalScrollBarPolicy = 21

Notes:

  • This won't work in the Designer unless you open the window containing the repeater while preview mode is active, but will work consistently in the client
  • 1 is a 'magic' index into the template repeater; it always contains two components (unless we change it in some future Ignition version) - a 'loading' overlay that's usually invisible, and the scrollpane that contains the actual templates.
  • 21 is the 'magic' constant defined in ScrollPaneConstants as VERTICAL_SCROLLBAR_NEVER.
1 Like

If you're uncomfortable with having magic numbers in your code, you can import the JScrollPane class, and replace the number 21 with JScrollPane.VERTICAL_SCROLLBAR_NEVER.

2 Likes

Thank you ! It works perfectly

Also, while in this instance getComponent(1) will probably always work, I've learned to not trust component hierarchies to be static. It's usually better to set up a generic library script for something like this. For example, if there was a script in the project library called "componentScripts", these functions could be added to it:

# Perform necessary imports
from javax.swing import JScrollPane

# This function recursively finds the first nested scroll pane from a given component and returns it
def getScrollPane(component):
	for subComponent in component.components:
		if isinstance(subComponent, JScrollPane):
			return subComponent
		else:
			scrollPane = getScrollPane(subComponent)
			if scrollPane is not None:
				return scrollPane

# Hides the vertical scroll bar for a given JScrollPane
def hideVerticalScrollBar(scrollPane):
	scrollPane.verticalScrollBarPolicy = JScrollPane.VERTICAL_SCROLLBAR_NEVER

Then, the script would be called from the propertyChange event handler in this way:

# Run only once when the component is initialized
# This won't run in the designer unless preview mode is active prior to opening the window
if event.propertyName == "componentRunning":
	
	# Get the scrollpane from the template repeater
	scrollPane = componentScripts.getScrollPane(event.source)
	
	# Hide the vertical scroll bar if the scroll pane exists
	if scrollPane is not None:
		componentScripts.hideVerticalScrollBar(scrollPane)
4 Likes

I have a second question about the template repeater, is there a way to make the background of the template repeater transfer its event to the object behing?

I know that with popups i can use something like .Opaque(0) on the window object and it let me click through the background. Is there anything equivalent with the template repeater?

Simply add a ,0 to the end of your template repeater's background color property:
image

Thats the first thing I did, but the problem is that the Template repeater still catch the event when clicking on its invisible background instead of passing it to the object behind

No, Java Swing doesn't work like that.

Click through to what?

I had misread this as see through the background. Mapping the cursor actions to underlying [sibling] components can be done, but it's starting to sound like we're solving the wrong problem. Perhaps you could provide some more information about what the app is supposed to do?

I have a script that calls animation in the box behind the template repeater. But when the repeater place the templates like in the picture, it leaves alot of empty space.

The template repeater is about the size of the red box. The problem is whenever I click inside the box but not on a template , my script doesn't get called

When you do click a template, what calls your script? Is it a mouse click event on the template itself?

Where does the script live?

Edit:
If all you are doing is calling some animation script on a mouse clicked event, one option would be to add a mouse listener to your scroll pane.

If you further develop your existing initialization script, the code will look like this:

# Only runs once at initialization
# Won't run in designer unless preview mode is active prior to the window being opened.
if event.propertyName == 'componentRunning':
	# Nest the import, so it doesn't happen every time some property changes
	from java.awt.event import MouseAdapter
	
	# Create a listener to call your script when the empty space is clicked
	class ClickListener(MouseAdapter):
		def mouseClicked(self, event):
			print "Call animation script from here"
			
	# [...Previously developed code that obtains and manipulates the scroll pane...]
	
	# Add the mouse listener to the scroll pane
	scrollPane.addMouseListener(ClickListener())

This makes everything I wanted ! I sincerely thank you!

1 Like

Very useful idea!
I was needing this in a previous project, but never asked and got away ignoring it.
However now I must remove a horizontal Scrollbar for a textbox that is only double the height of the scrollbar and can not ignore it.

Until a specific solution for textbox Scollbar remove, I'll try to use these suggestions.