JavaFX:将控制台输出重定向到在JavaFX中创建的TextArea

15 篇文章 1 订阅
7 篇文章 0 订阅

一直对于控制台有个问题,他是如何捕获到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的使用真的少。--

  • 16
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 16
    评论
jfxrt.jar 是JavaFX Runtime的一个JAR文件,它包含了JavaFX应用程序的运行时库。如果在使用JavaFX开发应用程序时遇到了"找不到javafx:jar"的错误,可能是因为以下几个原因: 1. 版本不匹配:jfxrt.jar 的具体路径和命名可能会因为不同版本的JavaFX而有所不同。在JavaFX 1.x版本,通常可以在JDK安装目录的 jre/lib 目录下找到 jfxrt.jar。但是在JavaFX 2.x及更高版本JavaFX已经被合并到了Java SDK,不再需要单独的 jfxrt.jar 文件。 2. 缺少依赖:如果使用了一些需要依赖JavaFX的库或工具,但是没有正确地配置jar文件或类路径。在这种情况下,需要确保jfxrt.jar的路径被正确地添加到你的项目的构建路径。 3. 环境变量配置错误:有时会遇到环境变量配置错误的情况,导致Java虚拟机无法正确地找到jfxrt.jar文件。在这种情况下,可以检查和更新JAVA_HOME和PATH环境变量,确保它们指向正确的JDK安装目录。 解决这个问题的方法有几种: - 如果你使用的是JavaFX 2.x或更高版本,那么直接使用Java SDK即可,不需要单独的 jfxrt.jar 文件。检查你的开发环境和项目配置,确保JavaFX已经正确地集成到JDK。 - 如果你使用的是较旧版本的JavaFX,确保jfxrt.jar的路径被正确地添加到你的项目的构建路径。在IDE,可以在项目的构建路径或依赖项添加 jfxrt.jar。 - 检查和更新JAVA_HOME和PATH环境变量,确保它们指向正确的JDK安装目录。此外,还可以尝试重新安装JDK或JavaFX,确保它们被正确地安装和配置。 总之,"找不到javafx:jar"的错误通常出现在JavaFX版本不匹配、依赖缺失或环境变量配置错误的情况下。根据具体的开发环境和项目配置,可以采取相应的方法来解决这个问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

离离原上草77

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值