Sort JTable Except for Last Row

后端 未结 5 1250
盖世英雄少女心
盖世英雄少女心 2020-12-03 23:54

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 c

5条回答
  •  庸人自扰
    2020-12-04 00:31

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

提交回复
热议问题