Adicionar e remover colunas no jtablemodel em tempo de execução

Boa noite galera, desculpa por esta criando mais um tópico, mas infelizmente não encontrei algo q eu pretendo fazer ate achei outras possibilidade de implementação desse problema mais nada viável quero ver se vcs me entendi e se pode me ajuda, é seguinte eu utilizo o modelo de jtablemodel na minha aplicação mais queria fazer algo ai mais com ele mas infelizmente eu não sei por onde começa pretendo cria uma opção onde o usuário determinar quais colunas q ele deseja exibir na tela a parti dos jCheckbox onde vai ter todas as colunas disponível para exibição então de acordo ele for selecionando é adicionado a coluna. abaixo deixo um modelo de como quero fazer e o meu código fonte do jtablemodel

package TableModel;

import java.util.ArrayList;
import java.util.List;
import javax.swing.table.AbstractTableModel;
import MenuEstoque.ManutencaoEstoqueModel;
import Util.Ulti;

public class ManutencaoEstoqueTableModel extends AbstractTableModel {

    private List<ManutencaoEstoqueModel> linhas;
    private String[] colunas = new String[]{
        "Código:","Nome do Produto:", "Custo Médio:", "Estoque:", "Est. Atual:","Diferença:","Total:","Tipo:","Vlr Venda:"};

    public ManutencaoEstoqueTableModel() {
        linhas = new ArrayList<>();
    }

    public ManutencaoEstoqueTableModel(List<ManutencaoEstoqueModel> listaDeVendaDet) {
        linhas = new ArrayList<>(listaDeVendaDet);
    }

    @Override
    public int getColumnCount() {
        return colunas.length;
    }

    @Override
    public int getRowCount() {
        return linhas.size();
    }

    @Override
    public String getColumnName(int columnIndex) {
        return colunas[columnIndex];
    }

  
	@Override
    public Class<?> getColumnClass(int columnIndex) {

        switch (columnIndex) {
            case 0:
                return String.class;
            case 1:
                return String.class;
            case 2:
                return String.class;
            case 3:
                return String.class;
            case 4:
                return String.class;
            case 5:
                return String.class;
            case 6:
                return String.class;
            case 7:
                return String.class;
            case 8:
                return String.class;
            default:
                throw new IndexOutOfBoundsException("columnIndex out of bounds");
        }
    }

    /*
     * Retorna o valor da célula especificada pelos índices da linha e da
     * coluna.
     */
    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        ManutencaoEstoqueModel obj = linhas.get(rowIndex);
        

        switch (columnIndex) {
            case 0:
                return obj.getId_produto();
            case 1:
                return obj.getProduto();
            case 2:
                return Ulti.dF.format(obj.getVlr_custo());
            case 3:
                 return Ulti.dF.format(obj.getQuant_ant());
            case 4:
                return Ulti.dF.format(obj.getAjuste());
            case 5:
                return Ulti.dF.format(obj.getDiferenca());
            case 6:
                return Ulti.dF.format(obj.getVlr_total());
            case 7:
                return obj.getFlag();
            case 8:
                return Ulti.dF.format(obj.getVlr_venda());
            default:
                throw new IndexOutOfBoundsException("columnIndex out of bounds");
        }
    }

    /*
     * Seta o valor da célula especificada pelos índices da linha e da coluna.
     * Aqui ele está implementado para não fazer nada, até porque este table
     * model não é editável.
     */
    @Override
    public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
        ManutencaoEstoqueModel obj = linhas.get(rowIndex);

//        System.out.println("columnIndex: " + columnIndex);

        switch (columnIndex) {
            case 0:
//                obj.setId(rowIndex);
                break;
            case 1:
//                obj.setNome(null);
                break;
            case 2:
//                obj.setVlr_venda(rowIndex);
                break;
            case 3:
//                obj.setEst_atual(rowIndex);
                break;
            case 4:
//                obj.setId_venda_cab(rowIndex);
                break;
            default:
                throw new IndexOutOfBoundsException("columnIndex out of bounds");
        }
    }

    ;

	/* Retorna um valor booleano que define se a célula em questão
	 * pode ser editada ou não.
	 * Este método é utilizado pela JTable na hora de definir o editor da célula.
	 * Neste caso, estará sempre retornando false, não permitindo que nenhuma
	 * célula seja editada. */
	@Override
    public boolean isCellEditable(int rowIndex, int columnIndex) {
        switch (columnIndex) {
            case 0:
                return true;
            default:
                return false;
        }
    }

    ////////////////////////////////////////////////////////////
    // Os métodos declarados até aqui foram as implementações //
    // de TableModel, que são continuamente utilizados        //
    // pela JTable para definir seu comportamento,            //
    // por isso o nome Table Model (Modelo da Tabela).        //
    //                                                        //
    // A partir de agora, os métodos criados serão            //
    // particulares desta classe. Eles serão úteis            //
    // em algumas situações.                                  //
    ////////////////////////////////////////////////////////////
    /*
     * Retorna o sócio da linha especificada.
     */
    public ManutencaoEstoqueModel getManutecaoEstoque(int indiceLinha) {
        return linhas.get(indiceLinha);
    }

    public void addManutecaoEstoque(ManutencaoEstoqueModel obj) {
        linhas.add(obj);
        int ultimoIndice = getRowCount() - 1;
        fireTableRowsInserted(ultimoIndice, ultimoIndice);
    }

    public void removeManutecaoEstoque(int indiceLinha) {
        linhas.remove(indiceLinha);
        fireTableRowsDeleted(indiceLinha, indiceLinha);
    }

    public void addListaDeManutecaoEstoque(List<ManutencaoEstoqueModel> obj) {
        int tamanhoAntigo = getRowCount();
        linhas.addAll(obj);
        fireTableRowsInserted(tamanhoAntigo, getRowCount() - 1);
    }

    public void limpar() {
        linhas.clear();
        fireTableDataChanged();
    }

    public boolean isEmpty() {
        return linhas.isEmpty();
    }

    public List<ManutencaoEstoqueModel> getLinhas() {
        return linhas;
    }

     public double getTotal() {
        double total = 0;
        for (ManutencaoEstoqueModel p : linhas) {
                total += p.getVlr_total();
        }
        return total;
    }
}

Aqui tem um exemplo de como adicionar colunas : http://www.guj.com.br/java/277458-adicionar-colunas-a-tablemodel-personalizado--resolvido

basta adicionar um valuechangelistener no checkbox e chamar o método, ou então em um botão para confirmar.

bom dia ErickRAR, vir o link q vc me recomendou ate consegui fazer uma implementação mais vir, q para da certo a implementação tive q mexer nos métodos: public Class<?> getColumnClass(int columnIndex), public Object getValueAt(int rowIndex, int columnIndex) só que ai eu tenho duvida porque em certas tabela utilizar a implementação desse métodos para fazer alguns calculo então não sei como implementa após a implementação dessa coluna o q eu queria mesmo era só passar o nome da coluna e o tipo de dados para o tablemodel q eu tenho já pronto e ele de alguma maneira seta o valor correto para aquela nova coluna.
Mas muito obrigado por sua atenção mais tarde vou tentar se consigo fazer algo pelo menos vc me deu uma luz, um forte abraço e fique com DEUS.