我需要在 JScrollPane 中创建一个具有可调整列大小的 JTable(当用户增加列宽时 - 出现水平滚动条)。
为此,我使用了 table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
。
此外,当视口(viewport)足够宽以包含整个表格时 - 列应拉伸(stretch)以填充视口(viewport)宽度。
为此,我重写了 JTable 类的 getScrollableTracksViewportWidth()
方法,如下所示:
@Override
public boolean getScrollableTracksViewportWidth() {
return getPreferredSize().width < getParent().getWidth();
}
这种方法效果很好,除了一件事:当我第一次尝试调整列大小时,它会将自己的宽度返回到起始位置。如果我快速调整列大小并释放鼠标表,则继续正常工作。
那么,这种行为的原因是什么?为什么即使 getScrollableTracksViewportWidth()
返回 false,表格也会尝试调整大小?或者,也许您可以提出更好的解决方案来实现这种调整模式?
波纹管是上述问题的一个简单的工作示例:
import javax.swing.*;
public class TestTable {
private static Object[][] data = new Object[][] {
{ "a", "b", "c" },
{ "d", "e", "f" }
};
private static Object[] colNames = new Object[] { "1", "2", "3" };
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JTable table = new JTable(data, colNames) {
@Override
public boolean getScrollableTracksViewportWidth() {
return getPreferredSize().width < getParent().getWidth();
}
};
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new JScrollPane(table));
frame.pack();
frame.setVisible(true);
}
});
}
}
最佳答案
当您在水平滚动条不可见时尝试增加列的大小时,默认的 doLayout()
逻辑似乎不起作用,所以我去掉了默认逻辑并且只是接受了列的宽度而不尝试调整它。
import javax.swing.*;
import javax.swing.table.*;
public class TestTable {
private static Object[][] data = new Object[][] {
{ "a", "b", "c" },
{ "d", "e", "f" }
};
private static Object[] colNames = new Object[] { "1", "2", "3" };
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JTable table = new JTable(data, colNames)
{
@Override
public boolean getScrollableTracksViewportWidth()
{
return getPreferredSize().width < getParent().getWidth();
}
@Override
public void doLayout()
{
TableColumn resizingColumn = null;
if (tableHeader != null)
resizingColumn = tableHeader.getResizingColumn();
// Viewport size changed. May need to increase columns widths
if (resizingColumn == null)
{
setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
super.doLayout();
}
// Specific column resized. Reset preferred widths
else
{
TableColumnModel tcm = getColumnModel();
for (int i = 0; i < tcm.getColumnCount(); i++)
{
TableColumn tc = tcm.getColumn(i);
tc.setPreferredWidth( tc.getWidth() );
}
// Columns don't fill the viewport, invoke default layout
if (tcm.getTotalColumnWidth() < getParent().getWidth())
setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
super.doLayout();
}
setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
}
};
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new JScrollPane(table));
frame.pack();
frame.setVisible(true);
}
});
}
}
编辑为使用 AUTO_RESIZE_ALL_COLUMNS。
关于java - 仅当适合视口(viewport)时才启用 JTable 的自动调整大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15234691/