Limit Number of Selected Rows for a Table

I am trying to limit the number of selected rows on a Vision table. I have tried all 3 selection modes but none of them are doing what I am expecting. Is there a way to allow only 2 selected rows in a Vision Table?

Not trivially, but it would technically be possible.

You'll have to manually create a custom ListSelectionModel implementation via scripting and apply it to the inner Java Swing table component.

This might be a starting point for this scenario but it may require some refining as I had to place the script under onMouseClick and onDoubleClick. Also, the script doesn't handle multiple row selections when the user drags the mouse. This is implemented on a Power Table. If you want to apply a similar scripting to a Table you will need replace 'table = event.source' with 'table = event.source.getTable()'.

def onMouseClick(self, rowIndex, colIndex, colName, value, event):
	from javax.swing import ListSelectionModel

	# Get the table component
	table = event.source

	# Get the selection model
	selectionModel = table.getSelectionModel()
	
	# Get selected rows
	selectedRows = table.getSelectedRows()
	
	# If more than 2 rows are selected, trim the selection
	if len(selectedRows) > 2:
		
		#Optional Error Box
		#system.gui.errorBox("Row selections limited to two", "Error")
		
		#Remove the lastest row selection.
		selectedRows.remove(rowIndex)
		
		#Rebuild the selection model with the original rows
		for index, row in enumerate(selectedRows):
			if index == 0:
				selectionModel.setSelectionInterval(row, row)
			else:
				selectionModel.addSelectionInterval(row, row)
1 Like

For a standard Table component, you can add this script to the propertyChange event.

if event.propertyName == 'componentRunning':
    from javax.swing import DefaultListSelectionModel

    class LimitedSelectionModel(DefaultListSelectionModel):
        def __init__(self,maxSelections = 2):
            self.maxSelections = maxSelections
            self.setSelectionMode(DefaultListSelectionModel.MULTIPLE_INTERVAL_SELECTION)

        def setSelectionInterval(self,index0,index1):
            if self.selectedItemsCount < self.maxSelections:
                self.super__setSelectionInterval(index0,index1)
            elif index0 == index1:
                self.clearSelection()
                self.super__addSelectionInterval(index0,index1)
            else:
                self.fireValueChanged(False) #ignore this selection

        def addSelectionInterval(self,index0,index1):
            if self.selectedItemsCount < self.maxSelections:
                self.super__addSelectionInterval(index0,index1)
            elif index0 == index1:
                self.clearSelection()
                self.super__addSelectionInterval(index0,index1)
            else:
                self.fireValueChanged(False) #ignore this selection

    if not isinstance(event.source.table.selectionModel,LimitedSelectionModel):
        event.source.table.selectionModel = LimitedSelectionModel()

This handles drag selections and broken intervals. If you don't want to support broken intervals (selected rows with non-selected rows between) then change selection mode from MULTIPLE_INTERVAL_SELECTION to SINGLE_INTERVAL_SELECTION.

If in the future you decide that you want to change the max selections then you can provide the constructor with an integer value that will be used instead of the default 2.

If you are using a power table then you should add this script to the initialize extension function, and change the event.source.table to self

2 Likes