Boa tarde galera, to com uma Dúvida aqui envolvendo JTable dentro de uma tela de vendas, seguinte.: Tenho uma tela de vendas onde o usuário terá um ComboBox para verificar quais mercadorias ele possui, ele irá selecionar a mercadoria que ele nescessita e clicar no botão incluir, essa mercadoria irá para a JTable, 1° Dúvida, como fazer um evento onde a JTable recebe esse dado selecionado após o usuário clicar no botão incluir??? 2° Dúvida, na JTable terá um campo chamado R$Preço, que irá conter o preço de cada mercadoria, então caso o usuário selecione mais de uma mercadoria, como fazer para somar o preço de cada mercadoria contida na JTable…??? Se o usuario selecionar 3 mercadorias, como somar o preço dessas tres que estão contidas na JTable???
Alem claro de TableModel, customizando o teu proprio utilizando o AbstractTableModel…
A
Anderson_S
Fernando Generoso da Rosa:
Aconselho a vc estudar duas coisas:
ActionListener
Padrao Observer
Alem claro de TableModel, customizando o teu proprio utilizando o AbstractTableModel…
Então cara, eu sei utilizar o ActionListener, mas eu não estou conseguindo pensar numa lógica pra colocar dentro desse evento, e eu ja tenho meu TableModel criado…
Marky.Vasconcelos
Simples. Dentro do ActionListener crie um novo objeto do tipo que o seu TableModel trabalha e mande adicionar nele.
Voce precisa guardar a referencia do Model para isso.
A
Anderson_S
Certo, eu entendi mas não to conseguindo visualizar na programação, será que tem como você me da um exemplo de como seria na pratica esse evento??
Vo postar meu Model..
packageApresentacao;importNegocio.Venda;importjava.util.ArrayList;importjava.util.List;importjavax.swing.table.AbstractTableModel;publicclassContatoTableModelextendsAbstractTableModel{privatestaticfinalintCOL_NOME=0;privatestaticfinalintCOL_QUANTIDADE=1;privatestaticfinalintCOL_DESCRICAO=2;privatestaticfinalintCOL_PRECO=3;privateList<Venda>venda;// Esse é um construtor, que recebe a nossa lista de ContatospublicContatoTableModel(List<Venda>venda){this.venda=newArrayList<Venda>(venda);}publicintgetRowCount(){// Quantas linhas tem sua tabela? Uma para cada item da lista.returnvenda.size();}publicintgetColumnCount(){// Quantas colunas tem a tabela? Nesse exemplo, só 3.return4;}publicStringgetColumnName(intcolumnIdx){// Qual é o nome das nossas colunas?if(columnIdx==COL_NOME)return"Nome";if(columnIdx==COL_QUANTIDADE)return"Quantidade";if(columnIdx==COL_DESCRICAO)return"Descição";if(columnIdx==COL_PRECO)return"Preço";return"";// Nunca deve ocorrer}publicObjectgetValueAt(introw,intcolumn){// Precisamos retornar o valor da coluna column e da linha row.Contatocon=venda.get(row);if(column==COL_NOME)returnvenda.getINome();if(column==COL_QUANTIDADE)returnvenda.getQuantidade();if(column==COL_DESCRICAO)returnvenda.getDescricao();if(column==COL_PRECO)returnvenda.getTPreco();return"";// Nunca deve ocorrer}publicvoidsetValueAt(ObjectaValue,introwIndex,intcolumnIndex){// Vamos alterar o valor da coluna columnIndex na linha rowIndex com o// valor aValue passado no parâmetro.// Note que vc poderia alterar 2 campos ao invés de um só.Vendavenda=Venda.get(rowIndex);if(columnIndex==COL_NOME)venda.setNome(aValue.toString());if(columnIndex==COL_QUANTIDADE)venda.setQuantidade(aValue.toString());if(columnIndex==COL_DESCRICAO)venda.setDescricao(aValue.toString());if(columnIndex==COL_PRECO)con.setPreco(aValue.toString());}publicClass<?>getColumnClass(intcolumnIndex){// Qual a classe das nossas colunas? Como estamos exibindo texto, é// string.returnString.class;}publicbooleanisCellEditable(introwIndex,intcolumnIndex){// Indicamos se a célula da rowIndex e da columnIndex é editável. Nossa// tabela toda é.returntrue;}publicvoiddelete(introw){venda.remove(row);fireTableRowsDeleted(row,row);}publicvoidadd(Vendav){Venda.add(v);//adiciona o novo contato no modelothis.fireTableRowsInserted(venda.size()-1,venda.size()-1);}// Já que esse tableModel é de contatos, vamos fazer um get que retorne um// contato inteiro.// Isso elimina a necessidade de chamar o getValueAt() nas telas.publicVendaget(introw){returnvenda.get(row);}}
Ai Marky, eu digitei um valor no TextField e clique no botão incluir que contem o método que você me passo, ai ta dando o seguinte erro.
Outra coisa, o usuário pode quere inserir vários nomes dentro dessa JTable, como eu faço???
Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: javax.swing.table.DefaultTableModel cannot be cast to Apresentacao.ContatoTableModel
at Apresentacao.KK.incluirActionPerformed(KK.java:108)
at Apresentacao.KK.access$000(KK.java:21)
at Apresentacao.KK$1.actionPerformed(KK.java:67)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)
at java.awt.Component.processMouseEvent(Component.java:6038)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3260)
at java.awt.Component.processEvent(Component.java:5803)
at java.awt.Container.processEvent(Container.java:2058)
at java.awt.Component.dispatchEventImpl(Component.java:4410)
at java.awt.Container.dispatchEventImpl(Container.java:2116)
at java.awt.Component.dispatchEvent(Component.java:4240)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4322)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:3986)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3916)
at java.awt.Container.dispatchEventImpl(Container.java:2102)
at java.awt.Window.dispatchEventImpl(Window.java:2429)
at java.awt.Component.dispatchEvent(Component.java:4240)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:121)
Fernando_Generoso_da
cara…na hora que tu instanciar o teu JTable, passa uma instancia de ContatoTableModel:
JTable table = new JTable(new ContatoTableModel());
Assim a tua JTable ira ficar com uma istancia do teu table model, e nao com a do default table model.
Abraco
A
Anderson_S
Fernando Generoso da Rosa:
cara…na hora que tu instanciar o teu JTable, passa uma instancia de ContatoTableModel:
JTable table = new JTable(new ContatoTableModel());
Assim a tua JTable ira ficar com uma istancia do teu table model, e nao com a do default table model.
Abraco
Deu errado cara,agora ainda de corrigir esse erro que citei acima, também tenho que implementar uma solução para o usuário inserir vários nomes na JTable
que é coisa que eu não sei…
Fernando_Generoso_da
Posta o codigo inteiro ai da tua classe, onde tu instancia a jtable…
A
Anderson_S
Pois é, você viu minha dúvida no início do tópico???
Que classe você quer???
eu to tentando implementar o método que o MArky me passo para inserir o nome na JTable após o usuário digitar o nome no TextField e clicar no botão incluir
Estou trabalhando com o visual Editor do NetBenns…
Fernando_Generoso_da
a classe visual, onde tem a jtable
A
Anderson_S
Pra que você quer essa classe, sendo que o problema ta no método que eu to tentando implementar…???
Marky.Vasconcelos
Cade o código que coloca os dados dentro da sua JTable?
Pelo visto voce esta usando o DefaultTableModel. Voce precisa trabalhar com o TableModel que voce criou, com ele será possivel fazer o que voce quer.
A
Anderson_S
Marky, vou postar o meu método incluir, onde o usuário digita um nome no textfield e clica no botao incluir e o nome aparece na JTable, mas tem um problema com esse método que eu criei, por que toda vez que o usuário clicar no botão incluir, ele faz uma instancia da TableModel e lança o nome dentro dela, e seta o modelo na JTable, caso o usuário queira inserir mais de um nome na JTable, ele clica no botão incluir e o dado é sobrescrevido, por que será criada outra instancia da JTable, o certo sería , cada vez que o usuário digita-se um nome no textfield e clica-se no botão incluir, tinha que ir aparecendo os nomes dentro da JTable, eu queria resolver esse problema.... mas não to conseguindo, ja pesquisei na internet, mas não achei solução.. :cry:
MÉTODO QUE INCLUI NA JTABLE
private void incluirActionPerformed(java.awt.event.ActionEvent evt) {
if(evt.getSource() == incluir){
List<Contato> minhaLista = new ArrayList<Contato>();
Contato contato = new Contato(recebe_nome.getText());
minhaLista.add(contato);
ModelTeste modelo = new ModelTeste(minhaLista);
tabela.setModel(modelo);
}
}
Marky.Vasconcelos
A resposta que voce quer está na sua pergunta.
Voce nao precisa ficar instanciando toda hora o TableModel. Instancie uma vez, coloque-o na tabela, depois disso, toda alteração faz com a mesma instancia.
A
Anderson_S
Certo, mas como eu vo instanciar-la, sendo que durante sua instancia ele pede uma lista???
Eu estou utilizando o Visual Editor do netbens
Marky.Vasconcelos
Horas, mude seu TableModel para não receber uma Lista ou então passe uma lista vazia.
Depois disso voce só vai adicionar itens pelo método add pela ação.
A
Anderson_S
Marky.Vasconcelos:
Horas, mude seu TableModel para não receber uma Lista ou então passe uma lista vazia.
Depois disso voce só vai adicionar itens pelo método add pela ação.
Como meu TableModel ficaría para caso ele não recebe-se uma lista??? ou como passar uma lista vazia pra ele???
A
Anderson_S
Ai Marky, eu criei um método para instanciar a JTable... que foi esse...
Como eu estou utilizando o VisualEditor do NetBeans... ele vai junto com o initComponent(), para ser instanciado em tempo de execução..
ESSE É O MÉTODO
private void instanciaModel(){
List<Contato> lista = null;
ModelTeste modelo = new ModelTeste(lista);
tabela.setModel(modelo);
}
Ai eu editei o método de incluir na JTable, ele fico da seguinte maneira..
private void incluirActionPerformed(java.awt.event.ActionEvent evt) {
if(evt.getSource() == incluir){
Contato contato = new Contato(recebe_nome.getText());
ModelTeste model = (ModelTeste)tabela.getModel();
model.add(contato);
}
}
Uma lista ‘null’ nao é uma lista vazia, é uma lista que não existe.
O correto para criar o Model seria.
List<Contato> lista = new ArrayList<Contato>();
ModelTeste modelo = new ModelTeste(lista);
A
Anderson_S
[b]Ai Marky, vlw cara, deu certinho!!!
Qualquer coisa eu aviso blz???
Obrigado!!![/b] :mrgreen:
A
Anderson_S
Ai Marky, eu tentei fazer uma coisa mais profissional aqui, o usuário vai digitar o nome no TextField e vai clicar no botão incluir, inves de add esse nome na Table, fazer uma busca no banco e add na JTable tudo referente a aquele nome, mas ele poderia buscar mais de um nome e add na JTable, desse mesmo jeito que tava antes.. como sería???
Meu método que busca no banco é esse
..
public List<Contato> buscar(String nome) throws SQLException{
Connection conn = Conexao.getConexao();
// Nesta Rotína, nescessita de utilizar o contrutor
// para inicializa-lo com o parametro de deseja consultar
Contato contato = new Contato(nome);
String sql = "Select * from usuario where nome=?";
PreparedStatement stmt = conn.prepareStatement(sql);
stmt.setString(1, contato.getNome());
ResultSet rs = stmt.executeQuery();
List<Contato> listar= new ArrayList<Contato>();
while(rs.next()){
Contato cont = new Contato(rs.getInt("idusuario"));
cont.setNome(rs.getString("nome"));
cont.setIdade(rs.getString("idade"));
cont.setTelefone(rs.getString("telefone"));
listar.add(cont);
}
rs.close();
stmt.close();
return listar;
}
Marky.Vasconcelos
Não entendi sua dúvida.
A
Anderson_S
É assim, o textfield vai ser considerado um campo pra buscas, o usuário irá digitar um possível nome para realizar a busca, caso o nome exista, todos os dados referente aquele nome serão lançados na JTable, a cada vez que o usuário realizar uma busca, os dados terão de ser inseridos na JTable, sem sobrescrever… é quase igual a esse outro i, a diferença é que será realizado uma consulta no banco, antes de inserir na JTable, mas poderam ser inseridos mais de um campo na tabela, ou seja, várias buscas poderam ser feitas, e os dados da JTable não poderam ser Sobrescritos…
O método que busca os dados no banco é esse ai que citei acima…
Obrigado!!
Marky.Vasconcelos
Horas, se for o que eu entendi, voce tem duas soluções.
Altere seu TableModel para aceitar uma List estilo addAll e adicione todos os itens da List dentro do seu model, ou então faça um for no evento e adicione no model um por um dos resultados.
A
Anderson_S
A cada busca que o usuáio fazer no banco, a JTable irá receber os dados referente a busca… se for realizada mais de uma busca, todas elas terão que estar contidas na JTable…
Essa sua segunda solução eu achei mais viável para o meu problema…como sería um código fonte dela…???
Tentei mais não to conseguindo visualizar!!!
Marky.Vasconcelos
Seria mais ou menos assim:
private void incluirVariosActionPerformed(java.awt.event.ActionEvent evt) {
List<Contato> list = new DAO.buscar(recebe_nome.getText());
ModelTeste model = (ModelTeste)tabela.getModel();
for(Contato contato : list)
model.add(contato);
}
Se voce criar o método addAll no TableModel voce faria algo assim.
private void incluirVariosActionPerformed(java.awt.event.ActionEvent evt) {
List<Contato> list = new DAO.buscar(recebe_nome.getText());
ModelTeste model = (ModelTeste)tabela.getModel();
model.addAll(list);
}
Acho a segunda opção mais interessante, voce tem um model semelhante a uma List que é facil de manipular. E esse método no TableModel será bem simples.
A
Anderson_S
Certo Marky, por enquanto eu estou sem tempo por que estou fazendo estágio, mas assim que sair um tempinho eu vo codificar e testar pra ver se deu certinho… por enquanto eu não vou colocar [RESOLVIDO] no tópico Oks??
Marky.Vasconcelos
Sem problemas, tópico “[RESOLVIDO]” é duvida resolvida, quando não lhe restarem mais fique a vontade para mudar.