Alimentando uma JList com informações do banco de dados

20 respostas
R

Pessoal,

Estou com o seguinte problema tenho este método:

public String buscaLista(String qry){

        try{
            ResultSet resultado = statement.executeQuery(qry);

            String a="";

            ResultSetMetaData metaData = resultado.getMetaData();
            int numeroDeColunas = metaData.getColumnCount();

            if (numeroDeColunas < 0){
                System.out.println("Conexão Ok");
            }

            for(int i = 1; i <= numeroDeColunas; i++){

                a=metaData.getColumnName(i);
                System.out.printf("%-8s\t", metaData.getColumnName(i));
                System.out.println();
                return a;
            }
            while (resultado.next())
            {
                for(int i = 1; i <= numeroDeColunas; i++)

                    a=metaData.getColumnName(i);
                    System.out.printf("%-8s\t", resultado.getObject(i));
                    System.out.println();
                    return a;
            }
        }
        catch (SQLException ex) {
            JOptionPane.showMessageDialog(null, ex);
        }
        return ("Teste");
    }

Copiei ele de algum lugar e para o que esta especificado (imprimir o resultado) esta perfeito, mas eu queria poder alimentar uma jlist...

alguém pode me ajudar??? ou tem algum exemplo para eu dar uma olhada e conseguir me guiar????

Obrigado....Abs

20 Respostas

J

Olá amigo, isso que você está querendo fazer é simples, o primeiro passo é transformar os resultados do banco de dados em um ArrayList de Strings com os valores que você deseja exibir, depois use o método toArray da interface java.util.List que retorna um array comum de Objects, o JList possuí um método chamado setListData, que recebe um array de objetos como parâmetro, use o retorno do método do ArrayList como parâmetro do método setListData do JList e a sua lista terá os dados que você deseja do banco de dados.

Exemplo:

List&lt;String&gt; dados = new ArrayList&lt;String&gt;();
/* Coloque aqui o código que popula a lista com os dados do banco */
/* Caso o JList seja novo você pode inserir os dados da seguinte forma */
JList lista = new JList(dados);

/* Senão utilize o método setListData */]
lista.setListData(dados.toArray());
R

Amigo, li seu post tentei fazer mas não deu… você não consegue me mostrar em um exemplo por favor.

Abs

J

Fala cara, me fala qual parte do código vc não entendeu, de qualquer forma estou enviando um novo exemplo.

/* Cria o ArrayList */
List&lt;String&gt; dados = new ArrayList&lt;String&gt;();
/* Realiza a query */
ResultSet resultado = statement.executeQuery(qry);

/* Itera no resultado e popula o ArrayList, não lembro se a sintaxe está correta, mas é algo semelhante */
while(resultado.next()) {
	/* Esta linha adiciona uma linha da consulta no Array List */
	dados.add(resultado.getString("nome_da_coluna_no_banco"));
}

/* Com o array populado, você pode criar o seu JList */
/* Caso o JList seja novo, use a linha abaixo: */
JList lista = new JList(dados);
/* Caso o JList  exista, use a linha abaixo: */
lista.setListData(dados.toArray());
R

Fala meu amigo,

blz consegui entender o esquema, consegui fazer meu banco armazenar tudo na minha classe de conexão e enviar para a classe que chamou.

até ai tudo ótimo, agora parei no seguinte, você me disse neste ponto do código:

/* Com o array populado, você pode criar o seu JList */   
/* Caso o JList seja novo, use a linha abaixo: */   
JList lista = new JList(dados);   
/* Caso o JList  exista, use a linha abaixo: */   
lista.setListData(dados.toArray());

neste caso estou criando um objeto JList, mas no caso estou utilizando o netbeans e joguei no JFrame o JList (puxando e arrastando) agora como eu faço para ele receber o valor de "dados" (como no seu exemplo).

Olha meu código para você ter uma idéia:

CL_ConexaoBanco lista = new CL_ConexaoBanco();

                String qry;

                qry = "Select * from agenda";

                List recebe = new ArrayList();
                //aqui minha variavel recebe o valor que volta da classe de conexão com o resultado da pesquisa
                recebe = lista.buscaLista(qry);
                //aqui utilizei da sua forma e deu certo
                JList Jlista = new JList();
                Jlista.setListData(recebe.toArray());
                //agora queria saber para jogar no meu lstLista que eu criei
                this.lstLista. ??????

pode me ajudar cara .
Muito Obrigado por enquanto.
Abs.

J

Olá amigo,

você pode fazer da mesma forma que lhe mostrei, use o método setListData, o JList que você criou com o Netbeans pode ser acessado como qualquer outro objeto:

