Exclusão de linha usando AbstractTableModel

Quando efetuo um cadastro e em seguida uma exclusão do objeto cadastrado o mesmo exclui do banco de dados mas não atualiza a tabela pro usuário (não exclui a linha da tabela). Porém, ao realizar um cadastro e em seguida fechar o JInternalFrame e abrir novamente, realizando a exclusão, ele irá exclui da tabela. Alguém sabe o motivo disto ocorrer ?

AbstractTableModel

package br.com.clinica.model.modelotabela;

import br.com.clinica.model.objetos.Funcionario;
import java.util.ArrayList;
import javax.swing.table.AbstractTableModel;

public class FuncionarioModeloTabela extends AbstractTableModel {

    private ArrayList<Funcionario> funcionarios = new ArrayList();
    private String[] nomeColuna = {"ID", "Nome", "Idade", "CPF", "Sexo"};

    @Override
    public int getRowCount() {
        return this.funcionarios.size();
    }

    @Override
    public int getColumnCount() {
        return this.nomeColuna.length;
    }

    @Override
    public String getColumnName(int column) {
        return this.nomeColuna[column];

    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {

        switch (columnIndex) {

            case 0:
                return this.funcionarios.get(rowIndex).getId();

            case 1:
                return this.funcionarios.get(rowIndex).getNome();

            case 2:
                return this.funcionarios.get(rowIndex).getIdade();
            case 3:
                return this.funcionarios.get(rowIndex).getCpf();

            case 4:
                return this.funcionarios.get(rowIndex).getSexo();

        }
        return null;
    }

    @Override
    public void setValueAt(Object valor, int rowIndex, int columnIndex) {

        switch (columnIndex) {

            case 1:
                this.funcionarios.get(rowIndex).setNome((String) valor);
                break;

            case 2:
                this.funcionarios.get(rowIndex).setIdade(Integer.parseInt((String) valor));
                break;
            case 3:
                this.funcionarios.get(rowIndex).setCpf((String) valor);
                break;

            case 4:
                this.funcionarios.get(rowIndex).setSexo((String) valor);
                break;

        }

    }

    public void addRow(Funcionario funcionario) {
        this.funcionarios.add(funcionario);
        this.fireTableDataChanged();

    }

    public void removeRow(int linha) {
        this.funcionarios.remove(linha);
        this.fireTableRowsDeleted(linha, linha);
    }

}

Controller

public void btnExcluir() {

        FuncionarioDAO repositorio = new FuncionarioDAO();
        if (this.view.getTabelaFuncionario().getSelectedRow() != - 1) {
            int linha = this.view.getTabelaFuncionario().getSelectedRow();
            long codigo = Long.parseLong(String.valueOf(this.view.getTabelaFuncionario().getValueAt(linha, 0)));

            Funcionario funcionario = repositorio.listarPorId(codigo);

            switch (JOptionPane.showConfirmDialog(null, " Tem certeza que deseja excluir ? ", "Confirmar exclusão", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE)) {

                case 0:
                    this.modelo.removeRow(linha);
                    repositorio.excluir(funcionario);
                    break;

                case 1:
                    break;
            }
        } else {
            JOptionPane.showMessageDialog(null, "Escolha um funcionário");
        }

    }

view

private void btnExcluirActionPerformed(java.awt.event.ActionEvent evt) {                                           
        // TODO add your handling code here:
        this.controller.btnExcluir();
    }

Para testar, troque o this.fireTableRowsDeleted(linha, linha); por this.fireTableDataChanged(); no método removeRow.

Continua sem funcionar amigo. Ele só funciona quando fecho o JInternalFrame. Quando realizo o cadastro e fecho o JInternalFrame, abrindo novamente e realizando a exclusão ele irá excluir normalmente. Notei que ele dispara essa exception.

Exception in thread "AWT-EventQueue-0" java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
	at java.util.ArrayList.rangeCheck(ArrayList.java:659)
	at java.util.ArrayList.remove(ArrayList.java:498)
	at br.com.clinica.model.modelotabela.FuncionarioModeloTabela.removeRow(FuncionarioModeloTabela.java:82)
	at br.com.clinica.controller.FuncionarioController.btnExcluir(FuncionarioController.java:215)
	at br.com.clinica.view.telas.TelaFuncionario.btnExcluirActionPerformed(TelaFuncionario.java:480)
	at br.com.clinica.view.telas.TelaFuncionario.access$500(TelaFuncionario.java:10)
	at br.com.clinica.view.telas.TelaFuncionario$6.actionPerformed(TelaFuncionario.java:317)
	at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)
	at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2348)
	at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
	at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
	at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
	at java.awt.Component.processMouseEvent(Component.java:6539)
	at javax.swing.JComponent.processMouseEvent(JComponent.java:3324)
	at java.awt.Component.processEvent(Component.java:6304)
	at java.awt.Container.processEvent(Container.java:2239)
	at java.awt.Component.dispatchEventImpl(Component.java:4889)
	at java.awt.Container.dispatchEventImpl(Container.java:2297)
	at java.awt.Component.dispatchEvent(Component.java:4711)
	at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4904)
	at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4535)
	at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4476)
	at java.awt.Container.dispatchEventImpl(Container.java:2283)
	at java.awt.Window.dispatchEventImpl(Window.java:2746)
	at java.awt.Component.dispatchEvent(Component.java:4711)
	at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:760)
	at java.awt.EventQueue.access$500(EventQueue.java:97)
	at java.awt.EventQueue$3.run(EventQueue.java:709)
	at java.awt.EventQueue$3.run(EventQueue.java:703)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:74)
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:84)
	at java.awt.EventQueue$4.run(EventQueue.java:733)
	at java.awt.EventQueue$4.run(EventQueue.java:731)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:74)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:730)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:205)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)

Parece que a linha que está sendo passada é 1, e o array possui apenas 1 item. Nesse caso, a linha deveria ser zero.

Na verdade, acredito que isso ocorre por conta do método que fiz para preencher a tabela. No construtor da view eu chamo esse método para que ele possa preencher a tabela assim que a janela for carregada. Achas que está correto desta forma ? No momento que faço a alteração ou exclusão, ele só atualiza a tabela quando fecho o JInternalFrame.

 public void atualizarTabela() {

        PacienteDAO repositorio = new PacienteDAO();

        ArrayList<Funcionario> funcionarios = repositorio.listarTodos();

        for (Funcionario funcionario : funcionarios) {

            modelo.addRow(paciente);

        }

AddRow

 public void addRow(Funcionario funcionario) {
        this.funcionarios.add(funcionario);
           
        this.fireTableDataChanged();

Desnecessário esse laço aí, passa simplesmente sua lista diretamente para o seu TableModel e faz um fireTableDataChanged.

Nem usa o addRow e removeRow.

Você especializa o AbstractTableModel justamente para não ficar chamando o addRow e removeRow.

Manipule diretamente sua lista de objetos e mande a JTable se repintar através do fireTableDataChanged.

1 curtida