Atualizar JTable e TableModel

2 respostas
eliasfsjunior

Galera, estou com um problema simples, mas, não estou conseguindo resolver… rs rs rs
Eu tenho uma table e um tableModel. O problema que é quando eu removo/altero/adiciono um novo objeto, quero que essa table seja atualizada. Já tentei usar o método fireTableDataChanged do AbstractTableModel… Já tentei dar repaint na table… E um monte de coisas, nada funcionou. Qual a melhor maneira de atualizar a tabela? Eu não estou usando DefaultTableModel, pq todo mundo fala para não usar isso. :slight_smile:

Reparem que os métodos de adicionar e excluir estava dentro do formulário (estão comentados), mas em todos os fóruns que pesquisei, o pessoal cria os métodos dentro do TableModel.

Formulário que contém a JTable;

public class FormCadastroMercado extends JInternalFrame {
	
    private static final long serialVersionUID = 5092513957287336599L;
    private static FormCadastroMercado singleton = null;
    private JTextField txtIdMercado;
    private JTextField txtNomeMercado;
    private MercadoBean mercado;
    private JTable table;
    private JScrollPane scrollPane;
    private MercadoTableModel tableModel;
 
    public FormCadastroMercado() {
		setTitle("Cadastro de Mercado");
		setClosable(true);
		setDefaultCloseOperation(JInternalFrame.HIDE_ON_CLOSE);
		setBounds(15, 15, 550, 300);    	
		getContentPane().setLayout(null);
		
		JPanel panel = new JPanel();
		panel.setBounds(10, 11, 514, 249);
		getContentPane().add(panel);
		panel.setLayout(null);
		
		JLabel lblId = new JLabel("ID");
		lblId.setFont(new Font("Tahoma", Font.PLAIN, 12));
		lblId.setBounds(10, 26, 19, 14);
		panel.add(lblId);
		
		txtIdMercado = new JTextField();
		txtIdMercado.setEditable(false);
		txtIdMercado.setBounds(57, 24, 115, 20);
		txtIdMercado.setText("");
		panel.add(txtIdMercado);
		txtIdMercado.setColumns(10);
		
		JLabel lblNome = new JLabel("Nome");
		lblNome.setFont(new Font("Tahoma", Font.PLAIN, 12));
		lblNome.setBounds(10, 51, 39, 14);
		panel.add(lblNome);
		
		txtNomeMercado = new JTextField();
		txtNomeMercado.setBounds(57, 49, 115, 20);
		txtNomeMercado.setText("");
		panel.add(txtNomeMercado);
		txtNomeMercado.setColumns(10);
		
		JPanel navegation = new JPanel();
		navegation.setBounds(182, 11, 322, 74);
		panel.add(navegation);
		navegation.setLayout(null);
		
		JButton btnSalvar = new JButton("Salvar");
		btnSalvar.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				
				mercado = new MercadoBean();				
				mercado.setNome(txtNomeMercado.getText());
				try {
					mercado.setId(new Integer(txtIdMercado.getText()));
					tableModel.salvarMercado(mercado);
				} catch (NumberFormatException nfe) {
					// Do Nothing
				} catch (AplicacaoException ape) {
					JOptionPane.showMessageDialog(null, ape.getMessage(), "ERRO:", 1);
				}
				tableModel.fireTableDataChanged();
			}
		});
		btnSalvar.setBounds(13, 11, 81, 23);
		navegation.add(btnSalvar);
		
		JButton btnExcluir = new JButton("Excluir");
		btnExcluir.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				
				mercado = new MercadoBean();
				try {
					mercado.setId(new Integer(txtIdMercado.getText()));
					tableModel.excluirMercado(mercado);
					JOptionPane.showMessageDialog(null, "Mercado removido com sucesso!", "Confirmação", 1);
				} catch (NumberFormatException nfe) {
					JOptionPane.showMessageDialog(null, "Selecione um mercado para remover", "Erro:", 1);
				}
				tableModel.fireTableDataChanged();
			}
		});
		btnExcluir.setBounds(203, 11, 89, 23);
		navegation.add(btnExcluir);
		
		JButton btnNovo = new JButton("Novo");
		btnNovo.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				statusNovo();
			}
		});
		btnNovo.setBounds(104, 11, 89, 23);
		navegation.add(btnNovo);
		
		JButton btnPrevious = new JButton("");
		btnPrevious.setBounds(13, 40, 47, 23);
		navegation.add(btnPrevious);
		btnPrevious.setIcon(new ImageIcon(FormCadastroMercado.class.getResource("/com/eliasjunior/msb/winapp/cadastro/img/anterior.png")));
		
		JButton btnFirst = new JButton("");
		btnFirst.setBounds(85, 40, 59, 23);
		navegation.add(btnFirst);
		btnFirst.setIcon(new ImageIcon(FormCadastroMercado.class.getResource("/com/eliasjunior/msb/winapp/cadastro/img/primeiro.png")));
		
		JButton btnNext = new JButton("");
		btnNext.setBounds(245, 40, 47, 23);
		navegation.add(btnNext);
		btnNext.setIcon(new ImageIcon(FormCadastroMercado.class.getResource("/com/eliasjunior/msb/winapp/cadastro/img/proximo.png")));
		
		JButton btnLast = new JButton("");
		btnLast.setBounds(154, 40, 59, 23);
		navegation.add(btnLast);
		btnLast.setIcon(new ImageIcon(FormCadastroMercado.class.getResource("/com/eliasjunior/msb/winapp/cadastro/img/ultimo.png")));
		
		/** Criando a Tabela **/
		
		scrollPane = new JScrollPane();
		scrollPane.setBounds(10, 96, 494, 142);
		panel.add(scrollPane);
		
		table = new JTable();
		tableModel = new MercadoTableModel();
		table.setModel(tableModel);
		
		table.getColumnModel().getColumn(MercadoTableModel.COLUNA_ID).setMinWidth(30);
		table.getColumnModel().getColumn(MercadoTableModel.COLUNA_ID).setMaxWidth(50);
		table.getColumnModel().getColumn(MercadoTableModel.COLUNA_ID).setPreferredWidth(40);
		
		DefaultTableCellRenderer ALIGN_LEFT = new DefaultTableCellRenderer();  
		ALIGN_LEFT.setHorizontalAlignment(SwingConstants.LEFT);  
		table.getColumnModel().getColumn(MercadoTableModel.COLUNA_ID).setCellRenderer(ALIGN_LEFT);
		table.getColumnModel().getColumn(MercadoTableModel.COLUNA_NOME).setCellRenderer(ALIGN_LEFT);
		
		table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
			@Override
			public void valueChanged(ListSelectionEvent e) {
				
				MercadoBean mercado = tableModel.get(table.getSelectedRow());
				try {
					txtIdMercado.setText(mercado.getId().toString());
					txtNomeMercado.setText(mercado.getNome());
				} catch (Exception err) { /** Do Nothing **/ }
			}
		});
		
		scrollPane.setViewportView(table);
		scrollPane.setVisible(true);
    }
    
    public static FormCadastroMercado getInstance() {
        if (singleton == null) 
        	singleton = new FormCadastroMercado();
        return singleton;
    }
    
    private void statusNovo() {
    	table.clearSelection();
    	txtIdMercado.setText("");
    	txtNomeMercado.setText("");
    }

    /**
    private void salvarMercado() {
    	
    	MercadoBean mercado = new MercadoBean();
    	int id = 0;
    	try {
    		id = Integer.parseInt(txtIdMercado.getText());
    	} catch (NumberFormatException nfe) {
    		System.out.println("ERRO: Integer.parseInt(txtIdMercado.getText());");
    	}
    	
    	if (txtIdMercado.getText().equals("")) {
    		// Se o ID estiver vazio, cria um novo mercado
    		mercado.setNome(txtNomeMercado.getText().toUpperCase());
        	mercadoDAO.store(mercado);
        	JOptionPane.showMessageDialog(null, "Mercado "+txtNomeMercado.getText().toUpperCase()
        			+" gravado com sucesso!", "Confirmação", 1);
    	}
    	if (id > 0) {
    		// Se o ID for maior que ZERO, atualiza
    		mercado.setId(id);
    		mercado.setNome(txtNomeMercado.getText().toUpperCase());
        	mercadoDAO.update(mercado);
        	JOptionPane.showMessageDialog(null, "Mercado alterado com sucesso!", "Confirmação", 1);
    	}
    	statusNovo();
    }
    
    private void excluirMercado() {
    	try {
    		int id = Integer.parseInt(txtIdMercado.getText());
    		if (JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(null, "Deseja remover" +
    				" o mercado: "+txtNomeMercado.getText(), "Confirmação", JOptionPane.YES_NO_OPTION)) {
    			MercadoBean mercado = new MercadoBean();
        		mercado.setId(id);
    			mercadoDAO.remove(mercado);
    			JOptionPane.showMessageDialog(null, "Mercado removido com sucesso!", "Confirmação", 1);
    		}
    	} catch (NumberFormatException nfe) {
    		System.out.println("ERRO: Integer.parseInt(txtIdMercado.getText());");
    		JOptionPane.showMessageDialog(null, "Selecione um mercado para excluir!", "ERRO:", 1);
    	} finally {
    		statusNovo();
    	}
    }
    
    **/
}

