2

Please have a look at the below code.

import java.awt.*;
import java.awt.event.*;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
import javax.swing.table.*;

public class TableBasic extends JFrame
{

    final Class<?>[] columnClasses = new Class<?>[] {Date.class, String.class, Long.class, Boolean.class};



    public TableBasic()
    {

        String[] columnNames = {"Date", "String", "Long", "Boolean"};
        Object[][] data =
        {
            {getJavaDate("13-11-2020"), "A", new Long(1), Boolean.TRUE },
            {getJavaDate("13-11-2018"), "B", new Long(2), Boolean.FALSE},
            {getJavaDate("12-11-2015"), "C", new Long(9), Boolean.TRUE },
            {getJavaDate("12-11-2015"), "D", new Long(4), Boolean.FALSE},
            {null, null, null, null},
            {getJavaDate("12-11-2016"), "N/A", new Long(16), Boolean.FALSE}

        };

        DefaultTableModel model = new DefaultTableModel(data, columnNames) 
        {
            @Override
            public Class<?> getColumnClass(int column) 
            {
                return columnClasses[column];
            }
        };

        JTable table = new JTable();
        table.setModel(model);
        table.setPreferredScrollableViewportSize(table.getPreferredSize());
        table.setAutoCreateRowSorter(true);
        table.getColumnModel().getColumn(0).setCellRenderer(tableCellRenderer);

        // Sort the rows
        DefaultRowSorter sorter = ((DefaultRowSorter)table.getRowSorter()); 
        ArrayList list = new ArrayList();
        list.add( new RowSorter.SortKey(0, SortOrder.DESCENDING) );
        sorter.setSortKeys(list);
        sorter.sort();

        JScrollPane scrollPane = new JScrollPane( table );
        getContentPane().add( scrollPane );
    }

    //Use the Cell Renderer to convert date formats
    private TableCellRenderer tableCellRenderer = new DefaultTableCellRenderer() 
    {

        SimpleDateFormat f = new SimpleDateFormat("dd-MM-yyyy");

        public Component getTableCellRendererComponent(JTable table,Object value, boolean isSelected, boolean hasFocus,int row, int column) 
        {
            if( value instanceof Date) 
            {
                value = f.format(value);
            }
            return super.getTableCellRendererComponent(table, value, isSelected,hasFocus, row, column);
        }
    };

    //Convert String to java.util.Date
    private Date getJavaDate(String s)
    {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
            Date d = sdf.parse(s);
             return d;

        } catch (ParseException ex) {
            Logger.getLogger(TableBasic.class.getName()).log(Level.SEVERE, null, ex);
            return null;
        }
    }





    public static void main(String[] args)
    {
        TableBasic frame = new TableBasic();
        frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
        frame.pack();
        frame.setLocationRelativeTo( null );
        frame.setVisible(true);
    }
}

Can you see the last 2 rows of this table? They are summery rows, which display the summery of the above rows. Now, I need to sort these rows, except the last 2 rows (in real application, these data will be loaded from database).

When the sorting took place, this is the result.

enter image description here

As you can see, the last 2 rows also got sorted out. I went through number of posts trying to find a way to avoid sorting this Last 2 rows, but I couldn't do anything that is working.

halfer
  • 19,824
  • 17
  • 99
  • 186
PeakGen
  • 21,894
  • 86
  • 261
  • 463

2 Answers2

4

comments


real solution should be

  • another (two) JTable in JPanel (laid by GridBagLayout) for JTable where JScrollBar never will be used, both JTables will be sync with/by using TableColumnModelListener, override setValueAt in both JTables models for sync value between XxxTableModels

  • easiest as is possible to do without playing with official bugs, footer is again sync with/by using TableColumnModelListener, then JTable is separate Object for scrollable, filtering, sorting, etc,

Community
  • 1
  • 1
mKorbel
  • 109,525
  • 20
  • 134
  • 319
2

You can try to introduce an artificial invisible column (existing in model only) which keeps the summary row number. Thus simple row have 0 value and summary row has 1 (or 2, 3) values. Then include the column in sort columns list.

Working

import java.awt.*;
import java.awt.event.*;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
import javax.swing.table.*;

public class TableBasic extends JFrame
{

    final Class<?>[] columnClasses = new Class<?>[] {Date.class, String.class, Long.class, Boolean.class, Integer.class};



    public TableBasic()
    {

        String[] columnNames = {"Date", "String", "Long", "Boolean", "invisible"};
        Object[][] data =
                {
                        {getJavaDate("13-11-2020"), "A", new Long(1), Boolean.TRUE , 0},
                        {getJavaDate("13-11-2018"), "B", new Long(2), Boolean.FALSE, 0},
                        {getJavaDate("12-11-2015"), "C", new Long(9), Boolean.TRUE , 0},
                        {getJavaDate("12-11-2015"), "D", new Long(4), Boolean.FALSE, 0},
                        {null, null, null, null, 1},
                        {getJavaDate("12-11-2016"), "N/A", new Long(16), Boolean.FALSE, 2}

                };

        DefaultTableModel model = new DefaultTableModel(data, columnNames)
        {
            @Override
            public Class<?> getColumnClass(int column)
            {
                return columnClasses[column];
            }
        };

        JTable table = new JTable();
        table.setModel(model);
        table.setPreferredScrollableViewportSize(table.getPreferredSize());
        table.setAutoCreateRowSorter(true);
        table.getColumnModel().getColumn(0).setCellRenderer(tableCellRenderer);
        table.removeColumn(table.getColumnModel().getColumn(4));

        // Sort the rows
        DefaultRowSorter sorter = ((DefaultRowSorter)table.getRowSorter());
        ArrayList list = new ArrayList();
        list.add( new RowSorter.SortKey(4, SortOrder.ASCENDING) );
        list.add( new RowSorter.SortKey(0, SortOrder.DESCENDING) );
        sorter.setSortKeys(list);
        sorter.sort();

        JScrollPane scrollPane = new JScrollPane( table );
        getContentPane().add( scrollPane );
    }

    //Use the Cell Renderer to convert date formats
    private TableCellRenderer tableCellRenderer = new DefaultTableCellRenderer()
    {

        SimpleDateFormat f = new SimpleDateFormat("dd-MM-yyyy");

        public Component getTableCellRendererComponent(JTable table,Object value, boolean isSelected, boolean hasFocus,int row, int column)
        {
            if( value instanceof Date)
            {
                value = f.format(value);
            }
            return super.getTableCellRendererComponent(table, value, isSelected,hasFocus, row, column);
        }
    };

    //Convert String to java.util.Date
    private Date getJavaDate(String s)
    {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
            Date d = sdf.parse(s);
            return d;

        } catch (ParseException ex) {
            Logger.getLogger(TableBasic.class.getName()).log(Level.SEVERE, null, ex);
            return null;
        }
    }





    public static void main(String[] args)
    {
        TableBasic frame = new TableBasic();
        frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
        frame.pack();
        frame.setLocationRelativeTo( null );
        frame.setVisible(true);
    }
}
StanislavL
  • 56,971
  • 9
  • 68
  • 98
  • +1 ignored by RowSorter is about rows in model and/or synchonized with filtered output in the JTables view , buggy combinations, [more info here](http://stackoverflow.com/questions/6187566/problem-formatting-fields-in-a-jtable-differences-between-integer-and-double) – mKorbel Nov 14 '14 at 12:45
  • please OPs to want to apply RowSorter but excluding last two Rows (from JTables view), not about multilpe RowKeys and SortKeys – mKorbel Nov 14 '14 at 13:34