Update a Jtable within a Jframe through another Jframe

3

I have a JFrame , where inside it has a JTable and a JButton (Change) that calls another JFrame. In this other JFrame, a change of data is performed according to the row selected in the table and saved in the DB when clicking on a JButton.

My problem is that the data is not updated automatically in my JTable when saving the change, so how do I call a function from a JFrame that is already open?

It does not work to do the following:

public class JFAltera extends javax.swing.JFrame {
    ...
    private void jbSalvarActionPerformed(java.awt.event.ActionEvent evt) {
        JFrameTabela jFrameTabela = new JFrameTabela();
        jFrameTabela.atualizaJTable();
    }
    ...
}

public class JFrameTabela extends javax.swing.JFrame {
    ...
    public void atualizaJTable(){
        ...
    }
    ...
}

Because I do not want to instantiate a new JFrame, but call the (public) function of a JFrame that is already open.

Verifiable example of class:

JFrame class:

import javax.swing.table.DefaultTableModel;

public class JFrameTabela extends javax.swing.JFrame {

    public JFrameTabela() {
        initComponents();
        readJTable(); // Atualiza os dados na tabela
    }

    public void readJTable(){

        DefaultTableModel tableModel = (DefaultTableModel) jTable.getModel();

        //Inicia a tabela com 0 linhas novamente
        tableModel.setNumRows(0);

        //Inserir 10 Linhas
        for(int i = 0; i < 10; i++){
            tableModel.addRow(new Object[]{
                "Teste 1",
                "Teste 2",
                "Teste 3",
                "Teste 4"
            });
        }
    }

    @SuppressWarnings("unchecked")                        
    private void initComponents() {

        jScrollPane1 = new javax.swing.JScrollPane();
        jTable = new javax.swing.JTable();
        jbAlterar = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jTable.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null}
            },
            new String [] {
                "Title 1", "Title 2", "Title 3", "Title 4"
            }
        ));
        jScrollPane1.setViewportView(jTable);

        jbAlterar.setText("Alterar");
        jbAlterar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jbAlterarActionPerformed(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()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addGap(226, 226, 226)
                        .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(layout.createSequentialGroup()
                        .addGap(426, 426, 426)
                        .addComponent(jbAlterar)))
                .addContainerGap(401, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addGap(28, 28, 28)
                .addComponent(jbAlterar)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 70, Short.MAX_VALUE)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 228, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(89, 89, 89))
        );

        pack();
    }                      

    private void jbAlterarActionPerformed(java.awt.event.ActionEvent evt) {                                          
        //Abro o meu JFrameAltera e envio os dados da linha selecionada
        JFrameAltera obj = new JFrameAltera();
        obj.setVisible(true);
        obj.preencheDados(jTable.getValueAt(jTable.getSelectedRow(),0).toString(),
                jTable.getValueAt(jTable.getSelectedRow(),1).toString(),
                jTable.getValueAt(jTable.getSelectedRow(),2).toString(),
                jTable.getValueAt(jTable.getSelectedRow(),3).toString());
    }                                         

    public static void main(String args[]) {

        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(JFrameTabela.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(JFrameTabela.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(JFrameTabela.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(JFrameTabela.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }

        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new JFrameTabela().setVisible(true);
            }
        });
    }

    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JTable jTable;
    private javax.swing.JButton jbAlterar;                 
}

JFrame class Change:

public class JFrameAltera extends javax.swing.JFrame {


    public JFrameAltera() {
        initComponents();
    }

    public void preencheDados(String string1, String string2, String string3, String string4){

        //Preenche os campos com as informações das linha selecionada no "JFrameTabela"
        jf1.setText(string1);
        jf2.setText(string2);
        jf3.setText(string3);
        jf4.setText(string4);
    }

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

