versão 1.1
Motivação
Porque estou escrevendo este post: pois não consegui achar em nenhum lugar da net resumidinho e especial o que estava procurando, encontrei muita coisa mas fragmentada, o que mais chegou perto do que eu queria foram:
http://nealbuerger.com/2012/01/java-gui-using-abstracttablemodel/
http://www.guj.com.br/java/132698-jtable-removendo-colunas-em-tempo-de-execucao#714736
Objetivo
Cria um JTable que utiliza um Vector / LinkedList para armazenar objetos que serão criados dinamicamente pelos usuários através do preenchimento de campos de texto.
Foi utilizado o NetBeans versão 7.2, o editor visual dele está ficando bom 🙂
Veja na imagem abaixo o resultado final
Execução
Este exemplo irá trabalha com uma classe abstrata chamada conta e uma classe concreta chamada ContaCorrente
package bancob; public abstract class Conta { private String cliente; private int numero; private double saldo; public Conta(String cliente, int numero, double saldo) { this.cliente = cliente; this.numero = numero; this.saldo = saldo; } public String getCliente() { return cliente; } public void setCliente(String cliente) { this.cliente = cliente; } public int getNumero() { return numero; } public void setNumero(int numero) { this.numero = numero; } public double getSaldo() { return saldo; } public void setSaldo(double saldo) { this.saldo = saldo; } public abstract void sacar(double valor); public abstract void depositar(double valor); } package bancob; public class ContaCorrente extends Conta { private double limite; public ContaCorrente(double limite, String cliente, int numero, double saldo) { super(cliente, numero, saldo); this.limite = limite; } public double getLimite() { return limite; } public void setLimite(double limite) { this.limite = limite; } @Override public void sacar(double valor) { if(valor maior= (this.getSaldo()+limite)){ System.out.println("Sacou "+valor); this.setSaldo(this.getSaldo()-valor); } else { System.out.println("Saldo insuficiente"); } } @Override public void depositar(double valor) { throw new UnsupportedOperationException("Not supported yet."); } JTable é o objeto da API swing responsável por exibir uma tabela, imagina uma planilha do excel. O JTAble não deve ficar responsável por absolutamente nada do que diz respeito a gestão dos dados que serão exibidos o componente caberá a função de definir onde no JFrame será exibida a tabela, todo o resto deve ser programado em uma classe auxiliar que irá extender a classe AbstractTableModel. Nesta classe você irá definir a quantidade de colunas, de que maneira cada uma delas será exibida, quais serão os dados e de que maneira eles (os dados serão manipulados). Segue abaixo o código completo da aplicação funcionando. |
package bancob; import java.text.DecimalFormatSymbols; import java.util.Locale; import java.util.Vector; import javax.swing.JOptionPane; import javax.swing.table.AbstractTableModel; public class ListarContaCorrete extends javax.swing.JDialog { ModeloTabelaContas modelo = new ModeloTabelaContas(); int linhaselecionada; ContaCorrente contaSelecionada; public ListarContaCorrete(java.awt.Frame parent, boolean modal) { super(parent, modal); initComponents(); tbContas.setModel(modelo); } @SuppressWarnings("unchecked") // <editor-fold defaultstate="collapsed" desc="Generated Code"> private void initComponents() { jScrollPane1 = new javax.swing.JScrollPane(); tbContas = new javax.swing.JTable(); txtnome = new javax.swing.JTextField(); jLabel1 = new javax.swing.JLabel(); jLabel2 = new javax.swing.JLabel(); jLabel3 = new javax.swing.JLabel(); jButton1 = new javax.swing.JButton(); jButton2 = new javax.swing.JButton(); txtidconta = new javax.swing.JLabel(); jButton3 = new javax.swing.JButton(); jButton4 = new javax.swing.JButton(); txtsaldo = new javax.swing.JFormattedTextField(); txtlimite = new javax.swing.JFormattedTextField(); setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); jScrollPane1.setViewportView(tbContas); tbContas.getAccessibleContext().setAccessibleName(""); jLabel1.setText("Nome:"); jLabel2.setText("Saldo:"); jLabel3.setText("Limite:"); jButton1.setText("Salvar"); jButton1.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton1ActionPerformed(evt); } }); jButton2.setText("Carregar"); jButton2.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton2ActionPerformed(evt); } }); txtidconta.setText("Conta: não selecionada"); jButton3.setText("Remover"); jButton3.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton3ActionPerformed(evt); } }); jButton4.setText("Limpar"); jButton4.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton4ActionPerformed(evt); } }); txtsaldo.setFormatterFactory(new javax.swing.text.DefaultFormatterFactory(new javax.swing.text.NumberFormatter(new java.text.DecimalFormat("#0.00")))); txtlimite.setFormatterFactory(new javax.swing.text.DefaultFormatterFactory(new javax.swing.text.NumberFormatter(new java.text.DecimalFormat("#0.00")))); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addComponent(jLabel1) .addGap(10, 10, 10) .addComponent(txtnome, javax.swing.GroupLayout.PREFERRED_SIZE, 190, javax.swing.GroupLayout.PREFERRED_SIZE)) .addComponent(txtidconta) .addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jLabel2) .addComponent(jLabel3)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) .addComponent(txtsaldo, javax.swing.GroupLayout.DEFAULT_SIZE, 75, Short.MAX_VALUE) .addComponent(txtlimite))) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addComponent(jButton1) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jButton4) .addGap(14, 14, 14))) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 12, Short.MAX_VALUE) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addComponent(jButton2) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jButton3)) .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 436, javax.swing.GroupLayout.PREFERRED_SIZE)) .addContainerGap()) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(txtidconta) .addComponent(jButton2) .addComponent(jButton3)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 252, javax.swing.GroupLayout.PREFERRED_SIZE) .addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(txtnome, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jLabel1)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jLabel2) .addComponent(txtsaldo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jLabel3) .addComponent(txtlimite, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jButton1) .addComponent(jButton4)))) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); pack(); }// </editor-fold> private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) { String nome = txtnome.getText(); if(nome.equals("")){ JOptionPane.showMessageDialog(this, "Nome obrigatório"); txtnome.requestFocus(); return; } double limite = 0; if(!txtlimite.getText().equals("")){ limite = Double.parseDouble(txtlimite.getText().replace(",", ".")); } double saldo = 0; if(!txtsaldo.getText().equals("")){ saldo = Double.parseDouble(txtsaldo.getText().replace(",", ".")); } ContaCorrente c = new ContaCorrente(limite, nome, 10, saldo); if(contaSelecionada == null){ modelo.insertData(c); } else { modelo.updateData(c, linhaselecionada); linhaselecionada = -1; contaSelecionada = null; } } private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) { linhaselecionada = tbContas.getSelectedRow(); if(linhaselecionada == -1){ JOptionPane.showMessageDialog(null, "Selecione uma linha"); } contaSelecionada = modelo.get(linhaselecionada); txtidconta.setText("Conta: "+Integer.toString(linhaselecionada)); txtnome.setText(contaSelecionada.getCliente()); txtsaldo.setText(Double.toString(contaSelecionada.getSaldo())); txtlimite.setText(Double.toString(contaSelecionada.getLimite())); } private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) { int opcao = JOptionPane.showConfirmDialog(this, "Deseja Remover a Conta?"); if(opcao == JOptionPane.YES_OPTION){ if(tbContas.getSelectedRow() >= 0){ modelo.delete(tbContas.getSelectedRow()); JOptionPane.showMessageDialog(this, "Conta removida com sucesso"); } } } private void jButton4ActionPerformed(java.awt.event.ActionEvent evt) { linhaselecionada = -1; contaSelecionada = null; txtidconta.setText("Conta: não sellecionada"); txtnome.setText(""); txtlimite.setText(""); txtsaldo.setText(""); } /** * @param args the command line arguments */ public static void main(String args[]) { /* Set the Nimbus look and feel */ //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) "> /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel. * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html */ try { for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { if ("Nimbus".equals(info.getName())) { javax.swing.UIManager.setLookAndFeel(info.getClassName()); break; } } } catch (ClassNotFoundException ex) { java.util.logging.Logger.getLogger(ListarContaCorrete.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (InstantiationException ex) { java.util.logging.Logger.getLogger(ListarContaCorrete.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (IllegalAccessException ex) { java.util.logging.Logger.getLogger(ListarContaCorrete.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (javax.swing.UnsupportedLookAndFeelException ex) { java.util.logging.Logger.getLogger(ListarContaCorrete.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } //</editor-fold> /* Create and display the dialog */ java.awt.EventQueue.invokeLater(new Runnable() { public void run() { ListarContaCorrete dialog = new ListarContaCorrete(new javax.swing.JFrame(), true); dialog.addWindowListener(new java.awt.event.WindowAdapter() { @Override public void windowClosing(java.awt.event.WindowEvent e) { System.exit(0); } }); dialog.setVisible(true); } }); } // Variables declaration - do not modify private javax.swing.JButton jButton1; private javax.swing.JButton jButton2; private javax.swing.JButton jButton3; private javax.swing.JButton jButton4; private javax.swing.JLabel jLabel1; private javax.swing.JLabel jLabel2; private javax.swing.JLabel jLabel3; private javax.swing.JScrollPane jScrollPane1; private javax.swing.JTable tbContas; private javax.swing.JLabel txtidconta; private javax.swing.JFormattedTextField txtlimite; private javax.swing.JTextField txtnome; private javax.swing.JFormattedTextField txtsaldo; // End of variables declaration } class ModeloTabelaContas extends AbstractTableModel { private static final int COL_NOME = 0; private static final int COL_SALDO = 1; private static final int COL_LIMITE = 2; private String[] columnNames = {"Nome","Saldo","Limite"}; private Vector contas = new Vector(); @Override public int getRowCount() { return contas.size(); } @Override public int getColumnCount() { return columnNames.length; } @Override public String getColumnName(int col){ return columnNames[col]; } @Override public Object getValueAt(int rowIndex, int columnIndex) { ContaCorrente c = (ContaCorrente) contas.get(rowIndex); switch(columnIndex){ case COL_SALDO: return c.getCliente(); case COL_LIMITE: return c.getSaldo(); default: return c.getLimite(); } } public void insertData(ContaCorrente c){ contas.add(c); fireTableDataChanged(); } public void updateData(ContaCorrente c, int pos){ contas.remove(pos); contas.add(pos,c); fireTableDataChanged(); } public ContaCorrente get(int i){ return (ContaCorrente) contas.get(i); } public void delete(int i){ contas.remove(i); fireTableDataChanged(); } } |