Search code examples
javaswingjtablepreferredsize

JTable setPreferredWidth() for columns displaying incorrectly


I have a JTable with an AbstractTabelModel displayed. I tried to create a void method in my project that sets the width of each column to the length of the longest value in the column. Here is the method that I am using right now, where "accountWindow" is the JTable:

public void setColumnWidths(){
    accountWindow.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
    for (int i = 0; i < accountWindow.getColumnCount(); i++){
        int greatestStringLength = 2;
        for (int z = 0; z < accountWindow.getRowCount(); z++){
            if (accountWindow.getValueAt(z, i).toString().length() > greatestStringLength){
                System.out.println("Width SET");
                greatestStringLength = accountWindow.getValueAt(z, i).toString().length();
                accountWindow.getColumnModel().getColumn(i).setPreferredWidth(greatestStringLength);
            }
            //System.out.println(accountWindow.getValueAt(z, i).toString());
            //System.out.println("Greatest Value: " + greatestValueWidth);
        }
    }
}

The method is called correctly in my Controller class (MVC), but it is setting the width of each column to essentially 0. Method is called after the table is updated and the fireTableData() method is called and account information is displayed. I have added the JTable to a scroll pane. Any comments or suggestions would be appreciated.


Solution

  • The width needs to be specified in pixels not characters in the String.

    if (accountWindow.getValueAt(z, i).toString().length() > greatestStringLength){
    

    Looks to me like you are just getting the number of characters in the String, not the width it takes to render the String. That is 20 characters will NOT render in 20 pixels. The width of the String will vary for different Fonts.

    Check out Table Column Adjuster for the solution on how to determine the rendered width. It gives a simple usage and a custom class that you can use which has more features.

    Both solutions will actually invoke the renderer used by the table to determine the maximum width.