I’m trying to create a simple app that allows me to redirect all System.out to a JavaFX TextArea
within my app.
For this, I created a CustomOutputStream
class from the OutputStream
class. Here’s the code for it:
//package name //imports public class CustomOutputStream extends OutputStream { private TextArea terminal; public CustomOutputStream(TextArea terminal) { this.terminal = terminal; } @Override public void write(int b) throws IOException { terminal.setText(terminal.getText() + String.valueOf((char) b)); } }
In my AppController.java
file, I put TextArea
as protected so I can access it from another class in the same package:
@FXML protected static TextArea textArea_terminal;
Now this AppContoller.java
, at the press of a button calls a function (runShell()
) from another class. This function (runShell()
) is the function that invokes another function of the Channel
class whose output I’m hoping to put in the TextArea
. As such, for this I implemented my CustomOutputStream
this way:
PrintStream printStream = new PrintStream(new CustomOutputStream(AppController.textArea_terminal)) ; System.setOut(printStream); channel.setOutputStream(System.out); //channel is an instance of my class whose output I need.
Unfortunately, despite this, there is no output in the TextArea
nor in the IDE terminal. And when I added System.out.println("hello")
to test the printStream
, a NullPointerException
occured.
I’m thinking either there’s an issue with the way I pass the TextArea
variable or perhaps an issue with the thread being occupied by my function in channel
.
Any ideas why is this caused and how to resolve it?
Advertisement
Answer
I understand my issue is of a very specific nature and my question was perhaps too broad to convey that sufficiently.
My objective was to get the System.err messages from the output of the exec function in the JSch library and display it in a JavaFX TextArea. As such, I needed to get the error stream from a remote server, not the error stream of my local program.
I attempted to create an OutputStream to perform this but it didn’t solve my issue. As such, I figured out a workaround:
First I wrote the errors from the JSch channel (within which I run my exec fucntion) to a file:
File file = new File("tempOut/errorLog.txt"); FileOutputStream fos = new FileOutputStream(file); PrintStream ps = new PrintStream(fos); System.setErr(ps); ((ChannelExec) channel).setErrStream(System.err);
Then I read that file and display its contents in my GUI:
FileReader fileReader = new FileReader(file); BufferedReader br = new BufferedReader(fileReader); //creates a buffering character input stream String line; while ((line = br.readLine()) != null) { terminalOut = textArea_terminalOut.getText(); terminalOut = terminalOut + "nn" + line; }
And that’s basically the workaround I figured out for this. If there’s a better way, I’d still appreciate it.