
Use a custom TableCellRenderer:
    // column 1
    col = table.getColumnModel().getColumn(1);
    col.setHeaderRenderer(new EditableHeaderRenderer( new JButton("Button")));
    // column 2     
    col = table.getColumnModel().getColumn(2);
    col.setHeaderRenderer(new EditableHeaderRenderer( new JToggleButton("Toggle")));
    // column 3
    col = table.getColumnModel().getColumn(3);
    col.setHeaderRenderer(new EditableHeaderRenderer( new JCheckBox("CheckBox")));
class EditableHeaderRenderer implements TableCellRenderer {
    private JTable table = null;
    private MouseEventReposter reporter = null;
    private JComponent editor;
    EditableHeaderRenderer(JComponent editor) {
        this.editor = editor;
        this.editor.setBorder(UIManager.getBorder("TableHeader.cellBorder"));
    }
    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) {
        if (table != null && this.table != table) {
            this.table = table;
            final JTableHeader header = table.getTableHeader();   
            if (header != null) {   
                this.editor.setForeground(header.getForeground());   
                this.editor.setBackground(header.getBackground());   
                this.editor.setFont(header.getFont());
                reporter = new MouseEventReposter(header, col, this.editor);
                header.addMouseListener(reporter);
            }
        }
        if (reporter != null) reporter.setColumn(col);
        return this.editor;
    }
    static public class MouseEventReposter extends MouseAdapter {
        private Component dispatchComponent;
        private JTableHeader header;
        private int column  = -1;
        private Component editor;
        public MouseEventReposter(JTableHeader header, int column, Component editor) {
            this.header = header;
            this.column = column;
            this.editor = editor;
        }
        public void setColumn(int column) {
            this.column = column;
        }
        private void setDispatchComponent(MouseEvent e) {
            int col = header.getTable().columnAtPoint(e.getPoint());
            if (col != column || col == -1) return;
            Point p = e.getPoint();
            Point p2 = SwingUtilities.convertPoint(header, p, editor);
            dispatchComponent = SwingUtilities.getDeepestComponentAt(editor, p2.x, p2.y);
        }
        private boolean repostEvent(MouseEvent e) {
            if (dispatchComponent == null) {
                return false;
            }
            MouseEvent e2 = SwingUtilities.convertMouseEvent(header, e, dispatchComponent);
            dispatchComponent.dispatchEvent(e2);
            return true;
        }
        @Override
        public void mousePressed(MouseEvent e) {
            if (header.getResizingColumn() == null) {
                Point p = e.getPoint();
                int col = header.getTable().columnAtPoint(p);
                if (col != column || col == -1) return;
                int index = header.getColumnModel().getColumnIndexAtX(p.x);
                if (index == -1) return;
                editor.setBounds(header.getHeaderRect(index));
                header.add(editor);
                editor.validate();
                setDispatchComponent(e);
                repostEvent(e);
            }
        }
        @Override
        public void mouseReleased(MouseEvent e) {
            repostEvent(e);
            dispatchComponent = null;
            header.remove(editor);
        }
    }
}
Please note that components with popupmenu (e.g. JComboBox or JMenu) don't work well. See: JComboBox fails to expand in JTable TableHeader).
But you can use a MenuButton in the TableHeader:

class MenuButtonTableHeaderRenderer extends JPanel implements TableCellRenderer {
    private int     column  = -1;
    private JTable  table   = null;
    private MenuButton b;
    MenuButtonTableHeaderRenderer(String name, JPopupMenu menu) {
        super(new BorderLayout());
        b = new MenuButton(ResourceManager.ARROW_BOTTOM, menu);
        b.setBorder(BorderFactory.createEmptyBorder(1,1,1,1));
        JLabel l = new JLabel(name);
        l.setFont(l.getFont().deriveFont(Font.PLAIN));
        l.setBorder(BorderFactory.createEmptyBorder(1,5,1,1));
        add(b, BorderLayout.WEST);
        add(l, BorderLayout.CENTER);
        setBorder(UIManager.getBorder("TableHeader.cellBorder"));
    }
    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) {
        if (table != null && this.table != table) {
            this.table = table;
            final JTableHeader header = table.getTableHeader();   
            if (header != null) {   
                setForeground(header.getForeground());   
                setBackground(header.getBackground());   
                setFont(header.getFont());
                header.addMouseListener(new MouseAdapter() {
                    @Override
                    public void  mouseClicked(MouseEvent e) {
                        int col = header.getTable().columnAtPoint(e.getPoint());
                        if (col != column || col == -1) return;
                        int index = header.getColumnModel().getColumnIndexAtX(e.getPoint().x);
                        if (index == -1) return;
                        setBounds(header.getHeaderRect(index));
                        header.add(MenuButtonTableHeaderRenderer.this);
                        validate();
                        b.doClick();
                        header.remove(MenuButtonTableHeaderRenderer.this);
                        header.repaint();   
                    }
                });
            }
        }
        column = col;
        return this;
    }
}