Search code examples
javaswingjtabledefaulttablemodel

Update JTable from DefaultTableModel


so what i want to do is update a JTable when a button is pressed. Im using a DefaultTableModel as a source. Table class:

import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import java.awt.Dimension;

public class TableDemo extends JPanel {
    String[] columnNames = {"Tipo","Cantidad"};
    DefaultTableModel dtm = new DefaultTableModel(null,columnNames);
    final JTable table = new JTable(dtm);

 public TableDemo() {
    table.setPreferredScrollableViewportSize(new Dimension(500, 700));
    table.setFillsViewportHeight(true);
    JScrollPane scrollPane = new JScrollPane(table);
    add(scrollPane);
 }

 public void addRow(Object [] row)
 {
     dtm.addRow(row);
 }

}

the form class:

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextField;

public class MyForm extends JFrame {

JPanel panel;
JLabel label;
JTextField txtName;
JTextField txtSurname;
JButton btnAccept;
TableDemo tb  = new TableDemo();

public MyForm(){
    initControls();
}

private void initControls() {
    setTitle("Form Example");
    setSize(600, 400);
    setDefaultCloseOperation(DISPOSE_ON_CLOSE);
    setLocationRelativeTo(null);

    panel = new JPanel();       
    panel.setLayout(null);

    label = new JLabel("Welcome to Swing");
    label.setBounds(50, 10, 200, 30);

    txtName = new JTextField();
    txtName.setBounds(50, 50, 200, 30);

    txtSurname = new JTextField();
    txtSurname.setBounds(270, 50, 200, 30);

    btnAccept = new JButton("Add");
    btnAccept.setBounds(120, 100, 150, 30);

    onAcceptClick();
    TableDemo tablePanel = new TableDemo();

    panel.add(label);
    panel.add(txtName);
    panel.add(txtSurname);
    panel.add(btnAccept);

    JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
            tablePanel,panel );
    splitPane.setDividerLocation(205);
    splitPane.setEnabled(false);

    getContentPane().add(splitPane);
}

private void onAcceptClick() {
    btnAccept.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            tb.addRow(new Object[]{"taza",txtName.getText()});

        }
    });
public static void main(String[] args) {
    //Initilizer init = new Initilizer();

    Runnable init = new Runnable() {

        @Override
        public void run() {
            MyForm form = new MyForm();
            form.setVisible(true);
        }
    };

    SwingUtilities.invokeLater(init);   
}
}

As you can see i call the addRow function but in never updates in the JTable, what am i missing? Thnx


Solution

  • You're creating two TableDemo objects -- one you add to the GUI, tablePanel, the other you add a row to, tb;

    // ...
    
    TableDemo tb  = new TableDemo();  // TableDemo #1. Never displayed
    
    private void initControls() {
        // ...
    
        TableDemo tablePanel = new TableDemo();   // TableDemo #2
    
        // ...
    
        //  TableDemo #2 is here added to the GUI
        JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, tablePanel,panel );
    
        // ...
    }
    
    btnAccept.addActionListener(new ActionListener() {
    
        @Override
        public void actionPerformed(ActionEvent e) {
    
            // here you add a row to the non-displayed TableDemo #1
            tb.addRow(new Object[]{"taza",txtName.getText()});
        }
    });
    

    Solution: Don't do this (obviously)! Use only one TableDemo instance, display it and make changes to it. So get rid of the tablePanel variable and only use the tb variable.

    Other problems:

    • You're using null layouts. While null layouts and setBounds() might seem to Swing newbies like the easiest and best way to create complex GUI's, the more Swing GUI'S you create the more serious difficulties you will run into when using them. They won't resize your components when the GUI resizes, they are a royal witch to enhance or maintain, they fail completely when placed in scrollpanes, they look gawd-awful when viewed on all platforms or screen resolutions that are different from the original one.