簡體   English   中英

如何凍結 JTable 中的行

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM