Java Swing - 更新JTable时出现问题

时间:2011-07-11 19:07:31

标签: java swing jtable

在给定的代码中,swingworker线程将捕获数据包,将其字段封装到字符串数组中,然后将此字符串数组作为行添加到GUI中的jtable中。我的JTable遵循AbstractTableModel。我使用新数据手动复制JTable中的旧数据,然后使用FireTableDataChanged()方法,以便更改反映在GUI中的表中。但GUI表仍然是空白的。我无法使用新数据更新JTable。我也尝试使用DefaultTableModel,但结果相同。

/ * ** * ** * ** * ** * CaptureThread类 * ** * ** * * * * **** /

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课程 * * * * ** * ** * * /

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;
        }
    }

2 个答案:

答案 0 :(得分:4)

我无法运行你的代码,但我相信你的进程方法应该接受一个String of String数组作为参数,然后在其中有一个for循环,你在其中遍历列表,将String数组添加到循环内部的模型中。如果添加@Override注释,我想知道编译器是否会抱怨该进程没有真正覆盖超级方法。也许是这样的事情:

@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();
  }
}

请注意,代码尚未经过测试。

答案 1 :(得分:4)

您必须覆盖的SwingWorker方法具有以下签名:

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

其中你必须循环遍历几个数组(它们可以通过多次调用publish来累积。)

相反,你在你的类中定义一个全新的方法(它不会覆盖任何东西,因此永远不会被调用)。