java - 仅当适合视口(viewport)时才启用 JTable 的自动调整大小

标签 java swing jtable preferredsize jviewport

我需要在 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/

相关文章:

java - 新手 : Build error running Struts2 on JBoss from Eclipse

java - 无法将值放入数组列表中

java - 在 Java Web 应用程序中加载 Applet 时出现 ClassNotFoundException

java - 停止 Swing 中事件的默认行为

javascript - 从试图多次获取相同数据的 JavaScript 函数获取 NaN

java - JTable 行中的重复值

java - 无法获取隐藏的 JTable 列

Java 正则表达式令人困惑

java - 如何使模态 JDialog 在显示后立即执行代码

java - 如何将 JFileChooser 限制为目录?