2016-12-21 13 views
2

私は新しいプロジェクトに取り組んでいます。私はJavaからイーサネットを介して外部のコンピュータ(Linux)にコマンドを送信しようとしています。私はシェル接続を作成するためにJschを使用しています。シェルの入力と出力をSystem.outとSystem.inに設定しました。System.inをJavaFX TextFieldにリダイレクトするにはどうすればよいですか?

((ChannelShell)channel).setInputStream(System.in); 
((ChannelShell)channel).setOutputStream(System.out); 

コンソールで動作します。しかし、私はjavafx GUIアプリケーションからリモートにする必要があります。私はすでにのTextAreaにはSystem.outのリダイレクトを解決した:

public void redirectOutputStream() { 
     OutputStream out = new OutputStream() { 

      private final StringBuilder sb = new StringBuilder(); 

      @Override 
      public void write(int b) throws IOException { 
       if (b == '\r') { 
        return; 
       } 

       if (b == '\n') { 
        final String tmp = sb.toString() + "\n"; 
        text.add(tmp); 
        updateText(text); 
        sb.setLength(0); 
       } else { 
        sb.append((char) b); 
       } 
      } 
     }; 

     System.setOut(new PrintStream(out, true)); 
     // System.setErr(new PrintStream(out, true)); 
    } 

しかし、私は、テキストフィールドに何かを書くことができるように、今、私は、テキストフィールドにSystem.inをリダイレクトするためにも必要Enterキーを押しますとにシェルを介してそれを送信外部コンピュータ。

助けていただければ幸いです。ありがとう!

