Search code examples
javaswingjtableglazedlistsjxtable

Views sorting and filtering: GlazedList sorting and filtering + JTable vs Glazed event list+JXTable


I want to create user views (tables) with sorting and filtering capabilities. I use EventList (Glazed Lists) as source for EventTableModel. There are also Sorted List and some filtering items in GlazedLists, so I can use them for creating view. But I found JXTable and it has methods for sorting and filtering, and this how I want it to work: sorting and filtering must provide UI component and model just can hold data:

EventList<Item> source=new BasicEventList<Item>();
TableModel model=new DefaultEventTableModel<Item>(source,tableFormat); // It'll be
//perfect if I could create model without tableFormat,
//because it's presentation of data,
//but in GlazedLists I can't :( ...
JTalbe ui=new JXTable(model); // UI with sorting and filtering

But GlazedLists also provide SortedList (decorator for EventList with Sorting), and some filtering methods.

EventList<Item> source=new BasicEventList<Item>();
SortedList<Item> sortedSource=new SortedList<Item>(source,comparator);
TableModel model=new DefaultEventTableModel<Item>(sortedSource,tableFormat); 
// model with sorting... not very beautifull for me, but what do you think?

JTable ui=new JTable(model); // UI with sorting provided by model

And the question is: what model is better. Or maybe both are wrong, and what do use for creating views?


Solution

  • I vote for GlazedLists, because it works. Yes, the TableModel that you use with the table is tightly coupled to the view, but you decouple that table model from your source data.

    GlazedLists' sorting and filtering features are much more flexible than the one on JXTable. Just make sure you don't have them both turned on, or things will get confusing. Here's my usual code snippet for using a SortedList with a JXTable:

    private <T> EventTableModel<T> setupTable(JXTable table, TableFormat<T> tf, EventList<T> displayItems, SortedList<T> sortedItems)
    {
        table.setColumnControlVisible(true);
        table.setSortable(false);
        table.getTableHeader().setDefaultRenderer(new JTableHeader().getDefaultRenderer());
    table.setAutoCreateRowSorter(false);
    table.setRowSorter(null);
    
        EventTableModel<T> etm = new EventTableModel<T>(displayItems, tf);
        table.setModel(etm);
    
        TableComparatorChooser.install(table, sortedItems, AbstractTableComparatorChooser.SINGLE_COLUMN);
        return etm;
    }
    

    What this does:

    • turn on the column picker gadget on the upper right of the JXTable
    • turn off JXTable's builtin sorting
    • install GlazedLists' sorting features instead
    • setup the table with an EventTableModel derived from the TableFormat

    Note that you pass in two EventLists, a displayItems which is the list at the end of the pipeline, and a sortedList used for controlling which column is used for sorting, which can be earlier in the pipeline than the displayItems list. (If your last element is the sortedList, without any processing after that, just pass the list in twice.)