CL_ConexaoBanco lista = new CL_ConexaoBanco();

                String qry;

                qry = "Select * from agenda";

                List recebe = new ArrayList();
                //aqui minha variavel recebe o valor que volta da classe de conexão com o resultado da pesquisa
                recebe = lista.buscaLista(qry);
                //aqui utilizei da sua forma e deu certo
                JList Jlista = new JList();
                Jlista.setListData(recebe.toArray());
                /*Use o método setListData da mesma forma, a diferença é que o netbeans cuidou da criação do objeto para você, neste caso o nome do objeto é lstLista, basta utiliza-la da mesma forma que um JList criado na mão. */
                this.lstLista. setListData(recebe.toArray());
R

Fala amigo,

Seguinte não tem essa opção para mim, estou colocando a imagem para você ver:

Link caso não consiga ver pelo de cima:
http://img197.imageshack.us/i/imagemhts.jpg

O que estou fazendo de errado?

Abs.

J

Amigo, esse lstLista é um objeto de qual classe?

Se fosse da classe JList ele certamente teria este método.

R

Então amigo essa lstLista é o nome que eu dei para o componente list que arrastei para meu jframe.

J

Amigo verifica por favor se esse List que você arrastou é um javax.swing.JList ou um java.awt.List, se for isso realmente não vai funcionar.

Vlw!!!

R

Amigo funcionou, comi bola legal…muito obrigado…

agora mais uma pergunta…

Se eu quiser trazer todas as columas como eu faço?

Abs

J

Olá, o problema estava no List AWT mesmo?

Para armazenar as colunas do banco em memória é necessário criar uma estrutura que seja semelhante a tabela que você deseja armazenar, digamos que a sua tabela seja formada das seguintes colunas:

CREATE TABLE pessoas (
  id INT AUTO INCREMENT NOT NULL,
  nome VARCHAR(60) NOT NULL,
  email VARCHAR(255)
);

Crie uma classe que seja exatamente igual a esta tabela, ou seja, crie um Java Bean mapeando a tabela:

public class Pessoas {

  /* Atributos */
  private int id;
  private String nome;
  private String email;

  /* Construtores */
  public Pessoas() {}
  public Pessoas(int id, String nome, String email) {
    this.id = id;
    this.nome = nome;
    this.email = email;
  }
  
  /* Insira aqui os métodos Getters e Setters, use o Netbeans para fazer isso para você */
  
}

Para obter as colunas do banco use um código parecido com o seguinte:

/* Cria o ArrayList */
List&lt;Pessoa&gt; pessoas = new ArrayList&lt;Pessoa&gt;();
/* Realiza a query */
ResultSet resultado = statement.executeQuery(qry);

/* Itera no resultado e popula o ArrayList, não lembro se a sintaxe está correta, mas é algo semelhante */
while(resultado.next()) {
	/* Esta linha adiciona uma linha da consulta no Array List */
        /*Criando um objeto da classe Pessoa */
        Pessoa P = new Pessoa();
        /*Populando o objeto com os dados do banco */
        P.setId(resultado.getInt("id"));
        P.setNome(resultado.getString("nome"));
        P.setEmail(resultado.getString("email"));
        /*Adicionando o objeto P a lista de Pessoas */
        pessoas.add(P);
}

/* A melhor forma de utilizar esta lista é com um JTable, procure no Google alguns tutoriais de utilização do mesmo */

for(int i=0;i&lt;pessoas.size();i++) {
  /*Imprimindo o ID */
  System.out.println(pessoas.get(i).getId());
  /*Imprimindo o Nome */
  System.out.println(pessoas.get(i).getNome());
  /*Imprimindo o Email */
  System.out.println(pessoas.get(i).getEmail());
}

Se o seu objetivo for imprimir os dados no JList que já possui, crie um método toString personalizado na classe Pessoa que concatena os valores que deseja imprimir.

Depois utilize os mesmos passos usados quando você trabalhou com uma lista de Strings.

Bem é isso.

Quando estive mais experiente, dê uma olhada no Hibernate e nas práticas de padrões de projeto, isso vai lhe dar uma visão muito melhor sobre as coisas.
>

R

Cara to desde das 11 da noite procurando algum exemplo de jtable pro meu caso e não consigo…pode me ajudar???

cara to desesperado, pelo jeito jtable é complexo e tenho 3 dias pra terminar o projeto e 6 listas para imprimir na tela…

se puder me ajudar…

abs.

R

Cara achei este exemplo e parece ser reutilizavel, mas não consegui usar,....pode me ajudar:

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.Vector;

import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.table.DefaultTableModel;

public class TableGrid extends JTable {

	private DefaultTableModel tableModel;

	private void setTableModel(DefaultTableModel _tableModel) {
		this.tableModel = _tableModel;
	}
	private DefaultTableModel getTableModel() {
		return this.tableModel;
	}

	public TableGrid() {
		super();
		this.setAutoResizeMode(AUTO_RESIZE_ALL_COLUMNS);
		this.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
	}

