Java-Prozess mit gleichzeitigen Eingabe- / Ausgabestreams

Ich versuche, eine Art Konsole / Terminal zu erstellen, mit der der Benutzer eine Zeichenfolge eingeben kann, die dann in einen Prozess umgewandelt und die Ergebnisse ausgedruckt werden. Genau wie eine normale Konsole. Ich habe jedoch Probleme beim Verwalten der Eingabe- / Ausgabestreams. Ich habe in @ geschadieser Thread, aber diese Lösung trifft leider nicht auf mein Problem zu.

Neben den Standardbefehlen wie "ipconfig" und "cmd.exe" muss ich in der Lage sein, ein Skript auszuführen und denselben Eingabestrom zu verwenden, um einige Argumente zu übergeben, wenn das Skript Eingaben anfordert.

Zum Beispiel sollte es mir nach dem Ausführen eines Skripts "python pyScript.py" möglich sein, weitere Eingaben an das Skript zu übergeben, wenn es danach fragt (Beispiel: raw_input), und gleichzeitig die Ausgabe des Skripts zu drucken. Das grundlegende Verhalten, das Sie von einem Terminal erwarten würden.

Was ich bisher habe:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;

public class Console extends JFrame{

    JTextPane inPane, outPane;
    InputStream inStream, inErrStream;
    OutputStream outStream;

    public Console(){
        super("Console");
        setPreferredSize(new Dimension(500, 600));
        setLocationByPlatform(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // GUI
        outPane = new JTextPane();
        outPane.setEditable(false);
        outPane.setBackground(new Color(20, 20, 20));
        outPane.setForeground(Color.white);
        inPane = new JTextPane();
        inPane.setBackground(new Color(40, 40, 40));
        inPane.setForeground(Color.white);
        inPane.setCaretColor(Color.white);

        JPanel panel = new JPanel(new BorderLayout());
        panel.add(outPane, BorderLayout.CENTER);
        panel.add(inPane, BorderLayout.SOUTH);

        JScrollPane scrollPanel = new JScrollPane(panel);

        getContentPane().add(scrollPanel);

        // LISTENER
        inPane.addKeyListener(new KeyListener(){
            @Override
            public void keyPressed(KeyEvent e){
              if(e.getKeyCode() == KeyEvent.VK_ENTER){
                    e.consume();
                    read(inPane.getText());
                }
            }
            @Override
            public void keyTyped(KeyEvent e) {}

            @Override
            public void keyReleased(KeyEvent e) {}
        });


        pack();
        setVisible(true);
    }

    private void read(String command){
        println(command);

        // Write to Process
        if (outStream != null) {
            System.out.println("Outstream again");
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outStream));
            try {
                writer.write(command);
                //writer.flush();
                //writer.close();
            } catch (IOException e1) {
                e1.printStackTrace();
            }
        }

        // Execute Command
        try {
            exec(command);
        } catch (IOException e) {}

        inPane.setText("");
    }

    private void exec(String command) throws IOException{
        Process pro = Runtime.getRuntime().exec(command, null);

        inStream = pro.getInputStream();
        inErrStream = pro.getErrorStream();
        outStream = pro.getOutputStream();

        Thread t1 = new Thread(new Runnable() {
            public void run() {
                try {
                    String line = null;
                    while(true){
                        BufferedReader in = new BufferedReader(new InputStreamReader(inStream));
                        while ((line = in.readLine()) != null) {
                            println(line);
                        }
                        BufferedReader inErr = new BufferedReader(new InputStreamReader(inErrStream));
                        while ((line = inErr.readLine()) != null) {
                            println(line);
                        }
                        Thread.sleep(1000);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
        t1.start();
    }

    public void println(String line) {
        Document doc = outPane.getDocument();
        try {
            doc.insertString(doc.getLength(), line + "\n", null);
        } catch (BadLocationException e) {}
    }

    public static void main(String[] args){
        new Console();
    }
}

Ich benutze das erwähnte @ nicProcessBuilder, da ich gerne zwischen fehler und normalem stream unterscheide.

UPDATE 29.08.2016

Mit Hilfe von @ArcticLord haben wir erreicht, was in der ursprünglichen Frage gestellt wurde. Jetzt geht es nur noch darum, seltsame Verhaltensweisen wie den nicht beendenden Prozess auszubügeln. Die Konsole hat einen "Stop" -Button, der einfach pro.destroy () aufruft. Aus irgendeinem Grund funktioniert dies jedoch nicht bei unendlich laufenden Prozessen, bei denen es sich um Spam-Ausgaben handelt.

Console:http: //pastebin.com/vyxfPEX

InputStreamLineBuffer:http: //pastebin.com/TzFamwZ

Beispielcode fürnich halt

public class Infinity{
    public static void main(String[] args){ 
        while(true){
            System.out.println(".");
        }
    }
}

Beispielcode, der stoppt:

import java.util.concurrent.TimeUnit;

public class InfinitySlow{
    public static void main(String[] args){ 
        while(true){
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(".");
        }
    }
}

Antworten auf die Frage(4)

Ihre Antwort auf die Frage