简体   繁体   English

Java Swing - 更新 JTable 时出现问题

[英]Java Swing - Problem updating the JTable

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.在给定的代码中,swingworker 线程将捕获数据包,将其字段封装到字符串数组中,然后将此字符串数组作为一行添加到 GUI 中的 jtable 中。 My JTable follows the AbstractTableModel.我的 JTable 遵循 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.我正在使用新数据手动复制 JTable 中的旧数据,然后使用 FireTableDataChanged() 方法使更改反映在 GUI 的表中。 But the GUI table remains blank.但是 GUI 表仍然是空白的。 I am not able to update my JTable with the new data.我无法用新数据更新我的 JTable。 I also tried to use DefaultTableModel but had the same result.我也尝试使用 DefaultTableModel 但结果相同。

/ * ** * ** * ** * ** * CaptureThread class * ** * ** * ** * **** / / * ** * ** * ** * ** * CaptureThread class * ** * ** * ** * **** /

package TestClasses;
import javax.swing.*;
import javax.swing.table.*;
import jpcap.*;
import jpcap.packet.*;

public class CaptureThread extends SwingWorker<Void,String[]>
{
    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();
    }
}

/ * ** * ** * ** * ** * ** * ** * MainWin class * ** * ** * ** * * / / * ** * ** * ** * ** * ** * ** * MainWin class * ** * ** * ** * * /

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")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//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();
    }// </editor-fold>//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;
        }
    }

I cannot run your code, but I believe that your process method should accept a List of String array as a parameter and then have a for loop in it where you iterate through the list adding String arrays to the model inside of the loop.我无法运行您的代码,但我相信您的处理方法应该接受一个字符串数组列表作为参数,然后在其中有一个 for 循环,您可以在其中迭代列表,将字符串 arrays 添加到循环内部的 model 中。 If you add the @Override annotation, I wonder if the compiler will complain that process doesn't truly override a super method.如果添加 @Override 注释,我想知道编译器是否会抱怨进程并没有真正覆盖超级方法。 Something like this perhaps:可能是这样的:

@Override // don't forget this!
public void process(List<String[]> chunks) {
  for(int i = 0; i < chunks.size(); i++) {
    model.addPacket(chunks.get(i));
    model.fireTableDataChanged();
  }
}

Note that code has not been tested.请注意,代码尚未经过测试。

The SwingWorker method you have to override has the following signature:您必须重写的SwingWorker方法具有以下签名:

@Override
protected void process(List<String[]> strs) {
    for(String[] str : strs) {
        model.addPacket(str);
    }
    model.fireTableDataChanged();
}

Therein you have to loop over several arrays (they may be accumulated from several calls to publish ).在其中,您必须遍历几个 arrays (它们可能是从多次调用中累积的publish )。

Instead you are defining a completely new method in your class (which does not override anything and therefore is never called).相反,您在 class 中定义了一个全新的方法(它不会覆盖任何东西,因此永远不会被调用)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM