title: Java Swing - Problem updating the JTable
body: <p>In the given code, a swingworker thread will capture the packets, encapsulate its fields into a string array and then add this string array as a row in the jtable in the GUI. My JTable follows the AbstractTableModel. I am manually copying the old data in JTable with the new data and then use FireTableDataChanged() methods so that the changes are reflected in the table in GUI. But the GUI table remains blank. I am not able to update my JTable with the new data. I also tried to use DefaultTableModel but had the same result. </p>
  
  <p>/<strong><em>*</em>**<em>*</em>**<em>*</em>**<em>*</em>**<em>*</em></strong><em>CaptureThread class</em><strong><em>*</em>**<em>*</em>**<em>*</em>**<em>*</em>****</strong>/</p>
  
  <pre><code>package TestClasses;
  import javax.swing.*;
  import javax.swing.table.*;
  import jpcap.*;
  import jpcap.packet.*;
  
  public class CaptureThread extends SwingWorker&lt;Void,String[]&gt;
  {
      JTable capture_tab;
      CaptureTableModel model;
      JpcapCaptor capture;
      CaptureThread(JpcapCaptor capture,CaptureTableModel model,JTable capture_tab)
      {
          this.capture = capture;
          this.model = model;
          this.capture_tab = capture_tab;
      }
      public Void doInBackground()
      {
          int pkt_count = 0,i=0;
          jpcap.packet.Packet p;
          ARPPacket arp_pkt;
          IPPacket ip_pkt;
          TCPPacket tcp_pkt;
          UDPPacket udp_pkt;        
          EthernetPacket eth_pkt;
          String new_pkt[] = new String[10];        
          while(!isCancelled())
          {              
              p = capture.getPacket();                 
              eth_pkt =(EthernetPacket)p.datalink;
              new_pkt[0] = Integer.toString(++pkt_count);
              new_pkt[1] = Long.toString(p.sec);            
              new_pkt[2] = eth_pkt.getSourceAddress();
              new_pkt[5] = eth_pkt.getSourceAddress();             
              if(eth_pkt.frametype==EthernetPacket.ETHERTYPE_ARP)
              {
                  System.out.println("ARP packet");
                  arp_pkt = (ARPPacket)p;
                  new_pkt[3] = "--";
                  new_pkt[4] = arp_pkt.sender_protoaddr.toString();
                  new_pkt[6] = "--";
                  new_pkt[7] = arp_pkt.target_protoaddr.toString();
                  new_pkt[8] = "ARP";
                  new_pkt[9] = "--";
              }
              else
              {
                  System.out.println("IP packet");
                  ip_pkt = (IPPacket)p;
                  new_pkt[3] = ip_pkt.src_ip.toString();
                  new_pkt[6] = ip_pkt.dst_ip.toString();
                  switch(ip_pkt.protocol)
                  {
                      case IPPacket.IPPROTO_ICMP:
                          new_pkt[4] = "--";
                          new_pkt[7] = "--";
                          new_pkt[8] = "ICMP";
                          System.out.println("ICMP packet");
                          break;
                      case IPPacket.IPPROTO_TCP:
                          tcp_pkt = (TCPPacket)ip_pkt;
                          new_pkt[4] = Integer.toString(tcp_pkt.src_port);
                          new_pkt[7] = Integer.toString(tcp_pkt.dst_port);
                          new_pkt[8] = "TCP";
                          System.out.println("TCP packet");
                          break;
                      case IPPacket.IPPROTO_UDP:
                          udp_pkt = (UDPPacket)ip_pkt;
                          new_pkt[4] = Integer.toString(udp_pkt.src_port);
                          new_pkt[7] = Integer.toString(udp_pkt.dst_port);
                          new_pkt[8] = "UDP";
                          System.out.println("UDP packet");
                          break;
                  }
                  new_pkt[9] = Integer.toString(ip_pkt.hop_limit);  
                  publish(new_pkt);
              }
          }
          return null;
      }
      public void process(String str[])
      {
          model.addPacket(str);
          model.fireTableDataChanged();
      }
  }
  </code></pre>
  
  <p>/<strong><em>*</em>**<em>*</em>**<em>*</em>**<em>*</em>**<em>*</em>**<em>*</em>**<em>*</em></strong><em>MainWin class</em><strong><em>*</em>**<em>*</em>**<em>*</em>**<em>*</em>*</strong>/</p>
  
  <pre><code>package TestClasses;
  import javax.swing.table.*;
  import javax.swing.*;
  import java.awt.*;
  import java.awt.event.*;
  import jpcap.*;
  import jpcap.packet.*;
  
  public class MainWin extends javax.swing.JFrame implements ActionListener
      {
      /** Creates new form Temp */
      public MainWin() {
          initComponents();
      }
  
      /** This method is called from within the constructor to
       * initialize the form.
       * WARNING: Do NOT modify this code. The content of this method is
       * always regenerated by the Form Editor.
       */
      @SuppressWarnings("unchecked")
      // &lt;editor-fold defaultstate="collapsed" desc="Generated Code"&gt;//GEN-BEGIN:initComponents
      private void initComponents() {
  
          model = new CaptureTableModel(packet,columnNames);
          capture_tab = new JTable(model);          
          dev = new SystemInterfaces();
          str = dev.getInterfaceList();
          jLabel1 = new javax.swing.JLabel();
          jLabel2 = new javax.swing.JLabel();        
          ipaddr_field = new javax.swing.JTextField();
          interface_combo = new javax.swing.JComboBox();
          promiscuous = new javax.swing.JCheckBox();
          jLabel3 = new javax.swing.JLabel();
          jComboBox1 = new javax.swing.JComboBox();            
          start_button = new javax.swing.JButton();
          stop_button = new javax.swing.JButton();
          clear_button = new javax.swing.JButton();
          save_button = new javax.swing.JButton();
          jMenuBar1 = new javax.swing.JMenuBar();
          menu1 = new javax.swing.JMenu();
          file_item1 = new javax.swing.JMenuItem();
          file_item2 = new javax.swing.JMenuItem();
          file_item3 = new javax.swing.JMenuItem();
          file_item4 = new javax.swing.JMenuItem();
          menu2 = new javax.swing.JMenu();
          menu3 = new javax.swing.JMenu();
          capture_item1 = new javax.swing.JMenuItem();
          capture_item2 = new javax.swing.JMenuItem();
          capture_item3 = new javax.swing.JMenuItem();
          menu4 = new javax.swing.JMenu();
          help_item1 = new javax.swing.JMenuItem();
  
          setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          getContentPane().setBackground(java.awt.Color.black);
          setTitle("Packet Tracer Tool");
  
          jLabel1.setBackground(java.awt.Color.black);
          jLabel1.setFont(new java.awt.Font("Times New Roman", 0, 14));
          jLabel1.setForeground(java.awt.Color.white);
          jLabel1.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
          jLabel1.setText("Interface:");
          jLabel1.setToolTipText("Select any interface from the list");
  
          interface_combo.setBackground(java.awt.Color.gray);
          interface_combo.setForeground(java.awt.Color.white);
          interface_combo.setModel(new javax.swing.DefaultComboBoxModel(str));
          interface_combo.addActionListener(this);  
          interface_combo.setActionCommand("select_interface");
  
          jLabel2.setBackground(java.awt.Color.black);
          jLabel2.setFont(new java.awt.Font("Times New Roman", 0, 14));
          jLabel2.setForeground(java.awt.Color.white);
          jLabel2.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
          jLabel2.setText("IP Address:");
          jLabel2.setToolTipText("IP Address of the selected interface");        
  
          ipaddr_field.setBackground(java.awt.Color.gray);
          ipaddr_field.setEditable(false);
          ipaddr_field.setFont(new java.awt.Font("Times New Roman", 0, 14));
          ipaddr_field.setForeground(java.awt.Color.white);
          ipaddr_field.setHorizontalAlignment(javax.swing.JTextField.CENTER);        
          ipaddr_field.setText(dev.getInterfaceIPAddr(interface_combo.getSelectedIndex()));
  
          promiscuous.setBackground(java.awt.Color.gray);
          promiscuous.setFont(new java.awt.Font("Times New Roman", 0, 14));
          promiscuous.setForeground(java.awt.Color.white);
          promiscuous.setSelected(true);
          promiscuous.setText("Promiscuous Mode");
          promiscuous.setToolTipText("Check if you want to enable promiscuous mode");
  
          jLabel3.setBackground(java.awt.Color.black);
          jLabel3.setFont(new java.awt.Font("Times New Roman", 0, 14));
          jLabel3.setForeground(java.awt.Color.white);
          jLabel3.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
          jLabel3.setText("Filter: ");
          jLabel3.setToolTipText("Select a filter to apply");
  
          jComboBox1.setBackground(java.awt.Color.gray);
          jComboBox1.setFont(new java.awt.Font("Times New Roman", 0, 14));
          jComboBox1.setForeground(java.awt.Color.white);
          jComboBox1.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
  
          capture_tab.setBackground(java.awt.Color.lightGray);
          capture_tab.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0), 2));
          capture_tab.setFont(new java.awt.Font("Times New Roman", 0, 14)); // NOI18N
          capture_tab.setForeground(java.awt.Color.white);        
          capture_tab.setPreferredScrollableViewportSize(new Dimension(500,70));
          capture_tab.setFillsViewportHeight(true);
          scroll = new javax.swing.JScrollPane(capture_tab);
  
          start_button.setBackground(java.awt.Color.gray);
          start_button.setFont(new java.awt.Font("Times New Roman", 0, 14)); // NOI18N
          start_button.setForeground(java.awt.Color.white);
          start_button.setText("START");
          start_button.setToolTipText("Start capture on the selected interface");
          start_button.addActionListener(this);
          start_button.setActionCommand("start");
  
          stop_button.setBackground(java.awt.Color.gray);
          stop_button.setFont(new java.awt.Font("Times New Roman", 0, 14)); // NOI18N
          stop_button.setForeground(java.awt.Color.white);
          stop_button.setText("STOP");
          stop_button.setToolTipText("Stop capture");
          stop_button.setText("STOP");
          stop_button.setActionCommand("stop");
  
          clear_button.setBackground(java.awt.Color.gray);
          clear_button.setFont(new java.awt.Font("Times New Roman", 0, 14)); // NOI18N
          clear_button.setForeground(java.awt.Color.white);
          clear_button.setText("CLEAR");
          clear_button.setToolTipText("Clear capture table");
  
          save_button.setBackground(java.awt.Color.gray);
          save_button.setFont(new java.awt.Font("Times New Roman", 0, 14)); // NOI18N
          save_button.setForeground(java.awt.Color.white);
          save_button.setText("SAVE");
          save_button.setToolTipText("Save captured packets to a file");
  
          menu1.setText("File");
  
          file_item1.setText("Open");
          menu1.add(file_item1);
  
          file_item2.setText("Save");
          menu1.add(file_item2);
  
          file_item3.setText("Save as");
          menu1.add(file_item3);
  
          file_item4.setText("Exit");
          menu1.add(file_item4);
  
          jMenuBar1.add(menu1);
  
          menu2.setText("Edit");
          jMenuBar1.add(menu2);
  
          menu3.setText("Capture");
  
          capture_item1.setText("Interface");
          menu3.add(capture_item1);
  
          capture_item2.setText("Start");
          menu3.add(capture_item2);
  
          capture_item3.setText("Stop");
          menu3.add(capture_item3);
  
          jMenuBar1.add(menu3);
  
          menu4.setText("Help");
  
          help_item1.setText("About");
          menu4.add(help_item1);
  
          jMenuBar1.add(menu4);
  
          setJMenuBar(jMenuBar1);
  
          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()
                  .addContainerGap()
                  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                      .addComponent(scroll, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 740, Short.MAX_VALUE)
                      .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
                          .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                              .addComponent(jLabel2)
                              .addComponent(jLabel1)
                              .addComponent(jLabel3))
                          .addGap(31, 31, 31)
                          .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                              .addComponent(ipaddr_field, javax.swing.GroupLayout.PREFERRED_SIZE, 102, javax.swing.GroupLayout.PREFERRED_SIZE)
                              .addComponent(interface_combo, 0, 643, Short.MAX_VALUE)
                              .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                                  .addComponent(jComboBox1, javax.swing.GroupLayout.Alignment.LEADING, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                  .addComponent(promiscuous, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
                      .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
                          .addComponent(start_button, javax.swing.GroupLayout.PREFERRED_SIZE, 86, javax.swing.GroupLayout.PREFERRED_SIZE)
                          .addGap(36, 36, 36)
                          .addComponent(stop_button, javax.swing.GroupLayout.PREFERRED_SIZE, 88, javax.swing.GroupLayout.PREFERRED_SIZE)
                          .addGap(35, 35, 35)
                          .addComponent(clear_button, javax.swing.GroupLayout.PREFERRED_SIZE, 87, javax.swing.GroupLayout.PREFERRED_SIZE)
                          .addGap(36, 36, 36)
                          .addComponent(save_button, javax.swing.GroupLayout.PREFERRED_SIZE, 90, javax.swing.GroupLayout.PREFERRED_SIZE)))
                  .addContainerGap())
          );
          layout.setVerticalGroup(
              layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
              .addGroup(layout.createSequentialGroup()
                  .addContainerGap()
                  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                      .addComponent(jLabel1)
                      .addComponent(interface_combo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                      .addComponent(jLabel2)
                      .addComponent(ipaddr_field, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                  .addComponent(promiscuous)
                  .addGap(18, 18, 18)
                  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                      .addComponent(jLabel3)
                      .addComponent(jComboBox1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                  .addGap(18, 18, 18)
                  .addComponent(scroll, javax.swing.GroupLayout.PREFERRED_SIZE, 300, javax.swing.GroupLayout.PREFERRED_SIZE)
                  .addGap(49, 49, 49)
                  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                      .addComponent(start_button, javax.swing.GroupLayout.DEFAULT_SIZE, 28, Short.MAX_VALUE)
                      .addComponent(stop_button, javax.swing.GroupLayout.DEFAULT_SIZE, 28, Short.MAX_VALUE)
                      .addComponent(clear_button, javax.swing.GroupLayout.DEFAULT_SIZE, 28, Short.MAX_VALUE)
                      .addComponent(save_button, javax.swing.GroupLayout.DEFAULT_SIZE, 28, Short.MAX_VALUE))
                  .addGap(111, 111, 111))
          );
  
          pack();
      }// &lt;/editor-fold&gt;//GEN-END:initComponents
  
      public void actionPerformed(ActionEvent e)
      {
          String action;
          action = e.getActionCommand();        
          if(action.equals("start"))
          {            
              capture = dev.openInterface(dev.getInterfaceByIndex(interface_combo.getSelectedIndex()),promiscuous.isSelected()); 
              capture_thread = new CaptureThread(capture,model,capture_tab);
              capture_thread.execute();
          }
          if(action.equals("stop"))
          {            
              capture_thread.cancel(true);            
          }
      }    
  
      public static void main(String args[]) {
          java.awt.EventQueue.invokeLater(new Runnable() {
  
              public void run() {
                  new MainWin().setVisible(true);
              }
          });
      }
      // Variables declaration - do not modify//GEN-BEGIN:variables
      private CaptureThread capture_thread;
      private SystemInterfaces dev;    
      private String str[] = null;
      private CaptureTableModel model;
      private JpcapCaptor capture;    
      private javax.swing.JMenuItem capture_item1;
      private javax.swing.JMenuItem capture_item2;
      private javax.swing.JMenuItem capture_item3;
      private javax.swing.JTable capture_tab;
      private javax.swing.JButton clear_button;
      private javax.swing.JMenuItem file_item1;
      private javax.swing.JMenuItem file_item2;
      private javax.swing.JMenuItem file_item3;
      private javax.swing.JMenuItem file_item4;
      private javax.swing.JMenuItem help_item1;
      private javax.swing.JComboBox interface_combo;
      private javax.swing.JTextField ipaddr_field;
      private javax.swing.JComboBox jComboBox1;
      private javax.swing.JLabel jLabel1;
      private javax.swing.JLabel jLabel2;
      private javax.swing.JLabel jLabel3;
      private javax.swing.JMenuBar jMenuBar1;
      private javax.swing.JScrollPane scroll;
      private javax.swing.JMenu menu1;
      private javax.swing.JMenu menu2;
      private javax.swing.JMenu menu3;
      private javax.swing.JMenu menu4;
      private javax.swing.JCheckBox promiscuous;
      private javax.swing.JButton save_button;
      private javax.swing.JButton start_button;
      private javax.swing.JButton stop_button;
      private String[][] packet = {{"#","#","#","#","#","#","#","#","#","#"}};
      private String[] columnNames = {"Sr. No.", "Time", "src MAC", "src IP", "src Port", "dest MAC", "dest IP", "dest Port", "Protocol", "TTL"};
      // End of variables declaration//GEN-END:variables
  }
  
  
  /************************************CaptureTableModel*********************/
      package TestClasses;
      import javax.swing.table.*;
  
      public class CaptureTableModel extends AbstractTableModel
      {
      String packet[][],columnNames[];
      CaptureTableModel(String[][] packet,String[] columnNames)
      {
          this.packet = packet;
          this.columnNames = columnNames;
      }    
      public int getColumnCount()
      {
          return columnNames.length;
      }
      public int getRowCount()
      {
          return packet.length;
      }
      public String getColumnName(int index)
      {
          return columnNames[index];
      } 
      public Object getValueAt(int row,int col)
          {
          return packet[row][col];
          }
      public Object[] getRow(int index)
          {
          return packet[index];
          }
      public void addPacket(String p[])
          {        
          String temp[][] = new String[getRowCount()+1][getColumnCount()];
          System.arraycopy(packet,0,temp,0,packet.length);
          temp[getRowCount()] = p;
          packet = temp;
          }
      }
  </code></pre>