javaswingjtablejtableheaderrowsorter

JTable - make one of the headers behave differently on click


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?


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".