Java 如何将JTable的所有列自动调整为相同的大小?

Java 如何将JTable的所有列自动调整为相同的大小?,java,swing,jtable,Java,Swing,Jtable,我正在项目中使用JTable。 我希望表格自动调整所有列的大小,使其大小相同,同时填充包含JScrollPane的宽度 我不能只将首选宽度设置为固定值,因为当用户调整框架大小时,我希望所有列都调整为相同大小,但有一个限制,即它仍然必须100%填充JScrollPane 例如,如果JScrollPane的宽度为1000,我有10列,我希望每列的大小都为100。 如果JScrollPane然后收缩到500,我希望每个列的大小调整到50 现在,我只是将JTable.setAutoResizeModeJ

我正在项目中使用JTable。 我希望表格自动调整所有列的大小,使其大小相同,同时填充包含JScrollPane的宽度

我不能只将首选宽度设置为固定值,因为当用户调整框架大小时,我希望所有列都调整为相同大小,但有一个限制,即它仍然必须100%填充JScrollPane

例如,如果JScrollPane的宽度为1000,我有10列,我希望每列的大小都为100。 如果JScrollPane然后收缩到500,我希望每个列的大小调整到50

现在,我只是将JTable.setAutoResizeModeJTable.AUTO_RESIZE_设置为OFF,结果如下:

我怎样才能做到这一点


谢谢。

调整JTable的大小后,您可以获得新的宽度JTable.getWidth,除以10进行必要的调整以获得整数结果,然后手动设置每列的宽度,看看是否有帮助。

调整JTable的大小后,您可以获得新的宽度JTable.getWidth,除以10进行必要的调整以获得整数结果,然后手动设置每列的宽度,看看是否有帮助。

当表格大小更改时,您需要某种方法来更新列模型

这个基本示例使用invalidate方法更新其列模型。它还将列设置为不可调整大小

这还会覆盖tables getScrollableTracksViewportWidth方法,以确保该表自动填充水平空间。这意味着它永远不会显示水平滚动条

public class SpringTable extends JTable {

    public SpringTable(TableModel dm) {
        super(dm);
        setAutoResizeMode(AUTO_RESIZE_OFF);
    }

    public SpringTable() {
        setAutoResizeMode(AUTO_RESIZE_OFF);
    }

    @Override
    public void doLayout() {
        int width = getWidth();
        int columnCount = getColumnCount();
        int columnSize = width / columnCount;
        for (int index = 0; index < columnCount; index++) {
            TableColumn column = getColumnModel().getColumn(index);
            column.setResizable(false);
            column.setPreferredWidth(width);
        }
        super.doLayout();
    }

    @Override
    public boolean getScrollableTracksViewportWidth() {
        return true;
    }

}

当表的大小改变时,您需要某种方法来更新列模型

这个基本示例使用invalidate方法更新其列模型。它还将列设置为不可调整大小

这还会覆盖tables getScrollableTracksViewportWidth方法,以确保该表自动填充水平空间。这意味着它永远不会显示水平滚动条

public class SpringTable extends JTable {

    public SpringTable(TableModel dm) {
        super(dm);
        setAutoResizeMode(AUTO_RESIZE_OFF);
    }

    public SpringTable() {
        setAutoResizeMode(AUTO_RESIZE_OFF);
    }

    @Override
    public void doLayout() {
        int width = getWidth();
        int columnCount = getColumnCount();
        int columnSize = width / columnCount;
        for (int index = 0; index < columnCount; index++) {
            TableColumn column = getColumnModel().getColumn(index);
            column.setResizable(false);
            column.setPreferredWidth(width);
        }
        super.doLayout();
    }

    @Override
    public boolean getScrollableTracksViewportWidth() {
        return true;
    }

}

在Windows 7上使用JDK7的JTable的默认行为是,当表的大小改变时,每个列的大小相等。只要您没有在表列上设置首选宽度,这似乎是可行的

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;

public class TestJTable {

    public static void main(String[] args) {
        new TestJTable();
    }