        jf1 = new javax.swing.JTextField();
        jf2 = new javax.swing.JTextField();
        jf3 = new javax.swing.JTextField();
        jf4 = new javax.swing.JTextField();
        jbSalvar = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jbSalvar.setText("Salvar");
        jbSalvar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jbSalvarActionPerformed(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()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addGap(117, 117, 117)
                        .addComponent(jf1, javax.swing.GroupLayout.PREFERRED_SIZE, 70, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(32, 32, 32)
                        .addComponent(jf2, javax.swing.GroupLayout.PREFERRED_SIZE, 71, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(36, 36, 36)
                        .addComponent(jf3, javax.swing.GroupLayout.PREFERRED_SIZE, 79, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(18, 18, 18)
                        .addComponent(jf4, javax.swing.GroupLayout.PREFERRED_SIZE, 77, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(layout.createSequentialGroup()
                        .addGap(241, 241, 241)
                        .addComponent(jbSalvar)))
                .addContainerGap(458, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(69, 69, 69)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jf1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jf2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jf3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jf4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(63, 63, 63)
                .addComponent(jbSalvar)
                .addContainerGap(292, Short.MAX_VALUE))
        );

        pack();
    }                      

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

        //Aqui eu gravo as informações no BD (Funcionando)

        //***********É aqui que eu preciso chamar minha função "readJTable" do "JFrameTabela" que já está aberto.
    }                                        


    public static void main(String args[]) {

        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(JFrameAltera.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(JFrameAltera.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(JFrameAltera.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(JFrameAltera.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new JFrameAltera().setVisible(true);
            }
        });
    }

    private javax.swing.JButton jbSalvar;
    private javax.swing.JTextField jf1;
    private javax.swing.JTextField jf2;
    private javax.swing.JTextField jf3;
    private javax.swing.JTextField jf4;

}
    
asked by anonymous 24.07.2017 / 17:21

1 answer

2

When working with more than one screen, it is always best to use only JFrame as the main screen and create JDialogs as secondary screens, because in addition to the modal feature, you can link them all to the main Frame.

As the code presented is very generic, I'll try to respond on top of it. Following the above tip, I recommend that you change the JFrameAltera class to be JDialog dependent on the JFrameTabela class, so it is much easier to exchange information between them.

So the class signature would look like this:

public class JFrameAltera extends javax.swing.JDialog {

Another detail is that in the button that opens the new window, you are passing the sequence between 1 and 4 as number of columns, when in fact the numbering of rows and columns in java always starts from 0, so the numbering for 4 columns goes from 0 to 3. Another problem is that you do not check if there are actually any selected rows in the table before retrieving the data, and this will pop ArrayIndexOutOfBoundsException , because the getSelectedRow() " returns -1 when there is no selection, and -1 is not part of the range of lines of a table.

In your class JFrameAltera , after changing to JDialog , the constructor will look like this:

public JFrameAltera(Frame parent, boolean isModal) {
    super(parent, isModal);
    initComponents();
}

The first parameter represents which frame the screen originated from, and the second one renders the modal screen (that is, while it is open, the originating screen is locked for change).

In the save button event, you will continue saving the new data in the database, and quit the screen by adding% with%.

Based on the code presented, you will create a method where you will abstract the data saved in an object and return it, I used the class this.dispose(); here only to demonstrate:

 public Object[] recuperaDados(){

    Object[] obj = {
     jf1.getText(),
     jf2.getText(),
     jf3.getText(),
     jf4.getText()
    };

     return obj;
 }

Now in the main class, in the same method where you open the change window, you will change as below:

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

    if (jTable.getSelectedRow() != -1) {
        JFrameAltera tela2 = new JFrameAltera(this, true);
        tela2.preencheDados(jTable.getValueAt(jTable.getSelectedRow(), 0).toString(),
                jTable.getValueAt(jTable.getSelectedRow(), 1).toString(),
                jTable.getValueAt(jTable.getSelectedRow(), 2).toString(),
                jTable.getValueAt(jTable.getSelectedRow(), 3).toString());
        tela2.setVisible(true);

        Object[] obj = tela2.recuperaDados();
        for (int i = 0; i < obj.length && i < jTable.getColumnCount(); i++) {
            jTable.setValueAt(obj[i], jTable.getSelectedRow(), i);
        }
    }
}

The method now checks if there is a selected line before the screen opens (% with%), and as soon as the screen is closed, it already retrieves the data and saves it to the table.

With these changes, the Object method loses its meaning and can be removed.

    
24.07.2017 / 20:02