2010-03-30 41 views
9

在JScrollPane中设置表格的最佳方式是什么?不管水平滚动,第一列总是在同一位置的屏幕上,并与在下面传递的列重叠?如何创建JTable,其中第一列始终位于JScrollPane视口中?

当滚动条位于最左侧时,这些列看起来很正常,但随着用户向右滚动,次列(2和on)在第一列下移动,直到最后一列出现在视?

我发现从埃克斯坦的“的Java Swing”书之类的,这是否采取了样本,但不允许在第一列的调整。我正在考虑一个方案,其中一个JPanel拥有一个水平结构和一个拥有辅助列的表以及另一个浮动在其上的JPanel(固定不管滚动)。该结构将保持视口范围不变,因为第一列浮动。理想情况下,我可以使用同一个模型在两张桌子上做,但我不确定整个想法是否是一个天真的解决方案。

我最想要的一个设置,其中多个表在同一垂直滚动面板,在那里他们所有的第一列排列并一起移动,并有单独的表之间只是有点水平的差距。

回答

12

Fixed Column Table可以满足您的大部分需求。

它不支持调整固定柱,所以你需要添加如下代码:

MouseAdapter ma = new MouseAdapter() 
{ 
    TableColumn column; 
    int columnWidth; 
    int pressedX; 

    public void mousePressed(MouseEvent e) 
    { 
     JTableHeader header = (JTableHeader)e.getComponent(); 
     TableColumnModel tcm = header.getColumnModel(); 
     int columnIndex = tcm.getColumnIndexAtX(e.getX()); 
     Cursor cursor = header.getCursor(); 

     if (columnIndex == tcm.getColumnCount() - 1 
     && cursor == Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR)) 
     { 
      column = tcm.getColumn(columnIndex); 
      columnWidth = column.getWidth(); 
      pressedX = e.getX(); 
      header.addMouseMotionListener(this); 
     } 
    } 

    public void mouseReleased(MouseEvent e) 
    { 
     JTableHeader header = (JTableHeader)e.getComponent(); 
     header.removeMouseMotionListener(this); 
    } 

    public void mouseDragged(MouseEvent e) 
    { 
     int width = columnWidth - pressedX + e.getX(); 
     column.setPreferredWidth(width); 
     JTableHeader header = (JTableHeader)e.getComponent(); 
     JTable table = header.getTable(); 
     table.setPreferredScrollableViewportSize(table.getPreferredSize()); 
     JScrollPane scrollPane = (JScrollPane)table.getParent().getParent(); 
     scrollPane.revalidate(); 
    } 
}; 

JTable fixed = fixedColumnTable.getFixedTable(); 
fixed.getTableHeader().addMouseListener(ma); 
+0

人力资源管理模式,我希望我的问题是比较晦涩得到答案迅速。这应该工作得非常好。我会用你提供的可调整大小的列代码来尝试它。谢谢。 – voodoogiant 2010-03-30 22:33:59

1

我认为你是在正确的轨道上。你在概念上有一个每行都有一个“标题栏”的表格。我会用两个表格 - 一个是最左边的一列,另一个是所有其他的。然后,我会将这些显示在JSplitPane中,左边的“最左列”表格和右边的其余部分。将有一个垂直滚动条控制两个表的y偏移量,并且一个水平滚动条控制右侧窗格(仅)。

您还可以使用JScrollPane中的高级功能设置“标题”组件上的主滚动区域的左侧。我从来没有做过,但是你可以将它用作行的'标题'。

4

JScrollPane中有一个区域专门为此,该行标题(见API :)

所有你需要做的是: - 此固定区域 创建一个额外的JTable - 把它挂到您的数据模型 的第一列 - 将其设置为行标题 - 在主表省略或删除第一列数据。

当滚动条向上和向下滚动时,两个表格将同步滚动,不添加任何代码。当滚动条水平滚动时,行标题始终保持可见状态,只有主表滚动。

在大多数情况下,唯一添加的代码,你需要是列大小调整,像camickr的例子。

2

退房这个班,从http://fahdshariff.blogspot.sg/2010/02/freezing-columns-in-jtable.html

import javax.swing.JScrollPane; 
import javax.swing.JTable; 
import javax.swing.JViewport; 
import javax.swing.table.DefaultTableModel; 
import javax.swing.table.JTableHeader; 
import javax.swing.table.TableModel; 
public class FrozenTablePane extends JScrollPane{  
    public FrozenTablePane(JTable table, int colsToFreeze){  
     super(table);  
     TableModel model = table.getModel();  
     //create a frozen model  
     TableModel frozenModel = new DefaultTableModel(         
       model.getRowCount(),         
       colsToFreeze);  
     //populate the frozen model  
     for (int i = 0; i < model.getRowCount(); i++) {  
      for (int j = 0; j < colsToFreeze; j++) {   
       String value = (String) model.getValueAt(i, j);   
       frozenModel.setValueAt(value, i, j);  
      }  
     } 
    //create frozen table 
    JTable frozenTable = new JTable(frozenModel); 
    //remove the frozen columns from the original table 
    for (int j = 0; j < colsToFreeze; j++) { 
    table.removeColumn(table.getColumnModel().getColumn(0)); 
    }  table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); 
    //format the frozen table  
    JTableHeader header = table.getTableHeader();  
    frozenTable.setBackground(header.getBackground());  
    frozenTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);  
    frozenTable.setEnabled(false);  
    //set frozen table as row header view 
    JViewport viewport = new JViewport();  
    viewport.setView(frozenTable); 
    viewport.setPreferredSize(frozenTable.getPreferredSize()); 
    setRowHeaderView(viewport); 
    setCorner(JScrollPane.UPPER_LEFT_CORNER, 
      frozenTable.getTableHeader()); 
    } 
} 

此后提取,只需调用类的构造方法:

JTable table = new JTable(<yourData>, <yourColumns>); 
FrozenTablePane frozenPane = new FrozenTablePane(table,1);//where 1 is the number of freezed column(s) 
相关问题