Miguel Ping Miguel Ping - 2 months ago 23
Groovy Question

Java Swing Table size

I'm having problems with JTables. I'm adding two tables to a panel, the tables are within a scrollpane, but when the app shows up, the tables always occupy more space than the number of rows, wasting my available space.

I'm using groovy and swingbuilder to create the tables, here's the code:

scrollPane(){
panel(layout: new MigLayout('wrap 3')) {
//main title
label(text: '<html><h1>blah</h1></html>',constraints: 'span 3') //title

//tables
def data = [[text: "ABC", combo: "abc"], [text: "DEF", combo: "def"]]
def items = ['abc', 'def', 'ghi', 'jkl']
def tableModelListener = { e -> println "${e.firstRow} ${e.column} ${e.type}" } as TableModelListener
scrollPane(constraints: 'span 3' ) {
table(id: 'serviceTable') {
current.setFillsViewportHeight(false)
tableModel(list: data) {
current.addTableModelListener(tableModelListener)
propertyColumn(header: 'Text', propertyName: 'text')
propertyColumn(header: 'Combo', propertyName: 'combo')
}
}
}
scrollPane(constraints: 'span 3' ) {
table(id: 'groupsTable') {
tableModel(list: data) {
current.addTableModelListener(tableModelListener)
propertyColumn(header: 'Text2', propertyName: 'text')
propertyColumn(header: 'Combo2', propertyName: 'combo')
}
}
}
}
}


And here's the result:
Image

What I want is to make the table height according to the number of rows, and if possible I'd like the table to occupy full width also. I think my problem is related to the parent panels, but I cannot find the cause.

Answer

@jfpoilpret is correct in that the preferredScrollableViewpoet size needs to be managed. The groovy way would be to bind it to the preferred size of the table. So if this was added inside of the outer scrollPane element it would automatically track the size:

[serviceTable, groupsTable].each { table ->
    bind(source:table, sourceProperty:'preferredSize', 
         target:table, targetProperty:'preferredScrollableViewportSize',
         converter: { ps -> 
             [ps.width + 100, 
              (table.rowCount > 20 ? 20: table.rowCount) * table.rowHeight]
         })
}

We can also do neat things with the binding like adding a converter that will limit the height to 20 rows (or whatever you want it to be limited to) so we still get scrollbars when the table gets too long.