2014-09-21 97 views
4

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

正如你可以推断,我也试图设置使用jcheckboxes列的visibilty。正如其他文章指出的那样,使用addColumn和removeColumn不会将列返回到原始位置。我以前使用过一个额外的类来保存列信息,例如列本身,其标识符和原始索引。这变得混乱,以及在列的可见性改变后添加/删除数据的问题。我注意到数据不在其正确的列中。因此,我选择设置列的最小宽度,preferredWidth和maxWidth。

jtable变得可见后无法设置列宽

现在我的问题是,当setColumnVisible设置为true时,下面的代码不会调整列的宽度。用julius summner miller的话来说,它为什么如此呢?

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(),验证()resizeAndRepaint()不工作,也不设置setAutoResizeMode为关闭。

注:你们有些人mayve发现,调整大小是实际可行的所有列被隐藏。然而,它仍然没有回答我的问题,为什么在调用setMin,setPreferred和setMax时不调整列大小。

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

提供的示例代码将用于显示上述,给用户隐藏字母或数字的选项

我也有6个jlist的,其中3个包含可用的字体系列,样式和大小,另外3个包含用户选择我使用另一个jtable来显示用户选择(列1选择了字体系列,列2字体样式,列3字体大小,列4字母,列5数字,列6标点符号和列7符号

用户将被允许选择哪些列是可见的。被更新,数据不是它应该是的。即用户选择隐藏列,数字和符号,然后选择要显示的新字体,样式和大小。

+0

@AndrewThompson,我会,但我不想让人问“你在哪里触发可视性?”或“你如何触发可视性”?我不认为代码是过度的。 – johnny 2014-09-21 01:05:37

+0

@AndrewThompson,我不想进入迂腐的战争,如果你不想回答,请不要评论。 – johnny 2014-09-21 01:12:47

+0

在提供免费建议的网站上,无论是好还是坏,您都无法直接控制人们在评论或答案中发布的内容,您也不应该这样做。关于我们所有人都可以或应该做的事,就是要感谢一些人花时间和精力考虑我们的问题,提出好的建议,低估不好的建议,忽视我们不真正关心的评论,并报告滥用职位。事实上,如果您愿意,可以随意忽略这些建议。 – 2014-09-21 01:22:23

回答

6

正如我已经指出的那样,删除表列,不仅增加了复杂性

我同意,我给你管理这个复杂的工作代码。即使可以用一行代码将它添加到程序中,我也看到您没有尝试过代码。

尝试加入,并从表

这不是一个问题,删除数据。 TableColumn所做的一切就是将TableModel中的数据映射到TableColumn。当你创建一个TableColumn时,它的默认列值为0。所以是的,除非你正确地处理这个问题,否则你会遇到问题,这就是为什么我给你一个工作代码的链接。

我的问题是为什么在调用setMin,setPreferred和setMax时不调整列大小。

答案是代码执行顺序很重要。这是首选的大小必须在最小/最大尺寸范围,所以你需要设置最后首选大小:

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

编辑:

简单的例子。你可以称它为MCVESSCCE

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工作正常,那么我不知道会发生什么。

+0

omg,lolololo ........就这么简单。 API中提到的任何地方(即命令优先)?我看到你的代码,并且没有试图冒犯你,setXXXwidth更简单。列不会是可调整的,也不会是可能的。但是感谢你清理那些让我坚持了几天的东西。 – johnny 2014-09-21 02:55:18

+0

@johnny'在API中提及的任何地方 - 是的,请阅读'setPreferredWidth()'API方法。 '这些列不会是可调整的,也不会是可调整的 - 这确实简化了这个要求,但是你现在从来没有这样的未来:) – camickr 2014-09-21 03:07:34

+0

它没有提到调用优先级的顺序,它只是说“如果preferredWidth超过最小值或最大宽度,它被调整到适当的极限值。“。人们可以肯定地认为调用的顺序是不相关的。 – johnny 2014-09-21 03:32:26