EDIT: 申し訳ありませんが、それでも私のために動作しません:(... 今私は、コードのこの作品(私はJavaFXのを使用しています)があります。システムの

/** Tmp queue for standard input redirecting */ 
BlockingQueue<Integer> stdInQueue = new LinkedBlockingQueue<>(); 



@Override 
    public void initialize(URL arg0, ResourceBundle arg1) { 
     redirectOutputStream(); 
     redirectInputStream(); 
} 


/** redirects standard System.out to GUI command_window */ 
public void redirectOutputStream() { 
    OutputStream out = new OutputStream() { 

     private final StringBuilder sb = new StringBuilder(); 

     @Override 
     public void write(int b) throws IOException { 
      if (b == '\r') { 
       return; 
      } 
      if (b == '\n') { 
       final String tmp = sb.toString() + "\n"; 
       text.add(tmp); 
       updateText(text); 
       sb.setLength(0); 
      } else { 
       sb.append((char) b); 
      } 
     } 
    }; 
    System.setOut(new PrintStream(out, true)); 
    System.setErr(new PrintStream(out, true)); 
} 

/** redirects standard System.in to GUI command_line */ 
public void redirectInputStream() { 
    InputStream in = new InputStream() { 

     @Override 
     public int read() throws IOException { 
      try { 
       int c = stdInQueue.take().intValue(); 
       return c; 
      } catch (InterruptedException exc) { 
       Thread.currentThread().interrupt(); 
       return -1; 
      } 
     } 
    }; 
    System.setIn(in); 
} 


@FXML 
    void sendButtonPressed(ActionEvent event) { 
     if (!command_line.getText().isEmpty()) { 
      for (char c : command_line.getText().toCharArray()) { 
       System.out.write(new Integer(c)); //display in ListView (output) 
       stdInQueue.add(new Integer(c)); 
      } 
      System.out.write(new Integer('\n')); //display in ListView (output)  
      stdInQueue.add(new Integer('\n')); 
      command_line.clear(); 
     } 
    } 

リダイレクトを。私は "コマンドライン" javafx TextFieldを持っているので、このTextFieldにリダイレクトするsshコマンドを書く必要があります。 「Enter」を押すか「send」をクリックするとSystem.inに送信されます"ボタンをクリックします。

私がこれを行う必要があるのは、System.inとSystem.outに設定されているSSH通信を使用しているからです。コンソール(テスト済み)では完全に動作しますが、私のGUIアプリケーションでは動作しません。

ありがとうございます。

+0

テキストフィールドにリンクされたInputStreamを作成できる場合は、 'System.setIn(...)'を使って試してみてください。 – Thomas

+0

申し訳ありませんが、私はコメントを編集する方法がわかりません...私はSystem.setIn(新しいInputStream())を使用しようとしました。私は "read()"メソッドをオーバーライドして成功していませんでした。 – Zuzana

答えて

0

あなたが個々の文字を送信するためにBlockingQueue<Integer>を設定して、入力ストリームはそれから文字を取ることができます:

BlockingQueue<Integer> stdInQueue = new LinkedBlockingQueue<>(); 

System.setIn(new InputStream() { 

    @Override 
    public int read() throws IOException { 
     try { 
      int c = stdInQueue.take().intValue(); 
      return c; 
     } catch (InterruptedException exc) { 
      Thread.currentThread().interrupt(); 
      return -1 ; 
     } 
    } 
}); 

textField.setOnAction(e -> { 
    for (char c : textField.getText().toCharArray()) { 
     stdInQueue.add(new Integer(c)); 
    } 
    stdInQueue.add(new Integer('\n')); 
    textField.clear(); 
}); 

は、ここでは簡単のデモです:テストのために私はちょうどそのバックグラウンドスレッドを設定System.inから読み取る:

import java.io.IOException; 
import java.io.InputStream; 
import java.util.concurrent.BlockingQueue; 
import java.util.concurrent.LinkedBlockingQueue; 

import javafx.application.Application; 
import javafx.scene.Scene; 
import javafx.scene.control.TextField; 
import javafx.scene.layout.StackPane; 
import javafx.stage.Stage; 

public class StdInFromTextField extends Application { 

    @Override 
    public void start(Stage primaryStage) { 

     TextField textField = new TextField(); 

     BlockingQueue<Integer> stdInQueue = new LinkedBlockingQueue<>(); 

     System.setIn(new InputStream() { 

      @Override 
      public int read() throws IOException { 
       try { 
        int c = stdInQueue.take().intValue(); 
        return c; 
       } catch (InterruptedException exc) { 
        Thread.currentThread().interrupt(); 
        return -1 ; 
       } 
      } 
     }); 

     textField.setOnAction(e -> { 
      for (char c : textField.getText().toCharArray()) { 
       stdInQueue.add(new Integer(c)); 
      } 
      stdInQueue.add(new Integer('\n')); 
      textField.clear(); 
     }); 

     // for testing: 
     Thread readThread = new Thread(() -> { 
      try { 
       int i ; 
       while ((i = System.in.read()) != -1) { 
        System.out.print((char)i); 
       } 
      } catch (IOException exc) { 
       exc.printStackTrace(); 
      } 
     }); 
     readThread.setDaemon(true); 
     readThread.start(); 

     primaryStage.setScene(new Scene(new StackPane(textField), 300, 120)); 
     primaryStage.show(); 
    } 

    public static void main(String[] args) { 
     launch(args); 
    } 
} 
+0

申し訳ありませんが、まだ私のために働いていない...私のコードを見ていただけますか? (編集を参照してください) – Zuzana

-1

[OK]を今すぐ作業コードがあります。問題は、私がSystem.inをリダイレクトする方法を理解していないことです(これはおそらく不可能です)。だから私はSSHコネクタから直接ストリームをリダイレクトしなければならなかった。

public class ToradexSSHCommunicator { 

String user; 
String password; 
String ip; 
int port; 

InputStream fromChannel; 
OutputStream toChannel; 

/** logger for error output feed */ 
private static final Logger LOGGER = Logger.getLogger(ToradexSSHCommunicator.class); 

public ToradexSSHCommunicator(String user, String password, String ip, int port) { 
    this.user = user; 
    this.password = password; 
    this.ip = ip; 
    this.port = port; 
} 

public void startup() { 
    Session session = null; 
    ChannelShell channel = null; 
    boolean isConnected = false; 

    JSch jsch = new JSch(); 
    while (!isConnected) { 
     try { 
      session = jsch.getSession(user, ip, port); 

      session.setPassword(password); 
      session.setConfig("StrictHostKeyChecking", "no"); 

      LOGGER.info("Establishing Toradex Connection..."); 
      session.setTimeout(1000); 
      session.connect(); 
      LOGGER.info("Toradex connection established."); 

      LOGGER.info("Creating Toradex channel..."); 
      channel = (ChannelShell) session.openChannel("shell"); 
      LOGGER.info("Toradex channel created."); 

      fromChannel = channel.getInputStream(); 
      toChannel = channel.getOutputStream(); 

      channel.connect(); 
      isConnected = true; 

     } 
     catch (JSchException e) { 
      LOGGER.error("Toradex connection error.....RECONNECTING", e); 
      session.disconnect(); 
     } 
     catch (IOException e) { 
      LOGGER.error("Toradex connection error.....RECONNECTING", e); 
      session.disconnect(); 
     } 
    } 

} 

public InputStream getFromChannel() { 
    return fromChannel; 
} 

public OutputStream getToChannel() { 
    return toChannel; 
    } 
} 

そして、これを使用するGUIのこの部分は、ストリーム::ここで

は、私がJSCHストリームで入力と出力を設定する方法です

@FXML 
private ListView<String> command_window_toradex; 
@FXML 
private TextField command_line; 

private ToradexSSHCommunicator comm; 

private BufferedReader br; 
private BufferedWriter bw; 

@FXML 
    void sendButtonPressed(ActionEvent event) { 
     executor.submit(new Task<Void>() { 

      @Override 
      protected Void call() throws Exception { 
       writeCommand(); 
       return null; 
      } 
     }); 
    } 

/** initialize SSH connection to Toradex and redirect input and output streams to GUI */ 
private void initToradex() { 
    comm = new ToradexSSHCommunicator(GuiConstants.TORADEX_USER, GuiConstants.TORADEX_PASSWORD, 
      GuiConstants.TORADEX_IP_ADDRESS, GuiConstants.TORADEX_PORT); 
    comm.startup(); 
    br = new BufferedReader(new InputStreamReader(comm.getFromChannel())); 
    bw = new BufferedWriter(new OutputStreamWriter(comm.getToChannel())); 
} 

private void writeCommand() throws IOException { 
    if (!command_line.getText().isEmpty()) { 
     String command = command_line.getText(); 
     bw.write(command + '\n'); 
     bw.flush(); 
     command_line.clear(); 
    } 
} 

private void readCommand() throws IOException { 
    String commandLine = null; 
    while (true) { 
     commandLine = br.readLine(); 
     textToradex.add(commandLine); 
    } 
} 

それは働きます!しかし、これはコード全体になっています。さらなる助けが必要な場合は、尋ねてください。

+0

私は申し訳ありません...:/ – Zuzana

+0

今、私の解決策です。 – Zuzana

関連する問題