I am working on new project. I am trying to send commands to external computer (Linux) through ethernet from Java. I am using Jsch to create shell connection. I set shell input and output to System.out and System.in.
((ChannelShell)channel).setInputStream(System.in);
((ChannelShell)channel).setOutputStream(System.out);
It works in console! But I need to remote it from javafx GUI app. I have already solved redirecting of System.out to TextArea:
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));
}
But now I need also to redirect System.in to TextField, so that I can write something into TextField, press enter and send it through shell to the external computer.
Any help would be appreciate. Thanks!
EDIT: Sorry, still doesn't work for me :( ... Now I have this piece of code (I am using 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();
}
}
The redirecting of System.out and System.err works perfectly. It is being displayed in javafx ListView.
The problem is still that under the ListView I have a "command line" javafx TextField and I need to write some ssh command into this TextField and redirect it to System.in when pressing "enter" or clicking on "send" button.
The reason why I need to do this is that I am using SSH communication, which is set for System.in and System.out. It fully works in console (tested), but not in my GUI app.
Thanks for any further advice!
You can set up a
BlockingQueue<Integer>
to send the individual characters to, and then have the input stream take characters from it:Here's a quick demo: for testing I just set up a background thread that reads from
System.in
: