[Java]简易编译器实现

一笑奈何 提交于 2019-12-25 13:20:34

设计原因

最近学期末,进入了专业实训课,借此机会将Swing方面的编程学习了一下,设计了一个简易编译器。为此我查阅了几乎所有监听事件类的具体方法及应用,已经实现了简单的编译及运行功能。

新人第一次写博客,此编译器仍然存在Bug与缺陷,若有不好的地方请多多指教
1.运行的程序仅限输出,控制台输入流管道被阻塞的问题还在解决中。
2.编辑框内可能会抛出BadLocationException异常
3.此编译器暂时仅实现文件的新建,打开,保存,编辑,运行/中断等功能)


设计展示

编辑框界面
编辑框界面

编辑框相关类
在这里插入图片描述


代码展示

主界面代码

package project;

import java.awt.event.*;
import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.awt.*;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import project.TextPane;
/**
 * 仿编译器
 * @author 14110
 *
 */
public class MainFrame extends JFrame{
	
	/**
	 * 
	 */
	private static final long serialVersionUID = -4697982052727623928L;
	
	private JFrame f=this;
	
	//定义运行进程
	private Process now;
	private Runtime run=Runtime.getRuntime();
	private BufferedReader br;
	private BufferedWriter wr;
	


	//定义组件
	static JTabbedPane top;   				//顶部选项
	static JClosableTabbedPane mainText;	//编辑框			
	static ControllArea bottom;				//底部
	static InFiles files_panel;				//左侧文件面板
	static ChooseFile chooseFile;			//文件选择器
	static JPanel left_panel;		
	static JPanel main_panel;
	static TopTools toptools;
	
	//当前界面输入内容
	private String content="";
	//当前路径
	private String path="";
	//键盘输入
	//private CharBuffer enter=CharBuffer.allocate(64);
	private ArrayList<Character>enter=new ArrayList<>();
	private String input="";
	
	//缓存
	private HashMap<Component, TextPane> textmap = mainText.gettextmap();
	
	
	static {
		//初始化
		bottom=new ControllArea();
		chooseFile=new ChooseFile();
		files_panel=new InFiles();
		mainText=new JClosableTabbedPane();
		left_panel=new JPanel();
		main_panel=new JPanel();
		toptools=new TopTools();
		top=toptools.getTools();
	}
	
	//获取当前文件的路径
	public String curPath() {
		this.path=textmap.get(mainText.getPane()).getPath();
		return this.path;
	}
	
	//获取当前界面
	public TextPane getNowPane() {
		return textmap.get(mainText.getPane());
	}
	

	

