如何冻结JTable中的行?
这应该与Microsoft Excel的工作方式类似,在Microsoft Excel中,用户可以选择一个单元格,然后右键单击并冻结/解冻行。我找到了很多关于冻结列的答案,但没有找到行。
谢谢!
发布于 2020-05-17 06:21:08
简而言之,您需要两个JScrollPanes:顶部的一个用于处理冻结的行(具有一个行标题来处理其冻结的列),底部的一个用于可滚动的行(也具有rowheader) -因此您最终需要管理4个表。不要在顶部的滚动窗格中使用滚动条:而是向下面的滚动窗格()的视区中添加一个ChangeListener,如下所示:
public void stateChanged(ChangeEvent e) {
Point p = spMain.getViewport().getViewPosition();
p.y = 0;
spHead.getViewport().setViewPosition(p);
}底部窗格的TableHeader需要隐藏(至少在显示顶部窗格时):
spMain.setColumnHeaderView(bodyTable.getTableHeader());
spMain.getColumnHeader().setVisible(false);我使用的JVM有一个“功能”,它使顶部窗格中的标题与底部的列对齐变得复杂,直到顶部的表至少有一行--只考虑在实际执行“冻结”时才使用顶部窗格。
发布于 2021-06-26 04:47:07
一种简单的方法是重写表模型的getValueAt()方法。
你可以这样做:
Supplier<Integer> firstVisibleRowIndexSupplier = () -> {
Point p = scrollPane.getViewport()
.getViewPosition();
return table.rowAtPoint(p);
};将firstVisibleRowIndexSupplier传递给表格模型。
在表格模型中:
@Override
public Object getValueAt(int row, int column) {
int firstVisibleRow = this.firstVisibleRowSupplier.get();
// Logic for returning data for the frozen rows, based on firstVisibleRow
}缺点是,当垂直向上滚动时,表格会缓存数据。解决此问题的方法是向垂直滚动条添加一个AdjustmentListener:
scrollPane.getVerticalScrollBar()
.addAdjustmentListener(e -> tableModel.refresh());使用
// TableModel
public void refresh() {
// Preserves selection
fireTableChanged(new TableModelEvent(this, //tableModel
this.firstVisibleRowSupplier.get(), //firstRow
getRowCount() - 1, //lastRow
TableModelEvent.ALL_COLUMNS, //column
TableModelEvent.UPDATE)); //changeType
}有了这个变通方法,有一个我还没有找到修复的小缺点:当用鼠标滚轮向上滚动时,冻结的行将在表更新之前短暂闪烁。当使用滚动条滚动或使用滚动条或鼠标滚轮向下滚动时,这种情况不会发生。
https://stackoverflow.com/questions/40565141
复制相似问题