Populando TableView com Models Diferentes - JavaFX

Boa noite Srs. Estou com dificuldades de encontrar solução para um problema com a população do TableView. Segue minha dúvida.

Tenho duas tabelas SQL, conforme abaixo: TBL_CIDADE e TBL_ESTADO. na tbl_cidade há uma chave estrangeira chamando a coluna id_estado. Assim quando o usuários insere uma cidade ele precisa passar o id do estado obrigatoriamente.


Como podem ver a

A parte SQL está tudo ok! o problema é quando eu listo as cidades na TableView que eu não estou sabendo implementar o código para tbm mostrar o nome do estado. Vejam abaixo que os codigos e os nomes das cidades aparecem, mas o estado eu não soube como puxar essa informação:

Se alguém puder indicar um artigo ou me dar uma luz de como implementar isso. eu agradeço mto!

Segue meus outros códigos:

ModeloCidade

package modelo;

public class ModEnderecoCidade {
    
    private String codIbge;
    private String cidade;
    private ModEnderecoEstado fkEstado; //Aqui eu acesso o objeto Estado

    public ModEnderecoCidade(String codIbge, String cidade, ModEnderecoEstado fkEstado) {
        this.codIbge = codIbge;
        this.cidade = cidade;
        this.fkEstado = fkEstado;
    }
    
    public ModEnderecoCidade(){
        
    }
    
    //Getters e Setters...
   
}

ModeloEstado

package modelo;

public class ModEnderecoEstado {
    
    private int indexador;
    private String estadoNome;
    private String estadoSigla;
    private ModEnderecoPais fk_pais;

    public ModEnderecoEstado(int indexador, String estadoNome, String estadoSigla, ModEnderecoPais fk_pais) {
        this.indexador = indexador;
        this.estadoNome = estadoNome;
        this.estadoSigla = estadoSigla;
        this.fk_pais = fk_pais;
    }
    
    public ModEnderecoEstado(){
        
    }

    //Getters e Setters...
    
}

ModeloTabelaCidade -> Modelo utilizado para popular a tabelaCidade

package modelo;

import javafx.beans.property.SimpleStringProperty;

public class ModeloTabelaConsultaCidade {
    
    private SimpleStringProperty  codigoIbge;
    private SimpleStringProperty  cidade;
    private SimpleStringProperty  fk_estado;

    public ModeloTabelaConsultaCidade(String codigoIbge , String cidade , String fk_estado) {
        this.codigoIbge = new SimpleStringProperty(codigoIbge);
        this.cidade = new SimpleStringProperty(cidade);
        this.fk_estado = new SimpleStringProperty(fk_estado);
    }
    
    public ModeloTabelaConsultaCidade(){
        
    }

    public String getCodigoIbge() {
        return codigoIbge.get();
    }

    public String getCidade() {
        return cidade.get();
    }

    public String getFk_estado() {
        return fk_estado.get();
    }
    
}

Classe DAO - Consulta cidade no Banco de Dados.

public ArrayList<ModEnderecoCidade> listaTabela() {
        ModEnderecoCidade modCidade;
        ModEnderecoEstado modEstado;
        ArrayList<ModEnderecoCidade> lista = new ArrayList<>();
        String sql = "SELECT "
                   + "codigo_ibge , "
                   + "cidade , "
                   + "fk_estado "
                   + "FROM "+tabela+" "
                   + "ORDER BY cidade";
        try {
            con.conectar();
            con.executaSQL(sql);
                while(con.resultSet.next()) {
                    modCidade = new ModEnderecoCidade();
                    modEstado = new ModEnderecoEstado();
                    modCidade.setCodIbge(con.resultSet.getString("codigo_ibge"));
                    modCidade.setCidade(con.resultSet.getString("cidade"));
                    modEstado.setIndexador(con.resultSet.getInt("fk_estado"));
                    modCidade.setFkEstado(modEstado);
                    lista.add(modCidade);
            con.desconectar();
                }
        } catch (SQLException e) {
            con.desconectar();
            JOptionPane.showMessageDialog(null, e);
        }
        return lista;
    }

Meu Controller.