    public TestJTable() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }


                String[] columnNames = {"Column1", "a", "a long long column name", "column4"};
                DefaultTableModel model = new DefaultTableModel(columnNames, 5);
                final JTable table = new JTable(model);

                JButton button = new JButton("Display Column Widths");
                button.addActionListener( new ActionListener()
                {
                    public void actionPerformed(ActionEvent e)
                    {
                        int columnCount = table.getColumnCount();

                        for (int index = 0; index < columnCount; index++)
                        {
                            TableColumn column = table.getColumnModel().getColumn(index);
                            System.out.print(column.getWidth() + ", ");
                        }

                        System.out.println();
                    }
                });

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new JScrollPane(table));
                frame.add(button, BorderLayout.SOUTH);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }
}

在Windows 7上使用JDK7的JTable的默认行为是,当表的大小改变时,每个列的大小相等。只要您没有在表列上设置首选宽度,这似乎是可行的

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;

public class TestJTable {

    public static void main(String[] args) {
        new TestJTable();
    }

    public TestJTable() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }


                String[] columnNames = {"Column1", "a", "a long long column name", "column4"};
                DefaultTableModel model = new DefaultTableModel(columnNames, 5);
                final JTable table = new JTable(model);

                JButton button = new JButton("Display Column Widths");
                button.addActionListener( new ActionListener()
                {
                    public void actionPerformed(ActionEvent e)
                    {
                        int columnCount = table.getColumnCount();

                        for (int index = 0; index < columnCount; index++)
                        {
                            TableColumn column = table.getColumnModel().getColumn(index);
                            System.out.print(column.getWidth() + ", ");
                        }

                        System.out.println();
                    }
                });

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new JScrollPane(table));
                frame.add(button, BorderLayout.SOUTH);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }
}

我在上一个项目中使用了这个

addComponentListener(new ComponentListener() {
    @Override public void componentShown(ComponentEvent e) {}
    @Override public void componentMoved(ComponentEvent e) {}           
    @Override public void componentHidden(ComponentEvent e) {}

    @Override
    public void componentResized(ComponentEvent e) {
        int w = table.getWidth() / table.getColumnCount();
        for(int i = 0; i < table.getColumnCount(); i++) {
            table.getColumn(i).setPreferredWidth(w);
        }
    }
});

我在上一个项目中使用了这个

addComponentListener(new ComponentListener() {
    @Override public void componentShown(ComponentEvent e) {}
    @Override public void componentMoved(ComponentEvent e) {}           
    @Override public void componentHidden(ComponentEvent e) {}

    @Override
    public void componentResized(ComponentEvent e) {
        int w = table.getWidth() / table.getColumnCount();
        for(int i = 0; i < table.getColumnCount(); i++) {
            table.getColumn(i).setPreferredWidth(w);
        }
    }
});

我怎样才能做到这一点你不能,不仅仅是。你需要把你的手弄脏…你也可以看看@MadProgrammer:谢谢你的链接,谢谢你的回答。我同意。我的手不会那么脏:我能做到吗你不能,不仅仅是。你需要把你的手弄脏…你也可以看看@MadProgrammer:谢谢你的链接,谢谢你的回答。我同意。我的手不会那么脏:有pMad,代码由@camickr@MadProgrammer:非常感谢您的提示,我将重写invalidate或doLayout方法fyi,当您运行此代码时,invalidate方法将被调用13次。当我尝试将帧大小调整1像素时,它又被调用了9次。如果确实需要此代码,请在另一个答案中查看我的发现,那么最好向表中添加ComponentListener并侦听ComponentResistized事件。或者可能没有经常调用doLayout。@camickr是的,我自己也考虑过使用ComponentListener,可能会比doLayout更好,因为doLayout是由@camickr@MadProgrammer:非常感谢你的提示,我将覆盖失效或释放方法fyi,运行此代码时,invalidate方法被调用13次。当我尝试将帧大小调整1像素时,它又被调用了9次。如果确实需要此代码,请在另一个答案中查看我的发现,那么最好向表中添加ComponentListener并侦听ComponentResistized事件。或者可能没有经常调用doLayout。@camickr是的,我自己也考虑过使用ComponentListener,doLayout可能会更好一般来说yep,可以这样做,但我会采用程序员给我的解决方案,我更喜欢直接重写JTable的方法,将代码保留在一个地方:是的,可以这样做,但我将采用程序员给我的解决方案,我更喜欢直接重写JTable的方法,将代码保留在一个地方: