[英]How to freeze rows in JTable
如何凍結JTable
行?
這應該與 Microsoft Excel 類似,在 Microsoft Excel 中,用戶可以選擇一個單元格並右鍵單擊並凍結/解凍行。 我找到了很多關於凍結列而不是行的答案。
謝謝!
簡短的回答是,您需要有兩個 JScrollPanes:頂部的一個處理凍結的行(帶有行標題來處理其凍結的列),底部的一個用於可滾動行(也帶有行標題) - 所以你最終得到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);
其余的並不是一帆風順,但如果您沒有生成的行號列來模擬 Excel,則可以讓您的生活更輕松,不允許凍結已經凍結的表格(您無法在 Excel 中執行此操作) ) 並且不允許排序(至少是凍結部分中的列。我使用的 JVM 有一個“功能”,它使頂部窗格中的標題與下方的列對齊變得復雜,直到頂部表至少有一個行 - 在實際執行“凍結”后僅考慮使用頂部窗格。
一個簡單的方法是覆蓋表模型的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
}
使用此解決方法,有一個我尚未找到修復的小缺點:當用鼠標滾輪向上滾動時,凍結的行將在表更新之前短暫閃爍。 使用滾動條滾動或使用滾動條或鼠標滾輪向下滾動時,這種情況不會發生太多。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.