java瘋狂演義----簡單java IDE工具

file:commonsjava

 1 package org.crazyit.editor.commons;
 2 
 3 import org.crazyit.editor.EditorFrame;
 4 import org.crazyit.editor.handler.add.AddHandler;
 5 
 6 /**
 7  * 添加的信息對象
 8  * 
 9  * @author yangenxiong yangenxiong2009@gmail.com
10  * @version  1.0
11  * <br/>網站: <a href="http://www.crazyit.org">瘋狂Java聯盟</a>
12  * <br>Copyright (C), 2009-2010, yangenxiong
13  * <br>This program is protected by copyright laws.
14  */
15 public class AddInfo {
16 
17     //字符串, 在新增界面的text前顯示, 例如: 文件名稱
18     private String info;
19     
20     //受新增操做影響的主frame
21     private EditorFrame editorFrame;
22     
23     //新增完後的處理類
24     private AddHandler handler;
25     
26     public AddInfo(String info, EditorFrame editorFrame, AddHandler handler) {
27         this.info = info;
28         this.editorFrame = editorFrame;
29         this.handler = handler;
30     }
31 
32     public AddHandler getHandler() {
33         return handler;
34     }
35 
36     public void setHandler(AddHandler handler) {
37         this.handler = handler;
38     }
39 
40     public String getInfo() {
41         return info;
42     }
43 
44     public void setInfo(String info) {
45         this.info = info;
46     }
47 
48     public EditorFrame getEditorFrame() {
49         return editorFrame;
50     }
51 
52     public void setEditorFrame(EditorFrame editorFrame) {
53         this.editorFrame = editorFrame;
54     }
55 
56 }
AddInfo
 1 package org.crazyit.editor.commons;
 2 
 3 import java.io.File;
 4 
 5 import javax.swing.JInternalFrame;
 6 
 7 import org.crazyit.editor.EditPane;
 8 
 9 /**
10  * 編輯的文件對象
11  * 
12  * @author yangenxiong yangenxiong2009@gmail.com
13  * @version  1.0
14  * <br/>網站: <a href="http://www.crazyit.org">瘋狂Java聯盟</a>
15  * <br>Copyright (C), 2009-2010, yangenxiong
16  * <br>This program is protected by copyright laws.
17  */
18 public class EditFile {
19 
20     //當前編輯的文件
21     private File file;
22     
23     //該文件是否已經被保存
24     private boolean saved;
25     
26     //該文件對應的窗口
27     private JInternalFrame iframe;
28     
29     //該文件所對應的編輯器
30     private EditPane editPane;
31     
32     public EditFile(File file, boolean saved, JInternalFrame iframe, 
33             EditPane editPane) {
34         this.file = file;
35         this.saved = saved;
36         this.iframe = iframe;
37         this.editPane = editPane;
38     }
39 
40     public EditPane getEditPane() {
41         return editPane;
42     }
43 
44     public void setEditPane(EditPane editPane) {
45         this.editPane = editPane;
46     }
47 
48     public JInternalFrame getIframe() {
49         return iframe;
50     }
51 
52 
53     public void setIframe(JInternalFrame iframe) {
54         this.iframe = iframe;
55     }
56 
57 
58     public boolean isSaved() {
59         return saved;
60     }
61 
62     public void setSaved(boolean saved) {
63         this.saved = saved;
64     }
65 
66     public File getFile() {
67         return file;
68     }
69 
70     public void setFile(File file) {
71         this.file = file;
72     }
73 
74     
75     
76 }
EditFile
 1 package org.crazyit.editor.commons;
 2 
 3 import java.io.File;
 4 
 5 import javax.swing.JInternalFrame;
 6 
 7 import org.crazyit.editor.EditPane;
 8 
 9 /**
10  * 編輯的文件對象
11  * 
12  * @author yangenxiong yangenxiong2009@gmail.com
13  * @version  1.0
14  * <br/>網站: <a href="http://www.crazyit.org">瘋狂Java聯盟</a>
15  * <br>Copyright (C), 2009-2010, yangenxiong
16  * <br>This program is protected by copyright laws.
17  */
18 public class EditFile {
19 
20     //當前編輯的文件
21     private File file;
22     
23     //該文件是否已經被保存
24     private boolean saved;
25     
26     //該文件對應的窗口
27     private JInternalFrame iframe;
28     
29     //該文件所對應的編輯器
30     private EditPane editPane;
31     
32     public EditFile(File file, boolean saved, JInternalFrame iframe, 
33             EditPane editPane) {
34         this.file = file;
35         this.saved = saved;
36         this.iframe = iframe;
37         this.editPane = editPane;
38     }
39 
40     public EditPane getEditPane() {
41         return editPane;
42     }
43 
44     public void setEditPane(EditPane editPane) {
45         this.editPane = editPane;
46     }
47 
48     public JInternalFrame getIframe() {
49         return iframe;
50     }
51 
52 
53     public void setIframe(JInternalFrame iframe) {
54         this.iframe = iframe;
55     }
56 
57 
58     public boolean isSaved() {
59         return saved;
60     }
61 
62     public void setSaved(boolean saved) {
63         this.saved = saved;
64     }
65 
66     public File getFile() {
67         return file;
68     }
69 
70     public void setFile(File file) {
71         this.file = file;
72     }
73 
74     
75     
76 }
WorkSpace

file:confignode

 1 package org.crazyit.editor.config;
 2 
 3 /**
 4  * 編譯配置對象
 5  * 
 6  * @author yangenxiong yangenxiong2009@gmail.com
 7  * @version  1.0
 8  * <br/>網站: <a href="http://www.crazyit.org">瘋狂Java聯盟</a>
 9  * <br>Copyright (C), 2009-2010, yangenxiong
10  * <br>This program is protected by copyright laws.
11  */
12 public class CompileConfig {
13 
14     //記錄源文件的目錄
15     public final static String SRC_DIR = "src";
16     
17     //記錄項目編譯目錄
18     public final static String OUTPUT_DIR = "classes";
19 }
CompileConfig

file:expectionwindows

 1 package org.crazyit.editor.exception;
 2 
 3 /**
 4  * 文件異常類
 5  * 
 6  * @author yangenxiong yangenxiong2009@gmail.com
 7  * @version  1.0
 8  * <br/>網站: <a href="http://www.crazyit.org">瘋狂Java聯盟</a>
 9  * <br>Copyright (C), 2009-2010, yangenxiong
10  * <br>This program is protected by copyright laws.
11  */
12 public class FileException extends RuntimeException {
13 
14     public FileException(String message) {
15         super(message);
16     }
17 }
Expection

file:handler數組

 1 package org.crazyit.editor.handler.add;
 2 
 3 import java.io.File;
 4 
 5 import javax.swing.JOptionPane;
 6 
 7 import org.crazyit.editor.AddFrame;
 8 import org.crazyit.editor.EditorFrame;
 9 import org.crazyit.editor.exception.FileException;
10 import org.crazyit.editor.tree.ProjectTreeModel;
11 import org.crazyit.editor.tree.ProjectTreeNode;
12 
13 /**
14  * 添加文件處理類
15  * 
16  * @author yangenxiong yangenxiong2009@gmail.com
17  * @version  1.0
18  * <br/>網站: <a href="http://www.crazyit.org">瘋狂Java聯盟</a>
19  * <br>Copyright (C), 2009-2010, yangenxiong
20  * <br>This program is protected by copyright laws.
21  */
22 public class AddFileHandler implements AddHandler {
23 
24     public void afterAdd(EditorFrame editorFrame, AddFrame addFrame, Object data) {
25         try {
26             //得到當前所選擇的樹節點
27             ProjectTreeNode selectNode = editorFrame.getSelectNode();
28             //獲取當前選擇節點所對應的文件
29             File folder = selectNode.getFile();
30             //若是folder不是一個目錄,則用selectNode的父節點(是一個目錄)做爲新文件的存放目錄
31             if (!folder.isDirectory()) {
32                 ProjectTreeNode parent = (ProjectTreeNode)selectNode.getParent();
33                 selectNode = parent;
34                 folder = parent.getFile();
35             }
36             //建立文件,放到folder下
37             File newFile = new File(folder.getAbsoluteFile() + File.separator + data);
38             //若是文件已經存在,就彈出提示並返回
39             if (newFile.exists()) {
40                 JOptionPane.showMessageDialog(addFrame, "文件已經存在");
41                 return;
42             }
43             newFile.createNewFile();
44             editorFrame.reloadNode(selectNode);
45             //使主編輯frame可用
46             editorFrame.setEnabled(true);
47             ///讓添加的frame不可見
48             addFrame.setVisible(false);
49         } catch (Exception e) {
50             throw new FileException("create file error: " + e.getMessage());
51         }
52     }
53 
54 }
AddFileHandler
 1 package org.crazyit.editor.handler.add;
 2 
 3 import java.io.File;
 4 
 5 import javax.swing.JOptionPane;
 6 
 7 import org.crazyit.editor.AddFrame;
 8 import org.crazyit.editor.EditorFrame;
 9 import org.crazyit.editor.exception.FileException;
10 import org.crazyit.editor.tree.ProjectTreeNode;
11 
12 /**
13  * 添加目錄處理類
14  * 
15  * @author yangenxiong yangenxiong2009@gmail.com
16  * @version  1.0
17  * <br/>網站: <a href="http://www.crazyit.org">瘋狂Java聯盟</a>
18  * <br>Copyright (C), 2009-2010, yangenxiong
19  * <br>This program is protected by copyright laws.
20  */
21 public class AddFolderHandler implements AddHandler {
22 
23     public void afterAdd(EditorFrame editorFrame, AddFrame addFrame, Object data) {
24         try {
25             //得到樹中所選取的節點
26             ProjectTreeNode selectNode = editorFrame.getSelectNode();
27             //獲取該節點所對應的文件對象
28             File folder = selectNode.getFile();
29             //若是folder不是一個目錄,則用selectNode的父節點(是一個目錄)做爲新目錄的父目錄
30             if (!folder.isDirectory()) {
31                 ProjectTreeNode parent = (ProjectTreeNode)selectNode.getParent();
32                 //讓當前所選擇的文件的父目錄做爲當前選擇的目錄
33                 selectNode = parent;
34                 folder = parent.getFile();
35             }
36             //建立一個文件目錄對象
37             File newFolder = new File(folder.getAbsoluteFile() + File.separator + data);
38             //若是該目錄已經存在,彈出提示並返回
39             if (newFolder.exists()) {
40                 JOptionPane.showMessageDialog(addFrame, "目錄已經存在");
41                 return;
42             }
43             //建立新的目錄
44             newFolder.mkdir();
45             //刷新樹的節點
46             editorFrame.reloadNode(selectNode);
47             //讓EditorFrame可用
48             editorFrame.setEnabled(true);
49             //讓添加的frame不可見
50             addFrame.setVisible(false);
51         } catch (Exception e) {
52             throw new FileException("create folder error: " + e.getMessage());
53         }
54     }
55 
56 }
AddFolderHandler
 1 package org.crazyit.editor.handler.add;
 2 
 3 import org.crazyit.editor.AddFrame;
 4 import org.crazyit.editor.EditorFrame;
 5 
 6 /**
 7  * 添加事件的接口
 8  * 
 9  * @author yangenxiong yangenxiong2009@gmail.com
10  * @version  1.0
11  * <br/>網站: <a href="http://www.crazyit.org">瘋狂Java聯盟</a>
12  * <br>Copyright (C), 2009-2010, yangenxiong
13  * <br>This program is protected by copyright laws.
14  */
15 public interface AddHandler {
16 
17     //新增完後須要作的事情,須要作的事情由實現類去實現
18     //參數爲EditorFrame,AddFrame,輸入的信息data
19     void afterAdd(EditorFrame editorFrame, AddFrame addFrame, Object data);
20 }
AddHandler
 1 package org.crazyit.editor.handler.add;
 2 
 3 import java.io.File;
 4 
 5 import javax.swing.JOptionPane;
 6 import javax.swing.JTree;
 7 
 8 import org.crazyit.editor.AddFrame;
 9 import org.crazyit.editor.EditorFrame;
