8387267: Editor for the last column in JTable is hard to activate after AUTO_RESIZE_LAST_COLUMN was configured
8388467: Test "api/javax_swing/interactive/JTableTests.html" JTable freezes during rapid column resize Reviewed-by: angorya, kizune, jdv
This commit is contained in:
@@ -453,6 +453,14 @@ public class JTable extends JComponent implements TableModelListener, Scrollable
|
||||
* needed.
|
||||
*/
|
||||
private boolean columnSelectionAdjusting;
|
||||
|
||||
/*
|
||||
* True after column widths have been initialized/synchronized by layout.
|
||||
* Used to distinguish the first preferred-width layout from later normal
|
||||
* AUTO_RESIZE_LAST_COLUMN layouts.
|
||||
*/
|
||||
private boolean columnWidthsInitialized;
|
||||
|
||||
/**
|
||||
* The last value of getValueIsAdjusting from the row selection models
|
||||
* valueChanged notification. Used to test if a repaint is needed.
|
||||
@@ -1264,12 +1272,6 @@ public class JTable extends JComponent implements TableModelListener, Scrollable
|
||||
autoResizeMode = mode;
|
||||
resizeAndRepaint();
|
||||
if (tableHeader != null) {
|
||||
if (mode == JTable.AUTO_RESIZE_LAST_COLUMN) {
|
||||
int colCnt = columnModel.getColumnCount();
|
||||
if (colCnt > 0) {
|
||||
tableHeader.setResizingColumn(columnModel.getColumn(colCnt - 1));
|
||||
}
|
||||
}
|
||||
tableHeader.resizeAndRepaint();
|
||||
}
|
||||
firePropertyChange("autoResizeMode", old, autoResizeMode);
|
||||
@@ -3193,21 +3195,8 @@ public class JTable extends JComponent implements TableModelListener, Scrollable
|
||||
*/
|
||||
|
||||
public void doLayout() {
|
||||
boolean prefWidthSet = false;
|
||||
TableColumn resizingColumn = getResizingColumn();
|
||||
// doLayout is called for both pack and show
|
||||
// so if initial preferred width is set by user then
|
||||
// it needs to be honoured even if resizingColumn
|
||||
// is set to last column on account of
|
||||
// AUTO_RESIZE_LAST_COLUMN autoResizeMode
|
||||
for (int i = 0; i < columnModel.getColumnCount(); i++) {
|
||||
if (columnModel.getColumn(i).getPreferredWidth() != 75
|
||||
&& columnModel.getColumn(i).getWidth() == 75) {
|
||||
prefWidthSet = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (resizingColumn == null || prefWidthSet) {
|
||||
if (resizingColumn == null) {
|
||||
setWidthsFromPreferredWidths(false);
|
||||
}
|
||||
else {
|
||||
@@ -3294,7 +3283,42 @@ public class JTable extends JComponent implements TableModelListener, Scrollable
|
||||
}
|
||||
}
|
||||
|
||||
private void accommodateLastColumnOnly() {
|
||||
int columnCount = getColumnCount();
|
||||
if (columnCount == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
int delta = getWidth() - getColumnModel().getTotalColumnWidth();
|
||||
if (delta != 0) {
|
||||
accommodateDelta(columnCount - 1, delta);
|
||||
}
|
||||
}
|
||||
|
||||
private void setWidthsFromPreferredWidthsLastColumnOnly() {
|
||||
int columnCount = getColumnCount();
|
||||
if (columnCount == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < columnCount - 1; i++) {
|
||||
TableColumn column = columnModel.getColumn(i);
|
||||
column.setWidth(column.getPreferredWidth());
|
||||
}
|
||||
|
||||
accommodateLastColumnOnly();
|
||||
}
|
||||
|
||||
private void setWidthsFromPreferredWidths(final boolean inverse) {
|
||||
if (!inverse && autoResizeMode == AUTO_RESIZE_LAST_COLUMN) {
|
||||
if (!columnWidthsInitialized) {
|
||||
setWidthsFromPreferredWidthsLastColumnOnly();
|
||||
} else {
|
||||
accommodateLastColumnOnly();
|
||||
}
|
||||
columnWidthsInitialized = true;
|
||||
return;
|
||||
}
|
||||
int totalWidth = getWidth();
|
||||
int totalPreferred = getPreferredSize().width;
|
||||
int target = !inverse ? totalWidth : totalPreferred;
|
||||
@@ -3323,6 +3347,7 @@ public class JTable extends JComponent implements TableModelListener, Scrollable
|
||||
};
|
||||
|
||||
adjustSizes(target, r, inverse);
|
||||
columnWidthsInitialized = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -3821,6 +3846,7 @@ public class JTable extends JComponent implements TableModelListener, Scrollable
|
||||
if (columnModel == null) {
|
||||
throw new IllegalArgumentException("Cannot set a null ColumnModel");
|
||||
}
|
||||
columnWidthsInitialized = false;
|
||||
TableColumnModel old = this.columnModel;
|
||||
if (columnModel != old) {
|
||||
if (old != null) {
|
||||
@@ -4634,6 +4660,10 @@ public class JTable extends JComponent implements TableModelListener, Scrollable
|
||||
* @see TableColumnModelListener
|
||||
*/
|
||||
public void columnAdded(TableColumnModelEvent e) {
|
||||
if (columnWidthsInitialized) {
|
||||
TableColumn column = columnModel.getColumn(e.getToIndex());
|
||||
column.setWidth(column.getPreferredWidth());
|
||||
}
|
||||
// If I'm currently editing, then I should stop editing
|
||||
if (isEditing()) {
|
||||
removeEditor();
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8234071 8387267
|
||||
* @summary AUTO_RESIZE_LAST_COLUMN should resize only the last column during table layout
|
||||
* @run main TestAutoResizeLastColumn
|
||||
*/
|
||||
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.table.TableColumnModel;
|
||||
|
||||
public class TestAutoResizeLastColumn {
|
||||
public static void main(String[] args) throws Exception {
|
||||
SwingUtilities.invokeAndWait(TestAutoResizeLastColumn::testLastColumnOnly);
|
||||
}
|
||||
|
||||
private static void testLastColumnOnly() {
|
||||
JTable table = new JTable(3, 3);
|
||||
table.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
|
||||
|
||||
if (table.getTableHeader().getResizingColumn() != null) {
|
||||
throw new RuntimeException(
|
||||
"AUTO_RESIZE_LAST_COLUMN must not set resizingColumn");
|
||||
}
|
||||
|
||||
TableColumnModel cm = table.getColumnModel();
|
||||
for (int i = 0; i < cm.getColumnCount(); i++) {
|
||||
cm.getColumn(i).setMinWidth(10);
|
||||
cm.getColumn(i).setPreferredWidth(100);
|
||||
cm.getColumn(i).setWidth(100);
|
||||
}
|
||||
|
||||
table.setSize(300, 100);
|
||||
table.doLayout();
|
||||
|
||||
assertWidth(cm, 0, 100);
|
||||
assertWidth(cm, 1, 100);
|
||||
assertWidth(cm, 2, 100);
|
||||
|
||||
table.setSize(360, 100);
|
||||
table.doLayout();
|
||||
|
||||
/*
|
||||
* AUTO_RESIZE_LAST_COLUMN means the +60 delta is absorbed by
|
||||
* the last column only.
|
||||
* Without fix all columns width will change to 120.
|
||||
*/
|
||||
assertWidth(cm, 0, 100);
|
||||
assertWidth(cm, 1, 100);
|
||||
assertWidth(cm, 2, 160);
|
||||
|
||||
table.setSize(330, 100);
|
||||
table.doLayout();
|
||||
|
||||
assertWidth(cm, 0, 100);
|
||||
assertWidth(cm, 1, 100);
|
||||
assertWidth(cm, 2, 130);
|
||||
}
|
||||
|
||||
private static void assertWidth(TableColumnModel cm, int column, int expected) {
|
||||
int actual = cm.getColumn(column).getWidth();
|
||||
if (actual != expected) {
|
||||
throw new RuntimeException(
|
||||
"Unexpected width for column " + column
|
||||
+ ": expected " + expected
|
||||
+ ", actual " + actual);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user