summaryrefslogtreecommitdiffstats
path: root/src/cppcheckplus/control/Main.java
blob: 4c84eac556197bcd5b1882e285f86ee76155313e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
package cppcheckplus.control;

import cppcheckplus.menu.MyMenuBar;
import cppcheckplus.outlookpanel.MyOutlookPanel;
import cppcheckplus.outlookpanel.MyOutlookPanelListItem;
import cppcheckplus.shortcut.MyShortcutPanel;
import cppcheckplus.shortcut.MyTree;
import cppcheckplus.tab.MyTabPage;
import cppcheckplus.tab.MyTabPage1;
import cppcheckplus.tab.MyTabPanel;
import cppcheckplus.tab.MyTabPanel1;
import cppcheckplus.text.FileTools;
import cppcheckplus.text.MyPanel;
import cppcheckplus.text.MyTextPanel;
import cppcheckplus.text.MyTextPanel1;
import cppcheckplus.text.ViewPanel;
import cppcheckplus.text.creatTable;
import java.awt.BorderLayout;
import java.awt.TextArea;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.plaf.TabbedPaneUI;
import javax.xml.parsers.ParserConfigurationException;


// 构造界面和各个工具的调用逻辑
public class Main extends JFrame {
    //private String target = "";// dump文件路径
    public static final int SUCCESS = 0; // 表示程序执行成功
    public static final String COMMAND = "java.exe -version"; // 要执行的语句
    public static final String SUCCESS_MESSAGE = "程序执行成功!";
    public static final String ERROR_MESSAGE = "程序执行出错:";
    public static final String ENTERWindows = "\r\n";
    public static final String ENTERLinux = "\n";
    // XML配置文件路径
    private final String menuBarXML;
    private final String outlookPanelXML;
    private final String settingsXML;
    private final String stdclangXML;
    // 界面组件
    private final MyContentPanel contentPanel;
    private final MyMenuBar menubar;
    private final JFileChooser jfc = new JFileChooser();// 文件选择器
    private final JFileChooser jfsettings = new JFileChooser();// 配置设定
    public MyTabPanel tabPanel;
    // 编辑代码的面板
    public MyTextPanel testCode;
    public String src = ""; // 目标源文件或目录的路径
    public String cppcheckPath = null;
    public String flawfinderPath = null;
    public String paracppcheck = null;
    public String paraflawfinder = null;
    public creatTable ct = new creatTable();
    private MyOutlookPanel outlookPanel;
    private MyTabPanel1 tabPanel2;
    private MyShortcutPanel shortcutPanel;
    private MyTree tree;
    // 标记是否修改了工具路径
    private boolean changedpathcpp = false;
    private boolean changedpathflaw = false;
    private MyTextPanel1 testPanel;
    private ViewPanel viewPanel;
    // 显示代码和检查进程的文本区域
    private JTextArea textCode;// 显示代码内容
    private TextArea textCheck;// 显示检查进度输出
    // 各工具的面板
    private MyTextPanel1 flawfinderPanel;
    private MyTextPanel1 cppcheckPanel;
    private MyTextPanel1 clangPanel;
    // 各工具的检测结果
    private TextArea flawfinderResult;//flawfinder检测结果
    private TextArea cppcheckResult;//cppcheck检测结果
    private TextArea clangResult;//clang检测结果
    // 文件操作相关
    private File result; // 存储打开的文件
    private File report; // 导出报告时选择的文件
    private File direct;  // 存储打开的目录
    private String tmpFileName = "";//tmp文件名
    //private static String inputResult = "inputResult.txt";
    //private static String errorResult = "errorResult.txt";
    private Main ui;
    private final String projectPath;

