Jtable getValueAt() behaving differently than expected

Asked

Viewed 851 times

5

I have a Jframe where there’s a Jtable that displays some data. When the user selects some records and clicks on a certain button, those selected records should be deleted.

When only one record is selected, everything works perfectly, but from two records start to occur problems.

Let’s say I decide to delete the following records:

Registros selecionados

By clicking on Delete selected record(s)(s), the result is this:

Registros não apagados

As it is possible to notice, the indexes are increasing by 2: 1(0), 3(2), 5(4) ...

That’s the code I’m using to do this:

public class NewJFrame extends javax.swing.JFrame {

    private DefaultTableModel tbModelo;

    private ArrayList<String[]> tableData = new ArrayList<String[]>();

    public NewJFrame() {
       tbModelo = new DefaultTableModel(null, new String[]{"ID", "Sequência", "Chave"}){
            //Torna as celulas da tabela readonly. Para permitir alterações retorne true;
            @Override
            public boolean isCellEditable(int row, int column) {
                return false;
            }
        };

        initComponents();

        //Impede que o usuário reposicione as colunas na tabela
        jTable1.getTableHeader().setReorderingAllowed(false);

        preencheTabela();
    }

    private void preencheTabela(){
        for(int i = 1; i < 10; i++){
            tbModelo.addRow(new String[]{String.valueOf(i),"0000", "1234"});
        }
    }

    //Desenha os elementos da UI
    private void initComponents() {

        jScrollPane1 = new javax.swing.JScrollPane();
        jTable1 = new javax.swing.JTable();
        jButton1 = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);


        jTable1.setModel(tbModelo);
        jScrollPane1.setViewportView(jTable1);

        jButton1.setText("Excluir");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 452, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jButton1))
                .addContainerGap(53, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 275, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jButton1)
                .addContainerGap(30, Short.MAX_VALUE))
        );

        pack();
    }

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        // TODO add your handling code here:
        int qtdLinhasSelecionadas = jTable1.getSelectedRowCount();

        if(qtdLinhasSelecionadas > 0){
            //Armazena os indices das linhas selecionadas
            int[] linhasSelecionadas = jTable1.getSelectedRows();

            for(int linha : linhasSelecionadas){

                //Extrai o valor da coluna 'ID' na JTable independente da sua posição na tela
                String user_id = (String) jTable1.getModel().getValueAt(jTable1.convertRowIndexToModel(linha), 0);

                tbModelo.removeRow(linha);

            }
        }

    }                                        

    private javax.swing.JButton jButton1;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JTable jTable1;

}

Also, by selecting all the records and clicking on Rule out, receives an Arrayindexoutofboundsexception:

Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 3 >= 2
at java.util.Vector.elementAt(Vector.java:474)
at javax.swing.table.DefaultTableModel.getValueAt(DefaultTableModel.java:648)
at leitorabntkey.GerarChave.btApagarSelecionadoActionPerformed(GerarChave.java:399)
at leitorabntkey.GerarChave.access$700(GerarChave.java:37)
at leitorabntkey.GerarChave$7.actionPerformed(GerarChave.java:227)
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:6533)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3324)
at java.awt.Component.processEvent(Component.java:6298)
at java.awt.Container.processEvent(Container.java:2236)
at java.awt.Component.dispatchEventImpl(Component.java:4889)
at java.awt.Container.dispatchEventImpl(Container.java:2294)
at java.awt.Component.dispatchEvent(Component.java:4711)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4888)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4525)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4466)
at java.awt.Container.dispatchEventImpl(Container.java:2280)
at java.awt.Window.dispatchEventImpl(Window.java:2746)
at java.awt.Component.dispatchEvent(Component.java:4711)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
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:76)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
at java.awt.EventQueue$4.run(EventQueue.java:731)
at java.awt.EventQueue$4.run(EventQueue.java:729)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
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)

According to getValueAt documentation it should return the cell value row x column, as in a matrix, but apparently that’s not what happens.

In Sage’s answer it is possible to see that getValueAt returns the values of cells based on the Jtable model (Defaulttablemodel in my case) and in what I could identify here, both the model and the view are with the same structure (Jtable is with column reorganization disabled).

Is there something I’m not realizing here? Or some other way to do what I intend?

1 answer

4


Try changing the following line:

String user_id =  (String)tableChavesRegistradas.getModel().getValueAt(tableChavesRegistradas.convertRowIndexToModel(linha), 0); 

What has to be converted is the internal table Intel to the equivalent in Tablemodel, you were using the method that does otherwise.

And to avoid bursting the exception during the deletion of multiple lines, follows the solution to solve the problem of ArrayIndexOutOfBoundsException:

if(qtdLinhasSelecionadas > 0){

    int[] linhasSelecionadas = jTable1.getSelectedRows();

    for(int i = linhasSelecionadas.length-1; i >= 0; i--){

        String user_id = (String) jTable1.getModel().getValueAt(jTable1.convertRowIndexToModel(linhasSelecionadas[i]), 0);

        tbModelo.removeRow(linhasSelecionadas[i]);
    }

}

Testing the change, the result was this:

inserir a descrição da imagem aqui

The secret of this for is to remove the selected lines from the larger indices for the smaller ones, because internally the DefaultTableModel rearranges the contents of the remaining rows at each removal, bursting the exception shown if you try to delete a larger Dice row. Always removing the larger Index, this will not happen.

  • It didn’t. Could it have something to do with the Defaulttablemodel? Or does the table model not interfere with this type of operation? I edited the question with a little more information.

  • @Fusrodah061 seems that the problem presented now is another different from the initial one, which was because of the Dice conversion. But anyway, if you present the excerpt of your table that is possible to run without database (put some standard data to test), would already suggest solution. My test wheel excluding selected and without launching that exception ai.

  • I edited the question with what I got by entering the data from an array of Strings and removing this data. Indexes continue to be "messy". This makes no sense, because debugging the program, the array int that receives the return of getSelectedRows() keeps the correct indices, however the getValueAt returns a value that does not correspond to that index.

  • 1

    @Fusrodah061 so you need to provide a [mcve] of your program. I made a very similar example here and it works normally. Without seeing the code of your program working, you can not find the problem, it will be only deductions.

  • Sorry for the confusion, it’s the first question I ask here. I rephrased the question and I believe it’s now more direct.

  • @Fusrodah061 edited the answer with the solution to the 2 problems.

Show 1 more comment

Browser other questions tagged

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