JTable ignores setPreferredWidth during initial layout when AUTO_RESIZE_LAST_COLUMN is enabled

XMLWordPrintable

    • b08
    • 24
    • generic
    • generic

      ADDITIONAL SYSTEM INFORMATION :
      $ java -version
      openjdk version "25.0.1" 2025-10-21
      OpenJDK Runtime Environment (build 25.0.1+8-Ubuntu-122.04)
      OpenJDK 64-Bit Server VM (build 25.0.1+8-Ubuntu-122.04, mixed mode, sharing)

      $ uname -a
      Linux raymond 6.8.0-90-generic #91~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Thu Nov 20 15:20:45 UTC 2 x86_64 x86_64 x86_64 GNU/Linux

      $ echo $XDG_CURRENT_DESKTOP
      ubuntu:GNOME

      A DESCRIPTION OF THE PROBLEM :
      In Java 25, JTable columns no longer respect the widths defined via TableColumn.setPreferredWidth(int) during the initial rendering/layout phase. Even when explicitly set, the columns default to an equal distribution or a generic size, unless the developer manually calls JTable.getTableHeader().setResizingColumn(null) after setting the widths.

      This behavior is a regression as it worked as expected in Java 21 and previous versions without any manual intervention on the TableHeader state. It appears that an internal "resizing" flag remains active or improperly initialized, blocking the application of preferred widths.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      1. Create a JTable with a DefaultTableModel.
      2. Set the auto-resize mode to AUTO_RESIZE_LAST_COLUMN.
      3. Iterate through columns to set specific widths using setPreferredWidth.
      4. Display the table in a JFrame.
      5. Observe the actual width of the columns.

      ---------- BEGIN SOURCE ----------
      import javax.swing.*;
      import javax.swing.table.DefaultTableModel;
      import javax.swing.table.TableColumnModel;

      public class JTableWidthRegression {
          public static void main(String[] args) {
              SwingUtilities.invokeLater(() -> {
                  JFrame frame = new JFrame("JTable Regression Java 25");
                  frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

                  String[] cols = {"ID", "Name", "Description", "Status"};
                  Object[][] data = {{1, "Mimi", "Testing Java 25 Regression", "Pending"}};
                  
                  DefaultTableModel model = new DefaultTableModel(data, cols);
                  final JTable tab = new JTable(model);

                  tab.getTableHeader().setReorderingAllowed(false);
                  tab.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);

                  TableColumnModel columnModel = tab.getColumnModel();
                  // Defined widths
                  int[] widths = {30, 200, 100, 50};

                  for (int i = 0; i < widths.length; i++) {
                      columnModel.getColumn(i).setPreferredWidth(widths[i]);
                  }

                  // Note: In Java 21, the following line was NOT required.
                  // In Java 25, the widths are ignored unless this is called:
                  // tab.getTableHeader().setResizingColumn(null);

                  frame.add(new JScrollPane(tab));
                  frame.pack();
                  frame.setSize(600, 200);
                  frame.setLocationRelativeTo(null);
                  frame.setVisible(true);

                  System.out.println("Actual column widths on screen:");
                  for (int i = 0; i < columnModel.getColumnCount(); i++) {
                      System.out.println("Column " + i + ": " + columnModel.getColumn(i).getWidth() + "px");
                  }
              });
          }
      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      table.getTableHeader().setResizingColumn(null);

      FREQUENCY :
      ALWAYS

            Assignee:
            Prasanta Sadhukhan
            Reporter:
            Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated: