Question

I have a simple JTable:

    String[] columnNames = {"Freetext",
                            "Numbers only",
                            "Combobox"};

    Object[][] data = {
    {"Kathy", new Integer(21), "Female"},
    {"John", new Integer(19), "Male"},
    {"Sue", new Integer(20), "Female"},
    {"Joe", new Integer(22), "Male"}
    };

    final JTable table = new JTable(data, columnNames);
    table.setPreferredScrollableViewportSize(new Dimension(500, 70));
    table.setAutoCreateRowSorter(true);
    table.setFillsViewportHeight(true);
    TableColumn comboboxCol = table.getColumnModel().getColumn(2);
    JComboBox comboBox = new JComboBox();
    comboBox.addItem("Male");
    comboBox.addItem("Female");
    comboboxCol.setCellEditor(new DefaultCellEditor(comboBox));       
    table.getColumnModel().getColumn(1).setCellEditor(new IntegerEditor(0, 100)); 

When I click on the colum header, it will alternate between ascending and descending sorting. I would like to add one more column header that will act differently on click, with other headers retaining their behaviour. How would you do that?

Was it helpful?

Solution

table.setAutoCreateRowSorter(true);: This action defines a row sorter that is an instance of TableRowSorter. This provides a table that does a simple locale-specific sort when the user clicks on a column header. You can specify sort order and precedence of the column for sorting using SortKeys:

TableRowSorter sorter = (TableRowSorter) table.getRowSorter();
List <RowSorter.SortKey> sortKeys = new ArrayList<RowSorter.SortKey>();
sortKeys.add(new RowSorter.SortKey(table.getColumnModel().getColumnIndex("aColumnID"), SortOrder.ASCENDING));
sortKeys.add(new RowSorter.SortKey(table.getColumnModel().getColumnIndex("bColumnID"), SortOrder.UNSORTED));
 // to specify no sorting should happen on 'bColumnID'
sorter.setSortKeys(sortKeys);

Again, If you want to specify event on the specific column, for example column with id bColumnID:

table.getTableHeader().addMouseListener(new MouseAdapter() {

   @Override
   public void mouseClicked(MouseEvent e) {
     super.mouseClicked(e); 
     JTableHeader header = (JTableHeader)(e.getSource());  
     JTable tableView = header.getTable();  
     TableColumnModel columnModel = tableView.getColumnModel();  
     int viewColumn = columnModel.getColumnIndexAtX(e.getX()); 

      if(columnModel.getColumn(viewColumn).getIdentifier().equals("bColumnID"))
      {
          JOptionPane.showMessageDialog(null, "Hi bColumnID header is clicked");
      }

      }


});

Edit:

however, I understood you wrong (that upon one of the column header click you want the table unsorted and do other action) but as @camickr has made that clear, use: sorter.setSortable(index, boolean).

More formally, for turning off sorting for specific column with column identifier e.g., "bColumnName":

sorter.setSortable(table.getColumnModel().getColumnIndex("bColumnName"), false);

to disable sorting for column with identifier "bColumnName".

OTHER TIPS

I want it to have completely different action - NOT extended action of sorter

Then you have a two step procedure:

  1. Disable sorting on the specific column. This is done by using setSortable(column, false) method of the DefaultRowSorter.

  2. Enable a different action when clicking on the table header. This is done by adding a MouseListener to the table header.

You would have to implement your own RowSorter and in the toggleSortOrder method you would need to allow your column with 4 options to toggle to a new sort that the other columns wouldn't have.

To update the display you could extend the DefaultTableCellHeaderRenderer class and add other sort order items beyond the ones that exist today.

Snippet from the class:

   SortOrder sortOrder = getColumnSortOrder(table, column);
             if (sortOrder != null) {
                 switch(sortOrder) {
                 case ASCENDING:
                     sortIcon = UIManager.getIcon(
                         "Table.ascendingSortIcon");
                     break;
                 case DESCENDING:
                     sortIcon = UIManager.getIcon(
                         "Table.descendingSortIcon");
                     break;
                 case UNSORTED:
                     sortIcon = UIManager.getIcon(
                         "Table.naturalSortIcon");
                     break;
                 }
            }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top