// -*- mode:java; encoding:utf-8 -*-
// vim:set fileencoding=utf-8:
// @homepage@

package example;

import java.awt.*;
import java.awt.event.ActionListener;
import java.util.stream.Stream;
import javax.swing.*;
import javax.swing.plaf.IconUIResource;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;

public final class MainPanel extends JPanel {
  private final String[] columnNames = {"String", "Integer", "Boolean"};
  private final Object[][] data = {
    {"aaa", 12, true}, {"bbb", 5, false},
    {"CCC", 92, true}, {"DDD", 0, false}
  };
  private final TableModel model = new DefaultTableModel(data, columnNames) {
    @Override public Class<?> getColumnClass(int column) {
      return getValueAt(0, column).getClass();
    }
  };
  private final JTable table = new JTable(model);
  private final transient RowSorter<? extends TableModel> sorter = new TableRowSorter<>(model);

  private static final Icon EMPTY_ICON = new EmptyIcon();
  private final Icon customAscendingSortIcon = new ImageIcon(getClass().getResource("ascending.png"));
  private final Icon customDescendingSortIcon = new ImageIcon(getClass().getResource("descending.png"));

  private Box makeRadioPane() {
    JRadioButton r0 = new JRadioButton("Default", true);
    JRadioButton r1 = new JRadioButton("Empty");
    JRadioButton r2 = new JRadioButton("Custom");
    ActionListener al = e -> {
      JRadioButton r = (JRadioButton) e.getSource();
      Icon ascending;
      Icon descending;
      if (r.equals(r0)) {
        ascending = UIManager.getLookAndFeelDefaults().getIcon("Table.ascendingSortIcon");
        descending = UIManager.getLookAndFeelDefaults().getIcon("Table.descendingSortIcon");
      } else if (r.equals(r1)) {
        ascending = new IconUIResource(EMPTY_ICON);
        descending = new IconUIResource(EMPTY_ICON);
      } else {
        ascending = new IconUIResource(customAscendingSortIcon);
        descending = new IconUIResource(customDescendingSortIcon);
      }
      UIManager.put("Table.ascendingSortIcon", ascending);
      UIManager.put("Table.descendingSortIcon", descending);
      table.getTableHeader().repaint();
    };
    Box box1 = Box.createHorizontalBox();
    box1.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5));
    ButtonGroup bg = new ButtonGroup();
    box1.add(new JLabel("Table Sort Icon: "));
    Stream.of(r0, r1, r2).forEach(rb -> {
      box1.add(rb);
      box1.add(Box.createHorizontalStrut(5));
      bg.add(rb);
      rb.addActionListener(al);
    });
    box1.add(Box.createHorizontalGlue());
    return box1;
  }

  private MainPanel() {
    super(new BorderLayout());
    table.setRowSorter(sorter);

    JButton clearButton = new JButton("clear SortKeys");
    clearButton.addActionListener(e -> sorter.setSortKeys(null));

    add(makeRadioPane(), BorderLayout.NORTH);
    add(clearButton, BorderLayout.SOUTH);
    add(new JScrollPane(table));
    setPreferredSize(new Dimension(320, 240));
  }

  public static void main(String[] args) {
    EventQueue.invokeLater(MainPanel::createAndShowGui);
  }

  private static void createAndShowGui() {
    try {
      UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
      ex.printStackTrace();
      Toolkit.getDefaultToolkit().beep();
    }
    JFrame frame = new JFrame("@title@");
    frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    frame.getContentPane().add(new MainPanel());
    frame.pack();
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
  }
}

class EmptyIcon implements Icon {
  @Override public void paintIcon(Component c, Graphics g, int x, int y) {
    /* Empty icon */
  }

  @Override public int getIconWidth() {
    return 0;
  }

  @Override public int getIconHeight() {
    return 0;
  }
}

@@ -329,49 +329,8 @@
 del;
-%0Aimport javax.swing.table.TableRowSorter;
 %0A%0Apu
@@ -383,21 +383,123 @@
 private 
-final
+static final Icon EMPTY_ICON = new EmptyIcon();%0A%0A  private MainPanel() %7B%0A    super(new BorderLayout());%0A   
  String%5B
@@ -550,29 +550,17 @@
 an%22%7D;%0A  
-private final
+ 
  Object%5B
@@ -572,16 +572,18 @@
 ata = %7B%0A
+  
     %7B%22aa
@@ -620,16 +620,18 @@
 e%7D,%0A    
+  
 %7B%22CCC%22, 
@@ -659,36 +659,26 @@
  false%7D%0A
+  
   %7D;%0A  
-private final
+ 
  TableMo
@@ -728,24 +728,26 @@
 umnNames) %7B%0A
+  
     @Overrid
@@ -795,24 +795,26 @@
 mn) %7B%0A      
+  
 return getVa
@@ -850,30 +850,22 @@
     
-%7D%0A
+  %7D%0A  
   %7D;%0A  
-private final
+ 
  JTa
@@ -901,176 +901,410 @@
 ;%0A  
-private final transient RowSorter%3C? extends TableModel%3E sorter = new TableRowSorter%3C%3E(mode
+  table.setAutoCreateRowSorter(true);%0A%0A    JButton clearButton = new JButton(%22clear SortKeys%22);%0A    clearButton.addActionListener(e -%3E table.getRowSorter().setSortKeys(nul
 l)
+)
 ;%0A%0A  
-private static final Icon EMPTY_ICON = new EmptyIcon();%0A  private final
+  add(makeRadioPane(table), BorderLayout.NORTH);%0A    add(clearButton, BorderLayout.SOUTH);%0A    add(new JScrollPane(table));%0A    setPreferredSize(new Dimension(320, 240));%0A  %7D%0A%0A  private Box makeRadioPane(JTable table) %7B%0A   
  Ico
@@ -1393,21 +1393,9 @@
 ;%0A  
-private final
+ 
  Ico
@@ -1483,41 +1483,8 @@
 %22));
-%0A%0A  private Box makeRadioPane() %7B
 %0A   
@@ -2863,393 +2863,8 @@
  %7D%0A%0A
-  private MainPanel() %7B%0A    super(new BorderLayout());%0A    table.setRowSorter(sorter);%0A%0A    JButton clearButton = new JButton(%22clear SortKeys%22);%0A    clearButton.addActionListener(e -%3E sorter.setSortKeys(null));%0A%0A    add(makeRadioPane(), BorderLayout.NORTH);%0A    add(clearButton, BorderLayout.SOUTH);%0A    add(new JScrollPane(table));%0A    setPreferredSize(new Dimension(320, 240));%0A  %7D%0A%0A
   pu

use JTable#setAutoCreateRowSorter(true) instead of JTable#setRowSorter(new TableRowSorter<TableModel>(model))