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)
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