    // 构造函数:初始化各个组件,加载配置文件,建立界面布局
    public Main() {
        projectPath = System.getProperty("user.dir");
        // 文件选择器初始目录
        jfc.setCurrentDirectory(new File("d://"));
        jfsettings.setCurrentDirectory(new File("d://"));

        // 配置文件路径
        menuBarXML = "cppcheckplus/control/menubar.xml";
        outlookPanelXML = "cppcheckplus/control/outlook.xml";
        settingsXML = "cppcheckplus/control/settings.xml";
        stdclangXML = "cppcheckplus/control/stdclang.xml";

        MyContorlUtil.loadToolsRoad(settingsXML, this);// 加载工具路径设置到当前对象中
        ct.initSTDClang(stdclangXML);// 设置clang配置

        // 加载菜单栏,注册事件监听
        menubar = MyContorlUtil.loadMenuBar(menuBarXML, new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                String command = e.getActionCommand();
                switch (command) {
                    case "OnMenuOpen":
                        // 打开文件
                        jfc.setFileSelectionMode(0);// 设定只能选择到文件
                        int state = jfc.showOpenDialog(null);
                        if (state == 1) {
                            return; // 撤销选择则返回
                        } else {
                            result = jfc.getSelectedFile();// result为选择到的文件
                            src = result.getAbsolutePath();
                            // 读取文件内容并显示到代码区
                            textCode.setText(FileTools.readFile(result));
                            // 如果代码标签页不存在,则创建一个
                            if (!tabPanel.isSelectTabComponents("代码")) {
                                tabPanel.addTab("代码", testCode);
                                tabPanel.isSelectTabComponents("代码");
                            }
                        }
                        break;
                    case "onMenuLoad":
                        // 加载目录:选择目录并更新目录树
                        jfc.setFileSelectionMode(1);// 只能选择到文件夹
//                    int state = jfc.showOpenDialog(null);
                        if (jfc.showOpenDialog(null) == 1) {
                            return;
                        }
                        direct = jfc.getSelectedFile();// 选择到的目录
                        src = direct.getAbsolutePath();
                        tree.setRootDir(direct);// 更新目录树
                        break;
                    case "onMenuSave":
                        // 保存文件
                        if (result != null) {
                            FileTools.writeFile(result, textCode.getText());
                        }
                        break;
                    case "onMenuClose":
                        // 关闭程序
                        System.exit(0);
                        break;
                    case "onMenuClean":
                        // 清空:清空代码、检查结果、进度信息,重置参数
                        textCode.setText("");
                        flawfinderResult.setText("");
                        cppcheckResult.setText("");
                        clangResult.setText("");
                        viewPanel.clearTable();
                        ct.clearall();
                        textCheck.setText("");
                        paracppcheck = "--enable=all";
                        break;
                    case "onMenuExport":
                        // 导出:将检查结果导出到xml文件
                        JFileChooser dialog = new JFileChooser();
                        dialog.setDialogTitle("另存为");
                        dialog.setFileSelectionMode(JFileChooser.FILES_ONLY);
                        dialog.setDialogType(JFileChooser.SAVE_DIALOG);
                        int r = dialog.showSaveDialog(ui);
                        if (r == JFileChooser.APPROVE_OPTION) {
                            report = dialog.getSelectedFile();
                            FileTools.writeFile(report, ct.results);
                        } else {
                            JOptionPane.showMessageDialog(null, "路径错误",
                                "提示", 2);
                        }
                        break;
                    case "onCppcheck":
                        // cppcheck检查
                        if (src != null && src.length() != 0) {
                            if (paracppcheck != null &&
                                paracppcheck.length() != 0) {
                                new Thread() {
                                    public void run() {
                                        execute(src, paracppcheck);
                                    }
                                }.start();
                            } else {
                                JOptionPane.showMessageDialog(null, "参数错误",
                                    "提示", 2);
                            }
                        } else {
                            JOptionPane.showMessageDialog(null, "目标路径错误",
                                "提示", 2);
                        }
                        break;
                    case "onClang":
                        // clang/clang-tidy检查
                        if (src != null && src.length() != 0) {
                            new Thread() {
                                public void run() {
                                    execute2(src);
                                }
                            }.start();
                        } else {
                            JOptionPane.showMessageDialog(null, "目标路径错误",
                                "提示", 2);
                        }
                        break;
                    case "onFlawfinder":
                        // flawfinder检查
                        if (src != null && src.length() != 0) {
                            new Thread() {
                                public void run() {
                                    tmpFileName = "tmp" + "src" + ".csv";
                                    execute3(src, paraflawfinder, tmpFileName);
                                }
                            }.start();
                        } else {
                            JOptionPane.showMessageDialog(null, "目标路径错误",
                                "提示", 2);
                        }
                        break;
                    case "onMenuAbout":
                        // 关于:显示软件信息
                        JOptionPane.showMessageDialog(null, "cppcheckplus",
                            "提示", 2);
                        break;
                    case "onOrderType":
                        // 按类型排序:生成表格并按类型排序
                        ct.makeTable();
                        ct.ord(2);
                        if (!tabPanel.isSelectTabComponents("结果")) {
                            viewPanel = new ViewPanel(ct.results);
                            tabPanel.addTab("结果", createPage(viewPanel));
                            tabPanel.isSelectTabComponents("结果");
                        } else {
                            viewPanel.update(ct.results);
                        }
                        break;
                    case "onOrderLevel":
                        // 按级别排序
                        ct.makeTable();
                        ct.ord(3);
                        if (!tabPanel.isSelectTabComponents("结果")) {
                            viewPanel = new ViewPanel(ct.results);
                            tabPanel.addTab("结果", createPage(viewPanel));
                            tabPanel.isSelectTabComponents("结果");
                        } else {
                            viewPanel.update(ct.results);
                        }
                        break;
                    case "onOrderFile":
                        // 按文件排序
                        ct.makeTable();
                        ct.ord(1);
                        if (!tabPanel.isSelectTabComponents("结果")) {
                            viewPanel = new ViewPanel(ct.results);
                            tabPanel.addTab("结果", createPage(viewPanel));
                            tabPanel.isSelectTabComponents("结果");
                        } else {
                            viewPanel.update(ct.results);
                        }
                        break;
                    case "onSetCppcheckRoad":
                        // cppcheck路径
                        jfsettings.setFileSelectionMode(0);// 设定只能选择到文件
//                    int state = jfsettings.showOpenDialog(null);
                        if (jfsettings.showOpenDialog(null) == 1) {
                            return; // 撤销则返回
                        } else {
                            File cppcheckFile = jfsettings.getSelectedFile();
                            String cppcheckPathTemp =
                                cppcheckFile.getAbsolutePath();
                            MyContorlUtil.fixSettingPath(settingsXML,
                                "cppcheck", cppcheckPathTemp);
                            changedpathcpp = true;
                        }
                        break;
                    case "onSetFlawfinderRoad":
                        // flawfinder路径
                        jfsettings.setFileSelectionMode(0);// 设定只能选择到文件
//                    int state = jfsettings.showOpenDialog(null);
                        if (jfsettings.showOpenDialog(null) == 1) {
                            return;// 撤销则返回
                        } else {
                            File flawfinderFile = jfsettings.getSelectedFile();
                            String flawfinderPathTemp =
                                flawfinderFile.getAbsolutePath();
                            MyContorlUtil.fixSettingPath(settingsXML,
                                "flawfinder", flawfinderPathTemp);
                            changedpathflaw = true;
                        }
                        break;
                }
            }
        });

        // 初始化主内容面板
        contentPanel = new MyContentPanel();
        try {
            initSwing();
        } catch (UnsupportedEncodingException e1) {
            e1.printStackTrace();
        }
    }

    public static void main(String[] args) throws ParserConfigurationException {

        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                MyContorlUtil.setupLookAndFeel();
                Main ui = new Main();
                ui.setVisible(true);
            }
        });
    }

    private void execute(String src, String para) {
        if (changedpathcpp) {
            MyContorlUtil.loadToolsRoad(settingsXML, this);
            changedpathcpp = false;
        }

        // 路径未配置,直接返回
        if (cppcheckPath == null) {
            return;
        }

        Runtime runtime = Runtime.getRuntime();
        Process p = null;
        Runtime runtime1 = Runtime.getRuntime();
        Process p1 = null;
        try {
            // 指定模板执行cppcheck,格式化输出信息
            p = runtime.exec(String.format(cppcheckPath +
                    " --template=\"cppcheck${file}${line}${severity}${id}${message}${cwe}\" %s %s",
                para, src));
            final InputStream is1 = p.getInputStream();
            final InputStream is2 = p.getErrorStream();

            // 不使用模板,捕获错误信息
            p1 =
                runtime.exec(String.format(cppcheckPath + " %s %s", para, src));
            System.out.printf(cppcheckPath + " %s %s%n", para, src);
            final InputStream is11 = p1.getInputStream();
            final InputStream is21 = p1.getErrorStream();

            // 处理标准输出
            new Thread() {
                @SuppressWarnings("resource")
                public void run() {

                    BufferedReader br1 =
                        new BufferedReader(new InputStreamReader(is1));
                    //StringBuilder l1 = new StringBuilder();
                    try {

                        String line1 = null;
                        int i = 0;
                        textCheck.setText("");
                        while ((line1 = br1.readLine()) != null) {
                            i++;
                            textCheck.append(i + " " + line1 + ENTERWindows);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                        System.out.println("inputError");
                    } finally {
                        try {
                            //textCheck.setText(new String(l1.toString().getBytes(), "utf-8"));
                            is1.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }.start();

            // 处理错误流
            new Thread() {
                public void run() {
                    BufferedReader br2 =
                        new BufferedReader(new InputStreamReader(is2));
                    StringBuilder l2 = new StringBuilder();
                    try {
                        String line2 = null;
                        while ((line2 = br2.readLine()) != null) {
                            ct.toRowsOfCppcheckResult(line2);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    } finally {
                        try {
                            is2.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }.start();

            // 第二次的错误流
            new Thread() {
                public void run() {
                    BufferedReader br2 =
                        new BufferedReader(new InputStreamReader(is21));
                    StringBuilder l2 = new StringBuilder();
                    cppcheckResult.setText("");
                    try {
                        String line2 = null;
                        int i = 0;
                        while ((line2 = br2.readLine()) != null) {
                            l2.append(i + " " + line2 + ENTERWindows);
                            i++;
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    } finally {
                        try {
                            cppcheckResult.setText(
                                new String(l2.toString().getBytes(),
                                    StandardCharsets.UTF_8));
                            is21.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }.start();

            // 等待两个进程结束
            int exitCode = p.waitFor();
            int exitCode1 = p1.waitFor();
            if (exitCode == SUCCESS) {
                System.out.println(SUCCESS_MESSAGE);

            } else {
                System.err.println(ERROR_MESSAGE + exitCode);
            }
            p.destroy();
            p1.destroy();
        } catch (Exception e) {
            try {
                // 出现异常则关闭相关流
                p.getErrorStream().close();
                p.getInputStream().close();
                p.getOutputStream().close();
                p1.getErrorStream().close();
                p1.getInputStream().close();
                p1.getOutputStream().close();
            } catch (Exception ee) {
            }
        }
        if (!tabPanel.isSelectTabComponents("结果")) {
            try {
                ct.makeTable();
                viewPanel = new ViewPanel(ct.results);
            } catch (Exception e1) {
                e1.printStackTrace();
                System.out.println("图表生成错误");
            }
            tabPanel.addTab("结果", createPage(viewPanel));
            tabPanel.isSelectTabComponents("结果");
        } else {
            try {
                ct.makeTable();
                viewPanel.update(ct.results);
            } catch (Exception e1) {
                e1.printStackTrace();
                System.out.println("图表生成错误");
            }
        }
    }

    private void execute2(String src) {
        // clamh-tidy 检查
        Runtime runtime = Runtime.getRuntime();
        Process p = null;
        try {
            // 修改为执行 clang-tidy
            String path = "C:\\MinGW\\include"; // FIXME: 需要修改为自己的路径
            Path srcPath = Paths.get(src);
            String execable;
            if (Files.isDirectory(srcPath)) {
                // 是目录,则检查这个目录下所有cpp文件
                execable = String.format(
                    "clang-tidy %s\\*.cpp --checks=* --header-filter=%s -- -std=c++17 -I %s",
                    src, src, path);
            } else {
                // 是文件,直接执行
                execable = String.format(
                    "clang-tidy %s --checks=* --header-filter=%s -- -std=c++17 -I %s",
                    src, src, path);
            }
            //String execable1 = String.format("clang-tidy %s --checks=* --header-filter=%s -- -std=c++17  -I %s", src, src, path);
            //String execable2 = String.format("clang-tidy %s\\*.cpp --checks=* --header-filter=%s -- -std=c++17  -I %s", src,src, path);
            //String execable = String.format("clang-tidy %s\\*.cpp --checks='*,misc-no-delete-this,-llvmlibc-restrict-system-libc-headers,-modernize-use-trailing-return-type' -- -std=c++17  -I %s", src, path);
            System.out.println(execable);

            // 执行
            p = runtime.exec(execable); // -- 表示之后是源文件
            final InputStream is1 = p.getInputStream(); // 标准输出流
            final InputStream is2 = p.getErrorStream(); // clang-tidy 的错误流

            // 处理标准输出
            new Thread() {
                public void run() {
                    BufferedReader br1 =
                        new BufferedReader(new InputStreamReader(is1));
                    StringBuilder l1 = new StringBuilder();
                    try {
                        String line1 = null;
                        while ((line1 = br1.readLine()) != null) {
                            // 只处理包含源文件路径的行
                            if (line1.contains(src)) {
                                l1.append(line1).append(ENTERWindows);
                                // 如果有需要,可以将标准输出进行处理
                                ct.toRowsOfClang(line1);
                            }
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    } finally {
                        try {
                            is1.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }.start();

            // FIXME: 这一部分是否必要?
            //new Thread() {
            //
            //
            //	public void run() {
            //		BufferedReader br2 = new BufferedReader(new InputStreamReader(is2));
            //		StringBuilder l2 = new StringBuilder();
            //		try {
            //			String line2 = null;
            //			int i = 0;
            //			clangResult.setText("");
            //			while ((line2 = br2.readLine()) != null) {
            //				l2.append(i + "  " + line2 + ENTERWindows);
            //				ct.toRowsOfClang(line2); // 可能需要根据 clang-tidy 的输出格式进行调整
            //				i++;
            //			}
            //		} catch (Exception e) {
            //			e.printStackTrace();
            //			System.out.println("inputError");
            //		} finally {
            //			try {
            //				clangResult.setText(l2.substring(0, l2.length()));
            //				is2.close();
            //			} catch (IOException e) {
            //				e.printStackTrace();
            //			}
            //		}
            //	}
            //}.start();

            int exitCode = p.waitFor();
            if (exitCode == SUCCESS) {
                System.out.println(SUCCESS_MESSAGE);

            } else {
                System.err.println(ERROR_MESSAGE + exitCode);
            }

            // 为什么需要关闭两次?
            p.destroy();
            p.destroy();
        } catch (Exception e) {
            try {
                p.getInputStream().close();
                p.getOutputStream().close();
                p.getErrorStream().close();
            } catch (Exception ee) {
            }
        }

        // 更新或者创建结果标签页,显示结果
        if (!tabPanel.isSelectTabComponents("结果")) {
            try {
                ct.makeTable();
                viewPanel = new ViewPanel(ct.results);
            } catch (Exception e1) {
                e1.printStackTrace();
                System.out.println("图表生成错误");
            }
            tabPanel.addTab("结果", createPage(viewPanel));
            tabPanel.isSelectTabComponents("结果");
        } else {
            try {
                ct.makeTable();
                viewPanel.update(ct.results);
            } catch (Exception e1) {
                e1.printStackTrace();
                System.out.println("图表生成错误");
            }
        }
    }

    private void execute3(String src, String para, String tmpFileName) {
        // flawfinder
        if (changedpathflaw) {
            MyContorlUtil.loadToolsRoad(settingsXML, this);
            changedpathflaw = false;
        }

        if (flawfinderPath == null) {
            return;
        }
        Runtime runtime = Runtime.getRuntime();
        Process p = null;
        Runtime runtime2 = Runtime.getRuntime();
        Process p2 = null;
        try {

            // 两个参数数组,一个是csv格式,一个是传入的参数
            String[] arguments =
                new String[] {"python", flawfinderPath, "--csv", src};
            String[] arguments2 =
                new String[] {"python", flawfinderPath, para, src};

            p = runtime.exec(arguments);
            p2 = runtime.exec(arguments2);
            final InputStream is1 = p.getInputStream();
            final InputStream is2 = p2.getInputStream();
            System.out.println(arguments2[1]);

            // csv结果添加到表格
            new Thread() {
                public void run() {
                    BufferedReader br1 =
                        new BufferedReader(new InputStreamReader(is1));
                    try {
                        String line1 = null;
                        while ((line1 = br1.readLine()) != null) {
                            ct.toRowsOfflawfinder(line1);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    } finally {
                        try {
                            is1.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }.start();

            // 普通结果显示在文本框
            new Thread() {
                public void run() {
                    //flawfinder result
                    BufferedReader br1 =
                        new BufferedReader(new InputStreamReader(is2));
                    StringBuilder l1 = new StringBuilder();
                    flawfinderResult.setText("");
                    try {
                        String line1 = null;
                        while ((line1 = br1.readLine()) != null) {
                            l1.append(line1 + ENTERWindows);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    } finally {
                        try {
                            flawfinderResult.setText(
                                l1.substring(0, l1.length()));
                            is2.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }.start();

            int exitCode = p.waitFor();
            int exitCode2 = p2.waitFor();
            if (exitCode == SUCCESS) {
                System.out.println(SUCCESS_MESSAGE);
            } else {
                System.err.println(ERROR_MESSAGE + exitCode);
            }
            p.destroy();
            p2.destroy();
        } catch (Exception e) {
            try {
                p.getErrorStream().close();
                p.getInputStream().close();
                p.getOutputStream().close();
                p2.getErrorStream().close();
                p2.getInputStream().close();
                p2.getOutputStream().close();
            } catch (Exception ee) {
            }
        }
        if (!tabPanel.isSelectTabComponents("结果")) {
            try {
                ct.makeTable();
                viewPanel = new ViewPanel(ct.results);
            } catch (Exception e1) {
                e1.printStackTrace();
                System.out.println("图表生成错误");
            }
            tabPanel.addTab("结果", createPage(viewPanel));
            tabPanel.isSelectTabComponents("结果");
        } else {
            try {
                ct.makeTable();
                viewPanel.update(ct.results);
            } catch (Exception e1) {
                e1.printStackTrace();
                System.out.println("图表生成错误");
            }
        }

    }

    private void initSwing() throws UnsupportedEncodingException {
        setTitle("Cppcheckplus");
        setDefaultCloseOperation(3); // 关闭窗口时退出程序
        setSize(1024, 768);

        // 设置窗口图标
        setIconImage(MyContorlUtil.getImage("control/images/logo2.png"));
        setContentPane(contentPanel);
        // 菜单栏在最上方
        contentPanel.add(menubar, "North");

        // 除却菜单栏之外的面板
        //JPanel centerPane = new JPanel(new BorderLayout());

        // 中间区域,除了菜单栏之外的所有内容
        MyPanel centerPane = new MyPanel(new BorderLayout());
        centerPane.setOpaque(true);
        //centerPane.setBackground(MyContorlUtil.CONTENT_PANE_BACKGROUND3);
        //centerPane.setBackground(MyContorlUtil.getImage("control/images/logo2.png"));
        centerPane.setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 0));
        contentPanel.add(centerPane, "Center");

        // 初始化各个标签页、侧边栏、目录树
        initTab();
        initTab2();
        initOutlookPanel();
        try {
            initShortcutPanel();
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        initTree();

        // 面板加入布局
        centerPane.add(outlookPanel, "West");
        centerPane.add(tabPanel, "Center");
        centerPane.add(shortcutPanel, "East");

        // 底部添加第二个标签页面板,用于显示检查结果
        contentPanel.add(tabPanel2, BorderLayout.SOUTH);
    }

    private void initTree() {
        tree = shortcutPanel.mytree;
        // 点击目录树节点,显示对应文件内容
        tree.setCode(textCode, this);
    }

    private void initOutlookPanel() {
        outlookPanel = new MyOutlookPanel(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String command = e.getActionCommand();
                System.out.println("Head:" + command);
            }

        }, new ListSelectionListener() {
            @Override
            public void valueChanged(ListSelectionEvent e) {
                boolean adjust = e.getValueIsAdjusting();
                if (!adjust) {
                    JList list = (JList) e.getSource();
                    Object[] selectionValues = list.getSelectedValues();
                    MyOutlookPanelListItem item =
                        (MyOutlookPanelListItem) selectionValues[0];
                    String command = item.getActionCommand();
                    if (command.equals("Chart2")) {
                        // 如果TabPanel不存在就create,否则就切换
                        if (!tabPanel.isSelectTabComponents("结果")) {
                            try {
                                ct.makeTable();
                                viewPanel = new ViewPanel(ct.results);
                            } catch (Exception e1) {
                                e1.printStackTrace();
                                System.out.println("图表生成错误");
                            }
                            tabPanel.addTab("结果", createPage(viewPanel));
                            tabPanel.isSelectTabComponents("结果");
                        }
                    } else if (command.equals("Map")) {
                        // 代码标签页
                        if (!tabPanel.isSelectTabComponents("代码")) {
                            tabPanel.addTab("代码", testCode);
                            tabPanel.isSelectTabComponents("代码");
                        }
                    } else if (command.equals("Process")) {
                        // 进度
                        if (!tabPanel.isSelectTabComponents("进度")) {
                            tabPanel.addTab("进度", textCheck);
                            tabPanel.isSelectTabComponents("进度");
                        }
                    }
                }
            }

        });
        // 根据XML配置文件加载Outlook面板内容
        MyContorlUtil.loadOutlookPanel(outlookPanelXML, outlookPanel);
    }

    private void initTab() {
        tabPanel = new MyTabPanel();
        tabPanel.addMouseListener(new MouseAdapter() {
            private boolean isMaximized() {
                return outlookPanel.isShrinked();
            }

            public void mouseClicked(MouseEvent e) {
                if (e.getClickCount() > 1) {
                    TabbedPaneUI ui = tabPanel.getUI();
                    int tabIndex =
                        ui.tabForCoordinate(tabPanel, e.getX(), e.getY());
                    if (tabIndex != -1) {
                        boolean maxed = isMaximized();
                        outlookPanel.setShrink(!maxed);
                        shortcutPanel.setShrink(!maxed);
                    }
                }
            }
        });

        testCode = new MyTextPanel();
        testPanel = new MyTextPanel1();
        viewPanel = new ViewPanel();
        textCode = testCode.getTextArea();
        textCheck = testPanel.getTextArea();
    }

    private void initTab2() {
        tabPanel2 = new MyTabPanel1();
        tabPanel2.addMouseListener(new MouseAdapter() {
            private boolean isMaximized() {
                return outlookPanel.isShrinked();
            }

            public void mouseClicked(MouseEvent e) {
                if (e.getClickCount() > 1) {
                    TabbedPaneUI ui = tabPanel2.getUI();
                    int tabIndex =
                        ui.tabForCoordinate(tabPanel2, e.getX(), e.getY());
                    if (tabIndex != -1) {
                        boolean maxed = isMaximized();
                        outlookPanel.setShrink(!maxed);
                        shortcutPanel.setShrink(!maxed);
                    }
                }
            }
        });

        flawfinderPanel = new MyTextPanel1();
        cppcheckPanel = new MyTextPanel1();
        clangPanel = new MyTextPanel1();
        flawfinderResult = flawfinderPanel.getTextArea();
        cppcheckResult = cppcheckPanel.getTextArea();
        clangResult = clangPanel.getTextArea();

        tabPanel2.addTab("cppcheck", createPage1(cppcheckPanel));
        tabPanel2.addTab("Clang", createPage1(clangPanel));
        tabPanel2.addTab("flawfinder", createPage1(flawfinderPanel));
    }

    private MyTabPage1 createPage1(JComponent pageContent) {
        MyTabPage1 page = new MyTabPage1(pageContent);
        return page;
    }

    private MyTabPage createPage(JComponent pageContent) {
        MyTabPage page = new MyTabPage(pageContent);
        return page;
    }

    //改造成目录树
    private void initShortcutPanel() throws UnsupportedEncodingException {
        shortcutPanel = new MyShortcutPanel();
        shortcutPanel.setTitle(
            new String("项目".getBytes(), StandardCharsets.UTF_8));
    }
}