0

ここに私が働こうとしているいくつかのコードがあります。基本的に、プロセスを開いたままにして、単一のセッションで新しいコマンドをフィードする必要があります。「exit」文字列コマンドが発行されると、プロセスは終了するはずです。助けてくれてありがとう....

Process process;
ArrayList<String>command;
ProcessBuilder builder;
Map<String, String> environ;
BufferedWriter bw;
BufferedReader br;
BufferedReader buffErrorStreamReader;

....

 try
    {
    command = new ArrayList<String>();
    command.add("cmd.exe");
    command.add("/c");
    //command.add(currentLine);

    builder = new ProcessBuilder(command);
    environ = builder.environment();

    builder.directory(new File("C://"));
    process = builder.start();

    }catch(Exception e)
          {
          System.out.println(e);
          }

    //Get a System.in Stream
    OutputStream output = process.getOutputStream();
    OutputStreamWriter osw = new OutputStreamWriter(output);
    bw = new BufferedWriter(osw);

    //Get a System.out Stream
    InputStream is = process.getInputStream();
    InputStreamReader isr = new InputStreamReader(is);
    br = new BufferedReader(isr);

    //Get a System.err Stream
    InputStream errorStream = process.getErrorStream();
    InputStreamReader errorStreamReader = new InputStreamReader(errorStream);
    buffErrorStreamReader = new BufferedReader(errorStreamReader);



....

//Read the command from my text component terminal
String currentLine = getCurrentLine();


    ///pass command to pipe input 
    bw.write(currentLine);
    System.out.println("wrote: "+currentLine);

    ///print response 
     String line;
    while ((line = br.readLine()) != null) 
    {
      System.out.println(line);
      //term.println(line);    
    }

    ///print any error response
    String errorLine;
    while ((errorLine = buffErrorStreamReader.readLine()) != null) 
    {
      System.out.println(errorLine);
      //term.println(errorLine);    
    }
4

4 に答える 4

0

エラー ストリームと入力ストリームの両方を EOS まで読み取っていますが、これはプロセスが終了するまで発生しません (または、30 年以上見たことがないので、stdout と stderr を閉じることはめったにありません)。通常の方法は、(a) エラー ストリームと出力ストリームをマージする、および/または (b) 別々のスレッドで読み取ることです。本質的に、外部プロセスではあまり知ることができないものです。

于 2012-10-23T09:26:29.683 に答える
0

これが私のターミナルのコードです。私が話しているコードは、VK.ENTER キーの switch ステートメントにあります。

注意。ディレクトリを変更する場合、絶対パスでのみ機能します。たとえば、「cd C://Users/Aubrey/」は、Users ディレクトリの「cd /Aubrey」ではありません!!!

/*
 * Terminal.java - A convienence console.
 * 
 * http://www.splashportal.net
 * 30/09/2012
 */
package terminal;

import java.awt.*;
import java.awt.event.*;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Map;
import javax.swing.JScrollPane;
public class Terminal extends Canvas
{
static final long serialVersionUID = 5479170142892558288L;

public static int WIDTH = 80, HEIGHT = 200;
static Process process;

public static final Color
    WHITE       = new Color(0xffffff),
    RED         = new Color(0xff0000),
    GREEN       = new Color(0x00cc00),
    BROWN       = new Color(0x996600),
    BLUE        = new Color(0x0000ff),
    DARK_GREEN  = new Color(0x009900),
    DARK_BLUE   = new Color(0x000099),
    LIGHT_GREY  = new Color(0x999999),
    DARK_GREY   = new Color(0x666666),
    CYAN        = new Color(0x00ffff),
    DARK_CYAN   = new Color(0x009999),
    DARK_YELLOW = new Color(0x999900),
    MAGENTA     = new Color(0xff00ff),
    YELLOW      = new Color(0xffff00),
    PURPLE      = new Color(0x990099),
    BLACK       = new Color(0x000000);

private static final Color[] COLORS = {
        WHITE           ,  // 0 @
        RED             ,  // 1 A
        GREEN           ,  // 2 B
        BROWN           ,  // 3 C
        BLUE            ,  // 4 D
        DARK_GREEN      ,  // 5 E
        DARK_BLUE       ,  // 6 F
        LIGHT_GREY      ,  // 7 G
        DARK_GREY       ,  // 8 H
        CYAN            ,  // 9 I
        DARK_CYAN       ,  // 10 J
        DARK_YELLOW     ,  // 11 K
        MAGENTA         ,  // 12 L
        YELLOW          ,  // 13 M
        PURPLE          ,  // 14 N
        BLACK           ,  // 15 O
    };

public static final int EFFECTS_UNDERLINE = 1;

private static final int
    ESC_NORMAL  = 0,
    ESC_ESCAPE  = 1,
    ESC_POS_Y   = 2,
    ESC_POS_X   = 3,
    ESC_FGCOLOR = 4,
    ESC_BGCOLOR = 5;