MercadoTableModel

public class MercadoTableModel extends AbstractTableModel {

	private static final long serialVersionUID = 6195893990275738966L;
	private static final ApplicationContext appContext = AppContext.getContext();
    private static final MercadoDAO mercadoDAO = (MercadoDAO) appContext.getBean("mercadoDAO");
    
	public static final int COLUNA_ID = 0;
	public static final int COLUNA_NOME = 1;
	
	private Map<Integer, MercadoBean> cache;
	
	public MercadoTableModel() {
		this.cache = new HashMap<Integer, MercadoBean>();
		this.cache = loadAllMercados();
	}
	
	@Override
	public String getColumnName(int c) {
		if(c == COLUNA_ID) return "ID";
		if(c == COLUNA_NOME) return "Nome do Mercado";
		return null;
	}
	
	@Override
	public int getColumnCount() {
		return 2;
	}
	
	@Override
	public int getRowCount() {
		//this.cache = loadAllMercados();
		return cache.size();
	}
	
	@Override
	public Object getValueAt(int rowIndex, int columnIndex) {
		
		MercadoBean mercado = cache.get(rowIndex);
		
		if(columnIndex == COLUNA_ID) 
			return mercado.getId(); 
		else if(columnIndex == COLUNA_NOME) 
			return mercado.getNome();
		
		return null;
	}
	