	public void setDataSet(ResultSet resultSet) {
		try {

			if (resultSet != null) {
				ResultSetMetaData metaData = resultSet.getMetaData();
				int numColunas = metaData.getColumnCount();
				Vector colunas = new Vector();
				boolean adiciona = true;
				for (int column = 0; column < numColunas; column++) {
					colunas.addElement(metaData.getColumnLabel(column + 1));
				}
				Vector linhas = new Vector();
				resultSet.beforeFirst();
				while (resultSet.next()) {
					Vector novaLinha = new Vector();
					for (int i = 1; i <= metaData.getColumnCount(); i++) {
						novaLinha.addElement(resultSet.getObject(i));
					}
					linhas.addElement(novaLinha);
				}
				this.setTableModel(new DefaultTableModel(linhas, colunas));
				setModel(this.getTableModel());
			}
		} catch (SQLException sql) {
			sql.printStackTrace();
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}
	/**
	 *  
	 * @param resultSet  - representa o Objeto(java.sql.ResultSet) com os dados retornados da base
	 * @param colunmName - representa o Objeto(java.util.Vector) com o nomes das colunas da tabela
	 * 
	 * 
	 */

	public void setDataSet(ResultSet resultSet, Vector colunmName) {
		try {
			if (resultSet != null && colunmName != null) {
				Vector linhas = new Vector();
				resultSet.beforeFirst();
				while (resultSet.next()) {
					Vector novaLinha = new Vector();
					for (int cont = 1;
						cont <= resultSet.getMetaData().getColumnCount();
						cont++) {
						novaLinha.addElement(resultSet.getObject(cont));
					}
					linhas.addElement(novaLinha);
				}
				this.setTableModel(new DefaultTableModel(linhas, colunmName));
				setModel(this.getTableModel());
			}
		} catch (SQLException sqlEx) {
			sqlEx.printStackTrace();
		}
	};

	public void setDataSet(Vector dados, Vector linhas) {
		this.setTableModel(new DefaultTableModel(linhas, dados));
		setModel(this.getTableModel());
	}

	/**
	 * 
	 * Método responsável por trazer todos os dados relativo a linha selecionada
	 * @param linha
	 * @param coluna
	 * @return
	 */

	public Object retornaDado(int linha) {
		if (this.tableModel != null && linha >= 0) {
			return ((Vector) this.tableModel.getDataVector().get(linha))
				.toArray();
		} else {
			return null;
		}
	}

        public Object retornaDado(int linha, int coluna) {
		return (this.getModel().getValueAt(linha, coluna));
	}

	public void setDataSet(Object[][] dados, Object[] colunasNames) {
		setModel(new DefaultTableModel(dados, colunasNames));
	}
}

abs

J

Olá amigo, eu achei um código em um fórum da Sun, o cara criou um Table Model que trabalha diretamente com um ResultSet, segue o código:

import java.sql.*;
import java.util.Vector;
import javax.swing.*;

import javax.swing.table.AbstractTableModel;
 
public class Main extends JFrame {

    private static final String DRIVER = 
            "oracle.jdbc.driver.OracleDriver";

    private static final String CONNECTION = 
            "jdbc:oracle:thin:@my-server:1521:database";

    private static final String USER = "user";
    private static final String PASS = "pass";

    private static final String QUERY = "select * from table";
            
    final ResultSetTableModel model = new ResultSetTableModel();

    
    Main() throws Exception {        
        // Add table to model
        add(new JScrollPane(new JTable(model)));

        // Connect to database, query result, set to database 
        Class.forName(DRIVER);
        Connection c = DriverManager.getConnection(CONNECTION,USER,PASS);
        ResultSet rs = c.createStatement().executeQuery(QUERY);        

        model.setResultSet(rs);        
        // Minimalistic frame initialization 
        pack();
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
    }

    
    public static void main(String[] arg) {
        SwingUtilities.invokeLater(new Runnable() {

            public void run() {
                try {
                    new Main().setVisible(true);

                } catch (Exception ex) {
                    System.err.println(ex.getMessage());
                    ex.printStackTrace();

                }
            }
        });
    }
}
/** Simple resultset table model */

class ResultSetTableModel extends AbstractTableModel {
    // Currently displayed result set

    private ResultSet rs;
    // Associated metadata
    private ResultSetMetaData rsMeta;
    // Column count

    private int columnCount;
    // Column nmaes
    private final Vector&lt;String&gt; columnNames = new Vector&lt;String&gt;();

    // Vector of rows
    private final Vector&lt;Object[]&gt; cache = new Vector&lt;Object[]&gt;();