10 import org.crazyit.editor.commons.WorkSpace;
11 import org.crazyit.editor.config.CompileConfig;
12 import org.crazyit.editor.exception.FileException;
13 
14 /**
15  * 添加項目處理類
16  * 
17  * @author yangenxiong yangenxiong2009@gmail.com
18  * @version  1.0
19  * <br/>網站: <a href="http://www.crazyit.org">瘋狂Java聯盟</a>
20  * <br>Copyright (C), 2009-2010, yangenxiong
21  * <br>This program is protected by copyright laws.
22  */
23 public class AddProjectHandler implements AddHandler {
24 
25     public void afterAdd(EditorFrame editorFrame, AddFrame addFrame, Object data) {
26         try {
27             //獲取工做空間所在的目錄
28             File spaceFolder = editorFrame.getWorkSpace().getFolder();
29             //建立.project文件
30             File projectFile = new File(spaceFolder.getAbsoluteFile() + 
31                     File.separator + data + ".project");
32             //建立項目目錄
33             File projectFolder = new File(spaceFolder.getAbsoluteFile() + File.separator + data);
34             //項目已經存在,彈出警告並返回
35             if (projectFile.exists() && projectFolder.exists()) {
36                 JOptionPane.showMessageDialog(addFrame, "項目已經存在");
37                 return;
38             }
39             //項目文件不存在, 建立項目文件
40             if (!projectFile.exists()) projectFile.createNewFile();
41             //項目目錄不存在, 建立項目文件目錄
42             if (!projectFolder.exists()) projectFolder.mkdir();
43             //建立項目的src目錄和編譯目錄
44             File src = new File(projectFolder.getAbsoluteFile() + 
45                     File.separator + CompileConfig.SRC_DIR);
46             //Java文件編譯的輸入目錄
47             File output = new File(projectFolder.getAbsoluteFile() + 
48                     File.separator + CompileConfig.OUTPUT_DIR);
49             //建立src和output兩個目錄
50             src.mkdir();
51             output.mkdir();
52             //刷新整棵樹
53             JTree newTree = editorFrame.getTreeCreator().createTree(editorFrame);
54             editorFrame.refreshTree(newTree); 
55             //讓EditorFrame變得可用
56             editorFrame.setEnabled(true);
57             //讓添加的frame不可見
58             addFrame.setVisible(false);
59         } catch (Exception e) {
60             throw new FileException("create project error: " + e.getMessage());
61         }
62     }
63 
64 }
AddProjectHandler

file:runapp

 1 package org.crazyit.editor.handler.run;
 2 
 3 import java.io.File;
 4 
 5 import org.crazyit.editor.EditorFrame;
 6 import org.crazyit.editor.config.CompileConfig;
 7 import org.crazyit.editor.util.CommandUtil;
 8 
 9 /**
10  * 運行Java文件處理類
11  * 
12  * @author yangenxiong yangenxiong2009@gmail.com
13  * @version  1.0
14  * <br/>網站: <a href="http://www.crazyit.org">瘋狂Java聯盟</a>
15  * <br>Copyright (C), 2009-2010, yangenxiong
16  * <br>This program is protected by copyright laws.
17  */
18 public class JavaRunHandler {
19 
20     public String run(EditorFrame editorFrame) {
21         try {
22             //得到項目目錄的路徑
23             String projectPath = editorFrame.getCurrentProject().getAbsolutePath();
24             //得到源文件的全路徑
25             String sourcePath = editorFrame.getCurrentFile().getFile().getAbsolutePath();
26             //得到項目的編譯路徑,項目目錄加CompileConfig中配置的輸出目錄
27             String classPath = editorFrame.getCurrentProject().getAbsolutePath() 
28                 + File.separator + CompileConfig.OUTPUT_DIR;
29             //獲取類名
30             String className = getClassName(projectPath, sourcePath);
31             //拼裝命令
32             String command = "java -cp \"" + classPath + "\" " + className;
33             Process p = CommandUtil.executeCommand(command);
34             return CommandUtil.getRunString(p);
35         } catch (Exception e) {
36             return e.getMessage();
37         }
38     }
39     
40     //根據項目目錄的路徑和Java源文件的路徑獲取一個類的全限定類名
41     private String getClassName(String projectPath, String sourcePath) {
42         String temp = projectPath + File.separator + CompileConfig.SRC_DIR + 
43         File.separator;
44         String result = sourcePath.replace(temp, "");
45         result = result.replace(".java", "");
46         result = result.replace(String.valueOf(File.separatorChar), ".");
47         return result;
48     }
49     
50 
51 }
JavaRunHandler

file:save編輯器

 1 package org.crazyit.editor.handler.save;
 2 
 3 import org.crazyit.editor.EditorFrame;
 4 import org.crazyit.editor.commons.EditFile;
 5 import org.crazyit.editor.util.FileUtil;
 6 
 7 /**
 8  * 執行普通保存的處理類
 9  * 
10  * @author yangenxiong yangenxiong2009@gmail.com
11  * @version  1.0
12  * <br/>網站: <a href="http://www.crazyit.org">瘋狂Java聯盟</a>
13  * <br>Copyright (C), 2009-2010, yangenxiong
14  * <br>This program is protected by copyright laws.
15  */
16 public class CommonSaveHandler implements SaveHandler {
17 
18     //提供一個保存方法,做爲普通的保存
19     public String save(EditorFrame editorFrame) {
20         EditFile editFile = editorFrame.getCurrentFile();
21         FileUtil.writeFile(editFile.getFile(), editFile.getEditPane().getText());
22         return null; 
23     }
24 
25 }
CommonSaveHandler
 1 package org.crazyit.editor.handler.save;
 2 
 3 import java.io.File;
 4 import java.io.FileWriter;
 5 import java.io.InputStream;
 6 
 7 import org.crazyit.editor.EditorFrame;
 8 import org.crazyit.editor.config.CompileConfig;
 9 import org.crazyit.editor.util.CommandUtil;
10 
11 /**
12  * 保存Java文件的處理類
13  * 
14  * @author yangenxiong yangenxiong2009@gmail.com
15  * @version  1.0
16  * <br/>網站: <a href="http://www.crazyit.org">瘋狂Java聯盟</a>
17  * <br>Copyright (C), 2009-2010, yangenxiong
18  * <br>This program is protected by copyright laws.
19  */
20 public class JavaSaveHandler extends CommonSaveHandler {
21 
22     
23     
24     public String save(EditorFrame editorFrame) {
25         //調用父類的保存方法
26         super.save(editorFrame);
27         return javac(editorFrame);
28     }
29 
30     //執行javac命令
31     private String javac(EditorFrame editorFrame) {
32         try {
33             //得到項目的編譯路徑,項目目錄加CompileConfig中配置的輸出目錄
34             String classPath = editorFrame.getCurrentProject().getAbsolutePath() 
35                 + File.separator + CompileConfig.OUTPUT_DIR;
36             //得到源文件的文件路徑
37             String filePath = editorFrame.getCurrentFile().getFile().getAbsolutePath();
38             //拼裝字符串命令,該命令只可在windows下運行
39             String command = "javac -d \"" + classPath + "\" \"" + filePath + "\"";
40             Process p = CommandUtil.executeCommand(command);
41             return CommandUtil.getProcessString(p);
42         } catch (Exception e) {
43             return e.getMessage();
44         }
45     }
46     
47 
48 }
JavaSaveHandler
 1 package org.crazyit.editor.handler.save;
 2 
 3 import org.crazyit.editor.EditorFrame;
 4 
 5 /**
 6  * 保存處理接口
 7  * 
 8  * @author yangenxiong yangenxiong2009@gmail.com
 9  * @version  1.0
10  * <br/>網站: <a href="http://www.crazyit.org">瘋狂Java聯盟</a>
11  * <br>Copyright (C), 2009-2010, yangenxiong
12  * <br>This program is protected by copyright laws.
13  */
14 public interface SaveHandler {
15 
16     //執行保存的接口方法
17     String save(EditorFrame editorFrame);
18 }
SaveHandler
 1 package org.crazyit.editor.handler.save;
 2 
 3 import org.crazyit.editor.EditorFrame;
 4 
 5 /**
 6  * 保存的中介者
 7  * 
 8  * @author yangenxiong yangenxiong2009@gmail.com
 9  * @version  1.0
10  * <br/>網站: <a href="http://www.crazyit.org">瘋狂Java聯盟</a>
11  * <br>Copyright (C), 2009-2010, yangenxiong
12  * <br>This program is protected by copyright laws.
13  */
14 public abstract class SaveMediator {
15 
16     //須要子類去實現的保存方法
17     public abstract String doSave(EditorFrame editorFramet);
18 }
SaveMediator
 1 package org.crazyit.editor.handler.save;
 2 
 3 import org.crazyit.editor.EditorFrame;
 4 import org.crazyit.editor.commons.EditFile;
 5 
 6 /**
 7  * 保存動做的中介者實現
 8  * 
 9  * @author yangenxiong yangenxiong2009@gmail.com
10  * @version  1.0
11  * <br/>網站: <a href="http://www.crazyit.org">瘋狂Java聯盟</a>
12  * <br>Copyright (C), 2009-2010, yangenxiong
13  * <br>This program is protected by copyright laws.
14  */
15 public class SaveMediatorConcrete extends SaveMediator {
16 
17     private SaveHandler commonHandler;
18     
19     private SaveHandler javaHandler;
20     
21     //構造兩個處理保存的對象
22     public SaveMediatorConcrete() {
23         this.commonHandler = new CommonSaveHandler();
24         this.javaHandler = new JavaSaveHandler();
25     }
26     
27     public String doSave(EditorFrame editorFrame) {
28         //得到當前編輯的文件名
29         String fileName = editorFrame.getCurrentFile().getFile().getName();
30         String result = null;
31         //判斷文件是否爲Java文件, 再決定處理類
32         if (fileName.endsWith(".java")) {//保存java文件
33             result = javaHandler.save(editorFrame);
34         } else {//執行普通的保存
35             result = commonHandler.save(editorFrame);
36         }
37         return result;
38     }
39 
40 }
SaveMediatorConcrete