package controller.administrativo;

    import dao.DAOcidade;
    import java.net.URL;
    import java.util.ArrayList;
    import java.util.ResourceBundle;
    import javafx.collections.FXCollections;
    import javafx.collections.ObservableList;
    import javafx.event.ActionEvent;
    import javafx.fxml.FXML;
    import javafx.fxml.Initializable;
    import javafx.scene.control.Button;
    import javafx.scene.control.TableColumn;
    import javafx.scene.control.TableView;
    import javafx.scene.control.TextField;
    import javafx.scene.control.cell.PropertyValueFactory;
    import javafx.scene.input.MouseEvent;
    import javafx.stage.Stage;
    import modelo.ModEnderecoCidade;
    import modelo.ModeloTabelaConsultaCidade;

    public class FXMLconsultaCidadeController implements Initializable {
        
        ModEnderecoCidade modCidade = new ModEnderecoCidade();
        DAOcidade daoCidade = new DAOcidade();
        
        @FXML private Button btnCarregar;
        @FXML private Button btnFechar;
        @FXML private TextField txtPesquisaCodigoIbge;
        @FXML private TextField txtPesquisaCidade;
        
        //Propriedades da TableView
        @FXML private TableView<ModeloTabelaConsultaCidade> tblCidade;
        @FXML private TableColumn<ModeloTabelaConsultaCidade, String> colCodigoIbge;
        @FXML private TableColumn<ModeloTabelaConsultaCidade, String> colCidade;
        @FXML private TableColumn<ModeloTabelaConsultaCidade, ?> colEstado; //Aqui carregar nomeEstado - Só não sei como =/
        
        @Override
        public void initialize(URL url, ResourceBundle rb) {
            carregarTabelaBancoDados();
        }
        
        //Metodo para carregar informações das Cidades na TableView
        public void carregarTabelaBancoDados(){
            ArrayList<ModEnderecoCidade> listaCidade = daoCidade.listaTabela();
            ObservableList<ModeloTabelaConsultaCidade> observableListTabela = FXCollections.observableArrayList();
            colCodigoIbge.setCellValueFactory(new PropertyValueFactory<>("codigoIbge"));
            colCidade.setCellValueFactory(new PropertyValueFactory<>("cidade"));
            colEstado.setCellValueFactory(new PropertyValueFactory<>("estado"));
            
            if(!observableListTabela.isEmpty()){
                observableListTabela.clear();
                System.out.println("Tabela Limpa");
            }
            listaCidade.stream().map((c) -> new ModeloTabelaConsultaCidade(
                    c.getCodIbge(),
                    c.getCidade() ,
                    c.getFkEstado().getEstadoNome()
            )).forEachOrdered((m) -> {
                observableListTabela.add(m);
            });
            tblCidade.setItems(observableListTabela);
            btnCarregar.setDisable(false);
        }

Agradeço se alguém me der uma luz!

A priori a coisa é bem simples e num modelo relacional você liga os registros em tabelas diferentes com [ inner | left | right ] join.

de uma olhada nesses exemplos

Não sei o nível de programação que você se encontra, mas pensar em sistema em camadas esta sempre mais próximo de algo melhor. Pool de conexões também são bem vindos.

Lamento não apresentar um código aqui, que de cara resolva seu problema.

Penso que se você resolver a questão do SELECT, todo o resto ficará simples.

Mas se quer mesmo algo profissional, te convido a dar um analisada e estudada no que citei.

Se mesmo depois de você ter resolvido a questo do SELECT e ainda assim não tiver conseguindo, vamos ver com mais calma seu codigo. Isso claro, se nenhum colega aqui do forum lançar luz a sua questão.

Cara, obgdo mesmo pela resposta! Eu realmente n havia pensado em usar a propria consulta sql pra resolver meu problema!
Eu realmente n gosto apenas de copiar códigos, gosto de entender os conceitos e aplica-los… agradeço a resposta… Vou implementar e te dou um toque quando der certo! Mto obgdo!

1 curtida

j-Menezes eu realizei a consulta e consegui obter o resultado, porém eu tentei de todas as formas carregar o objeto Fornecedor na TableView e não consegui!!! :sleepy:… Alguma sujestão? Segue minha consulta! o restante dos códigos eu mantive…

public ArrayList<ModFinanceiroPagarConta> listarContaPagar() {
        
        ArrayList<ModFinanceiroPagarConta> lista = new ArrayList<>();
        ModFinanceiroPagarConta mod;
        DAOparceiroNegocio daoParceiro = new DAOparceiroNegocio();
        ModAdministrativoParceiroNegocio modParceiro;
        String sql = "SELECT "
                   + "tbl_fin_pagar_conta.id_conta , "
                   + "tbl_fin_pagar_conta.numero_documento , "
                   + "tbl_fin_pagar_conta.valor_liquido , "
                   + "tbl_fin_pagar_conta.fk_fornecedor , "
                   + "tbl_fin_pagar_conta.status , "
                   + "tbl_adm_parceiro_negocio.indexador , "
                   + "tbl_adm_parceiro_negocio.razao_social "
                   + "FROM "+tabela+" "
                   + "INNER JOIN tbl_adm_parceiro_negocio ON indexador = tbl_fin_pagar_conta.fk_fornecedor "
                   + "ORDER BY id_conta";
        try {
            con.conectar();
            con.executaSQL(sql);
                while(con.resultSet.next()) {
                    mod = new ModFinanceiroPagarConta();
                    modParceiro = new ModAdministrativoParceiroNegocio();

                    NumberFormat nf = NumberFormat.getNumberInstance(Locale.US);
                    nf.setMaximumFractionDigits(2);
                    nf.setMinimumFractionDigits(2);
                    
                    mod.setIndexador(con.resultSet.getInt("id_conta"));
                    //System.out.println(mod.getIndexador());
                    mod.setNumeroDocumento(con.resultSet.getString("numero_documento"));
                    //System.out.println(mod.getNumeroDocumento());
                    mod.setValorLiquido(con.resultSet.getDouble("valor_liquido"));
                    //System.out.println(mod.getValorLiquido());
                    modParceiro.setRazaoSocial(con.resultSet.getString("razao_social"));
                    //System.out.println(modParceiro.getRazaoSocial());
                    mod.setFk_fornecedor(modParceiro);
                    //System.out.println(mod.getFk_fornecedor().getRazaoSocial());
                    mod.setStatus(con.resultSet.getString("status"));
                    
                    lista.add(mod);
                }
        } catch (SQLException e) {
            con.desconectar();
            JOptionPane.showMessageDialog(null, "Erro ao popular tabela parcela" + e);
        }
        return lista;
    }

A consulta está perfeita, se eu der um sout em cada objeto ele me imprimi exatamente o que eu quero, porém na hora de carregar a informação do fornecedor na tabela não aparece nada!.. Estou passando por algo que não estou vendo, se puder me dar uma luz, agradeço!

minha iteração com a tabela se mantem a mesma:

public void carregarContasPagar(){
ArrayList listaConta = daoPgto.listarContaPagar();
ObservableList observableListTabela = FXCollections.observableArrayList();

    colIndexadorCP.setCellValueFactory(new PropertyValueFactory<>("indexador"));
    colNumDocumentoCP.setCellValueFactory(new PropertyValueFactory<>("numeroDocumento"));
    colValorParcelaCP.setCellValueFactory(new PropertyValueFactory<>("valorConta"));
    colFornecedorCP.setCellValueFactory(new PropertyValueFactory<>("fk_fornecedor"));
    colStatusCP.setCellValueFactory(new PropertyValueFactory<>("status"));
    
    if(!observableListTabela.isEmpty()){
        observableListTabela.clear();
        System.out.println("Tabela Limpa");
    }
    
    listaConta.stream().map((ModFinanceiroPagarConta cp) -> new ModeloTabelaContaPagar(
        cp.getIndexador() , 
        cp.getNumeroDocumento() , 
        cp.getFk_fornecedor().getRazaoSocial() , 
        cp.getValorLiquido() , 
        cp.getStatus()
    )).forEachOrdered((m) -> {
        observableListTabela.add(m);
    });
    tblContaPagar.setItems(observableListTabela);
}

j-Menezes, o problema foi resolvido, agradeço a ajuda!

2 curtidas

Estou com o mesmo problema, oque tu fez para resolver?

Como tu resolveu?