Java jtable可见后无法设置列宽

Java jtable可见后无法设置列宽,java,swing,jtable,jtableheader,preferredsize,Java,Swing,Jtable,Jtableheader,Preferredsize,我已经阅读了Oracle的API数百次,阅读了无数的文章,无论是在这里还是在其他地方,在jtable变得可见之后,我仍然无法调整列的大小。 正如您可以推断的,我还尝试使用jcheckbox设置列的可见性。如其他文章所述,使用addColumn和removeColumn不会将列返回到其原始位置。我以前使用过一个附加类来保存列信息,例如列本身、其标识符和原始索引。在列的可见性更改后添加/删除数据的问题也变得很棘手。我注意到数据列不正确。因此,我选择设置列的minWidth、preferredWidt

我已经阅读了Oracle的API数百次,阅读了无数的文章,无论是在这里还是在其他地方,在jtable变得可见之后,我仍然无法调整列的大小。

正如您可以推断的,我还尝试使用jcheckbox设置列的可见性。如其他文章所述,使用addColumn和removeColumn不会将列返回到其原始位置。我以前使用过一个附加类来保存列信息,例如列本身、其标识符和原始索引。在列的可见性更改后添加/删除数据的问题也变得很棘手。我注意到数据列不正确。因此,我选择设置列的minWidth、preferredWidth和maxWidth。

现在我的问题是,当setColumnVisible设置为true时,下面的代码不会调整列的宽度。用朱利叶斯·萨姆纳·米勒的话说,为什么会这样

import java.awt.*;
import java.awt.event.*;

import java.util.*;

import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.*;
import javax.swing.table.*;

class run
{
    public static void main(String args[])
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                Viewer viewer = new Viewer();

                JFrame jframe = new JFrame();
                jframe.add(viewer);
                jframe.createBufferStrategy(1); // required for dual monitor issues
                jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                jframe.setLocation(50,100);
                jframe.pack();
                jframe.setVisible(true);
            }
        });
    }
}

class Viewer extends JPanel
{
    static final long serialVersionUID = 0;

    DefaultTableModel defaultTableModel;
    JTable jtable;
    JCheckBox jcheckBox[];

    public Viewer()
    {
        this.setLayout(new BorderLayout());

        JPanel jpanel = new JPanel(new BorderLayout());

        String columnNames[] = {"a","b","c","d","e"};

        Object tableData[][] = 
        {
            {"a1","b1","c1","d1","e1"},
            {"a2","b2","c2","d2","e2"},
            {"a3","b3","c3","d3","e3"}
        };

        defaultTableModel = new DefaultTableModel(tableData,columnNames);

        jtable = new JTable(defaultTableModel);

        JScrollPane jscrollPane = new JScrollPane(jtable);

        jpanel.add(jscrollPane,BorderLayout.CENTER);

        TableColumnModel tableColumnModel = jtable.getColumnModel();

        int columnCount = tableColumnModel.getColumnCount();

        jcheckBox = new JCheckBox[columnCount];

        JPanel visibility = new JPanel(new GridLayout(1,columnCount));

        for (int column = 0; column < columnCount; column++)
        {
            TableColumn tableColumn = tableColumnModel.getColumn(column);

            String identifier = (String)tableColumn.getIdentifier();

            jcheckBox[column] = new JCheckBox(identifier,true);
            jcheckBox[column].setName(identifier);
            jcheckBox[column].addActionListener(new ColumnListener());

            visibility.add(jcheckBox[column]);
        }

        jpanel.add(visibility,BorderLayout.SOUTH);

        this.add(jpanel,BorderLayout.CENTER);
    }

    public void setColumnVisible(String identifier, boolean setVisible)
    {
        TableColumn tableColumn = jtable.getColumn(identifier);

        int minWidth = 0;
        int preferredWidth = 0;
        int maxWidth = 0;

        if (setVisible)
        {
            minWidth = 100;
            preferredWidth = 100;
            maxWidth = 100;
        }

        tableColumn.setMinWidth(minWidth);
        tableColumn.setPreferredWidth(preferredWidth);
        tableColumn.setMaxWidth(maxWidth);

        //jtable.doLayout(); does not work
        //jtable.validate(); does not work
        //jtable.getTableHeader().resizeAndRepaint(); does not work
    }