file:treeide

 1 package org.crazyit.editor.tree;
 2 
 3 import javax.swing.tree.DefaultTreeModel;
 4 import javax.swing.tree.TreeNode;
 5 
 6 /**
 7  * 項目樹的Model對象
 8  * 
 9  * @author yangenxiong yangenxiong2009@gmail.com
10  * @version  1.0
11  * <br/>網站: <a href="http://www.crazyit.org">瘋狂Java聯盟</a>
12  * <br>Copyright (C), 2009-2010, yangenxiong
13  * <br>This program is protected by copyright laws.
14  */
15 public class ProjectTreeModel extends DefaultTreeModel {
16     
17     public ProjectTreeModel(ProjectTreeNode arg0) {
18         super(arg0);
19     }
20 
21     public void reload(ProjectTreeNode node, TreeCreator creator) {
22         //獲取node節點的父節點
23         ProjectTreeNode parent = (ProjectTreeNode)node.getParent();
24         //父節點爲null,返回,不須要reload
25         if (parent == null) return;
26         //獲取node節點在父節點的索引
27         int index = parent.getIndex(node);
28         //先裝node節點從parent中刪除
29         parent.remove(index);
30         //再經過TreeCreator獲取新的節點
31         node = creator.createNode(node.getFile());
32         //添加到父節點中
33         parent.insert(node, index);
34         //調用DefaultTreeModel的reload方法
35         super.reload(node);
36     }
37 
38     
39     
40     
41     
42 }
ProjectTreeModel
 1 package org.crazyit.editor.tree;
 2 
 3 import java.io.File;
 4 import java.util.ArrayList;
 5 import java.util.List;
 6 
 7 import javax.swing.tree.DefaultMutableTreeNode;
 8 
 9 /**
10  * 項目樹的節點對象
11  * 
12  * @author yangenxiong yangenxiong2009@gmail.com
13  * @version  1.0
14  * <br/>網站: <a href="http://www.crazyit.org">瘋狂Java聯盟</a>
15  * <br>Copyright (C), 2009-2010, yangenxiong
16  * <br>This program is protected by copyright laws.
17  */
18 public class ProjectTreeNode extends DefaultMutableTreeNode {
19 
20     //該節點對應的文件
21     private File file;
22     
23     //該節點下的子節點
24     private List<ProjectTreeNode> children;
25 
26     //ProjectTreeNode的構造器,參數分別時該節點對應的文件,是否容許有子節點
27     public ProjectTreeNode(File file, boolean allowsChildren) {
28         super(file.getName(), allowsChildren);
29         this.file = file;
30         //初始化該節點下的子節點集合
31         children = new ArrayList<ProjectTreeNode>();
32     }
33     
34     public File getFile() {
35         return file;
36     }
37 
38     public void setFile(File file) {
39         this.file = file;
40     }
41     
42     public List<ProjectTreeNode> getChildren() {
43         //清空children, 再從新獲取一次
44         children.removeAll(children);
45         for (int i = 0; i < getChildCount(); i++) {
46             children.add((ProjectTreeNode)getChildAt(i));
47         }
48         return this.children;
49     }
50 
51 
52 
53     
54     
55 }
ProjectTreeNode
 1 package org.crazyit.editor.tree;
 2 
 3 import java.awt.event.MouseAdapter;
 4 import java.awt.event.MouseEvent;
 5 
 6 import javax.swing.event.TreeSelectionEvent;
 7 
 8 import org.crazyit.editor.EditorFrame;
 9 
10 /**
11  * 項目樹選擇監聽器
12  * 
13  * @author yangenxiong yangenxiong2009@gmail.com
14  * @version  1.0
15  * <br/>網站: <a href="http://www.crazyit.org">瘋狂Java聯盟</a>
16  * <br>Copyright (C), 2009-2010, yangenxiong
17  * <br>This program is protected by copyright laws.
18  */
19 public class ProjectTreeSelectionListener extends MouseAdapter {
20 
21     //主界面的frame
22     private EditorFrame editorFrame;
23     
24     //將主界面的frame(EditorFrame)做爲構造參數傳入監聽器
25     public ProjectTreeSelectionListener(EditorFrame editorFrame) {
26         this.editorFrame = editorFrame;
27     }
28 
29     public void mousePressed(MouseEvent e) {
30         //獲得當前所選擇的節點
31         ProjectTreeNode selectNode = this.editorFrame.getSelectNode();
32         //若是沒有選擇節點,就返回
33         if (selectNode == null) return;
34         //若是選擇的是一個目錄,返回
35         if (selectNode.getFile().isDirectory()) return;
36         //使用EditorFrame的方法來打開文件
37         this.editorFrame.openFile(selectNode.getFile());
38     }
39 
40 }
ProjectTreeSelectionListener
 1 package org.crazyit.editor.tree;
 2 
 3 import java.io.File;
 4 
 5 import javax.swing.JTree;
 6 
 7 import org.crazyit.editor.EditorFrame;
 8 
 9 /**
10  * 樹建立接口
11  * 
12  * @author yangenxiong yangenxiong2009@gmail.com
13  * @version  1.0
14  * <br/>網站: <a href="http://www.crazyit.org">瘋狂Java聯盟</a>
15  * <br>Copyright (C), 2009-2010, yangenxiong
16  * <br>This program is protected by copyright laws.
17  */
18 public interface TreeCreator {
19 
20     /**
21      * 根據編輯的EditorFrame對象建立項目樹
22      * @param editorFrame
23      * @return
24      */
25     JTree createTree(EditorFrame editorFrame);
26     
27     /**
28      * 根據一個目錄建立它的節點
29      * @param folder
30      * @return
31      */
32     ProjectTreeNode createNode(File folder);
33 }
TreeCreator
  1 package org.crazyit.editor.tree;
  2 
  3 import java.io.File;
  4 import java.util.ArrayList;
  5 import java.util.List;
  6 
  7 import javax.swing.JTree;
  8 import javax.swing.tree.DefaultTreeCellRenderer;
  9 import javax.swing.tree.TreePath;
 10 
 11 import org.crazyit.editor.EditorFrame;
 12 import org.crazyit.editor.util.ImageUtil;
 13 
 14 /**
 15  * 樹建立實現類
 16  * 
 17  * @author yangenxiong yangenxiong2009@gmail.com
 18  * @version  1.0
 19  * <br/>網站: <a href="http://www.crazyit.org">瘋狂Java聯盟</a>
 20  * <br>Copyright (C), 2009-2010, yangenxiong
 21  * <br>This program is protected by copyright laws.
 22  */
 23 public class TreeCreatorImpl implements TreeCreator {
 24 
 25     
 26     @Override
 27     public JTree createTree(EditorFrame editorFrame) {
 28         File spaceFolder = editorFrame.getWorkSpace().getFolder();
 29         ProjectTreeNode root = new ProjectTreeNode(spaceFolder, true);
 30         ProjectTreeModel treeModel = new ProjectTreeModel(root);
 31         JTree tree = new JTree(treeModel);
 32         //獲取工做空間下面全部的目錄(即與有projectName.project相對應的目錄),也就是項目目錄
 33         List<File> projectFolders = getProjectFolders(spaceFolder);
 34         //遍歷項目目錄集合,併爲其建立子節點
 35         for (int i = 0; i < projectFolders.size(); i++) {
 36             //獲取循環中的目錄
 37             File projectFolder = projectFolders.get(i);
 38             //調用createNode建立它全部的子節點
 39             ProjectTreeNode node = createNode(projectFolder);
 40             //向根節點添加子節點(項目目錄)
 41             root.add(node);
 42         }
 43 
 44         //定製節點圖片
 45         DefaultTreeCellRenderer renderer = new DefaultTreeCellRenderer();
 46         //目錄打開時的圖片
 47         renderer.setOpenIcon(ImageUtil.getImageIcon(ImageUtil.FOLDER_OPEN));
 48         //節點沒有子節點的圖片
 49         renderer.setLeafIcon(ImageUtil.getImageIcon(ImageUtil.FILE));
 50         //目錄關閉時的圖片
 51         renderer.setClosedIcon(ImageUtil.getImageIcon(ImageUtil.FOLDER_CLOSE));
 52         //設置樹的部件處理類爲上面的renderer
 53         tree.setCellRenderer(renderer);
 54         //爲項目樹添加一個樹選擇監聽器
 55         tree.addMouseListener(new ProjectTreeSelectionListener(editorFrame));
 56         //建立根在項目樹中的路徑
 57         TreePath path = new TreePath(root);
 58         //讓樹默認展開根節點
 59         tree.expandPath(path);
 60         //設置樹的根節點不可見
 61         tree.setRootVisible(false);
 62         return tree;
 63     }
 64     
 65     /*
 66      * 根據一個目錄建立它的全部直接節點
 67      */
 68     private List<ProjectTreeNode> createNodes(File folder) {
 69         //獲取該目錄下的全部文件
 70         File[] files = folder.listFiles();
 71         List<ProjectTreeNode> result = new ArrayList<ProjectTreeNode>();
 72         //對該目錄下的全部文件的數組進行兩次遍歷
 73         for (File file : files) {
 74             //第一次遍歷,若是是目錄的話,就加入到結果集合中
 75             if (file.isDirectory()) {
 76                 result.add(new ProjectTreeNode(file, true));
 77             }
 78         }
 79         for (File file : files) {
 80             //第二次遍歷,若是非目錄的話,就加入到結果集合中
 81             if (!file.isDirectory()) {//再加普通文件
 82                 result.add(new ProjectTreeNode(file, false));
 83             }
 84         }
 85         return result;
 86     }
 87     
 88     //根據一個目錄去建立該目錄所對應的節點對象,該對象的全部的子節點都已經建立
 89     public ProjectTreeNode createNode(File folder) {
 90         //建立一個父節點,即本方法即將返回的節點對象
 91         ProjectTreeNode parent = null;
 92         //若是參數foler不是一個目錄的話,建立一個ProjectTreeNode對象並返回,代表它不容許擁有子節點
 93         if (!folder.isDirectory()) {
 94             return new ProjectTreeNode(folder, false);
 95         } else {
 96             //若是是一個目錄的話,則建立上面的parent,代表它是一個目錄,能夠擁有子節點
 97             parent = new ProjectTreeNode(folder, true);
 98         }
 99         //利用上面的parent節點去查找它下面全部的直接節點
100         List<ProjectTreeNode> nodes = createNodes(parent.getFile());
101         //獲取到parent下面的全部直接子節點後,再去循環遞歸調用本方法
102         for (ProjectTreeNode node : nodes) {
103             //遞歸建立子節點,並將返回的節點添加到parent中
104             parent.add(createNode(node.getFile()));
105         }
106         return parent;
107     }
108     
109     
110     /**
111      * 獲取工做空間目錄下全部的項目名稱
112      * @return
113      */
114     private List<String> getProjectNames(File spaceFolder) {
115         List<String> result = new ArrayList<String>();
116         for (File file : spaceFolder.listFiles()) {
117             if (file.getName().endsWith(".project")) {//取以.project結尾的文件
118                 result.add(file.getName().substring(0, file.getName().indexOf(".project")));
119             }
120         }
121         return result;
122     }
123     
124     /*
125      * 獲取工做空間目錄下全部的項目目錄
126      */
127     private List<File> getProjectFolders(File spaceFolder) {
128         List<String> projectNames = getProjectNames(spaceFolder);
129         List<File> result = new ArrayList<File>();
130         //獲取工做空間下面全部的文件
131         File[] files = spaceFolder.listFiles();
132         for (String projectName : projectNames) {
133             for (File file : files) {
134                 if (file.isDirectory()) {//若是工做空間下面的文件是目錄,再去判斷是不是項目目錄
135                     if (projectName.equals(file.getName())) {
136                         result.add(file);
137                     }
138                 }
139             }
140         }
141         return result;
142     }
143 }
TreeCreatorImpl

