How to make Jtable values the same as Arraylist<Pessoa>?

Asked

Viewed 510 times

9

I have an example program that adds objects of my class type Pessoa in a JTable and also in a ArrayList<T>, this program has three basic functionalities which are as follows::

  1. Add
  2. Alter
  3. Erase

See the program image:

Tela do programa exemplo

In the event of clicking the button Add a type object is added Pessoa in the JTable and also in a ArrayList<T> type of this class, see:

private void btnAddActionPerformed(java.awt.event.ActionEvent evt) {
    Pessoa pessoaAdd = new Pessoa(txtNome.getText(), obtemIdAtual(tablePessoas));
    listaPessoas.add(pessoaAdd);
    addPessoaToJTable(tablePessoas, pessoaAdd);
}

Notice that there is the method obtemIdAtual() which is responsible for generating the id sequentially, and as much as the values of the objects stored in the variable listaPessoas and the values added to the JTable tablePessoas are identical.

Reproducing the example

To play this example you will need the code of the Person class and also the code corresponding to the program screen, are two files. Follow the complete codes below.

Class code Person:

package aquicolocaseupacote;

public class Pessoa {
    private String nome;
    public String getNome() { return nome; }
    public void setNome(String nome) { this.nome = nome; }
    
    private int id;
    public int getId() { return id; }
    public void setId(int id) { this.id = id; }
    
    public Pessoa() { }
    
    public Pessoa(String nome, int id) {
        this.nome = nome; 
        this.id = id; 
    }
}

Screen code Mainexample:

package aquicolocaseupacote;

import java.awt.EventQueue;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

public class MainExemplo extends JFrame {
    private List<Pessoa> listaPessoas = new ArrayList<>();
    
    public MainExemplo() {
        initComponents();
    }
    
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        btnApagar = new javax.swing.JButton();
        btnAlterar = new javax.swing.JButton();
        btnAdd = new javax.swing.JButton();
        jScrollPane1 = new javax.swing.JScrollPane();
        tablePessoas = new javax.swing.JTable();
        jLabel1 = new javax.swing.JLabel();
        txtNome = new javax.swing.JTextField();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Exemplo");
        setResizable(false);

        btnApagar.setText("Apagar");
        btnApagar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnApagarActionPerformed(evt);
            }
        });

        btnAlterar.setText("Alterar");
        btnAlterar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnAlterarActionPerformed(evt);
            }
        });

        btnAdd.setText("Add");
        btnAdd.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnAddActionPerformed(evt);
            }
        });

        tablePessoas.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {

            },
            new String [] {
                "Id", "Nome"
            }
        ) {
            boolean[] canEdit = new boolean [] {
                false, false
            };

            public boolean isCellEditable(int rowIndex, int columnIndex) {
                return canEdit [columnIndex];
            }
        });
        jScrollPane1.setViewportView(tablePessoas);

        jLabel1.setText("Nome:");

        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()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addGroup(layout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE))
                    .addGroup(layout.createSequentialGroup()
                        .addContainerGap()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(layout.createSequentialGroup()
                                .addComponent(btnAdd)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                .addComponent(btnAlterar)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(btnApagar)
                                .addGap(0, 46, Short.MAX_VALUE))
                            .addGroup(layout.createSequentialGroup()
                                .addComponent(jLabel1)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(txtNome)))))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(9, 9, 9)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel1)
                    .addComponent(txtNome, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(18, 18, 18)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(btnApagar)
                    .addComponent(btnAlterar)
                    .addComponent(btnAdd))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 160, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        pack();
        setLocationRelativeTo(null);
    }// </editor-fold>                        

    private void btnAddActionPerformed(java.awt.event.ActionEvent evt) {                                       
        Pessoa pessoaAdd = new Pessoa(txtNome.getText(), obtemIdAtual(tablePessoas));
        listaPessoas.add(pessoaAdd);
        addPessoaToJTable(tablePessoas, pessoaAdd);
    }                                      

    private void btnAlterarActionPerformed(java.awt.event.ActionEvent evt) {                                           
        switch (btnAlterar.getText()) {
            case "Alterar":
                btnAdd.setEnabled(false);
                btnAlterar.setText("Salvar");
                break;
            case "Salvar":
                btnAdd.setEnabled(true);
                btnAlterar.setText("Alterar");
                break;
        }
    }                                          

    private void btnApagarActionPerformed(java.awt.event.ActionEvent evt) {                                          
        
    }                                         
    
    void addPessoaToJTable(JTable jTable, Pessoa pessoa) {
        DefaultTableModel model = (DefaultTableModel) jTable.getModel();        
        model.addRow(new Object[] { pessoa.getId(), pessoa.getNome() });
    }
    
    int obtemIdAtual(JTable jTable) {
        DefaultTableModel model = (DefaultTableModel) jTable.getModel();
        
        if (model.getRowCount() > 0) {
            return  (Integer) model.getValueAt(model.getRowCount() - 1, 0) + 1;
        }
        else {
            return 1;
        }
    }
    
    public static void main(String args[]) {                      
        EventQueue.invokeLater(() -> { 
            new MainExemplo().setVisible(true); 
        });
    }

    // Variables declaration - do not modify                     
    private javax.swing.JButton btnAdd;
    private javax.swing.JButton btnAlterar;
    private javax.swing.JButton btnApagar;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JTable tablePessoas;
    private javax.swing.JTextField txtNome;
    // End of variables declaration                   
}

