29 October 2015

How to make a JTable a specific number of rows high

Java Swing is rather complex. You can do just about anything, but it can be hard to know how to do it. I have for a long time tried to adapt the visible (preferred) size of a JTable. I know how many rows I would like to display, but it is hard to know how to write the code for it.

I figured out this code today:
package se.lesc.blog;

import java.awt.Insets;

import javax.swing.GroupLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import static javax.swing.GroupLayout.DEFAULT_SIZE;

public class TableRowDemo extends JFrame {

    Object[][] data = { {"Kathy", "Smith", "Snowboarding", new Integer(5), new Boolean(false)},
        {"John", "Doe", "Rowing", new Integer(3), new Boolean(true)},
        {"Sue", "Black", "Knitting", new Integer(2), new Boolean(false)},
        {"Jane", "White", "Speed reading", new Integer(20), new Boolean(true)},
        {"Joe", "Brown", "Pool", new Integer(10), new Boolean(false)}
    };
  
    String[] columnNames = {"First Name", "Last Name", "Sport", "# of Years", "Vegetarian"};
  
    public static void main(String [] args) {
        new TableRowDemo().setVisible(true);
    }
  
    public TableRowDemo() {
        GroupLayout layout = new GroupLayout(getContentPane());
      
        JLabel label = new JLabel("My table:");
        JTable table = new JTable(data, columnNames);
      
        JScrollPane tableScrollPane = new JScrollPane(table);
      
        int numberOfRowsToDisplay = 3;
      
        //Fetch the border "padding"
        Insets insets = tableScrollPane.getBorder().getBorderInsets(table);
      
        //Compute the total height of the table
        int preferredTableHeight = insets.bottom + insets.top
                        + (int) table.getTableHeader().getPreferredSize().getHeight() +
                        numberOfRowsToDisplay * table.getRowHeight();
      
        layout.setVerticalGroup(layout.createSequentialGroup()
            .addComponent(label)
            .addComponent(tableScrollPane, DEFAULT_SIZE, preferredTableHeight, DEFAULT_SIZE)
        );
      
        layout.setHorizontalGroup(layout.createParallelGroup()
            .addComponent(label)
            .addComponent(tableScrollPane)
        );

        getContentPane().setLayout(layout);
        pack();
    }
}