file: util工具

 1 package org.crazyit.editor.util;
 2 
 3 import java.io.File;
 4 import java.io.FileWriter;
 5 import java.io.IOException;
 6 import java.io.InputStream;
 7 
 8 /**
 9  * 命令工具類
10  * 
11  * @author yangenxiong yangenxiong2009@gmail.com
12  * @version  1.0
13  * <br/>網站: <a href="http://www.crazyit.org">瘋狂Java聯盟</a>
14  * <br>Copyright (C), 2009-2010, yangenxiong
15  * <br>This program is protected by copyright laws.
16  */
17 public class CommandUtil {
18     
19     public final static String WINDOWS_COMMAND = "cmd /c ";
20     
21     //返回進程process的錯誤信息
22     public static String getErrorMessage(Process process) {
23         return getProcessString(process.getErrorStream());
24     }
25     
26     private static String getProcessString(InputStream is) {
27         try {
28             StringBuffer buffer = new StringBuffer();
29             byte[] b = new byte[4096];
30             for (int n; (n = is.read(b)) != -1;)  
31                 buffer.append(new String(b, 0, n));
32             is.close();
33             return buffer.toString();
34         } catch (Exception e) {
35             return e.getMessage();
36         }
37     }
38     
39     //獲取一個進程的錯誤信息
40     public static String getProcessString(Process process) {
41         StringBuffer result = new StringBuffer();
42         //調用CommandUtil的方法
43         String errorString = getErrorMessage(process);
44         if (errorString.length() != 0) result.append("錯誤: " + errorString);
45         else result.append("執行完成");
46         return result.toString();
47     }
48     
49     //返回一個進程的信息
50     public static String getRunString(Process process) {
51         String error = getErrorMessage(process);
52         String message = getProcessString(process.getInputStream());
53         return error + message;
54     }
55     
56     //執行一個命令並返回相應的信息
57     public static Process executeCommand(String command) {
58         try {
59             //在windows下將命令生成一份bat文件, 再執行該bat文件
60             File batFile = new File("dump.bat");
61             if (!batFile.exists()) batFile.createNewFile();
62             //將命令寫入文件中
63             FileWriter writer = new FileWriter(batFile);
64             writer.write(command);
65             writer.close();
66             //執行該bat文件
67             Process process =Runtime.getRuntime().exec(WINDOWS_COMMAND + batFile.getAbsolutePath());
68             process.waitFor();
69             //將bat文件刪除
70             batFile.delete();
71             return process;
72         } catch (Exception e) {
73             return null;
74         }
75     }
76 }
CommandUtil
 1 package org.crazyit.editor.util;
 2 
 3 import java.io.File;
 4 import java.io.FileInputStream;
 5 import java.io.FileOutputStream;
 6 import java.io.IOException;
 7 import java.io.PrintStream;
 8 
 9 import javax.swing.JTextArea;
10 
11 import org.crazyit.editor.exception.FileException;
12 
13 /**
14  * 文件處理工具類
15  * 
16  * @author yangenxiong yangenxiong2009@gmail.com
17  * @version  1.0
18  * <br/>網站: <a href="http://www.crazyit.org">瘋狂Java聯盟</a>
19  * <br>Copyright (C), 2009-2010, yangenxiong
20  * <br>This program is protected by copyright laws.
21  */
22 public class FileUtil {
23     
24     //讀取一個文件的內容
25     public static String readFile(File file) {
26         StringBuffer result = new StringBuffer();
27         try    {
28             //使用IO流讀取文件
29             FileInputStream fis= new FileInputStream(file);
30             String content = null;
31             byte[] arr = new byte[1024];
32             int readLength ;
33             while ((readLength = fis.read(arr)) > 0) {
34                 content = new String(arr, 0, readLength);
35                 result.append(content);
36             }
37             fis.close();
38         }
39         catch(IOException e) {
40             throw new FileException("read '" + file.getAbsolutePath() + "' file error");
41         }
42         return result.toString();
43     }
44     
45     //使用IO流將參數content寫入到參數file中
46     public static void writeFile(File file, String content) {
47         try {
48             FileOutputStream fos = new FileOutputStream(file);
49             PrintStream ps = new PrintStream(fos);
50             ps.print(content);
51             ps.close();
52             fos.close();
53         } catch (IOException e) {
54             throw new FileException("write file error");
55         }
56     }
57 }
FileUtil
 1 package org.crazyit.editor.util;
 2 
 3 import java.awt.Image;
 4 import java.io.File;
 5 
 6 import javax.imageio.ImageIO;
 7 import javax.swing.ImageIcon;
 8 
 9 /**
10  * 圖片工具類
11  * 
12  * @author yangenxiong yangenxiong2009@gmail.com
13  * @version  1.0
14  * <br/>網站: <a href="http://www.crazyit.org">瘋狂Java聯盟</a>
15  * <br>Copyright (C), 2009-2010, yangenxiong
16  * <br>This program is protected by copyright laws.
17  */
18 public class ImageUtil {
19     
20     //目錄關閉圖片
21     public static String FOLDER_CLOSE = "images/folder-close.gif";
22     //目錄打開圖片
23     public static String FOLDER_OPEN = "images/folder-open.gif";
24     //無子節點的文件圖片
25     public static String FILE = "images/file.gif";
26     //使用ImageIO流讀取圖片
27     public static Image getImage(String path) {
28         try {
29             return ImageIO.read(new File(path));
30         } catch (Exception e) {
31             e.printStackTrace();
32             return null;
33         }
34     }
35     
36     public static ImageIcon getImageIcon(String path) {
37         return new ImageIcon(getImage(path));
38     }
39 }
ImageUtil

