How to add a function in jTable that sorts the column?

487 views Asked by At

I know that by using JTable the column is sorted when we click on the column heading, but what I want is that, when I right-click on the column name a function name 'sort' should be displayed. Any suggestion in doing it?

2

There are 2 answers

0
MadProgrammer On

Start by adding a MouseListener to the table. See How to write mouse listeners

You will need to translate the click point to a column, see JTable#columnAtPoint.

You will then need to update the SortKey for the table. Check out Sorting and Filtering for an example

0
kleopatra On

If I understand you correctly, you want to sort by some explicit action (triggered f.i. in a popup) instead of by the normal left-click.

If so, the tricky part is to force the ui-delegate to do nothing. There are two options:

  • hook into the default mouse listener installed by the ui delegate, as described in a recent QA
  • let the ui do its stuff, but fool it by a sorter implementation that doesn't follow the rules (beware: that's as dirty as the first approach!)

The mis-behaving sorter:

public class MyTableRowSorter extends TableRowSorter {

    public MyTableRowSorter(TableModel model) {
        super(model);
    }

    /**
     * Implemented to do nothing to fool tableHeader internals.
     */
    @Override
    public void toggleSortOrder(int column) {
    }

    /**
     * The method that really toggles, called from custom code.
     * 
     * @param column
     */
    public void realToggleSortOrder(int column) {
        super.toggleSortOrder(column);
    }

}

// usage

final JTable table = new JXTable(new AncientSwingTeam());
table.setRowSorter(new MyTableRowSorter(table.getModel()));
Action toggle = new AbstractAction("toggleSort") {

    @Override
    public void actionPerformed(ActionEvent e) {
        JXTableHeader header = SwingXUtilities.getAncestor(
                JXTableHeader.class, (Component) e.getSource());
        Point trigger = header.getPopupTriggerLocation();
        int column = trigger != null ? header.columnAtPoint(trigger) : -1;
        if (column < 0) return;
        int modelColumn = header.getTable().convertColumnIndexToModel(column);
        ((MyTableRowSorter) header.getTable().getRowSorter())
           .realToggleSortOrder(modelColumn);
    }
};
JPopupMenu menu = new JPopupMenu();
menu.add(toggle);
table.getTableHeader().setComponentPopupMenu(menu);

Yeah, couldn't resist throwing in some SwingX api, lazy me :-) With plain Swing, you'll have to write some lines more but the basics are the same: install the tricksy sorter and use its custom toggle sort to really sort whereever needed, f.i. in a mouseListener.