Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I have a JTable where the last row is the total row that aggregates all other rows. When the user clicks a column header on the table, rows are sorted by that column, except for the total row which should be always at bottom.

Is there a simple way to implement this with TableRowSorter?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
170 views
Welcome To Ask or Share your Answers For Others

1 Answer

Personally, I would create a single-row 2nd table with the header removed, and place it directly underneath the main table, so as to create the illusion of a last row.

Besides it solving your sorting problem, it will also persist as the user scrolls that main table, which is probably a good thing since it's a "totals" row.

You could even add a ColumnModelListener to the main table's TableColumnModel to synch up column resizing.

EDIT: Here's the general idea:

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())); 
  }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...