file:src佈局

  1 package org.crazyit.editor;
  2 
  3 import java.awt.event.ActionEvent;
  4 import java.awt.event.ActionListener;
  5 import java.awt.event.KeyAdapter;
  6 import java.awt.event.KeyEvent;
  7 import java.awt.event.WindowAdapter;
  8 
  9 import javax.swing.BoxLayout;
 10 import javax.swing.JButton;
 11 import javax.swing.JFrame;
 12 import javax.swing.JLabel;
 13 import javax.swing.JPanel;
 14 import javax.swing.JTextField;
 15 
 16 import org.crazyit.editor.commons.AddInfo;
 17 
 18 /**
 19  * 添加界面
 20  * 
 21  * @author yangenxiong yangenxiong2009@gmail.com
 22  * @version  1.0
 23  * <br/>網站: <a href="http://www.crazyit.org">瘋狂Java聯盟</a>
 24  * <br>Copyright (C), 2009-2010, yangenxiong
 25  * <br>This program is protected by copyright laws.
 26  */
 27 public class AddFrame extends JFrame {
 28 
 29     //該Frame的JPanel
 30     private JPanel mainPanel;
 31     
 32     //項目名稱
 33     private JPanel namePanel;
 34     
 35     //顯示文件的JLabel
 36     private JLabel nameLabel;
 37     
 38     //輸入名稱的JTextField
 39     private JTextField nameText;
 40     
 41     //放按鈕的Panel
 42     private JPanel buttonPanel;
 43     
 44     //肯定按鈕
 45     private JButton confirmButton;
 46     
 47     //取消按鈕
 48     private JButton cancelButton;
 49     
 50     
 51     public AddFrame(final AddInfo info) {
 52         mainPanel = new JPanel();
 53         namePanel = new JPanel();
 54         //設置nameLabel的文字
 55         nameLabel = new JLabel(info.getInfo());
 56         nameText = new JTextField("", 20);
 57         buttonPanel = new JPanel();
 58         confirmButton = new JButton("肯定");
 59         cancelButton = new JButton("取消");
 60         
 61         mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
 62         addWindowListener(new WindowAdapter() {
 63             public void windowClosing(java.awt.event.WindowEvent e) {
 64                 cancel(info);
 65             }
 66         });
 67         setLocation(200, 200);
 68         setResizable(false);
 69         //文本框前面的字
 70         namePanel.setLayout(new BoxLayout(namePanel, BoxLayout.X_AXIS));        
 71         namePanel.add(nameLabel);
 72         namePanel.add(nameText);
 73         nameText.addKeyListener(new KeyAdapter() {
 74             public void keyReleased(KeyEvent e) {
 75                 //判斷項目路徑與名稱是否有值, 若是兩個text field都有值, 則肯定按鈕可用
 76                 if (nameText.getText().equals("")) {
 77                     confirmButton.setEnabled(false);
 78                 } else {
 79                     confirmButton.setEnabled(true);
 80                 }
 81             }
 82         });
 83         
 84         //肯定和取消的按鈕
 85         buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.X_AXIS));
 86         confirmButton.setEnabled(false);
 87         buttonPanel.add(confirmButton);
 88         buttonPanel.add(new JLabel("    "));
 89         buttonPanel.add(cancelButton);
 90         
 91         //爲取消按鈕添加監聽器
 92         cancelButton.addActionListener(new ActionListener(){
 93             public void actionPerformed(ActionEvent e) {
 94                 cancel(info);
 95             }
 96         });
 97         //爲肯定按鈕添加監聽器
 98         confirmButton.addActionListener(new ActionListener() {
 99             public void actionPerformed(ActionEvent e) {
100                 //若是輸入框沒有值,返回
101                 if (nameText.getText() == "") return;
102                 handerConfirm(info);
103             }
104         });
105         mainPanel.add(namePanel);
106         mainPanel.add(buttonPanel);
107         add(mainPanel);
108         pack();
109     }
110     
111     //處理肯定按鈕的點擊
112     private void handerConfirm(AddInfo info) {
113         //獲取得用戶輸入
114         String data = nameText.getText();
115         //新增後會涉及的一些與業務相關的操做留給Handler類處理
116         info.getHandler().afterAdd(info.getEditorFrame(), this, data);
117     }
118     
119     private void cancel(AddInfo info) {
120         //設置EditorFrame可用
121         info.getEditorFrame().setEnabled(true);
122         //讓本窗口不可見
123         setVisible(false);
124     }
125     
126 
127     
128 }
AddFrame
 1 package org.crazyit.editor;
 2 
 3 import javax.swing.event.DocumentEvent;
 4 import javax.swing.event.DocumentListener;
 5 
 6 /**
 7  * 文檔監聽器
 8  * 
 9  * @author yangenxiong yangenxiong2009@gmail.com
10  * @version  1.0
11  * <br/>網站: <a href="http://www.crazyit.org">瘋狂Java聯盟</a>
12  * <br>Copyright (C), 2009-2010, yangenxiong
13  * <br>This program is protected by copyright laws.
14  */
15 public class EditDocumentListener implements DocumentListener {
16     //主界面對象
17     private EditorFrame editorFrame;
18     public EditDocumentListener(EditorFrame editorFrame) {
19         this.editorFrame = editorFrame;
20     }
21     public void changedUpdate(DocumentEvent e) {
22     }
23     public void insertUpdate(DocumentEvent e) {
24         //設置當前編輯的文件的saved屬性爲false
25         this.editorFrame.getCurrentFile().setSaved(false);
26     }
27     public void removeUpdate(DocumentEvent e) {
28     }
29 }
EditDocumentListener
  1 package org.crazyit.editor;
  2 
  3 import java.awt.BorderLayout;
  4 import java.awt.Color;
  5 import java.awt.Insets;
  6 import java.awt.event.ActionEvent;
  7 import java.awt.event.InputEvent;
  8 import java.io.File;
  9 import java.util.ArrayList;
 10 import java.util.List;
 11 
 12 import javax.swing.AbstractAction;
 13 import javax.swing.Action;
 14 import javax.swing.Box;
 15 import javax.swing.BoxLayout;
 16 import javax.swing.ImageIcon;
 17 import javax.swing.JDesktopPane;
 18 import javax.swing.JFileChooser;
 19 import javax.swing.JFrame;
 20 import javax.swing.JInternalFrame;
 21 import javax.swing.JMenu;
 22 import javax.swing.JMenuBar;
 23 import javax.swing.JOptionPane;
 24 import javax.swing.JScrollPane;
 25 import javax.swing.JSplitPane;
 26 import javax.swing.JTabbedPane;
 27 import javax.swing.JTextArea;
 28 import javax.swing.JToolBar;
 29 import javax.swing.JTree;
 30 import javax.swing.KeyStroke;
 31 import javax.swing.tree.TreePath;
 32 
 33 import org.crazyit.editor.commons.AddInfo;
 34 import org.crazyit.editor.commons.EditFile;
 35 import org.crazyit.editor.commons.WorkSpace;
 36 import org.crazyit.editor.handler.add.AddFileHandler;
 37 import org.crazyit.editor.handler.add.AddFolderHandler;
 38 import org.crazyit.editor.handler.add.AddProjectHandler;
 39 import org.crazyit.editor.handler.run.JavaRunHandler;
 40 import org.crazyit.editor.handler.save.SaveMediator;
 41 import org.crazyit.editor.handler.save.SaveMediatorConcrete;
 42 import org.crazyit.editor.tree.ProjectTreeModel;
 43 import org.crazyit.editor.tree.ProjectTreeNode;
 44 import org.crazyit.editor.tree.TreeCreator;
 45 
 46 /**
 47  * 編輯界面
 48  * 
 49  * @author yangenxiong yangenxiong2009@gmail.com
 50  * @version  1.0
 51  * <br/>網站: <a href="http://www.crazyit.org">瘋狂Java聯盟</a>
 52  * <br>Copyright (C), 2009-2010, yangenxiong
 53  * <br>This program is protected by copyright laws.
 54  */
 55 public class EditorFrame extends JFrame {
 56     
 57     //多文件的tab標題
 58     private JTabbedPane tabPane;
 59     
 60     //存放tabPane與desk
 61     private Box box;
 62     
 63     //建立一個多文檔的桌面容器
 64     private JDesktopPane desk;
 65     
 66     //用於分隔主編輯區和信息顯示區的容器
 67     private JSplitPane editorSplitPane;
 68     
 69     //能夠滾動的JScrollPane對象,用於放infoArea
 70     private JScrollPane infoPane;
 71     
 72     //用於顯示信息的文本域
 73     private JTextArea infoArea;
 74     
 75     //存放樹的可滾動容器
 76     private JScrollPane treePane;
 77     
 78     //整個界面的分隔組件的容器
 79     private JSplitPane mainSplitPane;
 80     
 81     //項目樹對象
 82     private JTree tree;
 83     
 84     //菜單欄對象
 85     private JMenuBar menuBar;
 86     
 87     //編輯菜單對象
 88     private JMenu editMenu;
 89     
 90     //文件菜單
 91     private JMenu fileMenu;
 92     
 93     //工具條
 94     private JToolBar toolBar;
 95     
 96     private WorkSpace workSpace;
 97     
 98     private TreeCreator treeCreator;
 99     
100     //添加的界面
101     private AddFrame addFrame;
102     
103     //文件選擇器
104     private FileChooser fileChooser;
105     
106     //當前正在編輯的文件對象
107     private EditFile currentFile;
108     
109     //窗口監聽器
110     private IFrameListener iframeListener;
111     
112     //打開文件的集合
113     private List<EditFile> openFiles = new ArrayList<EditFile>();
114 
115     //中介者對象
116     private SaveMediator saveMediator;
117     
118     //運行class文件的處理類
119     private JavaRunHandler runHandler;
120     
121     //新建文件的Action對象
122     private Action fileNew = new AbstractAction("新建文件", new ImageIcon("images/newFile.gif")) {
123         public void actionPerformed(ActionEvent e) {
124             newFile();
125         }
126     };
127     //新建目錄的Action對象
128     private Action folerNew = new AbstractAction("新建目錄", new ImageIcon("images/newFile.gif")) {
129         public void actionPerformed(ActionEvent e) {
130             newFolder();
131         }
132     };
133     //新建項目的Action對象
134     private Action projectNew = new AbstractAction("新建項目", new ImageIcon("images/newFile.gif")) {
135         public void actionPerformed(ActionEvent e) {
136             newProject();
137         }
138     };
139     //打開文件的Action對象
140     private Action open = new AbstractAction("打     開", new ImageIcon("images/open.gif")) {
141         public void actionPerformed(ActionEvent e) {
142             selectFile();
143         }
144     };
145     //保存文件的Action對象
146     private Action save = new AbstractAction("保     存", new ImageIcon("images/save.gif")) {
147         public void actionPerformed(ActionEvent e) {
148             saveFile(getCurrentFile());
149         }
150     };
151     //刷新樹的Action對象
152     private Action refresh = new AbstractAction("刷     新", new ImageIcon("images/refresh.gif")) {
153         public void actionPerformed(ActionEvent e) {
154             reloadNode(getSelectNode());
155         }
156     };
157     //運行文件的Action對象
158     private Action run = new AbstractAction("運     行", new ImageIcon("images/run.gif")) {
159         public void actionPerformed(ActionEvent e) {
160             run();
161         }
162     };
163     //退出的Action對象
164     private Action exit = new AbstractAction("退     出") {
165         public void actionPerformed(ActionEvent e) {
166             System.exit(0);//直接退出
167         }
168     };
169     //複製文本的Action對象
170     private Action copy = new AbstractAction("復     制", new ImageIcon("images/copy.gif")) {
171         public void actionPerformed(ActionEvent e) {
172             if (getCurrentFile() != null) {
173                 getCurrentFile().getEditPane().copy();
174             }
175         }
176     };
177     //剪切文本的Action對象
178     private Action cut = new AbstractAction("剪     切", new ImageIcon("images/cut.gif")) {
179         public void actionPerformed(ActionEvent e) {
180             if (getCurrentFile() != null) {
181                 getCurrentFile().getEditPane().cut();
182             }
183         }
184     };
185     //粘貼文本的Action對象
186     private Action paste = new AbstractAction("粘     貼", new ImageIcon("images/paste.gif")) {
187         public void actionPerformed(ActionEvent e) {
188             if (getCurrentFile() != null) {
189                 getCurrentFile().getEditPane().paste();
190             }
191         }
192     };
193     
194     public EditorFrame(String title, TreeCreator treeCreator) {
195         super(title); //設置標題
196         this.treeCreator = treeCreator;
197         this.iframeListener = new IFrameListener(this);
198         this.saveMediator = new SaveMediatorConcrete();
199         this.runHandler = new JavaRunHandler();
200     }
201     
202     public void initFrame(WorkSpace space) {
203         this.workSpace = space;
204         //設置窗口關閉,退出程序
205         setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
206         //建立主編輯區的tabPane
207         tabPane = new JTabbedPane(JTabbedPane.TOP, JTabbedPane.SCROLL_TAB_LAYOUT );
208         desk = new JDesktopPane();//建立JDesktopPane對象
209         desk.setBackground(Color.GRAY);//設置desk的背景顏色爲灰色
210         box = new Box(BoxLayout.Y_AXIS);//設置box的佈局
211         box.add(tabPane);
212         box.add(desk);
213         //建立信息顯示區的文本域
214         infoArea = new JTextArea("", 5, 50);
215         //將infoArea文本域做爲組件放到infoPane中
216         infoPane = new JScrollPane(infoArea);
217         //設置信息區不可編輯
218         infoArea.setEditable(false);
219         //建立這個分隔組件的容器,並將box對象和infoPane放置其中
220         editorSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, box, infoPane);
221         editorSplitPane.setDividerSize(3);
222         editorSplitPane.setDividerLocation(500);
223         //建立樹
224         tree = treeCreator.createTree(this);
225         //建立可滾動的容器對象
226         treePane = new JScrollPane(tree);
227         //建立主界面的JSplitPane,橫向,左邊爲treePane,右邊爲editorSplitPane
228         mainSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, treePane, 
229                 editorSplitPane);
230         //設置分隔條的位置
231         mainSplitPane.setDividerLocation(200);
232         //設置分隔條的粗細
233         mainSplitPane.setDividerSize(3);
234         add(mainSplitPane);
235         
236         //建立菜單欄對象
237         menuBar = new JMenuBar();
238         //建立編輯菜單對象
239         editMenu = new JMenu("編輯");
240         //建立文件菜單
241         fileMenu = new JMenu("文件");
242         //將文件菜單添加到菜單欄中
243         menuBar.add(fileMenu);
244         //將編輯菜單添加到菜單欄中
245         menuBar.add(editMenu);
246         //設置JFrame的菜單欄
247         setJMenuBar(menuBar);
248         
249         toolBar = new JToolBar();
250         toolBar.setFloatable(false);//設置工具欄不可移動
251         toolBar.setMargin(new Insets(0, 10, 5, 5));//設置工具欄的邊距
252         add(toolBar, BorderLayout.NORTH);//將工具欄添加到EditorFrame中
253         
254         pack();//使JFrame調整最佳大小
255         addListeners();
256     }
257     
258     public TreeCreator getTreeCreator() {
259         return treeCreator;
260     }
261     
262     //爲EditorFrame中的組件添加監聽器
263     public void addListeners() {
264         //新建文件的監聽器
265         fileMenu.add(fileNew).setAccelerator(KeyStroke.getKeyStroke('N', InputEvent.CTRL_MASK));
266         //新建目錄的監聽器
267         fileMenu.add(folerNew).setAccelerator(KeyStroke.getKeyStroke('F', InputEvent.CTRL_MASK));
268         //新建項目的監聽器
269         fileMenu.add(projectNew).setAccelerator(KeyStroke.getKeyStroke('P', InputEvent.CTRL_MASK));
270         //打開菜單添加監聽器
271         fileMenu.add(open).setAccelerator(KeyStroke.getKeyStroke('O', InputEvent.CTRL_MASK));
272         //爲保存菜單添加監聽器
273         fileMenu.add(save).setAccelerator(KeyStroke.getKeyStroke('S', InputEvent.CTRL_MASK));
274         //爲刷新菜單添加監聽器
275         fileMenu.add(refresh).setAccelerator(KeyStroke.getKeyStroke("F5"));
276         //爲運行菜單添加監聽器
277         fileMenu.add(run).setAccelerator(KeyStroke.getKeyStroke('R', InputEvent.CTRL_MASK));
278         fileMenu.add(exit);
279         //添加複製監聽器
280         editMenu.add(copy).setAccelerator(KeyStroke.getKeyStroke('C', InputEvent.CTRL_MASK));
281         //添加剪切監聽器
282         editMenu.add(cut).setAccelerator(KeyStroke.getKeyStroke('X', InputEvent.CTRL_MASK));
283         //添加粘貼監聽器
284         editMenu.add(paste).setAccelerator(KeyStroke.getKeyStroke('V', InputEvent.CTRL_MASK));
285     
286         //爲工具條添加各個操做
287         toolBar.add(fileNew).setToolTipText("新建文件");
288         toolBar.add(open).setToolTipText("打開");
289         toolBar.add(save).setToolTipText("保存");
290         toolBar.add(refresh).setToolTipText("刷新");
291         toolBar.add(run).setToolTipText("運行");
292         toolBar.add(copy).setToolTipText("複製");
293         toolBar.add(cut).setToolTipText("剪切");
294         toolBar.add(paste).setToolTipText("粘貼");
295         
296         //爲tabPane添加監聽器
297         tabPane.addChangeListener(new TabListener(this));
298     }
299     
300     //獲取編輯器主界面項目樹中所選中的節點
301     public ProjectTreeNode getSelectNode() {
302         //得到當前樹選擇的節點在樹中的路徑
303         TreePath path = tree.getSelectionPath();
304         //若是當前選擇了節點
305         if (path != null) {
306             //建立一個ProjectTreeNode對象並用於返回
307             ProjectTreeNode selectNode = (ProjectTreeNode)path.getLastPathComponent();
308             return selectNode;
309         }
310         //當前沒有選擇節就返回null
311         return null;
312     }
313     
314     //顯示iframe對象
315     public void showIFrame(JInternalFrame iframe) {
316         try {
317             iframe.setSelected(true);
318             iframe.toFront();
319         } catch (Exception ex) {
320         }
321     }
322     
323     //打開文件的方法
324     public void openFile(File file) {
325         if (currentFile != null) {
326             //若是參數file是當前正在編輯的文件
327             if (file.equals(currentFile.getFile())) return;
328         }
329         //在打開文件的集合中查找該文件, 再判斷該文件是否已經打開
330         EditFile openedFile = getOpenFile(file);
331         //若是文件已經打開了,調用打開方法(打開已經在編輯tab頁面中顯示的文件)
332         if (openedFile != null) {
333             openExistFile(openedFile, file);
334             return;
335         }
336         //打開新的文件
337         openNewFile(file);
338     }
339     
340     //從本類中記錄已經打開的文件集合中獲得與參數file同樣的EditFile對象
341     private EditFile getOpenFile(File file) {
342         for (EditFile openFile : openFiles) {
343             if (openFile.getFile().equals(file)) return openFile;
344         }
345         return null;
346     }
347     
348     //根據參數file獲取該file對應的tab頁中的索引
349     private int getFileIndex(File file) {
350         //若是從打開文件的集合中找不到與參數file對應的EditFile對象,返回-1
351         EditFile openFile = getEditFile(file);
352         if (openFile == null) return -1;
353         return getTabIndex(openFile.getIframe().getToolTipText());
354     }
355     
356     //在打開的文件中得到文件是file的EditFile對象
357     private EditFile getEditFile(File file) {
358         for (EditFile openFile : openFiles) {
359             if (openFile.getFile().equals(file)) return openFile;
360         }
361         return null;
362     }
363     
364     //根據tab頁中的tips找到所對應的在tabPane的索引
365     public int getTabIndex(String tips) {
366         for (int i = 0; i < this.tabPane.getTabCount(); i++) {
367             if (this.tabPane.getToolTipTextAt(i).equals(tips)) return i;
368         }
369         return -1;
370     }
371     
372     //打開已經存在的文件(已經在編輯文件集合中的文件),openFiles集合中的文件
373     public void openExistFile(EditFile openedFile, File willOpenFile) {
374         //將tab頁變成當前所選擇文件的索引
375         tabPane.setSelectedIndex(getFileIndex(willOpenFile));
376         //顯示iframe
377         showIFrame(openedFile.getIframe());
378         //設置當前打開文件
379         this.currentFile = openedFile;
380         //添加到當前打開的文件集合中
381         this.openFiles.add(openedFile);
382     }
383     
384     //打開一個不在編輯集合中的文件
385     public void openNewFile(File file) {
386         //設置EditorFrame的標題爲該文件的全路徑
387         setTitle(file.getAbsolutePath());
388         //建立一個JInternalFrame對象,title爲文件的絕對路徑
389         JInternalFrame iframe = new JInternalFrame(file.getAbsolutePath(), true, true, true, true);
390         
391         //新建一個EditPane對象
392         EditPane editPane = new EditPane(file);
393         
394         //爲EditPane添加鍵盤監聽器
395         editPane.getDocument().addDocumentListener(new EditDocumentListener(this));
396         iframe.add(new JScrollPane(editPane));
397         //爲JInternalFrame添加窗口監聽器
398         iframe.addInternalFrameListener(this.iframeListener);
399         desk.add(iframe);
400         iframe.show();
401         iframe.reshape(0, 0, 400, 300);
402         tabPane.addTab(file.getName(), null, null, file.getAbsolutePath());
403         tabPane.setSelectedIndex(tabPane.getTabCount() - 1);
404         //設置當前的文件對象
405         this.currentFile = new EditFile(file, true, iframe, editPane);
406         //將當前的文件加到打開的文件集合中
407         this.openFiles.add(this.currentFile);
408     }
409     
410     public void selectFile() {
411         fileChooser = new FileChooser(this);
412     }
413     
414     //新建文件的方法
415     public void newFile() {
416         //當沒有選擇一個節點而新建目錄的時候,須要提醒
417         if (getSelectNode() == null) {
418             JOptionPane.showMessageDialog(this, "請選擇目錄"); 
419             return;
420         }
421         AddInfo info = new AddInfo("文件名稱:", this, new AddFileHandler());
422         showAddFrame(info);
423     }
424     //顯示新增的界面
425     private void showAddFrame(AddInfo info) {
426         //使EditorFrame變爲不可用
427         setEnabled(false);
428         addFrame = new AddFrame(info);
429         addFrame.pack();
430         addFrame.setVisible(true);
431     }
432     
433     //刷新樹節點
434     public void reloadNode(ProjectTreeNode selectNode) {
435         if (selectNode == null) return; 
436         //刷新樹的節點
437         ProjectTreeModel model = (ProjectTreeModel)getTree().getModel();
438         //從新加載所選擇的節點
439         model.reload(selectNode, treeCreator);
440     }
441     
442     public WorkSpace getWorkSpace() {
443         return workSpace;
444     }
445     
446     public JTree getTree() {
447         return this.tree;
448     }
449     
450     //新建目錄的方法
451     public void newFolder() {
452         //當沒有選擇一個節點而新建目錄的時候,須要提醒
453         if (getSelectNode() == null) {
454             JOptionPane.showMessageDialog(this, "請選擇目錄"); 
455             return;
456         }
457         AddInfo info = new AddInfo("目錄名稱:", this, new AddFolderHandler());
458         showAddFrame(info);
459     }
460     
461     //新建項目的方法
462     public void newProject() {
463         AddInfo info = new AddInfo("項目名稱:", this, new AddProjectHandler());
464         showAddFrame(info);
465     }
466     
467     //從新在treePane中構造一次樹
468     public void refreshTree(JTree newTree) {
469         //將tree對象變爲參數中的newTree
470         this.tree = newTree;
471         //讓treePane(放樹的容器)設置newTree爲新的視圖
472         treePane.setViewportView(newTree);
473         //更新界面
474         treePane.updateUI();
475     }
476 
477     public EditFile getCurrentFile() {
478         return currentFile;
479     }
480 
481     public void setCurrentFile(EditFile currentFile) {
482         this.currentFile = currentFile;
483     }
484 
485     public List<EditFile> getOpenFiles() {
486         return openFiles;
487     }
488 
489     public JDesktopPane getDesk() {
490         return desk;
491     }
492 
493     public JTabbedPane getTabPane() {
494         return tabPane;
495     }
496     
497     //根據JInternalFrame標題找到JInternalFrame對象
498     public JInternalFrame getIFrame(String title) {
499         JInternalFrame[] iframes = desk.getAllFrames();
500         for (JInternalFrame iframe : iframes) {
501             if (iframe.getTitle().equals(title)) return iframe;
502         }
503         return null;
504     }
505     
506     //根據JInternalFrame在打開的文件集合中獲取相應的文件對象
507     public EditFile getEditFile(JInternalFrame iframe) {
508         for (EditFile openFile : openFiles) {
509             if (openFile.getIframe().equals(iframe)) return openFile;
510         }
511         return null;
512     }
513     
514     //詢問是否要保存, 參數爲將被打開的文件
515     public void askSave(EditFile file) {
516         //該份文件修改過沒有保存
517         if (!file.isSaved()) {
518             //彈出詢問
519             int val = JOptionPane.showConfirmDialog(this, "是否要保存?", "詢問", 
520                     JOptionPane.YES_NO_OPTION);
521             //點擊了須要保存
522             if (JOptionPane.YES_OPTION == val) {
523                 //調用EditorFrame的保存方法對文件進行保存
524                 saveFile(file);
525             }
526         }
527     }
528     
529     //用於保存當前所打開的文件
530     public void saveFile(EditFile file) {
531         if (file == null) return;
532         //調用中介者對象的方法去保存文件
533         String result = saveMediator.doSave(this);
534         //將結果放到信息顯示區的文本域中
535         infoArea.setText(result);
536         //寫完文件後,設置當前文件的保存狀態爲true,表示已經保存
537         file.setSaved(true);
538     }
539     
540     //關閉一個窗口
541     public void closeIFrame(JInternalFrame iframe) {
542         //得到當前的文件,即要關閉的文件對象
543         EditFile closeFile = getEditFile(iframe);
544         //設置本類中的currentFile屬性
545         afterClose(closeFile);
546         //得到該iframe在tab頁中對應的索引
547         int index = getTabIndex(iframe.getTitle());
548         //從tab頁中刪除
549         getTabPane().remove(index);
550         //從打開的文件集合中刪除這個關閉的文件
551         openFiles.remove(closeFile);
552     }
553     
554     //當關閉一份文件後,設置本對象的currentFile屬性
555     private void afterClose(EditFile closeFile) {
556         //獲取關閉文件在打開文件集合中的索引
557         int openFilesIndex = getEditFileIndex(closeFile);
558         //若是該文件已是全部打開的文件的最後一份
559         if (this.openFiles.size() == 1) {
560             this.currentFile = null;
561         } else {//若是還有其餘文件,判斷關閉的文件位置
562             if (openFilesIndex == 0) {
563                 //若是關閉的文件是第一份,拿集合中的第二份
564                 this.currentFile = openFiles.get(openFilesIndex + 1);
565             } else if (openFilesIndex == (openFiles.size() - 1)) {
566                 //若是關閉的是最後一份,取倒數第二份
567                 this.currentFile = openFiles.get(openFiles.size() - 2);
568             } else {
569                 //不是第一份,也不是最後一份
570                 this.currentFile = openFiles.get(openFilesIndex - 1);
571             }
572         }
573     }
574     
575     //獲取editFile在打開的文件集合中的索引
576     private int getEditFileIndex(EditFile editFile) {
577         for (int i = 0; i < this.openFiles.size(); i++) {
578             if (openFiles.get(i).equals(editFile)) return i;
579         }
580         return -1;
581     }
582     
583     //返回項目樹當前所選中的節點所屬的項目節點對應的目錄
584     public File getCurrentProject() {
585         //獲取根節點(工做空間)
586         ProjectTreeNode root = (ProjectTreeNode)getSelectNode().getRoot();
587         //獲取根節點下的全部子節點(即項目節點集合)
588         List<ProjectTreeNode> projects = root.getChildren();
589         ProjectTreeNode selectNode = getSelectNode();
590         if (selectNode != null) {
591             for (ProjectTreeNode project : projects) {
592                 //當前先中節點是該project下的子節點
593                 if (selectNode.isNodeAncestor(project)) {
594                     return project.getFile();
595                 }
596             }
597         }
598         return null;
599     }
600     
601     //運行文件的方法
602     public void run() {
603         //運行前先保存
604         saveFile(getCurrentFile());
605         //將結果顯示
606         String result = runHandler.run(this);
607         infoArea.setText(result);
608     }
609     
610 }
611 class FileChooser extends JFileChooser {
612     
613     private EditorFrame editorFrame;
614     
615     
616     public FileChooser(EditorFrame editorFrame){
617         //調用父類的構造器
618         //利用editorFrame的工做空間做爲文件選擇器打開時的默認目錄
619         super(editorFrame.getWorkSpace().getFolder());
620         this.editorFrame = editorFrame;
621         showOpenDialog(editorFrame);
622     }
623     
624     public void approveSelection() {
625         File file = getSelectedFile();
626         //設置樹當前選擇的節點爲null, 即樹沒有被選中
627         this.editorFrame.getTree().setSelectionPath(null);
628         this.editorFrame.openFile(file);
629         super.approveSelection();
630     }
631 }
EditorFrame
  1 package org.crazyit.editor;
  2 
  3 import java.awt.Color;
  4 import java.awt.Graphics;
  5 import java.awt.Insets;
  6 import java.awt.event.KeyAdapter;
  7 import java.awt.event.KeyEvent;
  8 import java.io.File;
  9 import java.io.FileNotFoundException;
 10 import java.util.ArrayList;
 11 import java.util.HashMap;
 12 import java.util.Map;
 13 import java.util.Scanner;
 14 
 15 import javax.swing.JTextPane;
 16 import javax.swing.text.Element;
 17 import javax.swing.text.SimpleAttributeSet;
 18 import javax.swing.text.StyleConstants;
 19 import javax.swing.text.StyledDocument;
 20 
 21 import org.crazyit.editor.util.FileUtil;
 22 
 23 /**
 24  * 編輯界面
 25  * 
 26  * @author yangenxiong yangenxiong2009@gmail.com
 27  * @version  1.0
 28  * <br/>網站: <a href="http://www.crazyit.org">瘋狂Java聯盟</a>
 29  * <br>Copyright (C), 2009-2010, yangenxiong
 30  * <br>This program is protected by copyright laws.
 31  */
 32 public class EditPane extends JTextPane {
 33 
 34     //樣式文檔對象
 35     protected StyledDocument doc;
 36     //構造一個文本格式器
 37     protected SyntaxFormatter formatter = new SyntaxFormatter("java.stx");
 38     private SimpleAttributeSet quotAttr = new SimpleAttributeSet();
 39     //保存文檔改變的開始位置
 40     private int docChangeStart = 0;
 41     //保存文檔改變的長度
 42     private int docChangeLength = 0;
 43     //定義文檔中行數文本的外觀屬性
 44     private SimpleAttributeSet lineAttr = new SimpleAttributeSet();
 45     
 46     public EditPane(File file) {
 47         this.setText(FileUtil.readFile(file));
 48         this.doc = getStyledDocument();
 49         //設置該文檔的頁邊距
 50         this.setMargin(new Insets(3, 40, 0, 0));
 51         syntaxParse();
 52         //添加按鍵監聽器,當按鍵鬆開時進行語法分析
 53         this.addKeyListener(new KeyAdapter() {
 54             public void keyReleased(KeyEvent ke)
 55             {
 56                 syntaxParse();
 57             }
 58         });
 59     }
 60 //    
 61 //    //重寫父類方法,使JTextPane不會自動換行
 62 //    public boolean getScrollableTracksViewportWidth() { 
 63 //        return (getSize().width < getParent().getSize().width - 100); 
 64 //    } 
 65 //
 66 //    //重寫父類方法,使JTextPane不會自動換行
 67 //    public void setSize(Dimension d) { 
 68 //        if (d.width < getParent().getSize().width) { 
 69 //           d.width = getParent().getSize().width; 
 70 //        } 
 71 //        d.width += 100; 
 72 //        super.setSize(d); 
 73 //    } 
 74     
 75     public void syntaxParse() {
 76         try {
 77             //獲取文檔的根元素,即文檔內的所有內容
 78             Element root = doc.getDefaultRootElement();
 79             //獲取文檔中光標插入符的位置
 80             int cursorPos = this.getCaretPosition();
 81             int line = root.getElementIndex(cursorPos);
 82             //獲取光標所在位置的行
 83             Element para = root.getElement(line);
 84             //定義光標所在行的行頭在文檔中位置
 85             int start = para.getStartOffset();
 86             //若是文檔修改位置比當前行還前
 87             if (start > docChangeStart)    {
 88                 start = docChangeStart;
 89             }
 90             //定義被修改部分的長度
 91             int length = para.getEndOffset() - start;
 92             if (length < docChangeLength) {
 93                 length = docChangeLength + 1;
 94             }
 95             //取出全部被修改的字符串
 96             String s = doc.getText(start, length);
 97             //以空格、點號等做爲分隔符
 98             String[] tokens = s.split("\\s+|\\.|\\(|\\)|\\{|\\}|\\[|\\]");
 99             //定義當前分析單詞的在s字符串中的開始位置
100             int curStart = 0;
101             boolean isQuot = false;
102             for (String token : tokens) {
103                 //找出當前分析單詞在s字符串的中位置
104                 int tokenPos = s.indexOf(token , curStart);
105                 if (isQuot && (token.endsWith("\"") || token.endsWith("\'"))) {
106                     doc.setCharacterAttributes(start + tokenPos, token.length(), quotAttr, false);
107                     isQuot = false;
108                 }
109                 else if (isQuot && !(token.endsWith("\"") || token.endsWith("\'"))) {
110                     doc.setCharacterAttributes(start + tokenPos, token.length(), quotAttr, false);
111                 }
112                 else if ((token.startsWith("\"") || token.startsWith("\'"))
113                     && (token.endsWith("\"") || token.endsWith("\'"))) {
114                     doc.setCharacterAttributes(start + tokenPos, token.length(), quotAttr, false);
115                 }
116                 else if ((token.startsWith("\"") || token.startsWith("\'"))
117                     && !(token.endsWith("\"") || token.endsWith("\'"))) {
118                     doc.setCharacterAttributes(start + tokenPos, token.length(), quotAttr, false);
119                     isQuot = true;
120                 }
121                 else {
122                     //使用格式器對當前單詞設置顏色
123                     formatter.setHighLight(doc , token , start + tokenPos, token.length());
124                 }
125                 //開始分析下一個單詞
126                 curStart = tokenPos + token.length();
127             }
128         }
129         catch (Exception ex) {
130             ex.printStackTrace();
131         }
132     }
133     //重畫該組件,設置行號
134     public void paint(Graphics g){
135         super.paint(g);
136         Element root = doc.getDefaultRootElement(); 
137         //得到行號
138         int line = root.getElementIndex(doc.getLength());
139         //設置顏色
140         g.setColor(new Color(230, 230, 230));
141         //繪製行數矩形框
142         g.fillRect(0, 0, this.getMargin().left - 10, getSize().height);
143         //設置行號的顏色
144         g.setColor(new Color(40, 40, 40));
145         //每行繪製一個行號
146         for (int count = 0, j = 1; count <= line; count++, j++) {
147             g.drawString(String.valueOf(j), 3, 
148                         (int)((count + 1) * 1.5020 * StyleConstants.getFontSize(lineAttr)));
149         }
150     }
151 }
152 class SyntaxFormatter {
153     //以一個Map保存關鍵字和顏色的對應關係
154     private Map<SimpleAttributeSet , ArrayList> attMap
155         = new HashMap<SimpleAttributeSet , ArrayList>();
156     //定義文檔的正常文本的外觀屬性
157     SimpleAttributeSet normalAttr = new SimpleAttributeSet();
158     public SyntaxFormatter(String syntaxFile) {
159         //設置正常文本的顏色、大小
160         StyleConstants.setForeground(normalAttr, Color.BLACK);
161         //StyleConstants.setFontSize(normalAttr, 14);
162         //建立一個Scanner對象,負責根據語法文件加載顏色信息
163         Scanner scaner = null;
164         try    {
165             scaner = new Scanner(new File(syntaxFile));
166         }
167         catch (FileNotFoundException e)    {
168             throw new RuntimeException("丟失語法文件:" + e.getMessage());
169         }
170         int color = -1;
171         ArrayList<String> keywords = new ArrayList<String>();
172         //不斷讀取語法文件的內容行
173         while(scaner.hasNextLine())    {
174             String line = scaner.nextLine();
175             //若是當前行以#開頭
176             if (line.startsWith("#")) {
177                 if (keywords.size() > 0 && color > -1) {
178                     //取出當前行的顏色值,並封裝成SimpleAttributeSet對象
179                     SimpleAttributeSet att = new SimpleAttributeSet();
180                     StyleConstants.setForeground(att, new Color(color));
181                     //StyleConstants.setFontSize(att, 14);
182                     //將當前顏色和關鍵字List對應起來
183                     attMap.put(att , keywords);
184                 }
185                 //從新建立新的關鍵字List,爲下一個語法格式準備
186                 keywords = new ArrayList<String>();
187                 color = Integer.parseInt(line.substring(1) , 16);
188             } else {
189                 //對於普通行,每行內容添加到關鍵字List裏
190                 if (line.trim().length() > 0) {
191                     keywords.add(line.trim());
192                 }
193             }
194         }
195         //把最後的關鍵字和顏色對應起來
196         if (keywords.size() > 0 && color > -1) {
197             SimpleAttributeSet att = new SimpleAttributeSet();
198             StyleConstants.setForeground(att, new Color(color));
199             attMap.put(att , keywords);
200         }
201     }
202     //返回該格式器里正常文本的外觀屬性
203     public SimpleAttributeSet getNormalAttributeSet() {
204         return normalAttr;
205     }
206     //設置語法高亮
207     public void setHighLight(StyledDocument doc , String token , 
208         int start , int length)    {
209         //保存須要對當前單詞對應的外觀屬性
210         SimpleAttributeSet currentAttributeSet = null;
211         outer :
212         for (SimpleAttributeSet att : attMap.keySet())
213         {
214             //取出當前顏色對應的全部關鍵字
215             ArrayList keywords = attMap.get(att);
216             //遍歷全部關鍵字
217             for (Object keyword : keywords)
218             {
219                 //若是該關鍵字與當前單詞相同
220                 if (keyword.toString().equals(token))
221                 {
222                     //跳出循環,並設置當前單詞對應的外觀屬性
223                     currentAttributeSet = att;
224                     break outer;
225                 }
226             }
227         }
228         //若是當前單詞對應的外觀屬性不爲空
229         if (currentAttributeSet != null){
230             //設置當前單詞的顏色
231             doc.setCharacterAttributes(start, length, currentAttributeSet, false);
232         } else {//不然使用普通外觀來設置該單詞
233             doc.setCharacterAttributes(start, length, normalAttr, false);
234         }
235     }
236 }
EditPane
 1 package org.crazyit.editor;
 2 
 3 import javax.swing.JInternalFrame;
 4 import javax.swing.event.InternalFrameAdapter;
 5 import javax.swing.event.InternalFrameEvent;
 6 
 7 import org.crazyit.editor.commons.EditFile;
 8 
 9 /**
10  * 窗口監聽器
11  * 
12  * @author yangenxiong yangenxiong2009@gmail.com
13  * @version  1.0
14  * <br/>網站: <a href="http://www.crazyit.org">瘋狂Java聯盟</a>
15  * <br>Copyright (C), 2009-2010, yangenxiong
16  * <br>This program is protected by copyright laws.
17  */
18 public class IFrameListener extends InternalFrameAdapter {
19 
20     private EditorFrame editorFrame;
21     
22     public IFrameListener(EditorFrame editorFrame) {
23         this.editorFrame = editorFrame;
24     }
25 
26     public void internalFrameActivated(InternalFrameEvent e) {
27         JInternalFrame iframe = editorFrame.getDesk().getSelectedFrame();
28         int tapIndex = editorFrame.getTabIndex(iframe.getTitle());
29         editorFrame.getTabPane().setSelectedIndex(tapIndex);
30     }
31 
32     public void internalFrameClosing(InternalFrameEvent e) {
33         //獲取當前關閉操做所對應的JInternalFrame
34         JInternalFrame iframe = (JInternalFrame)e.getSource();
35         //獲取當前操做的文件
36         EditFile editFile = editorFrame.getCurrentFile();
37         //詢問是否要保存
38         editorFrame.askSave(editFile); 
39         //關閉當前的iframe
40         editorFrame.closeIFrame(iframe);
41     }
42 }
IFrameListener
  1 package org.crazyit.editor;
  2 
  3 import java.awt.Label;
  4 import java.awt.event.ActionEvent;
  5 import java.awt.event.ActionListener;
  6 import java.io.File;
  7 
  8 import javax.swing.BoxLayout;
  9 import javax.swing.JButton;
 10 import javax.swing.JFileChooser;
 11 import javax.swing.JFrame;
 12 import javax.swing.JLabel;
 13 import javax.swing.JPanel;
 14 import javax.swing.JTextField;
 15 
 16 import org.crazyit.editor.commons.WorkSpace;
 17 
 18 /**
 19  * 工做空間界面
 20  * 
 21  * @author yangenxiong yangenxiong2009@gmail.com
 22  * @version  1.0
 23  * <br/>網站: <a href="http://www.crazyit.org">瘋狂Java聯盟</a>
 24  * <br>Copyright (C), 2009-2010, yangenxiong
 25  * <br>This program is protected by copyright laws.
 26  */
 27 public class SpaceFrame extends JFrame {
 28 
 29     private JPanel mainPanel;
 30     
 31     private JLabel infoLabel;
 32     
 33     private JPanel chosePanel;
 34     
 35     private JLabel workTextLabel;
 36     
 37     //工做空間中顯示用戶選擇文件目錄的JTextField
 38     private JTextField pathText;
 39     
 40     private JButton choseButton;
 41     
 42     
 43     private JPanel buttonPanel;
 44     
 45     //工做空間中的肯定按鈕
 46     private JButton confirmButton;
 47     
 48     private JButton cancelButton;
 49     
 50     private SpaceChooser chooser;
 51     
 52     //用戶選擇的文件目錄對象
 53     private File folder;
 54     
 55     public SpaceFrame(EditorFrame editorFrame) {
 56         mainPanel = new JPanel();
 57         infoLabel = new JLabel("請選擇工做空間");
 58         chosePanel = new JPanel();
 59         workTextLabel = new JLabel("工做空間: ");
 60         pathText = new JTextField("", 40);
 61         choseButton = new JButton("選擇");
 62         buttonPanel = new JPanel();
 63         confirmButton = new JButton("肯定");
 64         cancelButton = new JButton("取消");
 65         chooser = new SpaceChooser(this);
 66         
 67         //設置主Panel的佈局
 68         mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
 69         mainPanel.add(infoLabel);
 70         //設置選擇區的佈局
 71         chosePanel.setLayout(new BoxLayout(chosePanel, BoxLayout.X_AXIS));
 72         choseButton.addActionListener(new ChoseButtonListener(chooser));
 73         pathText.setEditable(false);
 74         chosePanel.add(workTextLabel);
 75         chosePanel.add(pathText);
 76         chosePanel.add(choseButton);
 77         mainPanel.add(chosePanel);
 78 
 79         confirmButton.setEnabled(false);
 80         //爲肯定按鈕添加肯定的事件, 即建立一個WorkSpace對象
 81         confirmButton.addActionListener(new ConfirmButtonListener(this, editorFrame));
 82         buttonPanel.add(confirmButton);
 83         buttonPanel.add(new Label("    "));
 84         buttonPanel.add(cancelButton);
 85         //爲取消按鈕添加退出事件
 86         cancelButton.addActionListener(new ActionListener() {
 87             public void actionPerformed(ActionEvent arg0) {
 88                 System.exit(0);
 89             }
 90         });
 91         mainPanel.add(buttonPanel);
 92         add(mainPanel);
 93         pack();
 94         setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 95         setLocation(300, 200);
 96         setResizable(false);
 97     }
 98 
 99     public File getFolder() {
100         return folder;
101     }
102 
103     public void setFolder(File folder) {
104         this.folder = folder;
105     }
106         
107     public JTextField getPathText() {
108         return pathText;
109     }
110 
111     public JButton getConfirmButton() {
112         return confirmButton;
113     }
114 }
115 
116 /**
117  * 肯定按鈕的監聽器
118  * @author hp
119  *
120  */
121 class ConfirmButtonListener implements ActionListener {
122     
123     private SpaceFrame spaceFrame;
124     
125     private EditorFrame editorFrame;
126     
127     public ConfirmButtonListener(SpaceFrame spaceFrame, EditorFrame editorFrame) {
128         this.spaceFrame = spaceFrame;
129         this.editorFrame = editorFrame;
130     }
131     
132     public void actionPerformed(ActionEvent arg0) {
133         //調EditorFrame的initFrame方法初始化界面
134         editorFrame.initFrame(new WorkSpace(spaceFrame.getFolder(), editorFrame));
135         //將EditorFrame設爲可見
136         editorFrame.setVisible(true);
137         editorFrame.setSize(900, 600);
138         //讓工做選擇空間界面不可見
139         spaceFrame.setVisible(false);
140     }
141 }
142 
143 /**
144  * 選擇按鈕的監聽器
145  * @author hp
146  *
147  */
148 class ChoseButtonListener implements ActionListener {
149 
150     private JFileChooser chooser;
151     
152     public ChoseButtonListener(JFileChooser chooser) {
153         this.chooser = chooser;
154     }
155     
156     @Override
157     public void actionPerformed(ActionEvent arg0) {
158         chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
159         chooser.showOpenDialog(null);
160     }
161     
162 }
163 
164 /**
165  * 文件選擇器
166  * @author hp
167  *
168  */
169 class SpaceChooser extends JFileChooser {
170     
171     private SpaceFrame spaceFrame;
172     
173     //須要將SpaceFrame做爲構造參數
174     public SpaceChooser(SpaceFrame spaceFrame) {
175         //設置選擇器打開時的目錄
176         super("/");
177         this.spaceFrame = spaceFrame;
178     }
179     
180     //重寫父類的選擇文件方法
181     public void approveSelection() {
182         //獲取用戶選擇的文件
183         File folder = getSelectedFile();
184         //設置SpaceFrame的屬性folder的值
185         spaceFrame.setFolder(folder);
186         //設置SpaceFrame文本框
187         spaceFrame.getPathText().setText(folder.getAbsolutePath());
188         //設置肯定按鈕可用
189         spaceFrame.getConfirmButton().setEnabled(true);
190         //調用父類的選擇文件方法
191         super.approveSelection();
192     }
193 }
SpaceFrame
 1 package org.crazyit.editor;
 2 
 3 import javax.swing.JInternalFrame;
 4 import javax.swing.JTabbedPane;
 5 import javax.swing.event.ChangeEvent;
 6 import javax.swing.event.ChangeListener;
 7 
 8 import org.crazyit.editor.commons.EditFile;
 9 
