MyConsole的效果如下
下面将代码贴出来,以作备忘。
MyConsole.java
package com.jison.MyConsole; import java.awt.Color; import java.awt.Font; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.io.File; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTextArea; /** * 命令提示符的外壳程序 * @version MyConsole-1.0 * @author jison * @email [email protected] * @time 2015-1-30 */ public class MyConsole { /** * MyConsole主窗体 */ private JFrame jf = new JFrame("MyConsole"); /** * MyConsole的终端文本区 */ private JTextArea consoleTextArea = new JTextArea(); /** * 将终端文本区加入到JScrollPane */ private JScrollPane jScrollPane = new JScrollPane(consoleTextArea); /** * 设置默认字体为等宽字体 */ private final Font DEFAULT_FONT = new Font(Font.MONOSPACED, Font.PLAIN, 13); /** * 控制器对象 */ private MyConsoleControl myConsoleControl; /** * 程序入口 * @param args */ public static void main(String[] args){ new MyConsole(); } public MyConsole(){ //初始化UI this.setMyConsoleUI(); //创建键盘监听 this.createKeyListener(); //获取当前路径 String nowPath = (new File(".")).getAbsolutePath(); nowPath = nowPath.substring(0, nowPath.length()-2); //设置当前路径 MyConsoleDto.getMyConsoleDto().setNowPath(nowPath); //获取终端控制器 myConsoleControl = new MyConsoleControl(); //读取运行cmd命令的信息 String[] cmdArray = new String[3]; cmdArray[0] = "cmd"; cmdArray[1] = "/c"; cmdArray[2] = "cmd"; myConsoleControl.execCmdThread(cmdArray, 300, consoleTextArea); } private void setMyConsoleUI(){ //设置终端文本区的字体和颜色 consoleTextArea.setBackground(Color.BLACK); consoleTextArea.setForeground(Color.LIGHT_GRAY); consoleTextArea.setFont(DEFAULT_FONT); consoleTextArea.setCaretColor(Color.LIGHT_GRAY); //设置终端文本区自动换行 consoleTextArea.setLineWrap(true); //垂直滚动条需要时自动出现 jScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); jf.add(jScrollPane); jf.setSize(680, 450); FrameUtil.setFrameCenter(jf); //设置窗口的默认关闭操作,退出应用程序 jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); jf.setVisible(true); } /** * 对consoleTextArea创建键盘监听 */ private void createKeyListener(){ consoleTextArea.addKeyListener(new KeyListener(){ @Override public void keyReleased(KeyEvent e) { //保护consoleText已打印文本信息不受编辑 myConsoleControl.protectHasPrintText(consoleTextArea); if(e.getKeyCode()==KeyEvent.VK_ENTER) { //回车键释放时的操作 //获取已打印的文本 String hasPrintText = MyConsoleDto.getMyConsoleDto().getStrConsoleText(); //读取当前文本 String nowConsoleText = consoleTextArea.getText(); //执行当前输入的命令 if(nowConsoleText.length()>hasPrintText.length()){ //获取当前输入的命令 String cmdStr = nowConsoleText.substring(hasPrintText.length()).trim(); //给每条命令加入"cmd /c"的前缀 cmdStr = "cmd /c "+cmdStr; //以空格截取输入命令的cmdArray String[] cmdArray = cmdStr.split(" "); //执行刚刚输入命令 myConsoleControl.execCmdThread(cmdArray, 30000, consoleTextArea); } } } @Override public void keyTyped(KeyEvent e) {} @Override public void keyPressed(KeyEvent e) {} }); } }
MyConsoleControl.java
package com.jison.MyConsole; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import javax.swing.JOptionPane; import javax.swing.JTextArea; import javax.swing.text.Document; /** * 处理控制台显示的信息 * @author jison * @email [email protected] * @time 2015-1-30 */ public class MyConsoleControl { /** * 对cd等切换目录的特殊命令的处理 * @param cmdArray */ public void execCdChange(String[] cmdArray){ //获取当前根目录 String nowRootDir = MyConsoleDto.getMyConsoleDto().getNowRootDir(); //当前要切换的目录 File dir = null; //对cd命令进行特殊处理 if(cmdArray[2].equals("cd")){ //如果命令数组的长度为4,表明cd命令输入了目录 if(cmdArray.length==4){ dir = new File(nowRootDir + cmdArray[3]); } } //切换根驱动器命令 if(cmdArray[2].length()==2 && cmdArray[2].charAt(1)==':'){ dir = new File(cmdArray[2]); } //记录当前目录和上一个目录 if(dir!=null && dir.exists() && dir.isDirectory()){ //将当前目录记录为上一个目录 MyConsoleDto.getMyConsoleDto().setPrePath(MyConsoleDto.getMyConsoleDto().getNowPath()); //将dir记录为当前目录 MyConsoleDto.getMyConsoleDto().setNowPath(dir.toString()); } } /** * 保护已打印文本不受编辑 */ public void protectHasPrintText(JTextArea consoleTextArea){ //获取已打印的文本 String hasPrintText = MyConsoleDto.getMyConsoleDto().getStrConsoleText(); //读取当前终端文本 String nowConsoleText = consoleTextArea.getText(); //如果当前终端文本的长度小于已打印文本的长度 if(consoleTextArea.getText().length()’字符之后 if(consoleTextArea.getText().charAt(hasPrintText.length()-1)!='>'){ //恢复已打印的文本 consoleTextArea.setText(hasPrintText); } } /** * 以追加的方式打印当前目录信息到consoleTextArea */ public void printDirInfo(JTextArea consoleTextArea){ String nowPath = MyConsoleDto.getMyConsoleDto().getNowPath(); consoleTextArea.append(nowPath+">"); //记录当前consoleTextArea的文本 MyConsoleDto.getMyConsoleDto().setStrConsoleText(consoleTextArea.getText()); //将光标移动到最后 consoleTextArea.setCaretPosition(consoleTextArea.getText().length()); } /** * 在限制时间内执行cmdArray命令 * @param cmdArray 命令数组 * @param time 时间单位为微秒 */ public void execCmdThread(String[] cmdArray, int time, JTextArea consoleTextArea){ //如果输入的命令为exit,则退出整个程序 if(cmdArray[2].equals("exit")){ System.exit(0); } //启动新的线程执行一条命令 Thread cmdThread = new Thread(new Runnable(){ @Override public void run() { outputCapture(cmdArray, consoleTextArea); } }); cmdThread.start(); try { cmdThread.join(time); } catch (InterruptedException e) { e.printStackTrace(); } //对cd等切换目录的特殊命令的处理 execCdChange(cmdArray); //插入一个换行符 if(!cmdArray[2].equals("cmd")){ consoleTextArea.append("\n"); } //打印当前目录信息 printDirInfo(consoleTextArea); } /** * 捕捉cmdArray命令的控制台输出 * @param cmdArray */ public void outputCapture(String[] cmdArray, JTextArea consoleTextArea){ Process process = null; try { File dir = new File(MyConsoleDto.getMyConsoleDto().getNowPath()); // 启动命令行指定程序的新进程 process = Runtime.getRuntime().exec(cmdArray, null, dir); } catch(IOException e) { System.err.println("创建进程时出错...\n" + e); System.exit(1); } // 获得新进程所写入的流 InputStream[] inStreams = new InputStream[] {process.getInputStream(), process.getErrorStream()}; //将终端信息追加到consoleTextArea this.toTextArea(consoleTextArea, inStreams); try { process.waitFor(); } catch (InterruptedException e) { e.printStackTrace(); } } /** * 在jTextArea上显示传入的InputStream数组的信息 * @param jTextArea 显示信息的文本区域 * @param inStreams 传入要显示的InputStream数组的信息 */ public void toTextArea(JTextArea jTextArea, InputStream[] inStreams){ for(int i = 0; i < inStreams.length; ++i){ startConsoleReaderThread(jTextArea, inStreams[i]); } } /** * 单独启用一个线程对控制台信息的处理 * @param jTextArea * @param inputStream */ private void startConsoleReaderThread(JTextArea jTextArea, InputStream inputStream) { final BufferedReader br = new BufferedReader(new InputStreamReader(inputStream)); new Thread(new Runnable() { public void run() { StringBuffer sb = new StringBuffer(); try { String s; Document doc = jTextArea.getDocument(); while((s = br.readLine()) != null) { boolean caretAtEnd = false; caretAtEnd = jTextArea.getCaretPosition() == doc.getLength() ? true : false; sb.setLength(0); jTextArea.append(sb.append(s).append('\n').toString()); if(caretAtEnd) jTextArea.setCaretPosition(doc.getLength()); } } catch(IOException e) { JOptionPane.showMessageDialog(null, "从BufferedReader读取错误:" + e); System.exit(1); } } }).start(); } }
MyConsoleDto.java
package com.jison.MyConsole; /** * 数据传输对象 * @author jison * @email [email protected] * @time 2015-1-30 */ public class MyConsoleDto { /** * 使用单例模式设计 */ private static MyConsoleDto myConsoleDto; /** * 保存当前consoleTextArea的所有文本 */ private String strConsoleText; /** * 记录当前的根目录 */ private String nowRootDir; /** * 记录当前命令行打开的目录 */ private String nowPath; /** * 记录前一个目录 */ private String prePath; /** * 通过静态方法返回唯一实例 * @return */ public static MyConsoleDto getMyConsoleDto(){ if(myConsoleDto==null){ myConsoleDto = new MyConsoleDto(); } return myConsoleDto; } /** * 其余所有值的getter和setter方法 */ public String getStrConsoleText() { return strConsoleText; } public void setStrConsoleText(String strConsoleText) { this.strConsoleText = strConsoleText; } public String getNowPath() { return nowPath; } public void setNowPath(String nowPath) { this.nowPath = nowPath; } public String getPrePath() { return prePath; } public void setPrePath(String prePath) { this.prePath = prePath; } public String getNowRootDir() { this.setNowRootDir(this.nowPath.substring(0, 2)); return nowRootDir; } public void setNowRootDir(String nowRootDir) { this.nowRootDir = nowRootDir; } }
FrameUtil.java
package com.jison.MyConsole; import java.awt.Dimension; import java.awt.Toolkit; import javax.swing.JFrame; /** * 使JFrame窗口居中显示 * @author jison * @email [email protected] * @time 2015-1-30 */ public class FrameUtil { public static void setFrameCenter(JFrame jf){ //使窗口居中显示 Toolkit toolkit = Toolkit.getDefaultToolkit(); Dimension screen = toolkit.getScreenSize(); //先乘除,后加减,再位移 int x = (screen.width-jf.getWidth()) >> 1; int y = (screen.height-jf.getHeight() >> 1)-16; jf.setLocation(x,y); } }
没了,以上就是全部的代码了。