My difficulty

I’m not getting to implement the button routine Alter nor the button Erase, that is, when the user is going to make a change by clicking the change button the value (Person type object) must be changed both in the object that is in the variable listaPessoas as in Jtable tablePessoas and the same goes for the delete button.

I would like to know how I could make this implementation according to what this described above?

  • 2

    This is the solution to your problems https://answall.com/questions/121513/como-popular-uma-jtable-com-tablemodel-pr%C3%B3prio

1 answer

9


Implement the methods setValueAt() and getColumnClass in the Tablemodel, so that the Jtable know exactly what kind of data is in each column, and what to do with it when the table changes.

But to make it easier to maintain your table code, the ideal would be to create a TableModel own instead of using the DefaultTableModel, because in this way you abstract from the class of your screen and from the table itself, functionalities linked to the model, such as removing and adding new objects. I usually whenever I need to do a table on , from the standard of this answer modifying or adding what I need more.

So a basic model for your object could be made this way:

import java.util.ArrayList;
import javax.swing.table.AbstractTableModel;

public class PessoaTableModel extends AbstractTableModel {

    private ArrayList<Pessoa> lista;
    private final int COLUNA_NOME = 1;
    private final int COLUNA_ID = 0;
    private String[] columns = {"id", "nome"};
    private boolean[] columnsCanEdit = {false, true};

    public PessoaTableModel() {
        this.lista = new ArrayList<>();
    }

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

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

    @Override
    public boolean isCellEditable(int rowIndex, int columnIndex) {
        return columnsCanEdit[columnIndex];
    }

    @Override
    public Class<?> getColumnClass(int columnIndex) {
        switch (columnIndex) {
            case COLUNA_ID:
                return Integer.class;
            case COLUNA_NOME:
                return String.class;
            default:
                return String.class;
        }
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        Pessoa p = this.lista.get(rowIndex);

        switch (columnIndex) {
            case COLUNA_NOME:
                return p.getNome();
            case COLUNA_ID:
                return p.getId();
        }
        return null;
    }

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

        Pessoa p = this.lista.get(rowIndex);

        switch (columnIndex) {
            case COLUNA_NOME:
                p.setNome(String.valueOf(aValue));
                break;
            case COLUNA_ID:
                p.setId((int) aValue);
        }
        fireTableDataChanged();
    }

    //retornará o indice do objeto na lista do model
    private int indexOf(Pessoa p) {
        return this.lista.indexOf(p);
    }

    //adiciona um novo objeto e notifica os listerners da tabela
    public void addRow(Pessoa p) {
        this.lista.add(p);
        this.fireTableRowsInserted(this.indexOf(p), this.indexOf(p));
    }

    //remove um objeto do model pelo indice(linha) da tabela
    public void removeRow(int linha) {
        Pessoa p = this.lista.get(linha);
        this.lista.remove(linha);
        super.fireTableRowsDeleted(linha, linha);
    }
}

And then, just configure the model for your table in the main class of your Jtable:

model = new PessoaTableModel();
tablePessoas.setModel(model);

On the "Add" button, you change it so that it instantiates a person object and passes it to the model method:

private void btnAddActionPerformed(java.awt.event.ActionEvent evt) {
    Pessoa pessoaAdd = new Pessoa(txtNome.getText(), model.getRowCount());
    model.addRow(pessoaAdd);

}

To implement the deletion function, set the delete button this way:

private void btnApagarActionPerformed(java.awt.event.ActionEvent evt) {

    final int indiceRowModel = this.tablePessoas.getSelectedRow();
    model.removeRow(indiceRowModel);
}

