[RESOLVIDO] Filtrar jTable através de jCheckBox

Tenho uma tabela que é preenchida com dados do banco. A tabela traz todas as colunas do banco e seus respectivos dados.

Eu gostaria de filtrar esses dados, pra que o usuário traga apenas as colunas que desejar. Pra isso, pensei (e criei) uma tela com vários jCheckBox (sao 9 CheckBox, 8 (1 pra cada coluna do banco) + 1 “todos”).

Como faria pra filtra-los e mostrar a tabela apenas com as colunas selecionadas pelo usuário através dos CheckBox?

Nao sei se importa, mas trecho do código onde a tabela é preenchida com dados do banco:

public void preencherTabela (String Sql){

    ArrayList dados = new ArrayList(); 
    String [] colunas = new String [] {"Compactabilidad", "RCV", "RTH", "Friabilidad", "Permeabilidad", "Humedad", "Especimen", "Analista", "Temperatura"};
    conex.conectar();
    conex.executaSql(Sql);
    
    try{
        conex.rs.first();
        do{
            // Pesquisa no banco e preenche na tabela. Enquanto houver dados, eles serao jogados pra tabela //
            dados.add(new Object[] {conex.rs.getDouble("compactabilidad_arena_verde"), conex.rs.getDouble("rcv_arena_verde"), conex.rs.getDouble("rth_arena_verde"), conex.rs.getDouble("friabilidad_arena_verde"), conex.rs.getDouble("permeabilidad_arena_verde"), conex.rs.getDouble("humedad_arena_verde"), conex.rs.getDouble("especimen_arena_verde"), conex.rs.getString("analista_arena_verde"), conex.rs.getDouble("temperatura_arena_verde")});
        }while(conex.rs.next());
        
    }catch(SQLException ex){
        JOptionPane.showMessageDialog(null, "Erro ao preencher ArrayList \n " +ex.getMessage());
    }

ModeloTabelaEnVerde modelo = new ModeloTabelaEnVerde(dados, colunas);

    // Exemplo com uma das colunas do banco
    
    jTableArenaEnVerde.setModel(modelo);
    jTableArenaEnVerde.getColumnModel().getColumn(0).setPreferredWidth(120);
    jTableArenaEnVerde.getColumnModel().getColumn(0).setResizable(false);
tabela.removeColumn(table.getColumnModel().getColumn(INDEX_DA_COLUNA));

ou

tabela.getColumnModel().getColumn(INDEX_DA_COLUNA).setMaxWidth(0);
tabela.getColumnModel().getColumn(INDEX_DA_COLUNA).setMinWidth(0);
tabela.getTableHeader().getColumnModel().getColumn(INDEX_DA_COLUNA).setMaxWidth(0);
tabela.getTableHeader().getColumnModel().getColumn(INDEX_DA_COLUNA).setMinWidth(0);

Atualizacao:

Eu criei um método para cada “coluna” do checkbox. O problema agora é que selecionando mais de um checkbox, apenas o último selecionado é mostrado. Se apenas 1 é selecionado, a tabela é mostrada corretamente. Mas se mais de 1 é selecionado, nao aparecem todos, segue mostrando apenas 1.

Aqui minha “gambiarra”: Essa é a que eu tinha que buscava todas as colunas do banco

public void preencherTabela (String Sql){

    ArrayList dados = new ArrayList(); 
    String [] colunas = new String [] {"Compactabilidad", "RCV", "RTH", "Friabilidad", "Permeabilidad", "Humedad", "Especimen", "Analista", "Temperatura"};
    conex.conectar();
    conex.executaSql(Sql);
    
    try{
        conex.rs.first();
        do{
            // Pesquisa no banco e preenche na tabela. Enquanto houver dados, eles serao jogados pra tabela //
            dados.add(new Object[] {conex.rs.getDouble("compactabilidad_arena_verde"), conex.rs.getDouble("rcv_arena_verde"), conex.rs.getDouble("rth_arena_verde"), conex.rs.getDouble("friabilidad_arena_verde"), conex.rs.getDouble("permeabilidad_arena_verde"), conex.rs.getDouble("humedad_arena_verde"), conex.rs.getDouble("especimen_arena_verde"), conex.rs.getString("analista_arena_verde"), conex.rs.getDouble("temperatura_arena_verde")});
        }while(conex.rs.next());
        
    }catch(SQLException ex){
        JOptionPane.showMessageDialog(null, "Erro ao preencher ArrayList \n " +ex.getMessage());
    }


Agora criei um para cada coluna, por ex analista:


public void preencherTabelaAnalista (String Sql){
        ArrayList dados = new ArrayList(); // Linhas //
        String [] colunas = new String [] {"Analista"};
        conex.conectar();
        conex.executaSql(Sql);
        
        try{
            conex.rs.first();
            do{
                // Pesquisa no banco e preenche na tabela. Enquanto houver dados, eles serao jogados pra tabela //
                dados.add(new Object[] {conex.rs.getString("analista_arena_verde")});
            }while(conex.rs.next());
            
        }catch(SQLException ex){
            JOptionPane.showMessageDialog(null, "Erro ao preencher ArrayList \n " +ex.getMessage());
        }
        
        ModeloTabelaEnVerde modelo = new ModeloTabelaEnVerde(dados, colunas);
        
        jTableArenaEnVerde.setModel(modelo);
        jTableArenaEnVerde.getColumnModel().getColumn(0).setPreferredWidth(120);
        jTableArenaEnVerde.getColumnModel().getColumn(0).setResizable(false);
    }

E aqui o if que mostra a coluna de acordo com o checkbox selecionado:

if (jCheckBoxConsultaTabelaArenaVerdeTodos.isSelected()){
            preencherTabelaTodos("SELECT * FROM pruebas_arena_verde");
        }
        
        if (jCheckBoxConsultaTabelaEnVerdeAnalista.isSelected()){
            preencherTabelaAnalista("SELECT analista_arena_verde from pruebas_arena_verde");
        }

Vc tentou o que eu te mandei pelo menos?

1 curtida

Abner, tentei mas acredito que eu nao tenha entendido exatamente seu raciocínio.

Pelo que eu entendi, em ambas opcoes voce estaria “removendo” as colunas, correto? Ok, mas como exatamente eu filtraria os dados? Esse é o ponto da lógica nao entra na minha cabeca.

Eu colocaria todas as colunas com “tamanho 0”, assim elas nao apareceriam, mas aí como eu faria pra que elas apareçam com os dados/colunas corretos? Dentro de um if? De que forma?

Oi, bom dia!

Vamos la, o primeiro metodo (esconder_colunas()) vc pode colocar assim que preencher a tabela, tipo:

public void preencherTabela (String SQL){
    ........
    esconder_colunas();
}

Ou se preferir, deixar por padrao (sem o metodo) mostrando todas. eu acho melhor assim


O segundo metodo vc coloca dentro do if, exemplo:

if (jCheckBoxConsultaTabelaArenaVerdeTodos.isSelected()){ 
     //so acho melhor vc colocar um nome mais curto nas variaveis
     //ex: check_todos;
     esconder_colunas();
     mostrar_coluna(1); 
     //ai ao inves de deixar so o 1
     //vc coloca o numero da coluna q vc quer exibir.
     //ex: "quero mostrar a coluna "Compactabilidad",
     //vc coloca o valor 0. E assim vai
}

Metodos:

private void esconder_colunas() {
    try {
        //Vc tem 9 colunas, certo?
        //1 Compactabilidad, 2 RCV, 3 RTH, 4 Friabilidad, 5 Permeabilidad, 
        //6 Humedad, 7 Especimen, 8 Analista,  9 Temperatura.

        //Entao se vc tem 9 colunas, vc tem 8 indices.
        //OK, é chato ter que fazer isso (esconder as colunas) do 0 ao 8? 
        //Demais, entao faz assim:
        for (int i = 0; i <= tabela.getColumnCount() - 1; i++) {
            tabela.getColumnModel().getColumn(i).setMaxWidth(0);
            tabela.getColumnModel().getColumn(i).setMinWidth(0);
            tabela.getTableHeader().getColumnModel().getColumn(i).setMaxWidth(0);
            tabela.getTableHeader().getColumnModel().getColumn(i).setMinWidth(0);
        }
        //pronto, vc ja escondeu todas.             
    } catch (Exception e) {
        e.printStackTrace();
    }
}

private void mostrar_coluna(int coluna) {
    //Agora nao tem muito segredo, na hora que vc fizer o check
    //no CheckBox, vc coloca o numero da coluna que quer mostrar
    int tam_tabela = tabela.getSize().width;
    tabela.getColumnModel().getColumn(coluna).setMaxWidth(tam_tabela);
    tabela.repaint();
}

Porque é melhor fazer assim, do que buscar no banco a cada clique no jCheckBox?

  • mesmo que seja imperceptivel, buscar no banco gasta memoria, pensa o usuario fazer esse tipo de seleçao o tempo todo? Vai consumir memoria desnecessaria.
  • vc economiza tempo e codigo
  • e mais um monte de coisa que eu to com preguiça de citar kkkkkk
1 curtida

Abner, primeiramente agradeco demais sua ajuda. Muito obrigado mesmo. Mas sigo com o mesmo problema: Selecionando apenas um checkbox, ok, a tabela aparece filtrada, perfeita. O problema é que se mais de um checkbox é marcado, a tabela segue mostrando apenas uma coluna. Eu preciso que sejam mostradas as colunas de todos os checkbox selecionados.

Eu criei um botao “gerar tabela” ao lado dos checkbox, e estou colocando os ifs dentro desse botao. Tenho certeza que o erro tá aí, mas nao consigo identificar o que tá errado. Esse é o código com os ifs dentro do botao (coloquei só 2 colunas pra exemplo):

if (jCheckBoxConsultaTabelaEnVerdeRCV.isSelected()){
        esconderColunas();
        mostrarColuna(1);
    } 

if (jCheckBoxConsultaTabelaEnVerdeAnalista.isSelected()){
        esconderColunas();
        mostrarColuna(7);
    }

Onde voce acha que tá o erro que nao permite mostrar mais de 1 coluna? Se o if tá certo, existe alguma outra forma pra fazer isso? De novo, agradeco MUITO tua ajuda e paciencia.

OBS: Vou mudar o nome das variáveis, é que como estou comecando agora pra mim fica mais fácil entender o que tá acontecendo no código com os nomes extremamente (exageradamente kkk) descritivos. Terminando o código vou arrumar isso.

    esconderColunas();
    mostrarColuna(7);

Agora nao é mais erro, agora é mais a logica:

    mostrarColuna(1);
    mostrarColuna(7);

if (jCheckBoxConsultaTabelaEnVerdeRCV.isSelected()){
    mostrarColuna(1);
    mostrarColuna(7);
} else if (jCheckBoxConsultaTabelaEnVerdeAnalista.isSelected()){
    esconderColunas();
    mostrarColuna(7);
}

Se vc quiser esconder a coluna ao tirar a seleçao da caixa:

private void esconder_coluna_parcial(int coluna) {
    try {
            tabela.getColumnModel().getColumn(coluna).setMaxWidth(0);
            tabela.getColumnModel().getColumn(coluna).setMinWidth(0);
            tabela.getTableHeader().getColumnModel().getColumn(coluna).setMaxWidth(0);
            tabela.getTableHeader().getColumnModel().getColumn(coluna).setMinWidth(0);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

Ai a condiçao:

    if (jCheckBoxConsultaTabelaEnVerdeRCV.isSelected()){
        mostrarColuna(1);
    } else {
        esconder_coluna_parcial(1);
    }
1 curtida

Show cara, consegui. Muito obrigado!!

1 curtida