Version: 2.5.6 Update

This commit is contained in:
gh0stkey
2023-11-07 11:15:20 +08:00
parent 0225c00f69
commit bcb5177b54
6 changed files with 520 additions and 360 deletions

View File

@@ -7,7 +7,6 @@ import burp.ui.board.MessagePanel.Table;
import java.util.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import javax.swing.table.TableModel;
@@ -27,14 +26,28 @@ public class Databoard extends JPanel {
private static Boolean isMatchHost = false;
private JLabel hostLabel;
private JTextField hostTextField;
private JTabbedPane dataTabbedPaneA;
private JTabbedPane dataTabbedPaneB;
private JTabbedPane dataTabbedPane;
private JButton clearButton;
private JSplitPane splitPane;
private MessagePanel messagePanel;
private Table table;
DefaultComboBoxModel comboBoxModel = new DefaultComboBoxModel();
JComboBox hostComboBox = new JComboBox(comboBoxModel);
private SwingWorker<Object, Void> currentWorker;
private DefaultComboBoxModel comboBoxModel = new DefaultComboBoxModel();
private JComboBox hostComboBox = new JComboBox(comboBoxModel);
private ChangeListener changeListenerInstance = new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
int selectedIndex = dataTabbedPane.getSelectedIndex();
String selectedTitle = "";
if (selectedIndex != -1) {
selectedTitle = dataTabbedPane.getTitleAt(selectedIndex);
}
applyHostFilter(selectedTitle);
}
};
public Databoard(MessagePanel messagePanel) {
this.messagePanel = messagePanel;
@@ -42,8 +55,7 @@ public class Databoard extends JPanel {
}
private void cleanUI() {
dataTabbedPaneA.removeAll();
dataTabbedPaneB.removeAll();
dataTabbedPane.removeAll();
splitPane.setVisible(false);
}
@@ -70,8 +82,7 @@ public class Databoard extends JPanel {
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
hostLabel = new JLabel();
hostTextField = new JTextField();
dataTabbedPaneA = new JTabbedPane(JTabbedPane.TOP);
dataTabbedPaneB = new JTabbedPane(JTabbedPane.TOP);
dataTabbedPane = new JTabbedPane(JTabbedPane.TOP);
clearButton = new JButton();
//======== this ========
@@ -130,102 +141,120 @@ public class Databoard extends JPanel {
* 设置输入自动匹配
*/
private void setAutoMatch() {
isMatchHost = false;
for (String host : getHostByList()) {
comboBoxModel.addElement(host);
}
populateComboBoxModel();
hostComboBox.setSelectedItem(null);
hostComboBox.addActionListener(this::handleComboBoxAction);
hostComboBox.addActionListener(e -> {
if (!isMatchHost) {
if (hostComboBox.getSelectedItem() != null) {
String selectedHost = hostComboBox.getSelectedItem().toString();
hostTextField.setText(selectedHost);
populateTabbedPaneByHost(selectedHost);
}
}
});
// 事件监听
hostTextField.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
isMatchHost = true;
int keyCode = e.getKeyCode();
if (keyCode == KeyEvent.VK_SPACE && hostComboBox.isPopupVisible()) {
e.setKeyCode(KeyEvent.VK_ENTER);
}
if (keyCode == KeyEvent.VK_ENTER || keyCode == KeyEvent.VK_UP || keyCode == KeyEvent.VK_DOWN) {
e.setSource(hostComboBox);
hostComboBox.dispatchEvent(e);
if (keyCode == KeyEvent.VK_ENTER) {
String selectedItem = hostComboBox.getSelectedItem().toString();
hostTextField.setText(selectedItem);
populateTabbedPaneByHost(selectedItem);
hostComboBox.setPopupVisible(false);
return;
}
}
if (keyCode == KeyEvent.VK_ESCAPE) {
hostComboBox.setPopupVisible(false);
}
isMatchHost = false;
handleKeyEvents(e);
}
});
hostTextField.getDocument().addDocumentListener(new DocumentListener() {
@Override
public void insertUpdate(DocumentEvent e) {
updateList();
update(e);
}
@Override
public void removeUpdate(DocumentEvent e) {
updateList();
update(e);
}
@Override
public void changedUpdate(DocumentEvent e) {
updateList();
update(e);
}
private void updateList() {
isMatchHost = true;
comboBoxModel.removeAllElements();
String input = hostTextField.getText().toLowerCase();
if (!input.isEmpty()){
for (String host : getHostByList()) {
String lowerCaseHost = host.toLowerCase();
if (lowerCaseHost.contains(input)) {
if (lowerCaseHost.equals(input)) {
comboBoxModel.insertElementAt(lowerCaseHost, 0);
comboBoxModel.setSelectedItem(lowerCaseHost);
} else {
comboBoxModel.addElement(host);
}
}
}
}
hostComboBox.setPopupVisible(comboBoxModel.getSize() > 0);
isMatchHost = false;
public void update(DocumentEvent e) {
filterComboBoxList();
}
});
}
private void populateComboBoxModel() {
for (String host : getHostByList()) {
comboBoxModel.addElement(host);
}
}
private void handleComboBoxAction(ActionEvent e) {
if (!isMatchHost && hostComboBox.getSelectedItem() != null) {
String selectedHost = hostComboBox.getSelectedItem().toString();
hostTextField.setText(selectedHost);
populateTabbedPaneByHost(selectedHost);
}
}
private void handleKeyEvents(KeyEvent e) {
isMatchHost = true;
int keyCode = e.getKeyCode();
if (keyCode == KeyEvent.VK_SPACE && hostComboBox.isPopupVisible()) {
e.setKeyCode(KeyEvent.VK_ENTER);
}
if (Arrays.asList(KeyEvent.VK_ENTER, KeyEvent.VK_UP, KeyEvent.VK_DOWN).contains(keyCode)) {
e.setSource(hostComboBox);
hostComboBox.dispatchEvent(e);
if (keyCode == KeyEvent.VK_ENTER) {
updateTextFieldFromComboBox();
hostComboBox.setPopupVisible(false);
e.consume();
}
}
if (keyCode == KeyEvent.VK_ESCAPE) {
hostComboBox.setPopupVisible(false);
}
isMatchHost = false;
}
private void updateTextFieldFromComboBox() {
Object selectedItem = hostComboBox.getSelectedItem();
if (selectedItem != null) {
String selectedHost = selectedItem.toString();
hostTextField.setText(selectedHost);
populateTabbedPaneByHost(selectedHost);
}
}
private void filterComboBoxList() {
isMatchHost = true;
comboBoxModel.removeAllElements();
String input = hostTextField.getText().toLowerCase();
if (!input.isEmpty()) {
for (String host : getHostByList()) {
String lowerCaseHost = host.toLowerCase();
if (lowerCaseHost.contains(input)) {
if (lowerCaseHost.equals(input)) {
comboBoxModel.insertElementAt(lowerCaseHost, 0);
comboBoxModel.setSelectedItem(lowerCaseHost);
} else {
comboBoxModel.addElement(host);
}
}
}
}
hostComboBox.setPopupVisible(comboBoxModel.getSize() > 0);
isMatchHost = false;
}
private void applyHostFilter(String filterText) {
TableRowSorter<TableModel> sorter = (TableRowSorter<TableModel>) table.getRowSorter();
if (filterText.contains("*.")) {
filterText = StringHelper.replaceFirstOccurrence(filterText, "*.", "");
} else if (filterText.contains("*")) {
filterText = "";
}
RowFilter<TableModel, Integer> filter = RowFilter.regexFilter(filterText, 1);
sorter.setRowFilter(filter);
filterText = filterText.isEmpty() ? "*" : filterText;
@@ -262,51 +291,58 @@ public class Databoard extends JPanel {
selectedDataMap = dataMap.get(selectedHost);
}
// 由于removeChangeListener不知什么原因不生效因此建立两个tabbedPane
dataTabbedPaneA.removeAll();
dataTabbedPaneB.removeAll();
dataTabbedPane.removeAll();
ChangeListener changeListenerInstance = new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
int selectedIndex = dataTabbedPaneA.getSelectedIndex();
String selectedTitle = "";
if (selectedIndex != -1) {
selectedTitle = dataTabbedPaneA.getTitleAt(selectedIndex);
}
applyHostFilter(selectedTitle);
}
};
dataTabbedPane.setPreferredSize(new Dimension(500,0));
dataTabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
splitPane.setLeftComponent(dataTabbedPane);
if (selectedHost.equals("**")) {
dataTabbedPaneA.setPreferredSize(new Dimension(500,0));
dataTabbedPaneA.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
splitPane.setLeftComponent(dataTabbedPaneA);
for (Map.Entry<String, Map<String, List<String>>> entry : dataMap.entrySet()) {
JTabbedPane newTabbedPane = new JTabbedPane();
newTabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
if (currentWorker != null && !currentWorker.isDone()) {
currentWorker.cancel(true);
}
for (Map.Entry<String, List<String>> entrySet : entry.getValue().entrySet()) {
Thread t = new Thread(() -> {
String tabTitle = String.format("%s (%s)", entrySet.getKey(), entrySet.getValue().size());
newTabbedPane.addTab(tabTitle, new DataTable(entrySet.getKey(), entrySet.getValue()));
dataTabbedPaneA.addTab(entry.getKey(), newTabbedPane);
});
t.start();
try {
t.join();
} catch (Exception e) {
e.printStackTrace();
}
currentWorker = new SwingWorker<Object, Void>() {
@Override
protected Object[] doInBackground() throws Exception {
String tabTitle = String.format("%s (%s)", entrySet.getKey(),
entrySet.getValue().size());
DatatablePanel datatablePanel = new DatatablePanel(entrySet.getKey(),
entrySet.getValue());
datatablePanel.setTableListener(messagePanel);
return new Object[] {tabTitle, datatablePanel};
}
@Override
protected void done() {
if (!isCancelled()) {
try {
Object[] result = (Object[]) get();
newTabbedPane.addTab(result[0].toString(), (DatatablePanel) result[1]);
dataTabbedPane.addTab(entry.getKey(), newTabbedPane);
} catch (Exception e) {
e.printStackTrace();
}
}
}
};
currentWorker.execute();
}
}
dataTabbedPaneA.addChangeListener(changeListenerInstance);
dataTabbedPane.addChangeListener(changeListenerInstance);
} else {
dataTabbedPaneB.setPreferredSize(new Dimension(500,0));
dataTabbedPaneB.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
splitPane.setLeftComponent(dataTabbedPaneB);
dataTabbedPane.removeChangeListener(changeListenerInstance);
for (Map.Entry<String, List<String>> entry : selectedDataMap.entrySet()) {
String tabTitle = String.format("%s (%s)", entry.getKey(), entry.getValue().size());
dataTabbedPaneB.addTab(tabTitle, new DataTable(entry.getKey(), entry.getValue()));
DatatablePanel datatablePanel = new DatatablePanel(entry.getKey(), entry.getValue());
datatablePanel.setTableListener(messagePanel);
dataTabbedPane.addTab(tabTitle, datatablePanel);
}
}
@@ -332,103 +368,21 @@ public class Databoard extends JPanel {
}
hostTextField.setText(selectedHost);
}
}
class DataTable extends JPanel {
private final JTable table;
private final DefaultTableModel model;
private final JTextField searchField;
private TableRowSorter<DefaultTableModel> sorter;
public DataTable(String tableName, List<String> list) {
model = new DefaultTableModel();
table = new JTable(model);
sorter = new TableRowSorter<>(model);
table.setRowSorter(sorter);
table.setDefaultEditor(Object.class, null);
// 表格内容双击事件
table.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {
int selectedRow = table.getSelectedRow();
if (selectedRow != -1) {
String rowData = table.getValueAt(selectedRow, 0).toString();
messagePanel.applyMessageFilter(tableName, rowData);
ChangeListener changeListener = new ChangeListener() {
public void stateChanged(ChangeEvent e) {
JTabbedPane tabSource = (JTabbedPane) e.getSource();
int index = tabSource.getSelectedIndex();
if (index != -1) {
Component selectedComponent = tabSource.getComponentAt(index);
if (selectedComponent instanceof DatatablePanel) {
((DatatablePanel) selectedComponent).updatePageSize();
}
}
}
});
};
model.addColumn("Information");
for (String item : list) {
model.addRow(new Object[]{item});
}
String defaultText = "Search";
searchField = new JTextField(defaultText);
// 设置灰色默认文本Search
searchField.setForeground(Color.GRAY);
searchField.addFocusListener(new FocusListener() {
@Override
public void focusGained(FocusEvent e) {
if (searchField.getText().equals(defaultText)) {
searchField.setText("");
searchField.setForeground(Color.BLACK);
}
}
@Override
public void focusLost(FocusEvent e) {
if (searchField.getText().isEmpty()) {
searchField.setForeground(Color.GRAY);
searchField.setText(defaultText);
}
}
});
// 监听输入框内容输入、更新、删除
searchField.getDocument().addDocumentListener(new DocumentListener() {
@Override
public void insertUpdate(DocumentEvent e) {
performSearch();
}
@Override
public void removeUpdate(DocumentEvent e) {
performSearch();
}
@Override
public void changedUpdate(DocumentEvent e) {
performSearch();
}
private void performSearch() {
// 通过字体颜色来判断是否可以进行过滤
if (searchField.getForeground() == Color.BLACK) {
String searchText = searchField.getText();
if (sorter == null) {
sorter = new TableRowSorter<>(model);
table.setRowSorter(sorter);
}
RowFilter<DefaultTableModel, Object> rowFilter = RowFilter.regexFilter(String.format("%s%s", "(?i)", searchText), 0);
sorter.setRowFilter(rowFilter);
}
}
});
// 设置布局
JScrollPane scrollPane = new JScrollPane(table);
setLayout(new BorderLayout(0, 5));
add(scrollPane, BorderLayout.CENTER);
add(searchField, BorderLayout.SOUTH);
dataTabbedPane.addChangeListener(changeListener);
}
}
}