10 /**
11  * tab頁轉換監聽器
12  * 
13  * @author yangenxiong yangenxiong2009@gmail.com
14  * @version  1.0
15  * <br/>網站: <a href="http://www.crazyit.org">瘋狂Java聯盟</a>
16  * <br>Copyright (C), 2009-2010, yangenxiong
17  * <br>This program is protected by copyright laws.
18  */
19 public class TabListener implements ChangeListener {
20 
21     private EditorFrame editorFrame;
22     
23     public TabListener(EditorFrame editorFrame) {
24         this.editorFrame = editorFrame;
25     }
26     
27     public void stateChanged(ChangeEvent e) {
28         //得到當前點擊tab頁對象
29         JTabbedPane tab = (JTabbedPane)e.getSource();
30         //得到tab頁的索引
31         int index = tab.getSelectedIndex();
32         if (index == -1) return; 
33         //根據tab頁的tips(文件的絕對路徑)得到當前的JInternalFrame對象
34         JInternalFrame currentFrame = editorFrame.getIFrame(tab.getToolTipTextAt(index));
35         //讓當前點擊的JInternalFrame對象可見
36         editorFrame.showIFrame(currentFrame);
37         //根據當前的JInternalFrame對象得到對應的文件
38         EditFile currentFile = editorFrame.getEditFile(currentFrame);
39         //設置EditorFrame當前編輯的文件爲tab對應的文件
40         editorFrame.setCurrentFile(currentFile);
41     }
42 
43 }
TabListener
 1 package org.crazyit.editor;
 2 
 3 import org.crazyit.editor.tree.TreeCreator;
 4 import org.crazyit.editor.tree.TreeCreatorImpl;
 5 
 6 /**
 7  * 程序入口類
 8  * 
 9  * @author yangenxiong yangenxiong2009@gmail.com
10  * @version  1.0
11  * <br/>網站: <a href="http://www.crazyit.org">瘋狂Java聯盟</a>
12  * <br>Copyright (C), 2009-2010, yangenxiong
13  * <br>This program is protected by copyright laws.
14  */
15 public class Main {
16 
17     public static void main(String[] args) {
18         TreeCreator treeCreator = new TreeCreatorImpl();
19         //建立EditorFrame,暫時不用設置可見
20         EditorFrame editorFrame = new EditorFrame("ide", treeCreator);
21         //將editorFrame對象做爲SpaceFrame的構造參數
22         SpaceFrame spaceFrame = new SpaceFrame(editorFrame);
23         //讓SpaceFrame可見
24         spaceFrame.setVisible(true);
25     }
26 }
Main
相關文章
相關標籤/搜索