package example;
//-*- mode:java; encoding:utf8n; coding:utf-8 -*-
// vim:set fileencoding=utf-8:
//@homepage@
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;

public class MainPanel extends JPanel {
    public MainPanel() {
        super(new BorderLayout());
        String[] columnNames = {"", "Integer", "String"};
        Object[][] data = {{true, 1, "BBB"}, {false, 12, "AAA"},
            {true, 2, "DDD"}, {false, 5, "CCC"},
            {true, 3, "EEE"}, {false, 6, "GGG"},
            {true, 4, "FFF"}, {false, 7, "HHH"}};
        DefaultTableModel model = new DefaultTableModel(data, columnNames) {
            @Override public Class<?> getColumnClass(int column) {
                return getValueAt(0, column).getClass();
            }
        };
        JTable table = new JTable(model) {
            @Override public void updateUI() {
                super.updateUI();
                //XXX: Nimbus
                TableCellRenderer r = getDefaultRenderer(Boolean.class);
                if(r instanceof JComponent) {
                    ((JComponent)r).updateUI();
                }
            }
            @Override public Component prepareEditor(TableCellEditor editor, int row, int column) {
                Component c = super.prepareEditor(editor, row, column);
                if(c instanceof JCheckBox) {
                    JCheckBox b = (JCheckBox)c;
                    b.setBackground(getSelectionBackground());
                    b.setBorderPainted(true);
                }
                return c;
            }
        };
        table.getColumnModel().getColumn(0).setHeaderRenderer(new HeaderRenderer(table.getTableHeader(), 0));
        //table.getColumnModel().getColumn(1).setHeaderRenderer(new HeaderRenderer(table.getTableHeader(), 1));
        add(new JScrollPane(table));
        setPreferredSize(new Dimension(320, 240));
    }
    private JComponent makeTitledPanel(String title, JComponent c) {
        JPanel p = new JPanel(new BorderLayout());
        p.add(c);
        p.setBorder(BorderFactory.createTitledBorder(title));
        return p;
    }
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override public void run() {
                createAndShowGUI();
            }
        });
    }
    public static void createAndShowGUI() {
        try{
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        }catch(Exception e) {
            e.printStackTrace();
        }
        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 HeaderRenderer extends JCheckBox implements TableCellRenderer {
    public HeaderRenderer(JTableHeader header, final int targetColumnIndex) {
        super("Check All");
        setOpaque(false);
        setFont(header.getFont());
        header.addMouseListener(new MouseAdapter() {
            @Override public void mouseClicked(MouseEvent e) {
                JTableHeader header = (JTableHeader)e.getSource();
                JTable table = header.getTable();
                TableColumnModel columnModel = table.getColumnModel();
                int viewColumn  = columnModel.getColumnIndexAtX(e.getX());
                int modelColumn = table.convertColumnIndexToModel(viewColumn);
                if(modelColumn == targetColumnIndex) {
                    boolean b = isSelected()?false:true;
                    setSelected(b);
                    TableModel m = table.getModel();
                    for(int i=0; i<m.getRowCount(); i++) m.setValueAt(b, i, modelColumn);
                    header.repaint();
                }
            }
        });
    }
    @Override public Component getTableCellRendererComponent(JTable tbl, Object val, boolean isS, boolean hasF, int row, int col) {
        TableCellRenderer r = tbl.getTableHeader().getDefaultRenderer();
        JLabel l =(JLabel)r.getTableCellRendererComponent(tbl, val, isS, hasF, row, col);
        l.setIcon(new CheckBoxIcon(this));
        if(l.getPreferredSize().height>1000) { //XXX: Nimbus
            System.out.println(l.getPreferredSize().height);
            l.setPreferredSize(new Dimension(0, 28));
        }
        return l;
    }
}
class CheckBoxIcon implements Icon{
    private final JCheckBox check;
    public CheckBoxIcon(JCheckBox check) {
        this.check = check;
    }
    @Override public int getIconWidth() {
        return check.getPreferredSize().width;
    }
    @Override public int getIconHeight() {
        return check.getPreferredSize().height;
    }
    @Override public void paintIcon(Component c, Graphics g, int x, int y) {
        SwingUtilities.paintComponent(g, check, (Container)c, x, y, getIconWidth(), getIconHeight());
    }
}

@@ -166,24 +166,52 @@
 ax.swing.*;%0A
+import javax.swing.event.*;%0A
 import javax
@@ -226,16 +226,16 @@
 able.*;%0A
-
 %0Apublic 
@@ -360,16 +360,26 @@
 mes = %7B%22
+DESELECTED
 %22, %22Inte
@@ -834,32 +834,38 @@
      %7D;%0A        
+final 
 JTable table = n
@@ -1854,24 +1854,620 @@
 der(), 1));%0A
+%0A        model.addTableModelListener(new TableModelListener() %7B%0A            @Override public void tableChanged(TableModelEvent e) %7B%0A                if(e.getType()==TableModelEvent.UPDATE && e.getColumn()==0) %7B%0A                    TableColumn column = table.getColumnModel().getColumn(0);%0A                    String title = (String)column.getHeaderValue();%0A                    if(%22SELECTED%22.equals(title)) %7B%0A                        column.setHeaderValue(%22INDETERMINATE%22);%0A                        table.getTableHeader().repaint();%0A                    %7D%0A                %7D%0A            %7D%0A        %7D);%0A%0A
         add(
@@ -3627,19 +3627,8 @@
 per(
-%22Check All%22
 );%0A 
@@ -4277,16 +4277,18 @@
         
+//
 setSelec
@@ -4430,32 +4430,130 @@
 , modelColumn);%0A
+                    columnModel.getColumn(modelColumn).setHeaderValue(b?%22SELECTED%22:%22DESELECTED%22);%0A
                 
@@ -4892,19 +4892,27 @@
 nt(tbl, 
-val
+%22Check All%22
 , isS, h
@@ -4923,24 +4923,332 @@
  row, col);%0A
+        if(%22SELECTED%22.equals(val)) %7B%0A            setSelected(true);%0A            setEnabled(true);%0A        %7Delse if(%22DESELECTED%22.equals(val)) %7B%0A            setSelected(false);%0A            setEnabled(true);%0A        %7Delse%7B //INDETERMINATE%0A            setSelected(true);%0A            setEnabled(false);%0A        %7D%0A
         l.se

add INDETERMINATE status