    static boolean isBreak=false;
    static int heightCounter;
    static ArrayList lines;
    static Terminal term;
    static Frame f;
    static File startPath;

public static Color getColor(int i)
{
    return COLORS[i & 0x0f];
}
static String newPath = System.getenv("temp");


public static void main(String[] args)
{
    f = new Frame("Terminal Test");
    f.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent we) {
                f.dispose();
            }
        } );

    term = new Terminal();

     //add buffer_ image to a scrollpane somehow?
    scrollPane = new ScrollPane();

    scrollPane.add(term, buffer_);

    // disabling forward focus traversal allows TAB to reach the component
    term.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
            Collections.EMPTY_SET);
    term.addKeyListener(new KeyAdapter() {
            public void keyPressed(KeyEvent ke) {
                // handle special keys
                switch(ke.getKeyCode()) {
                    case KeyEvent.VK_UP:
                        term.print("\033A");
                        term.repaint();
                        break;
                    case KeyEvent.VK_DOWN:
                        term.print("\033B");
                        term.repaint();
                        break;
                    case KeyEvent.VK_RIGHT:
                        term.print("\033C");
                        term.repaint();
                        break;
                    case KeyEvent.VK_LEFT:
                        term.print("\033D");
                        term.repaint();
                        break;
                    case KeyEvent.VK_ENTER:

    //flag set to block printing of ">>" prompt                 
    isR=true;                    
    try{
    String currentLine = getCurrentLine();
    ArrayList<String>command = new ArrayList<String>();
    command.add("cmd.exe");
    command.add("/c");
    command.add(currentLine);
    System.out.println("Line-IN: "+currentLine);
    ProcessBuilder builder = new ProcessBuilder(command);
    Map<String, String> environ = builder.environment();

    if (currentLine.startsWith("cd")){      
    //startPath = new File(".").getAbsoluteFile();    

    //if an absolute path is specified and exists    
    if(new File(currentLine.substring(3)).exists())
    newPath=currentLine.substring(3);

    System.out.println("Directory : "+new File(newPath));
    builder.directory(new File(newPath));
    process = builder.start();
    InputStream is = process.getInputStream();
    InputStreamReader isr = new InputStreamReader(is);
    BufferedReader br = new BufferedReader(isr);

    InputStream errorStream = process.getErrorStream();
    InputStreamReader errorStreamReader = new InputStreamReader(errorStream);
    BufferedReader buffErrorStreamReader = new BufferedReader(errorStreamReader);

    String line;
    //term.println("");
    while ((line = br.readLine()) != null) {
      System.out.println(line);
      term.println(line);    
    }
    String errorLine;
    term.println("");
    while ((errorLine = buffErrorStreamReader.readLine()) != null) {
      //System.out.println(line);
      term.println(errorLine);    
    }
    buffErrorStreamReader.close();
    br.close();
    //not sure how to use this method to allow for an interactive prompt?
    //for example a "dir /p" command should allow the output to be paged per keypress!
    process.waitFor();
    //flags set to allow printing of ">>" prompt
    isR=false;
    isNew=true;

    System.out.println("Program terminated!");

    }else if(currentLine.startsWith("exit")||currentLine.startsWith("quit")){
                               System.exit(0);
    }else if(currentLine.startsWith("dir /p")){
        //try using dos batch?
    System.out.println("page...");
    command = new ArrayList<String>();
    command.add("cmd.exe");
    command.add("dir"); 
    builder.directory(new File(newPath));
    process = builder.start();
    InputStream is = process.getInputStream();
    InputStreamReader isr = new InputStreamReader(is);
    BufferedReader br = new BufferedReader(isr);

    String line;

    //write out to a FLAT FILE.
    File temp = new File("temp");
    PrintWriter tempOut = new PrintWriter(new FileWriter(temp));
    while ((line = br.readLine()) != null) {
    System.out.println(line);
    tempOut.println(line);    
    }
    //not sure how to use this method to allow for an interactive prompt?
    //for example a "dir /p" command should allow the output to be paged per keypress!
    process.waitFor();

    //flags set to allow printing of ">>" prompt

    br.close();
    tempOut.flush();
    tempOut.close();

    captureLines();  
    int index = 0;

    printPage(index);

    isR=false;
    isNew=true;

    System.out.println("Program terminated!");


    }else
    {    


    builder.directory(new File(newPath));
    process = builder.start();

    Thread t = new Thread() {
    public void run() {
        try{
        System.out.println("blah");
        InputStream is = process.getInputStream();
    InputStreamReader isr = new InputStreamReader(is);
    BufferedReader br = new BufferedReader(isr);

    InputStream errorStream = process.getErrorStream();
    InputStreamReader errorStreamReader = new InputStreamReader(errorStream);
    BufferedReader buffErrorStreamReader = new BufferedReader(errorStreamReader);



    String line;
    //term.println("");
    while ((line = br.readLine()) != null) {
      //System.out.println(line);
      term.println(line);    
    }
    String errorLine;
    //term.println("");
    while ((errorLine = buffErrorStreamReader.readLine()) != null) {
      //System.out.println(line);
      term.println(errorLine);    
    }
    buffErrorStreamReader.close();
    br.close();
    //not sure how to use this method to allow for an interactive prompt?
    //for example a "dir /p" command should allow the output to be paged per keypress!
    process.waitFor();

   //flags set to allow printing of ">>" prompt
    isR=false;
    isNew=true;  

    term.println("");
        }catch(Exception e){System.out.println(e);}
    }
};
t.start();




    System.out.println("Program terminated!");
} 

    }catch(Exception e){System.out.println(e);}
  }
}

            public void keyTyped(KeyEvent ke) {
                char c = ke.getKeyChar();
                if( c == KeyEvent.CHAR_UNDEFINED ) {
                    // handle special keys
                    switch(ke.getKeyCode()) {
                        case KeyEvent.VK_TAB:
                            c = '\t';
                            break;
                        case KeyEvent.VK_ESCAPE:
                            c = (char)27;
                            break;
                    }
                }
                if( c != KeyEvent.CHAR_UNDEFINED ) {
                    term.print(c);
                    term.repaint();
                }
            }
        } );

    f.add(scrollPane, BorderLayout.CENTER);
    term.validate();
    scrollPane.setSize(598, 316);
    //f.setSize(700, 400);
    f.pack();
    f.setVisible(true);

    term.println(DARK_GREY, WHITE, "vTerminal");
    //term.println(DARK_GREY, WHITE, ">>");
    term.requestFocus();
}

