Java 如何创建第一列始终位于JScrollPane视口中的JTable?

Java 如何创建第一列始终位于JScrollPane视口中的JTable?,java,swing,jtable,jscrollpane,Java,Swing,Jtable,Jscrollpane,在JScrollPane中设置表格的最佳方法是什么,这样第一列始终位于屏幕上的相同位置,而不考虑水平滚动和重叠从下面经过的列 当滚动条位于最左侧时,列看起来正常,但当用户向右滚动时,次列(2和2)会在第一列下方移动,直到最后一列出现在视口的最右侧 我从Eckstein的《JavaSwing》一书中找到了一个样本,可以做到这一点,但它不允许调整第一列的大小。我在考虑一个方案,其中一个JPanel持有一个水平结构,一个表持有第二列,另一个JPanel浮动在它们上面(无论滚动如何固定)。该结构将在第一

在JScrollPane中设置表格的最佳方法是什么,这样第一列始终位于屏幕上的相同位置,而不考虑水平滚动和重叠从下面经过的列

当滚动条位于最左侧时,列看起来正常,但当用户向右滚动时,次列(2和2)会在第一列下方移动,直到最后一列出现在视口的最右侧

我从Eckstein的《JavaSwing》一书中找到了一个样本,可以做到这一点,但它不允许调整第一列的大小。我在考虑一个方案,其中一个JPanel持有一个水平结构,一个表持有第二列,另一个JPanel浮动在它们上面(无论滚动如何固定)。该结构将在第一列浮动时保持视口范围不变。理想情况下,我可以使用相同的模型处理两个表,但我不确定整个想法是否是一个幼稚的解决方案


理想情况下,我希望设置多个表垂直位于同一滚动窗格上,其中所有的第一列对齐并一起移动,并且各个表之间只有很小的水平间隙

我认为你的思路是对的。从概念上讲,您拥有的是一个表,每行有一个“标题列”。我将使用两个表-一个表中有“最左边”列,另一个表中有所有其他列。然后我将在一个JSplitPane中展示这些内容,左边是“最左边的列”,右边是其余的列。将有一个垂直滚动条控制两个表的y偏移,还有一个水平滚动条控制右侧窗格(仅)

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

完成了您需要的大部分工作

它不支持调整固定列的大小,因此需要添加如下代码:

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

JScrollPane有一个专门用于此的区域,即行标题(请参见中的图:)

您需要做的只是: -为此固定区域创建一个额外的JTable -将其连接到数据模型的第一列 -将其设置为行标题 -并在主表中省略或删除第一列数据

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


在大多数情况下,您需要添加的唯一代码是调整列大小,如camickr的示例

查看这个类,从

import javax.swing.JScrollPane;
导入javax.swing.JTable;
导入javax.swing.JViewport;
导入javax.swing.table.DefaultTableModel;
导入javax.swing.table.JTableHeader;
导入javax.swing.table.TableModel;
公共类FrozenTablePane扩展了JScrollPane{
公共冻结表窗格(JTable table,int colsToFreeze){
超级(表);
TableModel模型=table.getModel();
//创建冻结模型
TableModel frozenModel=新的默认TableModel(
model.getRowCount(),
冷冻);
//填充冻结的模型
对于(inti=0;i
此后,只需调用构造函数方法:

JTable table = new JTable( <yourData>, <yourColumns> );
FrozenTablePane frozenPane = new FrozenTablePane(table,1);//where 1 is the number of freezed column(s)
JTable表=新的JTable(,);
FrozenTablePane frozenPane=新的FrozenTablePane(表1)//其中1是冻结列的数量

Hrmm,我希望我的问题更加晦涩难懂,以便迅速得到答案。这应该非常有效。我将尝试使用您提供的可调整大小的列代码。谢谢
JTable table = new JTable( <yourData>, <yourColumns> );
FrozenTablePane frozenPane = new FrozenTablePane(table,1);//where 1 is the number of freezed column(s)