英文:
How to redirect output from System.out to JavaFx TextArea
问题
我正在尝试创建一个简单的应用程序,允许我将所有的 System.out 重定向到 JavaFX 的 TextArea
中。
为此,我从 OutputStream
类创建了一个名为 CustomOutputStream
的类。以下是该类的代码:
//包名
//导入语句
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));
}
}
在我的 AppController.java
文件中,我将 TextArea
声明为 protected
,以便我可以从同一包中的另一个类中访问它:
@FXML
protected static TextArea textArea_terminal;
现在,在 AppController.java
中,当按下一个按钮时,会调用另一个类中的一个函数(runShell()
)。这个函数(runShell()
)会调用 Channel
类的另一个函数,我希望将该函数的输出放入 TextArea
中。因此,我通过以下方式实现了我的 CustomOutputStream
:
PrintStream printStream = new PrintStream(new CustomOutputStream(AppController.textArea_terminal));
System.setOut(printStream);
channel.setOutputStream(System.out); // channel 是我需要输出的类的实例。
然而,尽管如此,在 TextArea
中和 IDE 终端中都没有输出。当我添加 System.out.println("hello")
来测试 printStream
时,出现了 NullPointerException
。
我认为可能是我传递 TextArea
变量的方式存在问题,或者可能是由于 channel
中的函数占用了线程造成的问题。
有关导致这种情况的原因以及如何解决它的任何想法吗?
英文:
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?
答案1
得分: 0
我明白我的问题非常具体,也许我的问题过于宽泛,无法充分传达这一点。
我的目标是从JSch库中exec函数的输出中获取System.err消息,并将其显示在JavaFX的TextArea中。因此,我需要从远程服务器获取错误流,而不是获取本地程序的错误流。
我尝试创建一个OutputStream来实现这一点,但并没有解决我的问题。因此,我想出了一个解决方法:
首先,我将JSch通道(我在其中运行exec函数)的错误写入文件中:
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);
然后,我读取该文件并在GUI中显示其内容:
FileReader fileReader = new FileReader(file);
BufferedReader br = new BufferedReader(fileReader);
String line;
while ((line = br.readLine()) != null)
{
terminalOut = textArea_terminalOut.getText();
terminalOut = terminalOut + "\n\n" + line;
}
这基本上是我为此问题找到的解决方法。如果有更好的方法,我仍然会很感激。
英文:
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 + "\n\n" + line;
}
And that's basically the workaround I figured out for this. If there's a better way, I'd still appreciate it.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论