|
1 | 1 | package messageTab.Info; |
2 | 2 |
|
3 | 3 | import java.awt.Component; |
| 4 | +import java.util.ArrayList; |
4 | 5 | import java.util.List; |
5 | 6 |
|
6 | 7 | import javax.swing.JPanel; |
| 8 | +import javax.swing.SwingUtilities; |
7 | 9 | import javax.swing.SwingWorker; |
8 | 10 |
|
9 | 11 | import org.apache.commons.lang3.StringUtils; |
@@ -124,33 +126,62 @@ public void setMessage(byte[] content, boolean isRequest) { |
124 | 126 | return; |
125 | 127 | } else { |
126 | 128 | originContent = content; |
127 | | - SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() { |
| 129 | + SwingWorker<List<InfoEntry>, Void> worker = new SwingWorker<List<InfoEntry>, Void>() { |
| 130 | + /* |
| 131 | + * 一、doInBackground() |
| 132 | + 运行线程:在 后台线程(worker thread) 执行 |
| 133 | + 作用:执行耗时任务(例如网络请求、IO、分析计算) |
| 134 | + 线程安全性: |
| 135 | + 不是线程安全的 对 Swing 组件(UI)而言。 |
| 136 | + 在这里不能直接操作 Swing 组件(如 JTable、JLabel 等)。 |
| 137 | + 如果修改 UI,会有随机的显示错误、空指针、数据错乱等问题。 |
| 138 | + 二、done() |
| 139 | + 运行线程:在 事件派发线程(EDT, Event Dispatch Thread) 执行 |
| 140 | + 作用:后台任务结束后,更新 UI(比如刷新表格、显示结果、关闭加载动画等) |
| 141 | + 线程安全性: |
| 142 | + 是线程安全的 对 Swing 组件操作而言。 |
| 143 | + 因为 EDT 是 Swing 的唯一 UI 线程。 |
| 144 | + */ |
128 | 145 | @Override |
129 | | - protected Void doInBackground() throws Exception { |
130 | | - ((InfoPanel) panel).getTable().getInfoTableModel().clear(); |
131 | | - List<String> urls = FindUrlAction.findUrls(originContent); |
132 | | - |
133 | | - //清除JS\scss\vue等非接口URL |
134 | | - urls = FindUrlAction.removeJsUrl(urls); |
135 | | - for (String url : urls) { |
136 | | - InfoEntry aaa = new InfoEntry(url, InfoEntry.Type_URL); |
137 | | - ((InfoPanel) panel).getTable().getInfoTableModel().addNewInfoEntry(aaa); |
138 | | - } |
139 | | - |
140 | | - List<String> emails = EmailUtils.grepEmail(new String(originContent)); |
141 | | - emails = TextUtils.deduplicate(emails); |
142 | | - for (String email : emails) { |
143 | | - InfoEntry aaa = new InfoEntry(email, InfoEntry.Type_Email); |
144 | | - ((InfoPanel) panel).getTable().getInfoTableModel().addNewInfoEntry(aaa); |
145 | | - } |
146 | | - |
147 | | - if (((InfoPanel) panel).getTable().getInfoTableModel().getRowCount()==0) { |
148 | | - InfoEntry aaa = new InfoEntry("No Info To Display", InfoEntry.Type_URL); |
149 | | - ((InfoPanel) panel).getTable().getInfoTableModel().addNewInfoEntry(aaa); |
150 | | - } |
151 | | - |
152 | | - return null; |
153 | | - } |
| 146 | + protected List<InfoEntry> doInBackground() { |
| 147 | + List<InfoEntry> entries = new ArrayList<>(); |
| 148 | + |
| 149 | + List<String> urls = FindUrlAction.findUrls(originContent); |
| 150 | + urls = FindUrlAction.removeJsUrl(urls); |
| 151 | + for (String url : urls) { |
| 152 | + entries.add(new InfoEntry(url, InfoEntry.Type_URL)); |
| 153 | + } |
| 154 | + |
| 155 | + List<String> emails = EmailUtils.grepEmail(new String(originContent)); |
| 156 | + emails = TextUtils.deduplicate(emails); |
| 157 | + for (String email : emails) { |
| 158 | + entries.add(new InfoEntry(email, InfoEntry.Type_Email)); |
| 159 | + } |
| 160 | + |
| 161 | + if (entries.isEmpty()) { |
| 162 | + entries.add(new InfoEntry("No Info To Display", InfoEntry.Type_URL)); |
| 163 | + } |
| 164 | + |
| 165 | + return entries; |
| 166 | + } |
| 167 | + |
| 168 | + @Override |
| 169 | + protected void done() { |
| 170 | + try { |
| 171 | + List<InfoEntry> newEntries = get(); |
| 172 | + InfoTableModel model = ((InfoPanel) panel).getTable().getInfoTableModel(); |
| 173 | + |
| 174 | + // ✅ 所有 UI 更新都在 EDT 进行 |
| 175 | + SwingUtilities.invokeLater(() -> { |
| 176 | + model.clear(); |
| 177 | + for (InfoEntry e : newEntries) { |
| 178 | + model.addNewInfoEntry(e); |
| 179 | + } |
| 180 | + }); |
| 181 | + } catch (Exception ex) { |
| 182 | + ex.printStackTrace(); |
| 183 | + } |
| 184 | + } |
154 | 185 | }; |
155 | 186 | worker.execute(); |
156 | 187 | } |
|
0 commit comments