我有一个JTable
,其中最后一行是聚合所有其他行的总行。当用户单击表上的列标题时,行按该列排序,但总行应始终位于底部。
有没有一种简单的方法可以使用TableRowSorter
实现它?
就我个人而言,我会创建一个去掉标题的单行第二个表,并将其直接放在主表的下方,从而产生最后一行的错觉。
除了解决您的排序问题外,它还会在用户滚动该主表时持续存在,这可能是一件好事,因为它是一个“总计”行。
您甚至可以将ColumnModelListener
添加到主表的TableColumnModel
以同步列大小调整。
编辑:总体思路如下:
import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
public class TestFrame implements Runnable
{
JTable mainTable;
JTable fixedTable;
public static void main(String[] args)
{
SwingUtilities.invokeLater(new TestFrame());
}
public void run()
{
mainTable = new JTable(8, 3);
mainTable.getTableHeader().setReorderingAllowed(false);
mainTable.setAutoCreateRowSorter(true);
for (int r = 0; r < 8; r++)
{
for (int c = 0; c < 3; c++)
{
mainTable.setValueAt((int)(Math.random()*100), r, c);
}
}
mainTable.getColumnModel().addColumnModelListener(
new TableColumnModelListener()
{
public void columnAdded(TableColumnModelEvent e) {}
public void columnRemoved(TableColumnModelEvent e) {}
public void columnMoved(TableColumnModelEvent e) {}
public void columnSelectionChanged(ListSelectionEvent e) {}
public void columnMarginChanged(ChangeEvent e)
{
synchColumnSizes();
}
});
setVisibleRowCount(mainTable, 5);
JScrollPane scroll = new JScrollPane(mainTable);
scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
fixedTable = new JTable(1, 3);
fixedTable.setValueAt("will not sort or", 0, 0);
fixedTable.setValueAt("scroll but will", 0, 1);
fixedTable.setValueAt("resize with main", 0, 2);
JPanel p = new JPanel(new GridBagLayout());
p.setBorder(BorderFactory.createTitledBorder("Fixed Last Row"));
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.WEST;
p.add(scroll, gbc);
gbc.gridy = 1;
p.add(fixedTable, gbc);
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(p, BorderLayout.CENTER);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
private void synchColumnSizes()
{
TableColumnModel tcmMain = mainTable.getColumnModel();
TableColumnModel tcmFixed = fixedTable.getColumnModel();
for (int i = 0; i < tcmMain.getColumnCount(); i++)
{
int width = tcmMain.getColumn(i).getWidth();
tcmFixed.getColumn(i).setPreferredWidth(width);
}
}
public static void setVisibleRowCount(JTable table, int rows)
{
table.setPreferredScrollableViewportSize(new Dimension(
table.getPreferredScrollableViewportSize().width,
rows * table.getRowHeight()));
}
}
以下解决方案对我有效……
在您的表模型中,更新getRowCount()
成员以返回比所需少1行。
然后修改您的排序器报告的索引和行数,如下所示…
TableRowSorter<TableModel> sorter =
new DefaultTableRowSorter<TableModel>(this.getModel())
{
public int convertRowIndexToModel(int index)
{
int maxRow = super.getViewRowCount();
if (index >= maxRow)
return index;
return super.convertRowIndexToModel(index);
}
public int convertRowIndexToView(int index)
{
int maxRow = super.getModelRowCount();
if (index > maxRow)
return index;
return super.convertRowIndexToView(index);
}
public int getViewRowCount()
{
return super.getViewRowCount() + 1;
}
};
myTable.setRowSorter(sorter);
是否有一种简单的方法可以使用TableRowSorter实现此功能?
>
不简单
好主意,很有可能为RowSorter设置标志,它的Sorting Keys
除了String实例之外,所有ClassType都bug