Files
HaE/src/main/java/hae/component/board/table/Datatable.java

258 lines
9.4 KiB
Java
Raw Normal View History

2024-07-23 09:21:30 +08:00
package hae.component.board.table;
import burp.api.montoya.MontoyaApi;
import hae.component.board.message.MessageTableModel;
import hae.utils.ConfigLoader;
import hae.utils.UIEnhancer;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;
import javax.swing.table.TableRowSorter;
import java.awt.*;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
2024-09-19 17:08:46 +08:00
import java.util.ArrayList;
2024-07-23 09:21:30 +08:00
import java.util.Comparator;
import java.util.List;
import java.util.regex.Pattern;
public class Datatable extends JPanel {
private final MontoyaApi api;
private final ConfigLoader configLoader;
private final JTable dataTable;
private final DefaultTableModel dataTableModel;
private final JTextField searchField;
2024-09-19 17:08:46 +08:00
private final JTextField secondSearchField;
2024-07-23 09:21:30 +08:00
private final TableRowSorter<DefaultTableModel> sorter;
private final JCheckBox searchMode = new JCheckBox("Reverse search");
2025-01-17 17:56:35 +08:00
private final JCheckBox regexMode = new JCheckBox("Regex mode");
2024-07-23 09:21:30 +08:00
private final String tabName;
private final JPanel footerPanel;
public Datatable(MontoyaApi api, ConfigLoader configLoader, String tabName, List<String> dataList) {
this.api = api;
this.configLoader = configLoader;
this.tabName = tabName;
String[] columnNames = {"#", "Information"};
this.dataTableModel = new DefaultTableModel(columnNames, 0);
this.dataTable = new JTable(dataTableModel);
this.sorter = new TableRowSorter<>(dataTableModel);
2024-09-19 17:08:46 +08:00
this.searchField = new JTextField(10);
this.secondSearchField = new JTextField(10);
2024-07-23 09:21:30 +08:00
this.footerPanel = new JPanel(new BorderLayout(0, 5));
initComponents(dataList);
}
private void initComponents(List<String> dataList) {
2025-01-10 17:45:59 +08:00
dataTable.setRowSorter(sorter);
2025-01-17 17:56:35 +08:00
2024-07-23 09:21:30 +08:00
// 设置ID排序
2025-03-25 11:44:07 +08:00
sorter.setComparator(0, (Comparator<Integer>) Integer::compareTo);
2024-07-23 09:21:30 +08:00
for (String item : dataList) {
if (!item.isEmpty()) {
addRowToTable(new Object[]{item});
}
}
2024-09-19 17:08:46 +08:00
UIEnhancer.setTextFieldPlaceholder(searchField, "Search");
2024-07-23 09:21:30 +08:00
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();
}
});
2024-09-19 17:08:46 +08:00
UIEnhancer.setTextFieldPlaceholder(secondSearchField, "Second search");
secondSearchField.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();
}
});
2024-07-23 09:21:30 +08:00
// 设置布局
JScrollPane scrollPane = new JScrollPane(dataTable);
scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
2024-10-14 16:35:20 +08:00
TableColumn idColumn = dataTable.getColumnModel().getColumn(0);
idColumn.setPreferredWidth(50);
idColumn.setMaxWidth(100);
2024-07-23 09:21:30 +08:00
setLayout(new BorderLayout(0, 5));
JPanel optionsPanel = new JPanel();
optionsPanel.setLayout(new BoxLayout(optionsPanel, BoxLayout.X_AXIS));
// Settings按钮
2025-01-17 17:56:35 +08:00
JPanel settingMenuPanel = new JPanel(new GridLayout(2, 1));
2024-07-23 09:21:30 +08:00
settingMenuPanel.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
JPopupMenu settingMenu = new JPopupMenu();
settingMenuPanel.add(searchMode);
2025-01-17 17:56:35 +08:00
settingMenuPanel.add(regexMode);
regexMode.setSelected(true);
2024-07-23 09:21:30 +08:00
searchMode.addItemListener(e -> performSearch());
settingMenu.add(settingMenuPanel);
JButton settingsButton = new JButton("Settings");
setMenuShow(settingMenu, settingsButton);
optionsPanel.add(settingsButton);
optionsPanel.add(Box.createHorizontalStrut(5));
optionsPanel.add(searchField);
optionsPanel.add(Box.createHorizontalStrut(5));
2024-09-19 17:08:46 +08:00
optionsPanel.add(secondSearchField);
2024-07-23 09:21:30 +08:00
footerPanel.setBorder(BorderFactory.createEmptyBorder(2, 3, 5, 3));
footerPanel.add(optionsPanel, BorderLayout.CENTER);
add(scrollPane, BorderLayout.CENTER);
add(footerPanel, BorderLayout.SOUTH);
}
private void setMenuShow(JPopupMenu menu, JButton button) {
button.addActionListener(e -> {
Point buttonLocation = button.getLocationOnScreen();
Dimension menuSize = menu.getPreferredSize();
int x = buttonLocation.x + (button.getWidth() - menuSize.width) / 2;
int y = buttonLocation.y - menuSize.height;
menu.show(button, x - buttonLocation.x, y - buttonLocation.y);
});
}
private void addRowToTable(Object[] data) {
int rowCount = dataTableModel.getRowCount();
int id = rowCount > 0 ? (Integer) dataTableModel.getValueAt(rowCount - 1, 0) + 1 : 1;
Object[] rowData = new Object[data.length + 1];
rowData[0] = id;
System.arraycopy(data, 0, rowData, 1, data.length);
dataTableModel.addRow(rowData);
}
private void performSearch() {
2025-01-17 17:56:35 +08:00
RowFilter<Object, Object> firstRowFilter = getObjectObjectRowFilter(searchField, true);
RowFilter<Object, Object> secondRowFilter = getObjectObjectRowFilter(secondSearchField, false);
2024-07-23 09:21:30 +08:00
if (searchField.getForeground().equals(Color.BLACK)) {
2024-09-19 17:08:46 +08:00
sorter.setRowFilter(firstRowFilter);
if (secondSearchField.getForeground().equals(Color.BLACK)) {
List<RowFilter<Object, Object>> filters = new ArrayList<>();
filters.add(firstRowFilter);
filters.add(secondRowFilter);
sorter.setRowFilter(RowFilter.andFilter(filters));
}
}
}
2024-07-23 09:21:30 +08:00
2025-01-17 17:56:35 +08:00
private RowFilter<Object, Object> getObjectObjectRowFilter(JTextField searchField, boolean firstFlag) {
2025-03-25 11:44:07 +08:00
return new RowFilter<>() {
2024-09-19 17:08:46 +08:00
public boolean include(Entry<?, ?> entry) {
String searchFieldTextText = searchField.getText();
searchFieldTextText = searchFieldTextText.toLowerCase();
2025-01-17 17:56:35 +08:00
String entryValue = ((String) entry.getValue(1)).toLowerCase();
2025-01-10 17:45:59 +08:00
boolean filterReturn = searchFieldTextText.isEmpty();
2025-01-17 17:56:35 +08:00
boolean firstFlagReturn = searchMode.isSelected() && firstFlag;
if (regexMode.isSelected()) {
Pattern pattern = null;
try {
pattern = Pattern.compile(searchFieldTextText, Pattern.CASE_INSENSITIVE);
} catch (Exception ignored) {
}
if (pattern != null) {
filterReturn = filterReturn || pattern.matcher(entryValue).find() != firstFlagReturn;
}
} else {
filterReturn = filterReturn || entryValue.contains(searchFieldTextText) != firstFlagReturn;
2024-09-19 17:08:46 +08:00
}
2025-01-17 17:56:35 +08:00
return filterReturn;
2024-09-19 17:08:46 +08:00
}
};
2024-07-23 09:21:30 +08:00
}
public void setTableListener(MessageTableModel messagePanel) {
// 表格复制功能
dataTable.setTransferHandler(new TransferHandler() {
@Override
public void exportToClipboard(JComponent comp, Clipboard clip, int action) throws IllegalStateException {
if (comp instanceof JTable) {
StringSelection stringSelection = new StringSelection(getSelectedDataAtTable((JTable) comp).replace("\0", "").replaceAll("[\\p{Cntrl}&&[^\r\n\t]]", ""));
clip.setContents(stringSelection, null);
} else {
super.exportToClipboard(comp, clip, action);
}
}
});
dataTable.setDefaultEditor(Object.class, null);
// 表格内容双击事件
dataTable.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {
int selectedRow = dataTable.getSelectedRow();
if (selectedRow != -1) {
String rowData = dataTable.getValueAt(selectedRow, 1).toString();
messagePanel.applyMessageFilter(tabName, rowData);
}
}
}
});
}
public String getSelectedDataAtTable(JTable table) {
int[] selectRows = table.getSelectedRows();
StringBuilder selectData = new StringBuilder();
for (int row : selectRows) {
selectData.append(table.getValueAt(row, 1).toString()).append("\r\n");
}
if (!selectData.isEmpty()) {
selectData.delete(selectData.length() - 2, selectData.length());
} else {
return "";
}
return selectData.toString();
}
public JTable getDataTable() {
return this.dataTable;
}
}