Alteração de dados em um TableModel e atualização da interface no JTable

8 respostas
mcampos

Pessoal, estou usando um JTable associado a um TableModel que implementei para manipular um arquivo XML.
A leitura e gravação no arquivo XML e carregamento no JTable está OK, porém, quando altero um campo ou adiciono
uma linha no XML, os dados não são atualizados automaticamente no JTable, somente depois que eu redimensiono
a minha janela. No meu TableModel eu chamo os métodos fireTableRowsInserted e fireTableCellUpdated mas não
está fazendo efeito.
Abaixo um trecho de código das minhas classes.

public class XmlDataModel extends AbstractTableModel {
	public void addRow(String description, String fileName) {
		Element parent = doc.getDocumentElement();
		Element el = doc.createElement(ROOT_ELEMENT_TAG);
		el.setAttribute(colNames[descriptionCol], description);
		el.setAttribute(colNames[fileNameCol], fileName);
		parent.appendChild(el);
		
		int lines = getRowCount()-1;
		fireTableRowsInserted(lines, lines);  
	}
	
	public boolean isCellEditable(int r, int c) {
	    return false;
	}
	
	public void setValueAt(Object value, int r, int c) {
	    NodeList nl = doc.getElementsByTagName(ROOT_ELEMENT_TAG);
	    NamedNodeMap atribs = nl.item(r).getAttributes();
	    
	    Node node = atribs.getNamedItem(colNames[c]);
	    node.setNodeValue(value.toString());
	    atribs.setNamedItem(node);
	    fireTableCellUpdated(r,c);
	}
}

public class MainForm extends JFrame {
	private JTable tb;
	private XmlDataModel dataModel;
			
	public MainForm() {
                dataModel = new XmlDataModel(xmlFileName);
		tb = new JTable(dataModel);
		cp.add(new JScrollPane(tb));
		
		btnAdd = new JButton("Add row");
		btnAdd.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				dataModel.addRow("description", "name");
			}
		});		
	}
}

8 Respostas

mcampos

Pessoal, já olhei alguns tutoriais, inclusive alguns daqui, mas não sei o que está faltando. Alguém pode ajudar?

R

Vejo que você não redefiniu no seu TableModel o método getRowCount(), a tabela precisa dele para poder se redesenhar corretamente:

http://java.sun.com/javase/6/docs/api/javax/swing/table/TableModel.html#getRowCount()

A título de teste, você pode experimentar usar fireTableDataChanged() em seus métodos de inserção/alteração/exclusão de dados. Isso vai forçar o redesenho completo da JTable.

mcampos

Defini, é que não mostrei aqui.

mcampos

Usei fireTableDataChanged() nos métodos addRow e removeRow que tenho, mas não adiantou.
Neles também tenho fireTableRowsInserted(lines, lines) e fireTableRowsDeleted(row,row), respectivamente,
mas só depois que redimensiono o form é que atualiza.

R

Comportamento estranho o do seu programa. Pode tentar chamar JTable.repaint() após TableModel.addRow(), por exemplo? Só para complementar, o ponto ideal para chamar os eventos fire* e repaint() é o formulário onde a JTable está contida e não o TableModel.

mcampos

É não resolveu. No meu frame, quando o usuário clica em um botão são executadas as linhas abaixo, incluindo o q vc sugeriu:

dataModel.addRow(MEUS_PARAMETROS);

dataModel.saveXml();

dataModel.fireTableDataChanged();

tb.repaint();
R

Seu método getRowCount() está “enxergando” as possíveis alterações ocorridas no arquivo XML? Pode ser que ele esteja lendo os dados a partir de um cache de memória que não está sendo atualizado junto com o arquivo.

mcampos

Está, ele pega o total de nós que estão vinculados ao nó principal do arquivo xml:

public int getRowCount() {
	NodeList nl = doc.getElementsByTagName(ROOT_ELEMENT_TAG);
        return nl.getLength();
}
Criado 27 de junho de 2009
Ultima resposta 29 de jun. de 2009
Respostas 8
Participantes 2