JTable中的页脚行

将页脚行放入JTable的最佳方法是什么? 有没有人有任何示例代码来执行此操作?

到目前为止,我唯一想到的方法是在表模型中放一个特殊的行,它总是被排序到底部。


这是我最终得到的:

JTable mainTable = new JTable(mainTableModel); JTable footerTable = new JTable(footerModel); footerTable.setColumnModel(mainTable.getColumnModel()); // Disable selection in the footer. Otherwise you can select the footer row // along with a row in the table and that can look quite strange. footerTable.setRowSelectionAllowed(false); footerTable.setColumnSelectionAllowed(false); JPanel tablePanel = new JPanel(); BoxLayout boxLayout = new BoxLayout(tablePanel, BoxLayout.Y_AXIS); tablePanel.setLayout(boxLayout); tablePanel.add(mainTable.getTableHeader()); // This seems like a bit of a WTF tablePanel.add(mainTable); tablePanel.add(footerTable); 

排序工作正常,但选择页脚行有点奇怪。

尝试使用与数据表使用相同列模型的第二个JTable,并将页脚数据添加到该表。 在原始表下添加第二个(页脚)表。

 JTable footer = new JTable(model, table.getColumnModel()); panel.add(BorderLayout.CENTER, table); panel.add(BorderLayout.SOUTH, footer); 

看起来这个项目有一个名为JideScrollPane的组件,它宣告支持行页脚。 我自己没试过,但听起来它确实是你想要的! 该网站还有一个演示应用程序,你可以看到它在行动,它看起来很不错。

请注意,他们需要付出的代价似乎很多,但他们的JideScrollPane看起来是免费和开源的。

使用下面的两个表是一个很好的方法。

如果您希望能够调整/移动/删除列,则键不要在表之间重用相同的columnModel。 让听众做大小调整。 见例子:

 package snippet; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.ListSelectionModel; import javax.swing.SwingUtilities; import javax.swing.event.ChangeEvent; import javax.swing.event.ListSelectionEvent; import javax.swing.event.TableColumnModelEvent; import javax.swing.event.TableColumnModelListener; import javax.swing.table.TableColumnModel; public class FixedRow2Tables extends JFrame { private static final long serialVersionUID = 4676303089799270571L; Object[][] data; Object[] column; JTable footerTable, table; public FixedRow2Tables() { super("Fixed Row Example"); Object[][] mainData = new Object[][] { { "a", "", "", "", "", "" }, { "", "b", "", "", "", "" }, { "", "", "c", "", "", "" }, { "", "", "", "d", "", "" }, { "", "", "", "", "e", "" }, { "", "", "", "", "", "f" } }; Object[][] summaryData = { { "fixed1", "", "", "", "", "" }, { "fixed2", "", "", "", "", "" } }; column = new Object[] { "A", "B", "C", "D", "E", "F" }; table = new JTable(mainData, column); table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); footerTable = new JTable(summaryData, column); footerTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); footerTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); footerTable.setTableHeader(null); // footerTable.setColumnModel(table.getColumnModel()); table.getColumnModel().addColumnModelListener( new TableColumnModelListener() { @Override public void columnSelectionChanged(ListSelectionEvent e) { } @Override public void columnRemoved(TableColumnModelEvent e) { } @Override public void columnMoved(TableColumnModelEvent e) { } @Override public void columnMarginChanged(ChangeEvent e) { final TableColumnModel tableColumnModel = table .getColumnModel(); TableColumnModel footerColumnModel = footerTable .getColumnModel(); for (int i = 0; i < tableColumnModel.getColumnCount(); i++) { int w = tableColumnModel.getColumn(i).getWidth(); footerColumnModel.getColumn(i).setMinWidth(w); footerColumnModel.getColumn(i).setMaxWidth(w); // footerColumnModel.getColumn(i).setPreferredWidth(w); } footerTable.doLayout(); footerTable.repaint(); repaint(); } @Override public void columnAdded(TableColumnModelEvent e) { } }); JScrollPane scroll = new JScrollPane(table); scroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); scroll.setPreferredSize(new Dimension(400, 100)); getContentPane().add(scroll, BorderLayout.CENTER); getContentPane().add(footerTable, BorderLayout.SOUTH); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { FixedRow2Tables frame = new FixedRow2Tables(); frame.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { System.exit(0); } }); frame.pack(); frame.setVisible(true); } }); } } 

我唯一一次这样做,我只是在模型中添加了一行,如下所示:

  @Override public int getRowCount() { return _tableContents.size() + 1; } 

_tableContents当然是我模型背后的实际数据。 你必须要知道模型中的额外行(在setValueAt(…)之类的调用中)

祝你好运。

您可以尝试实现自己的TableCellRenderer ,用您的页脚替换最后一个可见行的呈现内容。 然而,这不会固定在表格的底部,它可能会在您滚动时上下移动。

我想最好的方法(但肯定不是最简单的方法)是查看JTableHeader组件的源代码,看看它是如何工作的,然后创建自己的JTableFooter组件。 您可以为页脚重用JTableHeader UI Delegate,我认为主要区别在于getHeaderRect()方法,它确定给定列标题区块的边界。

这是java bug数据库中提到的另一个解决方案

适用于我的解决方案是为视口绘制边框(您的JTable必须位于JScrollPane中)….

 import java.awt.*; import javax.swing.*; import javax.swing.border.*; import javax.swing.event.*; import javax.swing.table.*; class Application extends JFrame { public Application() { this.setBounds(100,100,500,200); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); String data[][] = {{"a1","b1","c1"},{"a2","b2","c2"},{"a3","b3","c3"}}; String columnNames[] = {"a","b","c"}; JTable jtable = new JTable(new DefaultTableModel(data,columnNames)); JScrollPane jscrollPane = new JScrollPane(jtable,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); jscrollPane.setBorder(new CompoundBorder(new MatteBorder(0,0,1,0,Color.gray),new EmptyBorder(0,0,0,0))); this.add(jscrollPane,BorderLayout.CENTER); JTable jtable_footer = new JTable(new DefaultTableModel(3,columnNames.length),jtable.getColumnModel()); SyncListener syncListener = new SyncListener(jtable,jtable_footer); this.add(jtable_footer,BorderLayout.SOUTH); } public static void main(String args[]) { SwingUtilities.invokeLater(new Runnable() { public void run() { Application application = new Application(); application.setVisible(true); } }); } } class SyncListener implements TableColumnModelListener { JTable jtable_data; JTable jtable_footer; public SyncListener(JTable main, JTable footer) { jtable_data = main; jtable_footer = footer; DefaultTableColumnModel dtcm = (DefaultTableColumnModel)jtable_data.getColumnModel(); dtcm.removeColumnModelListener(dtcm.getColumnModelListeners()[1]); dtcm.addColumnModelListener(this); } public void columnMarginChanged(ChangeEvent changeEvent) { for (int column = 0; column < jtable_data.getColumnCount(); column++) { jtable_footer.getColumnModel().getColumn(column).setWidth(jtable_data.getColumnModel().getColumn(column).getWidth()); } jtable_footer.repaint(); } public void columnAdded(TableColumnModelEvent e){} public void columnMoved(TableColumnModelEvent e){} public void columnRemoved(TableColumnModelEvent e){} public void columnSelectionChanged(ListSelectionEvent e){} }