	public void init() {
		//左侧面板
		left_panel.setLayout(new BoxLayout(left_panel,BoxLayout.Y_AXIS));
		left_panel.add(files_panel);
		//主面板
		main_panel.setLayout(new BoxLayout(main_panel,BoxLayout.Y_AXIS));
		main_panel.add(mainText);
		main_panel.add(bottom);
		mainText.setPreferredSize(new Dimension(500,320));

		//设置布局管理器
		f.setLayout(new BorderLayout());
		//添加组件
		f.add(top,BorderLayout.NORTH);
		f.add(main_panel,BorderLayout.CENTER);
		f.add(left_panel,BorderLayout.WEST);
		
		
		//添加监听器功能
		addListeners();
		
		//默认设置
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		final int inset = 50;
		Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
		f.setBounds(inset, inset, screenSize.width - inset*2
			, screenSize.height - inset * 2);
		f.setVisible(true);
		
		//添加控制器状态
		while(this.isVisible()) {
			try {
				Thread.sleep(1000);
				outer();
			} catch (InterruptedException e) {
				// TODO 自动生成的 catch 块
				e.printStackTrace();
			}
			
		}
	}
	
	
	//添加监听事件
	public void addListeners() {
		toptools.b1.addActionListener(new ActionListener() {
			//新建
			@Override
			public void actionPerformed(ActionEvent e) {
				mainText.addNewPane();
				System.out.println("当前缓存区大小:"+textmap.size());
			}
			
		});
		toptools.b2.addActionListener(new ActionListener() {
			//打开
			@Override
			public void actionPerformed(ActionEvent e) {
				String []infor=chooseFile.openfile(f);
				if(infor[0]!="") {
					if(files_panel.open(infor[1])) {
						mainText.addFilePane(infor);
					}else
						JOptionPane.showMessageDialog(f, "选择重复");
					System.out.println("当前缓存区大小:"+textmap.size());
				}else
					JOptionPane.showMessageDialog(f, "未选择文件");
			}
			
		});
		toptools.b3.addActionListener(new ActionListener() {
			//保存
			@Override
			public void actionPerformed(ActionEvent e) {
				if(mainText.getPane()!=null) {
					if(mainText.getSelectedIndex()!=-1&&
							mainText.getSelectedComponent().getName()=="unseted") {
						//获取
						content=getNowPane().getText();
						String []name=chooseFile.newSetfile(f, content);
						mainText.setTitleAt(mainText.getSelectedIndex(), name[0]);
						mainText.getPane().setName(name[0]);
						getNowPane().setName(name[0]);
						getNowPane().setPath(name[1]);
						files_panel.addChild(name[1]);
					}else {
						content=getNowPane().getText();
						if(chooseFile.setFile(curPath(), content)) {
							JOptionPane.showMessageDialog(f, "保存成功");
							getNowPane().setRes(false);
						}else {
							JOptionPane.showMessageDialog(f, "保存失败");
						}
					}
				}
			
			}
			
		});
		toptools.b4.addActionListener(new ActionListener() {
			//退出
			@Override
			public void actionPerformed(ActionEvent e) {
				System.exit(0);
			}
			
		});
			
		toptools.b5.addActionListener(new ActionListener() {
			//编译
			@Override
			public void actionPerformed(ActionEvent e) {
				if(getNowPane()==null||getNowPane().getName().equals("unseted")) {
					return;
				}else {
						String result="";
						String p=getNowPane().getPath();
						try {
							now=run.exec("javac "+p);
							br=new BufferedReader(new InputStreamReader(now.getErrorStream()));
							String read="";
							while((read=br.readLine())!=null) {
								result+=read+"\r\n";
							}
							//System.out.print(result);
							if(result==""){
									JOptionPane.showMessageDialog(f, "编译成功");
									getNowPane().setRes(true);
								}
							else {
								JOptionPane.showMessageDialog(f, "编译失败");
								bottom.setSelectedIndex(1);
								getNowPane().setRes(false);
							}
						} catch (IOException e1) {
							result=e1.getMessage();
							
						}finally{
							bottom.setErr(result);
						}
					}
				
			}
			
		});
		

		
		toptools.b6.addActionListener(new ActionListener() {
			//运行-中断
			@Override
			public void actionPerformed(ActionEvent e) {
				bottom.setSelectedIndex(0);
				if(toptools.b6.getText().equals("运行")) {
					bottom.getCon().setText("");
					if(getNowPane()!=null) {
						if(getNowPane().getRes()) {
							toptools.b6.setText("中断");
						}
						else
							JOptionPane.showMessageDialog(f, "Error:未编译或编译错误");	
					}
				}else {
					now.destroy();
					toptools.b6.setText("运行");
				}
			}
			
		});
		
	
		
		toptools.b7.addActionListener(new ActionListener() {
			//资源管理
			@Override
			public void actionPerformed(ActionEvent e) {
				
				if(left_panel.isVisible())
					left_panel.setVisible(false);
				else
					left_panel.setVisible(true);
				
			}
			
		});
		toptools.b8.addActionListener(new ActionListener() {
			//关于
			@Override
			public void actionPerformed(ActionEvent e) {
				JOptionPane.showMessageDialog(f, "更多功能敬请期待");	
				
			}
			
		});
		
		mainText.addMouseListener(new MouseListener() {

			@Override
			public void mouseClicked(MouseEvent e) {
				if(textmap.size()<files_panel.getCount()){
					files_panel.delete(mainText.getDel());
				}
			}

			@Override
			public void mousePressed(MouseEvent e) {}

			@Override
			public void mouseReleased(MouseEvent e) {}

			@Override
			public void mouseEntered(MouseEvent e) {}

			@Override
			public void mouseExited(MouseEvent e) {}
			
		});
		
		// 添加监听树节点选择事件的监听器
		InFiles.tree.addTreeSelectionListener(e -> {
			if(textmap.size()>=files_panel.getCount()&&
					e.getNewLeadSelectionPath()!=null) {
				files_panel.setSelect(e.getNewLeadSelectionPath().toString());
			    String name="";
				for(int i=0;i<textmap.size();i++) {
					name=mainText.getTitleAt(i);
					if(files_panel.getSelect().indexOf(name)>=0) {
						mainText.setSelectedIndex(i);
					}
				}
			
			}else {
				
			}
		    
		});

		//输入流监听器
		bottom.getCon().addKeyListener(new KeyListener() {
			@Override
			public void keyTyped(KeyEvent e) {
	
			}

			@Override
			public void keyPressed(KeyEvent e) {
				if(now!=null) {
					if(toptools.b6.getText().equals("中断")) {
						//获取输入的每行字符串
						if(e.getKeyCode()!=10) {
							if(enter.size()>0&&e.getKeyCode()==8)
								enter.remove(enter.size()-1);
							else
								enter.add(e.getKeyChar());
						}else {
							for(int i=0;i<enter.size();i++) {
								input+=enter.get(i);
							}
							enter.clear();
							
						}
							
						
					}
				}
				
			}

			@Override
			public void keyReleased(KeyEvent e) {
				
			}
			
		});
		
	
	
	}
	
	
	//控制器输出流
	public void outer() {
		if(toptools.b6.getText().equals("中断")) {
			// TODO 自动生成的方法存根
			
				System.out.println("开始运行");
				String p=getNowPane().getPath();
				try {
					now=run.exec("java "+p);
					br=new BufferedReader(new InputStreamReader(now.getInputStream()));
					wr=new BufferedWriter(new OutputStreamWriter(now.getOutputStream()));
					String result=null;
					while((result=br.readLine())!=null) {	
						if(result.length()==0) {
							inner();
						}
						System.out.println(result);
					}
					if(now.exitValue()==0) {
						toptools.b6.setText("运行");
					}else {
						inner();
					}
					
				} catch (IOException e1) {
					e1.printStackTrace();
					
				}finally{  
		            try {  
		                if(null!=wr){  
		                    wr.close();  
		                    wr=null;  
		                }  
		                if(null!=br){  
		                    br.close();  
		                    br=null;  
		                }  
		                if(null!=now)  
		                	now.destroy();  
		            } catch (IOException e) {  
		                // TODO Auto-generated catch block  
		                e.printStackTrace();  
		            }  
		        }  
			}
	}
	
	//控制器输入流
	public void inner() {	
		try {
        	wr.write(input);
			wr.write("\r\n"); 
			wr.flush();
			input="";
			outer();
		} catch (IOException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}  
	}
	
	
	
	
	
	
	//-----------------------------------------------------------------
		public static void main(String[] args)
		{
			MainFrame f=new MainFrame();
			f.init();
		}
}

  • 具体代码链接:
    链接: https://pan.baidu.com/s/1WLyPNMCpr3LG75No0Gt0QA
    提取码: gkdw

  • 此编译器的编写借鉴多篇博客,在此不一一列出

  • 第一次写博客,如有不好,请多多关照


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!