    /** Set new result set */
    public void setResultSet(ResultSet rs) throws SQLException {

        if (this.rs != null)
            this.rs.close();
        cache.clear();
        // 'Cache' some metadata data

        rsMeta = rs.getMetaData();
        columnCount = rsMeta.getColumnCount();
        columnNames.clear();
        for(int col = columnCount; col &gt; 0; col--) {

            columnNames.add(rsMeta.getColumnName(col));
        }
        // 'Cache' new resultest data
        while(rs.next()) {

            Object rowData[] = new Object[columnCount];
            for(int col = columnCount; col &gt; 0; col--)                 

                rowData[col - 1] = rs.getObject(col); 
            cache.add(rowData);
        }
        // Reload table structure
        fireTableStructureChanged();

    }
    /** Close result set */
    public void close() throws SQLException {

        rs.close();
    }
    /** ## TableModel interface ## */
    public String getColumnName(int column) {

        return columnNames.get(column);
    }
    /** ## TableModel interface ## */
    public Object getValueAt(int rowIndex, int columnIndex) {

        Object[] row = cache.get(rowIndex);
        return row[columnIndex];
    }
    /** ## TableModel interface ## */

    public int getRowCount() {
        return cache.size();
    }

    /** ## TableModel interface ## */
    public int getColumnCount() {
        return columnCount;

    }   
}

Para usar esse código basta criar uma instância deste ResultSetTableModel, setar o ResultSet e adicionar este model ao JTable.

R

Hahahah JC vou ficar devendo até a próxima vida para você…rs

agora por que minhas colunas saem na posição diferente dos dados???

http://img99.imageshack.us/i/imagemglt.jpg

e outra coisa, tenho como setar o tamanho das colunas?? ou alguma propriedade que eu deixo para ajeitar automaticamente???

Abs

J

Que bom que funcionou, eu nem testei essa classe, mas pelo código vi que deveria funcionar.

Se me lembro bem, o JTable tem essa capacidade sim, mas tu vai ter que alterar no model, dá uma estudada sobre o table model, se tu dominar ele, não vai ter mais problema com tabelas.

Da uma boa olhada nos tutoriais de JTable da Sun, e se tu entender bem esse esquema de model, não vai ter problema com o JList e nem com o JComboBox, ambos usam um model para exibir os dados, e os são bem parecidos.

Vlw!!

R

JC se eu mandar uma select com WHERE ele não aceita???

Estou tentando enviar uma clausula com where e não vai…

já viu isso???

Abs

I

Inicia ou seta o model do seu JTable com o resultado da função alimentaJTable

public DefaultTableModel alimentaJTable(String query){
		DefaultTableModel modelo = new DefaultTableModel();
		try{
			ResultSet rs = statement.executeQuery(query);
			if(!rs.first())
				return null;
			ResultSetMetaData rsmd = rs.getMetaData();
			int qtd_col = rsmd.getColumnCount();
			int linhas = qtdLinhas(rs);
			modelo.setColumnCount(qtd_col);
			modelo.setRowCount(linhas);
			modelo.setColumnIdentifiers(getNomeColunas(rsmd));
			for(int i=0;i<linhas;i++){
				rs.next();
				for(int j=0;j<qtd_col;j++)
					modelo.setValueAt(rs.getString(j+1), i, j);
			}
			return modelo;
		}catch(SQLException ex){
			return null;
		}
	}
	
	private int qtdLinhas(ResultSet rs){
		try{
			rs.last();
			int linha = rs.getRow();
			rs.beforeFirst();
			return linha;
		}catch(SQLException ex){
			return -1;
		}
	}
	
	private String[] getNomeColunas(ResultSetMetaData rsmd){
		try{
			String[] nomes = new String[rsmd.getColumnCount()];
			for(int i=1;i<=nomes.length;i++)
				nomes[i] = rsmd.getColumnName(i);
			return nomes;
		}catch(SQLException ex){
			return null;
		}
		
	}

Não tenho certeza se vai funcionar, fiz a função agora mas eu usei isso a poucos dias e funcionou na boa..se não der certo quando chegar em casa eu te passo a que fiz lá, q ja testei e funciona!

R

Galera achei a solução e vou postar aqui só par que se alguém entrar tenha a resposta:

Não sei por que mas a select não pode ter campos apelidados tipo:

select a.nome, b.senha from usuario a, login b

Por que eu não sei só sei que setando direto a tabela foi…rs

select usuario.nome, login.senha from usuario, login

se alguém souber a razão por favor poste ae…

abs

C

Não entendi porque ele inverte o nome das colunas, mas pra resolver nem foi difícil só inverter a logica do for onde ele insere os nomes das colunas.
Legal, tava procurando um jeito fácil de se fazer isso, a implementação dessa classe facilita mesmo.

De:

for(int col = columnCount; col > 0; col--)

Para:

for(int col = 1; col < columnCount+1; col++)
Criado 15 de junho de 2009
Ultima resposta 29 de jan. de 2010
Respostas 20
Participantes 4