在给定的代码中,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;
}
}
答案 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
来累积。)
相反,你在你的类中定义一个全新的方法(它不会覆盖任何东西,因此永远不会被调用)。