private int tileWidth_ = 8;
private int tileHeight_ = 12;
private static TerminalLine[] line_;
private int xCursor_;
private static int yCursor_;
private int xCursorSave_;
private int yCursorSave_;
private boolean wrap_ = true;
private boolean scroll_ = true;
private boolean cursorVisible_ = true;
private int tab_ = 8;
private int xOffset_ = 0;
private int yOffset_ = 0;
private int escapeMode_ = ESC_NORMAL;
/** First character held in an ESC Y Position Cursor command. */
private int escapeHold_ = -1;
private boolean reverseVideo_;
private byte effects_;

private static Image buffer_;
private static ScrollPane scrollPane;
private static Boolean isNew = false;
private static Boolean isR = false;
于 2012-10-24T11:30:22.260 に答える
0

//作業コードの 2 番目の部分

/** Creates a new terminal.  */
    public Terminal()
    {



        line_ = new TerminalLine[HEIGHT];
        for(int y = 0; y < HEIGHT; ++y) {
            line_[y] = new TerminalLine(WIDTH);
        }

        setBackground(DARK_GREY);
        setForeground(LIGHT_GREY);
        setFont( new Font("Monospaced", Font.PLAIN, 12) );
        clearScreen();
    }
    public static void captureLines(){

        String line;

        try{

        heightCounter=Terminal.HEIGHT;
        BufferedReader tempIn = new BufferedReader(new FileReader("temp"));
        term.println("");
        lines = new ArrayList();
        while((line = tempIn.readLine())!=null)
            {
            lines.add(line);
            }
        tempIn.close();

        }catch(Exception e){System.out.println(e);}
        return;
    }
    public static void printPage(int index){
        try{
        if(index<lines.size()){
        for (int i=0; i<25; i++){

            if(index==lines.size())
              return; 

           //System.out.println(index+" "+lines.get(index));
           term.println(lines.get(index).toString());
           index++;  
        }Thread.sleep(500);

        printPage(index);
        }else{return;}

    }catch(Exception e){System.out.println(e);}
    }

    public static String getCurrentLine(){
    TerminalLine currentLine = line_[getYCursor()];
        String command="";

                for(char c: currentLine.data){
                command+= c;
                        }
        String outString = command.substring(2);
        return (outString.trim());
    }

    public synchronized void clearScreen()
    {
        for(int y = 0; y < HEIGHT; ++y) {
            clearLine(y);
        }
        repaint();
    }

    public synchronized void clearLine(int line)
    {
        clearLine(line, 0, WIDTH-1);
    }

    public synchronized void clearLine(int y, int x0, int x1)
    {
        Color bg = getBackground();
        Color fg = getForeground();
        TerminalLine line = line_[y];


        for(int x = x0; x <= x1; ++x) {
            line.data[x] = ' ';
            line.bgColor[x] = bg;
            line.fgColor[x] = fg;
            line.effects[x] = 0;
        }
    }

    public synchronized boolean getCursorVisible()
    { return cursorVisible_; }

    public synchronized char getData(int x, int y)
    {
        return line_[y].data[x];
    }

    public synchronized Color getBgColor(int x, int y)
    {
        return line_[y].bgColor[x];
    }

    public synchronized byte getEffects(int x, int y)
    {
        return line_[y].effects[x];
    }

    public synchronized Color getFgColor(int x, int y)
    {
        return line_[y].fgColor[x];
    }

    public synchronized Dimension getMaximumSize()
    {
        return getPreferredSize();
    }

    public synchronized Dimension getMinimumSize()
    {
        return getPreferredSize();
    }

    public synchronized Dimension getPreferredSize()
    {
        return new Dimension(WIDTH * tileWidth_, HEIGHT * tileHeight_);
    }

    public boolean getReverseVideo()
    { return reverseVideo_; }

    public synchronized boolean getScroll()
    { return scroll_; }

    public synchronized int getTab()
    { return tab_; }

    public int getTileWidth()
    { return tileWidth_; }

    public int getTileHeight()
    { return tileHeight_; }

    public synchronized int getXOffset()
    { return xOffset_; }

    public synchronized int getYOffset()
    { return yOffset_; }

    public synchronized int getXCursor()
    { return xCursor_; }

    public static synchronized int getYCursor()
    { return yCursor_; }

    public synchronized void gotoxy(int x, int y)
    {
        xCursor_ = x;
        yCursor_ = y;
    }

    public synchronized void print(String s)
    {
        print(null, null, s);
    }

    public synchronized void print(Color bg, Color fg, String s)
    {
        for(int i = 0, len = s.length(); i < len; ++i) {
            print(bg, fg, s.charAt(i) );
        }
        repaint();
    }

    public synchronized void print(char c)
    {
        print(null, null, c);
    }

    public synchronized void print(Color bg, Color fg, char c)
    {
        if( escapeMode_ == ESC_NORMAL ) {
            switch(c) {
                case 7:     //  7 = BEL, bell
                    bell();
                    break;
                case '\b':  //  8 = BS, backspace
                    --xCursor_;
                    break;
                case '\t':  //  9 = HT, tab
                    xCursor_ = ((xCursor_ + tab_) / tab_) * tab_;
                    break;
                case '\n':  // 10 = LF, newline
                    xCursor_ = 0;
                    ++yCursor_;
                    //flag set to allow printing of ">>" prompt 
                    isNew=true;
                    break;
                case 11:    // 11 = VT, vertical tab
                case '\f':  // 12 = FF, form feed
                    ++yCursor_;
                    break;
                case '\r':  // 13 = CR, ignored because Java's newline is \n
                    break;
                case 27:    // 27 = ESC, enters escape mode
                    escapeMode_ = ESC_ESCAPE;
                    break;
                case 127: { // 127 = DEL, right-delete
                    int yc = yCursor_;
                    TerminalLine line = line_[yc];
                    for(int x = xCursor_; x < WIDTH-1; ++x) {
                        line.setData(x, line.bgColor[x+1], line.fgColor[x+1],
                            line.data[x+1], line.effects[x+1] );
                    }
                    setData(WIDTH-1, yc, null, null, ' ');
                    break;
                }
                default:
                    if( c < 32 ) {
                        // unknown control character
                        bell();
                    } else {
                        setData(xCursor_, yCursor_, bg, fg, c);
                        ++xCursor_;
                    }
            }
        } else {
            escapeMode_ = doEscape(c);
        } 
        // wrap cursor
        if( xCursor_ < 0 ) {
            if( wrap_ ) {
                xCursor_ = WIDTH-1;
                --yCursor_;
            } else {
                xCursor_ = 0;
            }
        } else if( xCursor_ >= WIDTH ) {
            if( wrap_ ) {
                xCursor_ = 0;
                ++yCursor_;
            } else {
                xCursor_ = WIDTH-1;
            }
        }
        if( yCursor_ < 0 ) {
            if( scroll_ ) {
                scrollDown(0);
            }
            yCursor_ = 0;
        } else if( yCursor_ >= HEIGHT ) {
            if( scroll_ ) {
                scrollUp(0);
            }
            yCursor_ = HEIGHT-1;
        }
        //cool flags here to print ">>" prompt: 1. when there is new line and 2. when the isR flag has detected the end of printing  in the return event.
        if(isR){
            isNew=false;

        }
        if(isNew){
            isNew=false;
         print(DARK_GREY, YELLOW, ">>");

        }
    }

    public synchronized void scrollDown(int topline)
    {
        // scroll down, exposing a blank line at top
        // don't waste the existing array, recycle it.
        TerminalLine line0 = line_[HEIGHT-1];
        // move all lines down
        for(int y = HEIGHT-1; y > topline; --y) {
            line_[y] = line_[y-1];
        }
        // put it at the top
        line_[topline] = line0;
        clearLine(topline);
    }

    public synchronized void scrollUp(int topline)
    {
        // scroll up, exposing a blank line at bottom
        // don't waste the existing array, recycle it.
        TerminalLine line0 = line_[topline];
        // move all lines up
        for(int y = topline; y < HEIGHT-1; ++y) {
            line_[y] = line_[y+1];
        }
        // put it at the end
        line_[HEIGHT-1] = line0;
        clearLine(HEIGHT-1);
    }

    private int doEscape(char c)
    {
        switch(escapeMode_) {
            case ESC_NORMAL:
                throw new IllegalStateException();
            case ESC_ESCAPE:
                // handled below
                break;
            case ESC_POS_Y:
                escapeHold_ = Math.max(0, Math.min(HEIGHT-1, (int)(c - 32)));
                return ESC_POS_X;
            case ESC_POS_X:
                yCursor_ = escapeHold_;
                xCursor_ = Math.max(0, Math.min(WIDTH-1, (int)(c - 32)));
                return ESC_NORMAL;
            case ESC_FGCOLOR:
                setForeground( getColor( (int)c ) );
                return ESC_NORMAL;
            case ESC_BGCOLOR:
                setBackground( getColor( (int)c ) );
                return ESC_NORMAL;
            default:
                throw new IllegalStateException("Unknown escape mode "+escapeMode_);
        }

        switch(c) {
            case 24:        // 24 = CAN, cancel escape
            case 26:        // 26 = SUB, cancel escape
            case 27:        // 27 = ESC, cancel escape
                return ESC_NORMAL;
            case 'A':       // Cursor Up
                if( yCursor_ > 0 ) {
                    --yCursor_;
                }
                return ESC_NORMAL;
            case 'B':       // Cursor Down
                if( yCursor_ < HEIGHT-1 ) {
                    ++yCursor_;
                }
                return ESC_NORMAL;
            case 'C':       // Cursor Forward
                if( xCursor_ < WIDTH-1 ) {
                    ++xCursor_;
                }
                return ESC_NORMAL;
            case 'D':       // Cursor Backward
                if( xCursor_ > 0 ) {
                    --xCursor_;
                }
                return ESC_NORMAL;
            case 'E':       // Clear Screen, Home Cursor
                clearScreen();
                xCursor_ = 0;
                yCursor_ = 0;
                return ESC_NORMAL;
            case 'H':       // Home Cursor
                xCursor_ = 0;
                yCursor_ = 0;
                return ESC_NORMAL;
            case 'I':       // Reverse Index
                --yCursor_;
                return ESC_NORMAL;
            case 'J':       // Erase to End of Page
                clearLine(yCursor_, xCursor_, WIDTH-1);
                for(int y = yCursor_+1; y < HEIGHT; ++y) {
                    clearLine(y);
                }
                return ESC_NORMAL;
            case 'K':       // Erase to End of Line
                clearLine(yCursor_, xCursor_, WIDTH-1);
                return ESC_NORMAL;
            case 'L':       // Insert Line
                scrollDown(yCursor_);
                xCursor_ = 0;
                return ESC_NORMAL;
            case 'M':       // Delete Line
                scrollUp(yCursor_);
                xCursor_ = 0;
                return ESC_NORMAL;
            case 'N': {     // Delete Character
                int yc = yCursor_;
                TerminalLine line = line_[yc];
                for(int x = xCursor_; x < WIDTH-1; ++x) {
                    line.setData(x, line.bgColor[x+1], line.fgColor[x+1],
                        line.data[x+1], line.effects[x+1] );
                }
                setData(WIDTH-1, yc, null, null, ' ');
                break;
            }
            case 'Y':       // Position Cursor
                return ESC_POS_Y;
            case 'b':       // Set Foreground Color
                return ESC_FGCOLOR;
            case 'c':       // Set Background Color
                return ESC_BGCOLOR;
            case 'd': {     // Erase from Beginning of Display
                int xc = xCursor_, yc = yCursor_;
                clearLine(yc, 0, xc);
                for(int y = 0; y < yc; ++y) {
                    clearLine(y);
                }
                return ESC_NORMAL;
            }
            case 'j':       // Save Cursor Position
                xCursorSave_ = xCursor_;
                yCursorSave_ = yCursor_;
                return ESC_NORMAL;
            case 'k':       // Restore Cursor Position
                xCursor_ = xCursorSave_;
                yCursor_ = yCursorSave_;
                return ESC_NORMAL;
            case 'l':       // Erase Entire Line
                clearLine(yCursor_);
                xCursor_ = 0;
                return ESC_NORMAL;
            case 'm':       // Enable Cursor
                cursorVisible_ = true;
                return ESC_NORMAL;
            case 'n':       // Disable Cursor
                cursorVisible_ = false;
                return ESC_NORMAL;
            case 'o':       // Erase from Beginning of Line
                clearLine(yCursor_, 0, xCursor_);
                return ESC_NORMAL;
            case 'p':       // Enable Reverse Video
                reverseVideo_ = true;
                return ESC_NORMAL;
            case 'q':       // Disable Reverse Video
                reverseVideo_ = false;
                return ESC_NORMAL;
            case 'r':       // Enable Underlining
                effects_ |= EFFECTS_UNDERLINE;
                return ESC_NORMAL;
            case 'u':       // Disable Underlining
                effects_ &= ~EFFECTS_UNDERLINE;
                return ESC_NORMAL;
            case 'v':       // Enable Wrapping
                wrap_ = true;
                return ESC_NORMAL;
            case 'w':       // Disable Wrapping
                wrap_ = false;
                return ESC_NORMAL;
        }
        // unknown escape code
        bell();
        return ESC_NORMAL;
    }

    public synchronized void println(String s)
    {
        println(null, null, s);
    }

    public synchronized void println(Color bg, Color fg, String s)
    {
        print(bg, fg, s);
        print(bg, fg, '\n');
        repaint();
    }

    public synchronized void setCursorVisible(boolean c)
    { cursorVisible_ = c; }

    public synchronized void setData(int x, int y, char c)
    {
        setData(x, y, null, null, c);
    }

    public synchronized void setData(int x, int y, Color bg, Color fg, char c)
    {
        setData(x, y, bg, fg, c, effects_);
    }

    public synchronized void setData(int x, int y, Color bg, Color fg, char c, byte effects)
    {
        if( bg == null ) {
            bg = getBackground();
        }
        if( fg == null ) {
            fg = getForeground();
        }
        if( reverseVideo_ ) {
            Color tmp = bg;
            bg = fg;
            fg = tmp;
        }
        TerminalLine line = line_[y];
        line.data[x] = c;
        line.bgColor[x] = bg;
        line.fgColor[x] = fg;
        line.effects[x] = effects;
    }

    public synchronized void setBgColor(int x, int y, Color b)
    {
        line_[y].bgColor[x] = b;
    }

    public synchronized void setEffects(int x, int y, byte e)
    {
        line_[y].effects[x] = e;
    }

    public synchronized void setFgColor(int x, int y, Color f)
    {
        line_[y].fgColor[x] = f;
    }

    public void setFont(Font font)
    {
        super.setFont(font);
        FontMetrics fm = Toolkit.getDefaultToolkit().getFontMetrics(font);
        tileWidth_ = fm.charWidth('W');
        tileHeight_ = fm.getHeight() - fm.getDescent();
        xOffset_ = 0;
        yOffset_ = -fm.getDescent();
        //System.out.println("tile "+tileWidth_+"x"+tileHeight_+", offset="+xOffset_+","+yOffset_);
    }

    public void setReverseVideo(boolean r)
    { reverseVideo_ = r; }

    public synchronized void setScroll(boolean s)
    { scroll_ = s; }

    public synchronized void setTab(int t)
    { tab_ = t; }

    public void setTileSize(int w, int h)
    {
        tileWidth_ = w;
        tileHeight_ = h;
        buffer_ = null;
    }

    public synchronized void setXOffset(int x)
    { xOffset_ = x; }

    public synchronized void setYOffset(int y)
    { yOffset_ = y; }

    public synchronized void setXCursor(int x)
    { xCursor_ = x; }

    public synchronized void setYCursor(int y)
    { yCursor_ = y; }

    public synchronized void paint(Graphics g)
    {
        if( buffer_ != null ) {
            g.drawImage(buffer_, 0, 0, null);
        }
    }

    public synchronized void update(Graphics gg)
    {
        if( buffer_ == null ) {
            Dimension d = getPreferredSize();
            buffer_ = createImage(d.width, d.height);
            if( buffer_ == null ) {
                repaint(100L); //wtf?
                return;
            }
        }

        Graphics g = buffer_.getGraphics();
        g.setFont( getFont() );
        FontMetrics fm = g.getFontMetrics();
        char[] cbuf = new char[1];  // for drawChars
        for(int y = 0; y < HEIGHT; ++y) {
            int sy = y * tileHeight_;
            TerminalLine line = line_[y];
            for(int x = 0; x < WIDTH; ++x) {
                int sx = x * tileWidth_;
                // background
                g.setColor( line.bgColor[x] );
                g.fillRect(sx, sy, tileWidth_, tileHeight_);
                // character
                g.setColor( line.fgColor[x] );
                cbuf[0] = line.data[x];
                g.drawChars(cbuf, 0, 1, sx + xOffset_,
                        sy + fm.getAscent() + yOffset_);
                // effects
                if( (line.effects[x] & EFFECTS_UNDERLINE) != 0 ) {
                    g.drawLine(sx, sy+tileHeight_-1,
                            sx+tileWidth_-1, sy+tileHeight_-1);
                }
                // borders for testing
                //g.drawLine(sx, sy, sx+tileWidth_-1, sy);
                //g.drawLine(sx, sy, sx, sy+tileHeight_-1);
            }
        }
        if( cursorVisible_ ) {
            Color bg = getBgColor(xCursor_, yCursor_);
            if( bg == BLACK ) {
                bg = WHITE;
            }
            g.setXORMode(bg);
            g.fillRect(xCursor_ * tileWidth_, yCursor_ * tileHeight_,
                    tileWidth_, tileHeight_);
            g.setPaintMode();
        }

        paint(gg);
    }

    }
    class TerminalLine
    {
    public Color[] bgColor;
    public Color[] fgColor;
    public char[] data;
    public byte[] effects;

    public TerminalLine(int width)
    {
        bgColor = new Color[width];
        fgColor = new Color[width];
        data = new char[width];
        effects = new byte[width];
    }
    public void setData(int x, Color bg, Color fg, char c, byte e)
    {
        data[x] = c;
        bgColor[x] = bg;
        fgColor[x] = fg;
        effects[x] = e;
    }   
 }
