我已经阅读了Oracle的API数百次,阅读了无数篇文章,无论是在这里还是其他地方,在jtable变为可见后,我仍然无法调整列的大小
正如您所推断的,我还试图使用jcheckboxes设置列的可见性。正如其他文章所指出的,使用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);
}
}
}
附录doLayout()、validate()resizeAndRepaint()不起作用,也不将setAutoResizeMode设置为off。
注意:正如你们中的一些人可能已经发现的那样,调整大小实际上是有效的AFTER所有列都被隐藏。然而,它仍然不能回答我的问题,即为什么在调用setMin、setPreferred和setMax时不调整列大小。
注意:我正在编写一个字体查看器,它可以同时显示多个字体系列、样式和大小。我有一个显示已安装字体的jtable(第1列显示字体系列,第2列显示相应字体的字母表,第3列显示相应的字体的数字(0-9)
提供的示例代码ive将用于显示上述内容,用户可以选择隐藏字母表或数字
我还有6个jlist,其中3个包含可用的字体系列、样式和大小,另外3个包含用户选择。我使用另一个jtable来显示用户选择(第1列所选字体系列、第2列字体样式、第3列字体大小、第4列字母表、第5列数字、第6列标点符号和第7列符号。
用户将被允许选择哪些列是可见的。不过,正如我所提到的,当更新显示表时,数据并不是它应该显示的位置。即用户选择隐藏列、数字和符号,然后选择要显示的新字体、样式和大小。
正如我所指出的,删除表列不仅增加了的复杂性
我同意,我为您提供了管理这种复杂性的工作代码。我看到你没有尝试这个代码,即使它可以用一行代码添加到你的程序中。
尝试从表中添加和删除数据
这不是问题。TableColumn所做的只是将数据从TableModel映射到TableColumn。创建TableColumn时,它的默认列值为0。所以,是的,除非你管理得当,否则你会遇到问题,这就是为什么我给了你一个工作代码的链接。
我的问题是,为什么在调用setMin、setPreferred和setMax时不调整列大小。
答案是代码执行的顺序很重要。这是首选尺寸必须在最小/最大尺寸范围内,所以您需要最后设置首选尺寸:
tableColumn.setMinWidth(minWidth);
tableColumn.setMaxWidth(maxWidth);
tableColumn.setPreferredWidth(preferredWidth);
编辑:
简单的例子。您可以将其称为MCVE
或SSCCE。
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() );
}
}
如果这不能验证API是否正常工作,那么我不知道会发生什么。