JavaFX:将控制台输出重定向到在JavaFX中创建的TextArea
一直对于控制台有个问题,他是如何捕获到println的内容?思路:我们可以将,控制台的内容从他的父类容器中截获,使它的内容可以显示到我们想让他显示的地方去。在控制台,system的out()方法一直在监控全局,system有个方法,system.setOut()是将监控的内容输出到指定地点,system.setErr()是将异常输出。这是主要的两个地点,通常情况下,在监控器打开的时候,会指...
一直对于控制台有个问题,他是如何捕获到println的内容?
思路:我们可以将,控制台的内容从他的父类容器中截获,使它的内容可以显示到我们想让他显示的地方去。
在控制台,system的out()方法一直在监控全局,system有个方法,system.setOut()是将监控的内容输出到指定地点,system.setErr()是将异常输出。这是主要的两个地点,通常情况下,在监控器打开的时候,会指定这两个地方,比如cmd会将这两个值设置为在cmd窗口下append()拼接。在eclipse中,会将这两个值指向console控制台。这个值是可以改变的。所以,我们可以用javafx写一demo,实现这个功能。
在Java中有个PrintSteram,这个有点像javafx中 的scene,只是一个容器,在printSteam中存放print()的内容,然后将它的内容铺写到指定的textArea中,这个文本框必须继承OutputStream类,实现他的write()方法,这里需要加一个监听,将printSteram的内容实时监控刷新,然后显示。
最后,附上代码。
main.java
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) {
try {
Parent root = FXMLLoader.load(getClass().getResource("../demo3/test.fxml"));
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
primaryStage.setTitle("控制台输出测试");
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
MainController.java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.TextArea;
public class MainController {
@FXML
private TextArea console;
private PrintStream ps;
public void initialize() {
ps = new ConsolePrint(console);
}
public void button(ActionEvent event) {
System.setOut(ps);
System.setErr(ps);
System.out.println("你好世界");
this.testIpConfig();
}
public void testIpConfig() {
Runtime runtime = Runtime.getRuntime();
try {
runtime.exec("ipconfig");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Process process = null;
try {
process = runtime.exec("cmd.exe /c dir d:\\");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
InputStream inputStream = process.getInputStream();
BufferedReader br = null;
//cmd系统默认设置为gbk码,这里解析为gbk码
br = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("GBK")));
String line = null;
try {
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public class ConsolePrint extends PrintStream {//可以正常解析utf8和gbk码
TextArea console;
public ConsolePrint(TextArea console) {
super(new ByteArrayOutputStream());
this.console = console;
}
@Override
public void write(byte[] buf, int off, int len) {
print(new String(buf, off, len));
}
@Override
public void print(String s) {
console.appendText(s);
}
}
public class Console extends OutputStream {
private TextArea console;
public Console(TextArea console) {
this.console = console;
}
public void appendText(String valueOf) {
console.appendText(valueOf);
}
public void write(int b) throws IOException {
appendText(String.valueOf((char) b));//这里解析非ascii码会出错乱码
}
}
}
test.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.control.TextArea?>
<?import javafx.scene.control.Button?>
<?import javafx.geometry.Insets?>
<BorderPane xmlns:fx="http://javafx.com/fxml/1" fx:controller="demo3.MainController">
<center>
<TextArea fx:id="console"/>
</center>
<bottom>
<Button onAction="#button" text="Output">
<BorderPane.alignment>CENTER</BorderPane.alignment>
<BorderPane.margin><Insets top="5" left="5" right="5" bottom="5"/></BorderPane.margin>
</Button>
</bottom>
</BorderPane>
启动测试
点击outPut试试
成功捕获到ipconfig的cmd执行命令的返回值,还有cmd的查询d盘命令的返回值。
-----------------------分割线---------------------------------
2020-03-25 更新
有提问说乱码问题,原来以为是cmd返回的流设置错误,是个小问题,测试后发现out拦截出问题了,在out的流中,只能转int值的char数据,也就是只能转ASCII码,对于中文问题不行,重写了定向流后解决该问题
ps:不得不吐槽一句,javafx的问题是真的难找答案啊。国内对于javafx的使用真的少。--
更多推荐
所有评论(0)