I had the morning off, and this seemed like a fun thing to try, so I developed this onMouseClick Extension Function script that reliably sets the column width to the largest string in the dropdown selection:
#def onMouseClick(self, [...], event):
from javax.swing import JComboBox
from java.awt.font import FontRenderContext, TextLayout
from java.awt import Font
if hasattr(self.table.getCellEditor(rowIndex, colIndex), 'component'):
editorComponent = self.table.getCellEditor(rowIndex, colIndex).component
if isinstance(editorComponent, JComboBox):
tableFont = self.font
widthSettingFont = Font(Font.MONOSPACED, tableFont.style, tableFont.size)
selectedColumnIndex = colIndex
columnModel = self.table.columnModel
selectedColumn = columnModel.getColumn(selectedColumnIndex)
selectedColumnWidth = selectedColumn.getPreferredWidth()
dropdown = editorComponent.getUI().getAccessibleChild(editorComponent, 0)
items = [editorComponent.renderer.getListCellRendererComponent(dropdown.getList(), editorComponent.model.getElementAt(row), -1, False, False).getText() for row in range(editorComponent.model.size)]
maxItemWidth = max([int(TextLayout(item, widthSettingFont, FontRenderContext(None, False, False)).bounds.width) for item in items])
if selectedColumnWidth < maxItemWidth:
widthDifference = float(maxItemWidth - selectedColumnWidth)
otherColumnCount = float(columnModel.columnCount - 1)
if otherColumnCount > 0:
widthOffset = int(widthDifference/otherColumnCount)
for otherColumnIndex in range(columnModel.columnCount):
if otherColumnIndex != selectedColumnIndex:
otherColumn = columnModel.getColumn(otherColumnIndex)
otherColumnWidth = otherColumn.getWidth()
otherColumn.setPreferredWidth(otherColumnWidth - widthOffset)
else:
selectedColumn.setPreferredWidth(maxItemWidth)
Here is the result:
Originally, I wanted to just set the preferred width of the clicked column, but I found that no matter what the column resize policy was, it would not reliably achieve the full width, so I had to add a calculated offset that causes each of the other columns to loose their share of the amount the selected column is gaining.
While moving the columns around works, I would prefer to change the dropdown width, but unfortunately, I've run out of time before I could achieve the proper result.
First Dropdown Width Adjustment Attempt
#def onMouseClick(self,[...], event):
from javax.swing import JComboBox
from java.awt import Dimension
from java.awt.font import FontRenderContext, TextLayout
from java.awt import Font
if hasattr(self.table.getCellEditor(rowIndex, colIndex), 'component'):
editorComponent = self.table.getCellEditor(rowIndex, colIndex).component
if isinstance(editorComponent, JComboBox):
tableFont = self.font
widthSettingFont = Font(Font.MONOSPACED, tableFont.style, tableFont.size)
dropdown = editorComponent.getUI().getAccessibleChild(editorComponent, 0)
items = [editorComponent.renderer.getListCellRendererComponent(dropdown.getList(), editorComponent.model.getElementAt(row), -1, False, False).getText() for row in range(editorComponent.model.size)]
maxItemWidth = max([int(TextLayout(item, widthSettingFont, FontRenderContext(None, False, False)).bounds.width) for item in items])
dropdown.setPreferredSize(Dimension(maxItemWidth, dropdown.getPreferredSize().height))
The above script produces the following result:
As can be seen in the picture, the dropdown has achieved the proper width, but the scrollable viewport has remained stubbornly the same size. Even when I get them and change them directly in the following manner:
dropdown.getComponent(0).setPreferredSize(Dimension(maxItemWidth, dropdown.getPreferredSize().height))
dropdown.getComponent(0).viewport.setPreferredSize(Dimension(maxItemWidth, dropdown.getPreferredSize().height))
I've also tried changing the size of the list itself:
dropdown.getList().setPreferredSize(Dimension(maxItemWidth, dropdown.getPreferredSize().height))
...and I've played around with the renderer a bit, but it just never came together. Perhaps I'll look at this again later with a fresh set of eyes.
Edit: See next post for dropdown width adjustment.