Your code with the above changes would look like this:

import java.awt.EventQueue;
import javax.swing.JFrame;

public class MainExemplo extends JFrame {

    private PessoaTableModel model;

    public MainExemplo() {
        initComponents();
        model = new PessoaTableModel();
        tablePessoas.setModel(model);
    }

    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        btnApagar = new javax.swing.JButton();
        btnAlterar = new javax.swing.JButton();
        btnAdd = new javax.swing.JButton();
        jScrollPane1 = new javax.swing.JScrollPane();
        tablePessoas = new javax.swing.JTable();
        jLabel1 = new javax.swing.JLabel();
        txtNome = new javax.swing.JTextField();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Exemplo");
        setResizable(false);

        btnApagar.setText("Apagar");
        btnApagar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnApagarActionPerformed(evt);
            }
        });

        btnAlterar.setText("Alterar");
        btnAlterar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnAlterarActionPerformed(evt);
            }
        });

        btnAdd.setText("Add");
        btnAdd.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnAddActionPerformed(evt);
            }
        });

        jScrollPane1.setViewportView(tablePessoas);

        jLabel1.setText("Nome:");

        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()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                                .addGroup(layout.createSequentialGroup()
                                        .addContainerGap()
                                        .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE))
                                .addGroup(layout.createSequentialGroup()
                                        .addContainerGap()
                                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                                .addGroup(layout.createSequentialGroup()
                                                        .addComponent(btnAdd)
                                                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                                        .addComponent(btnAlterar)
                                                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                                        .addComponent(btnApagar)
                                                        .addGap(0, 46, Short.MAX_VALUE))
                                                .addGroup(layout.createSequentialGroup()
                                                        .addComponent(jLabel1)
                                                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                                        .addComponent(txtNome)))))
                        .addContainerGap())
        );
        layout.setVerticalGroup(
                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(layout.createSequentialGroup()
                        .addGap(9, 9, 9)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                .addComponent(jLabel1)
                                .addComponent(txtNome, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addGap(18, 18, 18)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                .addComponent(btnApagar)
                                .addComponent(btnAlterar)
                                .addComponent(btnAdd))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 160, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        pack();
        setLocationRelativeTo(null);
    }// </editor-fold>                        

    private void btnAddActionPerformed(java.awt.event.ActionEvent evt) {
        Pessoa pessoaAdd = new Pessoa(txtNome.getText(), model.getRowCount() + 1);
        model.addRow(pessoaAdd);

    }

    //não precisa mais deste método
    private void btnAlterarActionPerformed(java.awt.event.ActionEvent evt) {
//        switch (btnAlterar.getText()) {
//            case "Alterar":
//                btnAdd.setEnabled(false);
//                btnAlterar.setText("Salvar");
//                break;
//            case "Salvar":
//                btnAdd.setEnabled(true);
//                btnAlterar.setText("Alterar");
//                break;
//        }
    }

    private void btnApagarActionPerformed(java.awt.event.ActionEvent evt) {

        //pega a localizacao da linha clicada
        final int indiceRowModel = this.tablePessoas.getSelectedRow();
        model.removeRow(indiceRowModel);
    }

    //não precisa mais deste método
//    int obtemIdAtual(JTable jTable) {
//        DefaultTableModel model = (DefaultTableModel) jTable.getModel();
//
//        if (model.getRowCount() > 0) {
//            return (Integer) model.getValueAt(model.getRowCount() - 1, 0) + 1;
//        } else {
//            return 1;
//        }
//    }

    public static void main(String args[]) {
        EventQueue.invokeLater(() -> {
            new MainExemplo().setVisible(true);
        });
    }

    // Variables declaration - do not modify                     
    private javax.swing.JButton btnAdd;
    private javax.swing.JButton btnAlterar;
    private javax.swing.JButton btnApagar;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JTable tablePessoas;
    private javax.swing.JTextField txtNome;
    // End of variables declaration                   
}

Working:

inserir a descrição da imagem aqui

Particularly I would not create a function to change graphically, since the model and the table can already do this, thanks to the implementation of the setValueAt combined with the method getColumnClass, unless there is a requirement requiring such separation.

Another detail is that the implementation is quite "raw" so that it does not make the code and the answer too extensive and run away from what was asked, because it needs to be validated before deleting, if there is something selected in the table so that it does not burst NullPointerExceptionin the model, and depending on the need, check if the object to be added no longer exists, etc.

Remembering that the methods that are not commented, are explained here what each of them does in the TableModel.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.