于 2012-10-24T11:35:13.633 に答える
0

私の完全なコードは機能しています。キャンバス上の現在の行からコマンドを受け取る端末があります。次に、「cmd.exe」、「/c」、および「現在の行からのコマンド文字列」パラメータを使用してプロセス ビルダーを組み立てます。最後に、ビルダー環境を取得し、ビルダー ディレクトリを設定します。次に、プロセスを開始し、プロセスの入力ストリームとエラー ストリームの両方を取得します。次に、これらの応答をキャンバス ターミナルに出力します。ただし、私のアプローチの問題は、すべてのプロセスで新しい cmd.exe (dos コマンド プロンプト) を開いていることです。したがって、基本的には、コマンドの送信 (新しいプロセス) 間でセッションが確立されないため、非対話型ターミナルです。プロセスはコマンドを受け取り、出力を出力して毎回終了します。私の質問は、インタラクティブな端末セッションをどのように実装できるかです。現在のパスを保存し、それを builder.directory メソッドで新しいプロセスに渡すことで、ディレクトリを変更する機能を正常に実装しました。また、builder.environment を使用して環境変数に対して同じことを行うことも可能かもしれません (しかし、私はそれを理解できません)。それは本当のセッションの印象を与えるでしょう. ストリームのスレッド化も試しましたが、うまくいきます。しかし、スレッドがコマンド応答を出力した後にプロセスが終了するため、間違っているに違いありません。ストリームのスレッド化も試しましたが、うまくいきます。しかし、スレッドがコマンド応答を出力した後にプロセスが終了するため、間違っているに違いありません。ストリームのスレッド化も試しましたが、うまくいきます。しかし、スレッドがコマンド応答を出力した後にプロセスが終了するため、間違っているに違いありません。

于 2012-10-24T10:56:54.463 に答える