JavaFX:将输入/输出/错误从ProcessBuilder重定向到TextArea?

JavaFX:将输入/输出/错误从ProcessBuilder重定向到TextArea?,java,io,javafx-8,processbuilder,Java,Io,Javafx 8,Processbuilder,我正在学习JavaFX并尝试使用它。我试图构建一个控制台/命令提示符。但我不知道如何将输入/输出/错误从ProcessBuilder重定向到TextArea 代码: 我解决了问题,没有必要关闭溪流。仅在每个命令末尾追加\n,并刷新流。特别感谢我的朋友JulioGessar,他在看了一眼代码之后为我提供了解决方案。这是代码。我希望这段代码可以用于使用Java和JavaFX创建自定义终端或终端模拟器。感谢@colti对我问题的回答 代码如下: /** * * @author n

我正在学习JavaFX并尝试使用它。我试图构建一个控制台/命令提示符。但我不知道如何将输入/输出/错误从ProcessBuilder重定向到TextArea

代码:


我解决了问题,没有必要关闭溪流。仅在每个命令末尾追加
\n
,并刷新流。特别感谢我的朋友JulioGessar,他在看了一眼代码之后为我提供了解决方案。这是代码。我希望这段代码可以用于使用Java和JavaFX创建自定义终端或终端模拟器。感谢@colti对我问题的回答

代码如下:

   /**
    *
    * @author nika
    */
    public class JavaFXConsole extends Application {

ProcessBuilder pb;
Process process;
TextArea ta;
String input = "";
int counter = 0;
BufferedReader stdInput, stdError;
OutputStream out;

//static BufferedReader stdInput, stdError;
//static Thread outputThread;
@Override
public void start(Stage primaryStage) throws InterruptedException {
    ta = new TextArea("/bin/bash\n");
    ta.setOnKeyTyped(new EventHandler<KeyEvent>() {

        @Override
        public void handle(KeyEvent event) {
            {

                input = input.concat(event.getCharacter());
                System.out.println(input);
            }

        }
    });

    final KeyCombination keyComb1 = new KeyCodeCombination(KeyCode.C,
            KeyCombination.CONTROL_DOWN);
    ta.setOnKeyPressed(new EventHandler<KeyEvent>() {

        @Override
        public void handle(KeyEvent event) {
            if (event.getCode() == KeyCode.ENTER) {
                try {
                    //getOutPut(input+"\n");
                    String command = input.replaceAll("\r", "") + "\n";
                    command = input.replaceAll("\b", "");
                    out.write(command.getBytes());
                    out.flush();
                    //getOutPut(command);
                    input = "";
                    System.out.println("Command Sent");
                } catch (IOException ex) {
                    Logger.getLogger(JavaFXConsole.class.getName()).log(Level.SEVERE, null, ex);
                }
            } else if (keyComb1.match(event)) {

                System.out.println("Control+C pressed");
            }else if (event.getCode()== KeyCode.BACK_SPACE){
             //    input=input.substring(0, input.length()-1);
              //  System.out.println(input);
            }

        }
    });

    HBox root = new HBox();
    root.getChildren().add(ta);

    pb = new ProcessBuilder("/bin/bash");
    new Thread(new Runnable() {

        @Override
        public void run() {
            try {
                process = pb.start();
                stdInput = new BufferedReader(new InputStreamReader(process.getInputStream()));

                stdError = new BufferedReader(new InputStreamReader(process.getErrorStream()));

                //OutputStream out;
                out = process.getOutputStream();

                StreamGobbler errorGobbler = new StreamGobbler(process.getErrorStream(), "ERROR");

    // any output?
                StreamGobbler outputGobbler = new StreamGobbler(process.getInputStream(), "OUTPUT");

    // start gobblers
                outputGobbler.start();
                errorGobbler.start();

                process.waitFor();

            } catch (IOException ex) {
                Logger.getLogger(JavaFXConsole.class.getName()).log(Level.SEVERE, null, ex);
            } catch (InterruptedException ex) {
                Logger.getLogger(JavaFXConsole.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }).start();

    Scene scene = new Scene(root, 300, 250);

    primaryStage.setTitle("Hello World!");
    primaryStage.setScene(scene);
    primaryStage.show();

}


private class StreamGobbler extends Thread {

    InputStream is;
    String type;

    private StreamGobbler(InputStream is, String type) {
        this.is = is;
        this.type = type;
    }

    @Override
    public void run() {
        try {
            InputStreamReader isr = new InputStreamReader(is);
            BufferedReader br = new BufferedReader(isr);
            String line = null;
            while ((line = br.readLine()) != null) {
                System.out.println(type + "> " + line);
                String str =line;
                 Platform.runLater(new Runnable() {

                        @Override
                        public void run() {
                            ta.appendText(">" + str + "\n");

                        }
                    });
            }
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
    }
}

/**
 * @param args the command line arguments
 */
public static void main(String[] args) {
    launch(args);
}

}
/**
*
*@作者尼卡
*/
公共类JavaFXConsole扩展了应用程序{
ProcessBuilder pb;
工艺过程;
文本区域ta;
字符串输入=”;
int计数器=0;
缓冲读取器标准输入,标准输出;
输出流输出;
//静态缓冲读取器stdInput,stdError;
//静态线程输出线程;
@凌驾
public void start(Stage primaryStage)抛出中断异常{
ta=新文本区域(“/bin/bash\n”);
ta.setOnKeyTyped(新的EventHandler(){
@凌驾
公共无效句柄(KeyEvent事件){
{
input=input.concat(event.getCharacter());
系统输出打印项次(输入);
}
}
});
final KeyCombination keyComb1=新的keycodecompbination(KeyCode.C,
按键组合。控制按钮(向下);
ta.setOnKeyPressed(新的EventHandler(){
@凌驾
公共无效句柄(KeyEvent事件){
if(event.getCode()==KeyCode.ENTER){
试一试{
//getOutPut(输入+“\n”);
String命令=input.replaceAll(“\r”和“)+“\n”;
command=input.replaceAll(“\b”和“”);
out.write(command.getBytes());
out.flush();
//getOutPut(命令);
输入=”;
System.out.println(“发送命令”);
}捕获(IOEX异常){
Logger.getLogger(JavaFXConsole.class.getName()).log(Level.SEVERE,null,ex);
}
}else if(keyComb1.匹配(事件)){
System.out.println(“控制+C按下”);
}else if(event.getCode()==KeyCode.BACK\u空格){
//input=input.substring(0,input.length()-1);
//系统输出打印项次(输入);
}
}
});
HBox根=新的HBox();
root.getChildren().add(ta);
pb=新的ProcessBuilder(“/bin/bash”);
新线程(newrunnable()){
@凌驾
公开募捐{
试一试{
process=pb.start();
stdInput=new BufferedReader(新的InputStreamReader(process.getInputStream());
stdError=新的BufferedReader(新的InputStreamReader(process.getErrorStream());
//输出流输出;
out=process.getOutputStream();
StreamGobbler errorGobbler=新的StreamGobbler(process.getErrorStream(),“ERROR”);
//有输出吗?
StreamGobbler outputGobbler=新的StreamGobbler(process.getInputStream(),“OUTPUT”);
//开始狼吞虎咽
outputGobbler.start();
errorGobbler.start();
process.waitFor();
}捕获(IOEX异常){
Logger.getLogger(JavaFXConsole.class.getName()).log(Level.SEVERE,null,ex);
}捕获(中断异常例外){
Logger.getLogger(JavaFXConsole.class.getName()).log(Level.SEVERE,null,ex);
}
}
}).start();
场景=新场景(根,300,250);
setTitle(“你好,世界!”);
初级阶段。场景(场景);
primaryStage.show();
}
私有类StreamGobbler扩展线程{
输入流为;
字符串类型;
私有StreamGobbler(InputStream为,字符串类型){
this.is=is;
this.type=type;
}
@凌驾
公开募捐{
试一试{
InputStreamReader isr=新的InputStreamReader(is);
BufferedReader br=新的BufferedReader(isr);
字符串行=null;
而((line=br.readLine())!=null){
系统输出打印项次(类型+“>”+行);
字符串str=行;
Platform.runLater(新的Runnable(){
@凌驾
公开募捐{
ta.appendText(“>”+str+“\n”);
}
});
}
}捕获(ioe异常ioe){
ioe.printStackTrace();
}
}
}
/**
*@param指定命令行参数
*/
公共静态void main(字符串[]args){
发射(args);
}
}

请参见此处的答案:(特别是控制器类)@colti但如何将输入从TextArea发送到ProcessBuilder?获得输出是容易的部分。但同时保持两者,我不知道我们如何才能做到这一点?阅读链接中的答案。创建一个线程来持续读取ProcessBuilder中的内容,并将读取的内容发送到JavaFX线程以更新TextArea。@colti是的,这就是我所说的获取输出很容易的部分。但是如何从文本区域向ProcessBuilder发送击键(输入)。您的帖子则相反:“从ProcessBuilder到TextArea”。无论如何,也要做同样的事情——创建一个线程来侦听TextArea上的击键(即keypressed事件),并将其发送给ProcessBuilder。
   Jan 22, 2015 10:54:57 PM javafxconsole.JavaFXConsole$2 handle
   SEVERE: null
java.io.IOException: Stream closed
at java.lang.ProcessBuilder$NullOutputStream.write(ProcessBuilder.java:433)
at java.io.OutputStream.write(OutputStream.java:116)
at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
at java.io.FilterOutputStream.close(FilterOutputStream.java:158)
at javafxconsole.JavaFXConsole$2.handle(JavaFXConsole.java:69)
at javafxconsole.JavaFXConsole$2.handle(JavaFXConsole.java:58)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)

at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Scene$KeyHandler.process(Scene.java:3931)
at javafx.scene.Scene$KeyHandler.access$1800(Scene.java:3877)
at javafx.scene.Scene.impl_processKeyEvent(Scene.java:2006)
at javafx.scene.Scene$ScenePeerListener.keyEvent(Scene.java:2468)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$KeyEventNotification.run(GlassViewEventHandler.java:197)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$KeyEventNotification.run(GlassViewEventHandler.java:147)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleKeyEvent(GlassViewEventHandler.java:227)
at com.sun.glass.ui.View.handleKeyEvent(View.java:544)
at com.sun.glass.ui.View.notifyKey(View.java:954)
at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
at com.sun.glass.ui.gtk.GtkApplication.lambda$null$45(GtkApplication.java:126)
at com.sun.glass.ui.gtk.GtkApplication$$Lambda$42/379110473.run(Unknown Source)
at java.lang.Thread.run(Thread.java:745)
   /**
    *
    * @author nika
    */
    public class JavaFXConsole extends Application {

ProcessBuilder pb;
Process process;
TextArea ta;
String input = "";
int counter = 0;
BufferedReader stdInput, stdError;
OutputStream out;

//static BufferedReader stdInput, stdError;
//static Thread outputThread;
@Override
public void start(Stage primaryStage) throws InterruptedException {
    ta = new TextArea("/bin/bash\n");
    ta.setOnKeyTyped(new EventHandler<KeyEvent>() {

        @Override
        public void handle(KeyEvent event) {
            {

                input = input.concat(event.getCharacter());
                System.out.println(input);
            }

        }
    });

    final KeyCombination keyComb1 = new KeyCodeCombination(KeyCode.C,
            KeyCombination.CONTROL_DOWN);
    ta.setOnKeyPressed(new EventHandler<KeyEvent>() {

        @Override
        public void handle(KeyEvent event) {
            if (event.getCode() == KeyCode.ENTER) {
                try {
                    //getOutPut(input+"\n");
                    String command = input.replaceAll("\r", "") + "\n";
                    command = input.replaceAll("\b", "");
                    out.write(command.getBytes());
                    out.flush();
                    //getOutPut(command);
                    input = "";
                    System.out.println("Command Sent");
                } catch (IOException ex) {
                    Logger.getLogger(JavaFXConsole.class.getName()).log(Level.SEVERE, null, ex);
                }
            } else if (keyComb1.match(event)) {

                System.out.println("Control+C pressed");
            }else if (event.getCode()== KeyCode.BACK_SPACE){
             //    input=input.substring(0, input.length()-1);
              //  System.out.println(input);
            }

        }
    });

    HBox root = new HBox();
    root.getChildren().add(ta);

    pb = new ProcessBuilder("/bin/bash");
    new Thread(new Runnable() {

        @Override
        public void run() {
            try {
                process = pb.start();
                stdInput = new BufferedReader(new InputStreamReader(process.getInputStream()));

                stdError = new BufferedReader(new InputStreamReader(process.getErrorStream()));

                //OutputStream out;
                out = process.getOutputStream();

                StreamGobbler errorGobbler = new StreamGobbler(process.getErrorStream(), "ERROR");

    // any output?
                StreamGobbler outputGobbler = new StreamGobbler(process.getInputStream(), "OUTPUT");

    // start gobblers
                outputGobbler.start();
                errorGobbler.start();

                process.waitFor();

            } catch (IOException ex) {
                Logger.getLogger(JavaFXConsole.class.getName()).log(Level.SEVERE, null, ex);
            } catch (InterruptedException ex) {
                Logger.getLogger(JavaFXConsole.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }).start();

    Scene scene = new Scene(root, 300, 250);

    primaryStage.setTitle("Hello World!");
    primaryStage.setScene(scene);
    primaryStage.show();

}


private class StreamGobbler extends Thread {

    InputStream is;
    String type;

    private StreamGobbler(InputStream is, String type) {
        this.is = is;
        this.type = type;
    }

    @Override
    public void run() {
        try {
            InputStreamReader isr = new InputStreamReader(is);
            BufferedReader br = new BufferedReader(isr);
            String line = null;
            while ((line = br.readLine()) != null) {
                System.out.println(type + "> " + line);
                String str =line;
                 Platform.runLater(new Runnable() {

                        @Override
                        public void run() {
                            ta.appendText(">" + str + "\n");

                        }
                    });
            }
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
    }
}

/**
 * @param args the command line arguments
 */
public static void main(String[] args) {
    launch(args);
}

}