How to trigger a method when finished editing a column of type Integer in JTable

0

I need to call a method that shows the user a message.

This method must be called just as the user finishes editing a JTable column of type Integer and the user has not entered an integer.

That is, the method should be called the moment the column becomes 'red'.

Below I will put a sample image that the articuno used in one of his posts, just to exemplify when the event should be called.

BelowisthecodeIamdeveloping.

publicclassDados{/***@returnthecoluna0*/publicStringgetColuna0(){returncoluna0;}/***@paramcoluna0thecoluna0toset*/publicvoidsetColuna0(Stringcoluna0){this.coluna0=coluna0;}/***@returnthecolunaInteiro*/publicIntegergetColunaInteiro(){returncolunaInteiro;}/***@paramcolunaInteirothecolunaInteirotoset*/publicvoidsetColunaInteiro(IntegercolunaInteiro){this.colunaInteiro=colunaInteiro;}privateStringcoluna0;privateIntegercolunaInteiro;}

.

publicclassTesteTableModelextendsAbstractTableModel{privateStringcolunas[]={"Coluna0", "colunaInteiro"};
    private List<Dados> dados;
    private final int COLUNA_0 = 0;
    private final int COLUNA_INTEIRO = 1;

    public TesteTableModel(List<Dados> dados) {
        this.dados = dados;
    }

    //retorna se a célula é editável ou não
    @Override
    public boolean isCellEditable(int rowIndex, int columnIndex) {
        return true;
    }

    //retorna o total de itens(que virarão linhas) da nossa lista
    @Override
    public int getRowCount() {
        return dados.size();
    }

    //retorna o total de colunas da tabela
    @Override
    public int getColumnCount() {
        return colunas.length;
    }

    //retorna o nome da coluna de acordo com seu indice
    @Override
    public String getColumnName(int indice) {
        return colunas[indice];
    }

    //determina o tipo de dado da coluna conforme seu indice
    @Override
    public Class<?> getColumnClass(int columnIndex) {
        switch (columnIndex) {
            case COLUNA_0:
                return String.class;
            case COLUNA_INTEIRO:
                return Integer.class;
            default:
                return String.class;
        }
    }
    //preenche cada célula da tabela
    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        Dados dados = this.dados.get(rowIndex);
        switch (columnIndex) {
            case COLUNA_0:
                return dados.getColuna0();
            case COLUNA_INTEIRO:
                return dados.getColunaInteiro();
            default:
                return null;
        }
    }
}

.

import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.HeadlessException;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;

public class GuiPrincipal extends JFrame {

    private JTable table;
    List<Dados> dados = new ArrayList<Dados>();

    public GuiPrincipal(JTable table) throws HeadlessException {
        this.table = table;
    }

    public void addDadosInDados() {
        Dados dado = new Dados();
        dado.setColuna0("Dado qualquer");
        dado.setColunaInteiro(1);
        dados.add(dado);
    }

    public GuiPrincipal() {
        setLayout(new FlowLayout());
        setSize(new Dimension(700, 300));
        setLocationRelativeTo(null);
        setTitle("Exemplo JTable");
        addDadosInDados();// add dados em dados       
        table = new JTable(new TesteTableModel(dados));
        table.setShowVerticalLines(false);
        table.setIntercellSpacing(new Dimension(0, 0));
        JScrollPane scrollPane = new JScrollPane(table);
        add(scrollPane);
    }

    // este é o método onde é executado nosso programa
    public static void main(String[] args) {
        GuiPrincipal gui = new GuiPrincipal();
        gui.setVisible(true);
    }
}

How do I trigger a method right now?

    
asked by anonymous 18.05.2018 / 22:04

1 answer

2

Try one of the suggested ways below:

1 - Using PropertyChangeListener

You can monitor when there are any cell edits in the table by adding a PropertyChangeListener to it, filtering only when cell edit listeners are notified:

table.addPropertyChangeListener(e -> {

    if("tableCellEditor".equals(e.getPropertyName())) {
        if(!table.isEditing())
            JOptionPane.showMessageDialog(this,"fim da edição em alguma celula");
    }
});

A problem like this is that it will go into the conditional whenever any cell in the table exits edit mode.

2 - Using a TableCellEditor

This form is a little more complicated, because in situations where you have a specific type of data in the column, you may need to create a TableCellEditor itself, as can be seen #

In this example of another answer, but to simplify the demonstration, I used the class DefaultTableCellEditor .

class ShowMessageCellEditor extends DefaultCellEditor{

    public ShowMessageCellEditor(JTextField textField) {
        super(textField);
    }

    @Override
    public boolean stopCellEditing() {
        JOptionPane.showMessageDialog(null, "celula modificada");
        return super.stopCellEditing();
    }
}

And to apply to the specific column:

table.getColumnModel().getColumn(1).setCellEditor(new ShowMessageCellEditor(new JTextField()));

In the getColumn(index) method you must pass the index of the table column that wants the action to occur at the end of the edit. Remember that indexes in java start at 0 instead of 1.

Columns of a JTable use editors that implement the CellEditor interface, and this interface has the stopCellEditing() , which detects when editing in the cell has been interrupted, and accepts the change even if it is partial, then notifying all listeners that cell is no longer in edit mode.

Previously, the version was using fireEditingStopped() , but the function of this method is to only notify listeners of the event that occurred, it is within stopCellEditing() that you should fire your method.

References:

23.05.2018 / 16:56