    class ColumnListener implements ActionListener
    {
        public void actionPerformed(ActionEvent actionEvent)
        {
            JCheckBox checkBox = (JCheckBox)actionEvent.getSource();

            boolean setVisible = checkBox.isSelected();

            String identifier = checkBox.getName();

            setColumnVisible(identifier,setVisible);
        }
    }
}
import java.awt.*;
导入java.awt.event.*;
导入java.util.*;
导入javax.swing.*;
导入javax.swing.border.*;
导入javax.swing.event.*;
导入javax.swing.table.*;
班跑
{
公共静态void main(字符串参数[])
{
SwingUtilities.invokeLater(新的Runnable()
{
公开募捐
{
查看器=新查看器();
JFrame JFrame=新JFrame();
jframe.add(查看器);
jframe.createBufferStrategy(1);//双监视器问题需要
jframe.setDefaultCloseOperation(jframe.EXIT_ON_CLOSE);
jframe.setLocation(50100);
jframe.pack();
jframe.setVisible(true);
}
});
}
}
类查看器扩展了JPanel
{
静态最终长SerialVersionId=0;
DefaultTableModel DefaultTableModel;
JTable-JTable;
JCheckBox JCheckBox[];
公众观众()
{
此.setLayout(新的BorderLayout());
JPanel JPanel=newjpanel(newborderlayout());
字符串列名[]={“a”、“b”、“c”、“d”、“e”};
对象tableData[][]=
{
{“a1”、“b1”、“c1”、“d1”、“e1”},
{“a2”、“b2”、“c2”、“d2”、“e2”},
{“a3”、“b3”、“c3”、“d3”、“e3”}
};
defaultTableModel=新的defaultTableModel(tableData,columnNames);
jtable=新的jtable(defaultTableModel);
JScrollPane JScrollPane=新的JScrollPane(jtable);
add(jscrollPane,BorderLayout.CENTER);
TableColumnModel TableColumnModel=jtable.getColumnModel();
int columnCount=tableColumnModel.getColumnCount();
jcheckBox=新的jcheckBox[列计数];
JPanel可见性=新的JPanel(新的GridLayout(1,columnCount));
for(int column=0;column


附录doLayout()、validate()resizeAndRepaint()不起作用,将setAutoResizeMode设置为off也不起作用。

注意:正如你们中的一些人可能已经发现的那样,在所有列都隐藏之后,调整大小实际上是有效的。但是,它仍然不能回答我的问题,即为什么在调用setMin、setPreferred和setMax时不调整列大小。

注意:我正在编写一个字体查看器,可以同时显示多个字体系列、样式和大小。我有一个显示已安装字体的jtable(第1列显示字体系列,第2列显示相应字体中的字母,第3列显示数字(0-9)在相应的字体中。

我提供的示例代码将用于显示上述内容,使用户可以选择隐藏字母或数字。

我还有6个jlist,其中3个包含可用的字体系列、样式和大小,其他3个包含用户选择。我使用另一个jtable来显示我们er选项(第1列选定字体系列、第2列字体样式、第3列字体大小、第4列字母、第5列数字、第6列标点符号和第7列符号)。

用户可以选择哪些列是可见的。但是,正如我提到的,当显示表更新时,数据不在其应该的位置。即用户选择隐藏列、数字和符号,然后选择要显示的新字体、样式和大小

正如我所指出的,删除表列不仅增加了复杂性

我同意,我给了你管理这种复杂性的工作代码。我看到你没有尝试代码e
    tableColumn.setMinWidth(minWidth);
    tableColumn.setMaxWidth(maxWidth);
    tableColumn.setPreferredWidth(preferredWidth);
import java.awt.*;
import javax.swing.table.*;

public class Main
{
    public static void main(String[] args)
    {
        TableColumn tc = new TableColumn();
        tc.setMinWidth(1);
        tc.setMaxWidth(10);
        tc.setPreferredWidth(15);
        System.out.println( tc.getPreferredWidth() );
    }
}