diff options
Diffstat (limited to 'src/cppcheckplus/control/UIFrame.java')
-rw-r--r-- | src/cppcheckplus/control/UIFrame.java | 491 |
1 files changed, 491 insertions, 0 deletions
diff --git a/src/cppcheckplus/control/UIFrame.java b/src/cppcheckplus/control/UIFrame.java new file mode 100644 index 0000000..a2a04ab --- /dev/null +++ b/src/cppcheckplus/control/UIFrame.java | |||
@@ -0,0 +1,491 @@ | |||
1 | package cppcheckplus.control; | ||
2 | |||
3 | import cppcheckplus.menu.MyMenuBar; | ||
4 | import cppcheckplus.outlookpanel.MyOutlookPanel; | ||
5 | import cppcheckplus.outlookpanel.MyOutlookPanelListItem; | ||
6 | import cppcheckplus.shortcut.MyShortcutPanel; | ||
7 | import cppcheckplus.shortcut.MyTree; | ||
8 | import cppcheckplus.tab.MyTabPage; | ||
9 | import cppcheckplus.tab.MyTabPage1; | ||
10 | import cppcheckplus.tab.MyTabPanel; | ||
11 | import cppcheckplus.tab.MyTabPanel1; | ||
12 | import cppcheckplus.text.FileTools; | ||
13 | import cppcheckplus.text.MyPanel; | ||
14 | import cppcheckplus.text.MyTextPanel; | ||
15 | import cppcheckplus.text.MyTextPanel1; | ||
16 | import cppcheckplus.text.ViewPanel; | ||
17 | import cppcheckplus.text.creatTable; | ||
18 | import java.awt.BorderLayout; | ||
19 | import java.awt.TextArea; | ||
20 | import java.awt.event.ActionEvent; | ||
21 | import java.awt.event.ActionListener; | ||
22 | import java.awt.event.MouseAdapter; | ||
23 | import java.awt.event.MouseEvent; | ||
24 | import java.io.BufferedReader; | ||
25 | import java.io.File; | ||
26 | import java.io.IOException; | ||
27 | import java.io.InputStream; | ||
28 | import java.io.InputStreamReader; | ||
29 | import java.io.UnsupportedEncodingException; | ||
30 | import java.nio.charset.StandardCharsets; | ||
31 | import java.nio.file.Files; | ||
32 | import java.nio.file.Path; | ||
33 | import java.nio.file.Paths; | ||
34 | import javax.swing.BorderFactory; | ||
35 | import javax.swing.JComponent; | ||
36 | import javax.swing.JFileChooser; | ||
37 | import javax.swing.JFrame; | ||
38 | import javax.swing.JList; | ||
39 | import javax.swing.JOptionPane; | ||
40 | import javax.swing.JTextArea; | ||
41 | import javax.swing.event.ListSelectionEvent; | ||
42 | import javax.swing.event.ListSelectionListener; | ||
43 | import javax.swing.plaf.TabbedPaneUI; | ||
44 | import toolsconfig.ToolsRegistry; | ||
45 | |||
46 | |||
47 | // 构造界面 | ||
48 | public class UIFrame extends JFrame { | ||
49 | // XML配置文件路径 | ||
50 | private final String menuBarXML; | ||
51 | private final String outlookPanelXML; | ||
52 | private final String settingsXML; | ||
53 | private final String stdclangXML; | ||
54 | // 界面组件 | ||
55 | private final MyContentPanel contentPanel; | ||
56 | private final MyMenuBar menubar; | ||
57 | private final JFileChooser jfc = new JFileChooser();// 文件选择器 | ||
58 | private final JFileChooser jfsettings = new JFileChooser();// 配置设定 | ||
59 | private final String projectPath; | ||
60 | public MyTabPanel centerTabPanel; | ||
61 | // 编辑代码的面板 | ||
62 | public MyTextPanel testCode; | ||
63 | public String src = ""; // 目标源文件或目录的路径 | ||
64 | public creatTable ct = new creatTable(); // 生成表格 | ||
65 | public TextArea textCheck;// 显示检查进度输出 | ||
66 | private MyOutlookPanel outlookPanel; | ||
67 | private MyTabPanel1 footTabPanel; | ||
68 | private MyShortcutPanel shortcutPanel; | ||
69 | private MyTree tree; | ||
70 | private MyTextPanel1 testPanel; | ||
71 | private ViewPanel viewPanel; | ||
72 | // 显示代码和检查进程的文本区域 | ||
73 | private JTextArea textCode;// 显示代码内容 | ||
74 | // 文件操作相关 | ||
75 | private File result; // 存储打开的文件 | ||
76 | private File report; // 导出报告时选择的文件 | ||
77 | private File dir; // 存储打开的目录 | ||
78 | |||
79 | // 构造函数:初始化各个组件,加载配置文件,建立界面布局 | ||
80 | public UIFrame() { | ||
81 | projectPath = System.getProperty("user.dir"); | ||
82 | // 文件选择器初始目录 | ||
83 | jfc.setCurrentDirectory(new File("d://")); | ||
84 | jfsettings.setCurrentDirectory(new File("d://")); | ||
85 | |||
86 | // 配置文件路径 | ||
87 | menuBarXML = "cppcheckplus/control/menubar.xml"; | ||
88 | outlookPanelXML = "cppcheckplus/control/outlook.xml"; | ||
89 | settingsXML = "toolsconfig/settings.xml"; | ||
90 | stdclangXML = "cppcheckplus/control/stdclang.xml"; | ||
91 | |||
92 | MyContorlUtil.loadToolsRoad(settingsXML, this);// 加载工具路径设置到当前对象中 | ||
93 | ct.initSTDClang(stdclangXML);// 设置clang配置 | ||
94 | |||
95 | // 加载菜单栏,注册事件监听 | ||
96 | menubar = MyContorlUtil.loadMenuBar(menuBarXML, new ActionListener() { | ||
97 | public void actionPerformed(ActionEvent e) { | ||
98 | String command = e.getActionCommand(); | ||
99 | switch (command) { | ||
100 | case "onMenuOpen": | ||
101 | // 打开文件 | ||
102 | jfc.setFileSelectionMode(JFileChooser.FILES_ONLY); | ||
103 | if (jfc.showOpenDialog(null) == | ||
104 | JFileChooser.CANCEL_OPTION) { | ||
105 | return; | ||
106 | } | ||
107 | result = jfc.getSelectedFile();// result为选择到的文件 | ||
108 | src = result.getAbsolutePath(); | ||
109 | // 读取文件内容并显示到代码区 | ||
110 | textCode.setText(FileTools.readFile(result)); | ||
111 | // 如果代码标签页不存在,则创建一个 | ||
112 | if (!centerTabPanel.isSelectTabComponents("代码")) { | ||
113 | centerTabPanel.addTab("代码", testCode); | ||
114 | centerTabPanel.isSelectTabComponents("代码"); | ||
115 | } | ||
116 | break; | ||
117 | case "onMenuLoad": | ||
118 | // 加载目录:选择目录并更新目录树 | ||
119 | jfc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); | ||
120 | if (jfc.showOpenDialog(null) == | ||
121 | JFileChooser.CANCEL_OPTION) { | ||
122 | return; | ||
123 | } | ||
124 | dir = jfc.getSelectedFile();// 选择到的目录 | ||
125 | src = dir.getAbsolutePath(); | ||
126 | tree.setRootDir(dir);// 更新目录树 | ||
127 | break; | ||
128 | case "onMenuSave": | ||
129 | // 保存文件 | ||
130 | if (result != null) { | ||
131 | FileTools.writeFile(result, textCode.getText()); | ||
132 | } | ||
133 | break; | ||
134 | case "onMenuClose": | ||
135 | // 关闭程序 | ||
136 | System.exit(0); | ||
137 | break; | ||
138 | case "onMenuClean": | ||
139 | // 清空:清空代码、检查结果、进度信息,重置参数 | ||
140 | textCode.setText(""); | ||
141 | viewPanel.clearTable(); | ||
142 | ct.clearall(); | ||
143 | textCheck.setText(""); | ||
144 | ToolsRegistry.forEach((name, tool) -> { | ||
145 | tool.clear(); | ||
146 | }); | ||
147 | break; | ||
148 | case "onMenuExport": | ||
149 | // 导出:将检查结果导出到xml文件 | ||
150 | JFileChooser dialog = new JFileChooser(); | ||
151 | dialog.setDialogTitle("另存为"); | ||
152 | dialog.setFileSelectionMode(JFileChooser.FILES_ONLY); | ||
153 | dialog.setDialogType(JFileChooser.SAVE_DIALOG); | ||
154 | int r = dialog.showSaveDialog(null); | ||
155 | if (r == JFileChooser.APPROVE_OPTION) { | ||
156 | report = dialog.getSelectedFile(); | ||
157 | FileTools.writeFile(report, ct.results); | ||
158 | } else { | ||
159 | JOptionPane.showMessageDialog(null, "路径错误", | ||
160 | "提示", 2); | ||
161 | } | ||
162 | break; | ||
163 | case "onCppcheck": | ||
164 | // cppcheck检查 | ||
165 | if (src != null && src.length() != 0) { | ||
166 | new Thread() { | ||
167 | public void run() { | ||
168 | ToolsRegistry.executeTool("cppcheck", src); | ||
169 | viewResult("cppcheck"); | ||
170 | } | ||
171 | }.start(); | ||
172 | } else { | ||
173 | JOptionPane.showMessageDialog(null, "目标路径错误", | ||
174 | "提示", 2); | ||
175 | } | ||
176 | break; | ||
177 | case "onClang": | ||
178 | // clang/clang-tidy检查 | ||
179 | if (src != null && src.length() != 0) { | ||
180 | new Thread() { | ||
181 | public void run() { | ||
182 | ToolsRegistry.executeTool("clangTidy", src); | ||
183 | viewResult("clangTidy"); | ||
184 | } | ||
185 | }.start(); | ||
186 | } else { | ||
187 | JOptionPane.showMessageDialog(null, "目标路径错误", | ||
188 | "提示", 2); | ||
189 | } | ||
190 | break; | ||
191 | case "onFlawfinder": | ||
192 | // flawfinder检查 | ||
193 | if (src != null && src.length() != 0) { | ||
194 | new Thread() { | ||
195 | public void run() { | ||
196 | ToolsRegistry.executeTool("flawfinder", src); | ||
197 | viewResult("flawfinder"); | ||
198 | } | ||
199 | }.start(); | ||
200 | } else { | ||
201 | JOptionPane.showMessageDialog(null, "目标路径错误", | ||
202 | "提示", 2); | ||
203 | } | ||
204 | break; | ||
205 | case "onMenuAbout": | ||
206 | // 关于:显示软件信息 | ||
207 | JOptionPane.showMessageDialog(null, "cppcheckplus", | ||
208 | "提示", 2); | ||
209 | break; | ||
210 | case "onOrderType": | ||
211 | // 按类型排序:生成表格并按类型排序 | ||
212 | ct.makeTable(); | ||
213 | ct.ord(2); | ||
214 | if (!centerTabPanel.isSelectTabComponents("结果")) { | ||
215 | viewPanel = new ViewPanel(ct.results); | ||
216 | centerTabPanel.addTab("结果", | ||
217 | createPage(viewPanel)); | ||
218 | centerTabPanel.isSelectTabComponents("结果"); | ||
219 | } else { | ||
220 | viewPanel.update(ct.results); | ||
221 | } | ||
222 | break; | ||
223 | case "onOrderLevel": | ||
224 | // 按级别排序 | ||
225 | ct.makeTable(); | ||
226 | ct.ord(3); | ||
227 | if (!centerTabPanel.isSelectTabComponents("结果")) { | ||
228 | viewPanel = new ViewPanel(ct.results); | ||
229 | centerTabPanel.addTab("结果", | ||
230 | createPage(viewPanel)); | ||
231 | centerTabPanel.isSelectTabComponents("结果"); | ||
232 | } else { | ||
233 | viewPanel.update(ct.results); | ||
234 | } | ||
235 | break; | ||
236 | case "onOrderFile": | ||
237 | // 按文件排序 | ||
238 | ct.makeTable(); | ||
239 | ct.ord(1); | ||
240 | if (!centerTabPanel.isSelectTabComponents("结果")) { | ||
241 | viewPanel = new ViewPanel(ct.results); | ||
242 | centerTabPanel.addTab("结果", | ||
243 | createPage(viewPanel)); | ||
244 | centerTabPanel.isSelectTabComponents("结果"); | ||
245 | } else { | ||
246 | viewPanel.update(ct.results); | ||
247 | } | ||
248 | break; | ||
249 | case "onSetCppcheckRoad": | ||
250 | // cppcheck路径 | ||
251 | jfsettings.setFileSelectionMode( | ||
252 | JFileChooser.FILES_ONLY); | ||
253 | if (jfsettings.showOpenDialog(null) == | ||
254 | JFileChooser.CANCEL_OPTION) { | ||
255 | return; | ||
256 | } else { | ||
257 | File cppcheckFile = jfsettings.getSelectedFile(); | ||
258 | String cppcheckPathTemp = | ||
259 | cppcheckFile.getAbsolutePath(); | ||
260 | MyContorlUtil.fixSettingPath(settingsXML, | ||
261 | "cppcheck", cppcheckPathTemp); | ||
262 | // changedpathcpp = true; | ||
263 | } | ||
264 | break; | ||
265 | case "onSetFlawfinderRoad": | ||
266 | // flawfinder路径 | ||
267 | jfsettings.setFileSelectionMode( | ||
268 | JFileChooser.FILES_ONLY); | ||
269 | if (jfsettings.showOpenDialog(null) == | ||
270 | JFileChooser.CANCEL_OPTION) { | ||
271 | return;// 撤销则返回 | ||
272 | } | ||
273 | File flawfinderFile = jfsettings.getSelectedFile(); | ||
274 | String flawfinderPathTemp = | ||
275 | flawfinderFile.getAbsolutePath(); | ||
276 | MyContorlUtil.fixSettingPath(settingsXML, "flawfinder", | ||
277 | flawfinderPathTemp); | ||
278 | // changedpathflaw = true; | ||
279 | break; | ||
280 | } | ||
281 | } | ||
282 | }); | ||
283 | |||
284 | // 初始化主内容面板 | ||
285 | contentPanel = new MyContentPanel(); | ||
286 | try { | ||
287 | initSwing(); | ||
288 | } catch (UnsupportedEncodingException e1) { | ||
289 | e1.printStackTrace(); | ||
290 | } | ||
291 | } | ||
292 | |||
293 | private void initSwing() throws UnsupportedEncodingException { | ||
294 | setTitle("Cppcheckplus"); | ||
295 | setDefaultCloseOperation(3); // 关闭窗口时退出程序 | ||
296 | setSize(1024, 768); | ||
297 | |||
298 | // 设置窗口图标 | ||
299 | setIconImage(MyContorlUtil.getImage("control/images/logo2.png")); | ||
300 | setContentPane(contentPanel); | ||
301 | // 菜单栏在最上方 | ||
302 | contentPanel.add(menubar, "North"); | ||
303 | |||
304 | // 除却菜单栏之外的面板 | ||
305 | //JPanel centerPane = new JPanel(new BorderLayout()); | ||
306 | |||
307 | // 中间区域,除了菜单栏之外的所有内容 | ||
308 | MyPanel centerPane = new MyPanel(new BorderLayout()); | ||
309 | centerPane.setOpaque(true); | ||
310 | //centerPane.setBackground(MyContorlUtil.CONTENT_PANE_BACKGROUND3); | ||
311 | //centerPane.setBackground(MyContorlUtil.getImage("control/images/logo2.png")); | ||
312 | centerPane.setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 0)); | ||
313 | contentPanel.add(centerPane, "Center"); | ||
314 | |||
315 | // 初始化各个标签页、侧边栏、目录树 | ||
316 | initTab(); | ||
317 | initTab2(); | ||
318 | initOutlookPanel(); | ||
319 | try { | ||
320 | initShortcutPanel(); | ||
321 | } catch (UnsupportedEncodingException e) { | ||
322 | // TODO Auto-generated catch block | ||
323 | e.printStackTrace(); | ||
324 | } | ||
325 | initTree(); | ||
326 | |||
327 | // 面板加入布局 | ||
328 | centerPane.add(outlookPanel, "West"); | ||
329 | centerPane.add(centerTabPanel, "Center"); | ||
330 | centerPane.add(shortcutPanel, "East"); | ||
331 | |||
332 | // 底部添加第二个标签页面板,用于显示检查结果 | ||
333 | contentPanel.add(footTabPanel, BorderLayout.SOUTH); | ||
334 | } | ||
335 | |||
336 | private void initTree() { | ||
337 | tree = shortcutPanel.mytree; | ||
338 | // 点击目录树节点,显示对应文件内容 | ||
339 | tree.setCode(textCode, this); | ||
340 | } | ||
341 | |||
342 | private void initOutlookPanel() { | ||
343 | outlookPanel = new MyOutlookPanel(new ActionListener() { | ||
344 | @Override | ||
345 | public void actionPerformed(ActionEvent e) { | ||
346 | String command = e.getActionCommand(); | ||
347 | System.out.println("Head:" + command); | ||
348 | } | ||
349 | }, new ListSelectionListener() { | ||
350 | @Override | ||
351 | public void valueChanged(ListSelectionEvent e) { | ||
352 | boolean adjust = e.getValueIsAdjusting(); | ||
353 | if (!adjust) { | ||
354 | JList list = (JList) e.getSource(); | ||
355 | Object[] selectionValues = list.getSelectedValues(); | ||
356 | MyOutlookPanelListItem item = | ||
357 | (MyOutlookPanelListItem) selectionValues[0]; | ||
358 | String command = item.getActionCommand(); | ||
359 | if (command.equals("Chart2")) { | ||
360 | // 如果TabPanel不存在就create,否则就切换 | ||
361 | if (!centerTabPanel.isSelectTabComponents("结果")) { | ||
362 | try { | ||
363 | ct.makeTable(); | ||
364 | viewPanel = new ViewPanel(ct.results); | ||
365 | } catch (Exception e1) { | ||
366 | e1.printStackTrace(); | ||
367 | System.out.println("图表生成错误"); | ||
368 | } | ||
369 | centerTabPanel.addTab("结果", | ||
370 | createPage(viewPanel)); | ||
371 | centerTabPanel.isSelectTabComponents("结果"); | ||
372 | } | ||
373 | } else if (command.equals("Map")) { | ||
374 | // 代码标签页 | ||
375 | if (!centerTabPanel.isSelectTabComponents("代码")) { | ||
376 | centerTabPanel.addTab("代码", testCode); | ||
377 | centerTabPanel.isSelectTabComponents("代码"); | ||
378 | } | ||
379 | } else if (command.equals("Process")) { | ||
380 | // 进度 | ||
381 | if (!centerTabPanel.isSelectTabComponents("进度")) { | ||
382 | centerTabPanel.addTab("进度", textCheck); | ||
383 | centerTabPanel.isSelectTabComponents("进度"); | ||
384 | } | ||
385 | } | ||
386 | } | ||
387 | } | ||
388 | |||
389 | }); | ||
390 | // 根据XML配置文件加载Outlook面板内容 | ||
391 | MyContorlUtil.loadOutlookPanel(outlookPanelXML, outlookPanel); | ||
392 | } | ||
393 | |||
394 | private void initTab() { | ||
395 | centerTabPanel = new MyTabPanel(); | ||
396 | centerTabPanel.addMouseListener(new MouseAdapter() { | ||
397 | private boolean isMaximized() { | ||
398 | return outlookPanel.isShrinked(); | ||
399 | } | ||
400 | |||
401 | public void mouseClicked(MouseEvent e) { | ||
402 | if (e.getClickCount() > 1) { | ||
403 | TabbedPaneUI ui = centerTabPanel.getUI(); | ||
404 | int tabIndex = | ||
405 | ui.tabForCoordinate(centerTabPanel, e.getX(), e.getY()); | ||
406 | if (tabIndex != -1) { | ||
407 | boolean maxed = isMaximized(); | ||
408 | outlookPanel.setShrink(!maxed); | ||
409 | shortcutPanel.setShrink(!maxed); | ||
410 | } | ||
411 | } | ||
412 | } | ||
413 | }); | ||
414 | |||
415 | testCode = new MyTextPanel(); | ||
416 | testPanel = new MyTextPanel1(); | ||
417 | viewPanel = new ViewPanel(); | ||
418 | textCode = testCode.getTextArea(); | ||
419 | textCheck = testPanel.getTextArea(); | ||
420 | } | ||
421 | |||
422 | private void initTab2() { | ||
423 | footTabPanel = new MyTabPanel1(); | ||
424 | footTabPanel.addMouseListener(new MouseAdapter() { | ||
425 | private boolean isMaximized() { | ||
426 | return outlookPanel.isShrinked(); | ||
427 | } | ||
428 | |||
429 | public void mouseClicked(MouseEvent e) { | ||
430 | if (e.getClickCount() > 1) { | ||
431 | TabbedPaneUI ui = footTabPanel.getUI(); | ||
432 | int tabIndex = | ||
433 | ui.tabForCoordinate(footTabPanel, e.getX(), e.getY()); | ||
434 | if (tabIndex != -1) { | ||
435 | boolean maxed = isMaximized(); | ||
436 | outlookPanel.setShrink(!maxed); | ||
437 | shortcutPanel.setShrink(!maxed); | ||
438 | } | ||
439 | } | ||
440 | } | ||
441 | }); | ||
442 | |||
443 | ToolsRegistry.forEach((name, tool) -> { | ||
444 | footTabPanel.addTab(name, createPage1(tool.textPanel)); | ||
445 | }); | ||
446 | } | ||
447 | |||
448 | private MyTabPage1 createPage1(JComponent pageContent) { | ||
449 | MyTabPage1 page = new MyTabPage1(pageContent); | ||
450 | return page; | ||
451 | } | ||
452 | |||
453 | private MyTabPage createPage(JComponent pageContent) { | ||
454 | MyTabPage page = new MyTabPage(pageContent); | ||
455 | return page; | ||
456 | } | ||
457 | |||
458 | //改造成目录树 | ||
459 | private void initShortcutPanel() throws UnsupportedEncodingException { | ||
460 | shortcutPanel = new MyShortcutPanel(); | ||
461 | shortcutPanel.setTitle( | ||
462 | new String("项目".getBytes(), StandardCharsets.UTF_8)); | ||
463 | } | ||
464 | |||
465 | public void viewResult(String toolName) { | ||
466 | if (!centerTabPanel.isSelectTabComponents("结果")) { | ||
467 | try { | ||
468 | ct.makeTable(); | ||
469 | viewPanel = new ViewPanel(ct.results); | ||
470 | } catch (Exception e1) { | ||
471 | e1.printStackTrace(); | ||
472 | System.out.println("图表生成错误"); | ||
473 | } | ||
474 | centerTabPanel.addTab("结果", createPage(viewPanel)); | ||
475 | centerTabPanel.isSelectTabComponents("结果"); | ||
476 | } else { | ||
477 | try { | ||
478 | ct.makeTable(); | ||
479 | viewPanel.update(ct.results); | ||
480 | } catch (Exception e1) { | ||
481 | e1.printStackTrace(); | ||
482 | System.out.println("图表生成错误"); | ||
483 | } | ||
484 | } | ||
485 | |||
486 | // 底部标签页切换到对应工具 | ||
487 | if (!footTabPanel.isSelectTabComponents(toolName)) { | ||
488 | footTabPanel.selectTabByOId(toolName); | ||
489 | } | ||
490 | } | ||
491 | } | ||