	@Override
	public Class<?> getColumnClass(int c) {
		
		Class<?> classe = null;
		if(c == COLUNA_ID) classe = Integer.class;
		if(c == COLUNA_NOME) classe = String.class;
		return classe;
	}
	
	private HashMap<Integer, MercadoBean> loadAllMercados() {
		
		HashMap<Integer, MercadoBean> result = new HashMap<Integer, MercadoBean>();
		
		List<MercadoBean> list = mercadoDAO.findAll();
		
		for (int i = 0; i < list.size(); i++) {
			MercadoBean mercado = list.get(i);
			result.put(i, mercado);
		}
    	
		return result;
	}
	
	public MercadoBean get(Integer index) {
		return cache.get(index);
	}
	
	public void salvarMercado(MercadoBean mercado) throws AplicacaoException {
		
		if (mercado.getNome().trim().equals("")) {
			throw new AplicacaoException("O nome não pode estar em branco!");
		}
		if (mercado.getId() > 0) {
			mercadoDAO.update(mercado);
		} else {
			mercadoDAO.store(mercado);
		}
		loadAllMercados();
		getRowCount();
	}
    
    public void excluirMercado(MercadoBean mercado) {
    	mercadoDAO.remove(mercado);
    	loadAllMercados();
    	getRowCount();
    }
}

2 Respostas

eliasfsjunior

Bom, ninguém respondeu, rs.
A única solução que achei para atualizar a tabela foi improvisar: criei um método para recriar a table, fiz da maneira abaixo.

É bizarro ter que fazer isso… Alguém tem alguma outra ideia ou sugestão? :smiley:

private void reloadTable() {
    	
    	panel.remove(scrollPane);
    	
    	scrollPane = new JScrollPane();
		scrollPane.setBounds(10, 96, 494, 142);
		panel.add(scrollPane);
    	
    	table = new JTable();
		
		tableModel = new ArtistaTableModel();
		table.setModel(tableModel);
		
		table.getColumnModel().getColumn(ArtistaTableModel.COLUNA_ID).setMinWidth(30);
		table.getColumnModel().getColumn(ArtistaTableModel.COLUNA_ID).setMaxWidth(50);
		table.getColumnModel().getColumn(ArtistaTableModel.COLUNA_ID).setPreferredWidth(40);
		
		DefaultTableCellRenderer ALIGN_LEFT = new DefaultTableCellRenderer();  
		ALIGN_LEFT.setHorizontalAlignment(SwingConstants.LEFT);  
		table.getColumnModel().getColumn(ArtistaTableModel.COLUNA_ID).setCellRenderer(ALIGN_LEFT);
		table.getColumnModel().getColumn(ArtistaTableModel.COLUNA_NOME).setCellRenderer(ALIGN_LEFT);
		
		table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
			@Override
			public void valueChanged(ListSelectionEvent e) {
				
				artista = tableModel.get(table.getSelectedRow());
				txtIdArtista.setText(artista.getId().toString());
				txtNomeArtista.setText(artista.getNome().toString());
			}
		});
		
		scrollPane.setViewportView(table);
		scrollPane.setVisible(true);
    	
    }
ViniGodoy

O correto seria chamar o fireTableDataChanged mesmo, caso o JTable inteiro mude.
Ou o fireTableRowsXXXX caso a linha da tabela sofra alterações.

Caso a tabela sofra uma mudança no número de colunas, então, use o fireTableStructureChanged.

O que definitivamente não é necessário é recriar o JTable.

Um dos possíveis problemas que você pode estar tendo é que nos métodos de salvar e excluir você está simplesmente chamando loadAllMercados().

O certo não seria alterar as linhas 85 e 91 do seu model para fazer:

this.cache = loadAllMercados()
Criado 13 de novembro de 2012
Ultima resposta 17 de nov. de 2012
Respostas 2
Participantes 2