2013-03-05 22 views
13

我需要在带有可调整列的JScrollPane中创建一个JTable(当用户增加列宽 - 出现水平滚动条时)。 对此,我使用table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);。 另外,当视口足够宽以包含整个表格时 - 列应拉伸以填充视口宽度。 要做到这一点我必须重写JTable类的getScrollableTracksViewportWidth()方法如下:只有在适合视口时才启用JTable的自动调整大小

@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); 
      } 
     }); 
    } 
} 

回答

17

这似乎是默认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。

+0

非常好,效果很好。 – user2137020 2013-03-06 08:56:17

+1

另请参阅:http://stackoverflow.com/questions/15499255/jtable-with-autoresize-horizo​​ntal-scrolling-and-shrinkable-first-column对于不同的实现。 – camickr 2013-03-20 16:17:20

+0

工程就像一个魅力!我发现唯一的解决方案是完美的。 – 2017-01-14 20:35:13

相关问题