如何将 STDIO 重定向到 java 应用程序上的 GUI 组件?

发布于 2024-10-10 10:58:18 字数 1307 浏览 4 评论 0原文

在 CI 上,我会简单地创建几个管道并使用 dup2 覆盖 std 文件描述符,而在另一端,我会利用阻塞 IO 在无限循环上为每个输出管道(sdtout、sdterr)创建一个线程管道来更新适合控制台建议的文本区域/画布。至于标准输入,我会监听此类组件上的关键事件,并将它们写入管道。

但是如何在 Java 上使用 swing 来执行此操作呢?

我无法将本机代码混合为项目指令。到目前为止,我已经破坏了许多项目指令,所以我无法继续下去......

此外,提供某种级别的终端仿真(例如 VT100)会很酷,但是如何在 unix 上通知 java 应用程序这种功能我会设置 TERM envvar。

在 CI 上会执行以下操作:

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>

static pthread_t workers[2];

static void *_worker(void *file)
{
    int c;
    if(!file) pthread_exit(NULL);

    while((c=fgetc(file))!=EOF) {
        // Sync and put C on the screen
    }

    pthread_exit(NULL);
}

int initConsole()
{
    int stdin_pipe[2], stdout_pipe[2], stderr_pipe[2];

    if(!(pipe(stdin_pipe)||pipe(stdout_pipe)||pipe(stderr_pipe))) {
        if(dup2(stdin_pipe[0], STDIN_FILENO)<0) return -1;
        if(dup2(stdout_pipe[1], STDOUT_FILENO)<0) return -1;
        if(dup2(stderr_pipe[1], STDERR_FILENO)<0) return -1;

        pthread_create(&workers[0], NULL, _worker, fdopen(stdout_pipe[0], "r"));
        pthread_create(&workers[1], NULL, _worker, fdopen(stderr_pipe[0], "r"));

        // Register a handler within the toolkit to push chars into the stdin_pipe

        return 0;
    }

    return -1;
}

On C I would simple create a couple of pipes and use dup2 to overwrite the std file descriptor, while on the other end I'd create a thread for each outputing pipes (sdtout, sdterr) on a infinite loop taking advantage of the blocking IO of pipes to updated the textArea/canvas fitting the propose of a console. As for the stdin, I would listen for key events on such component, writing those to the pipe.

But how can I perform that on Java with swing?

I can't mix native code as a project directive. I already broke many project directives so far, so I can't push on that...

Also it would be cool to provide some level of terminal emulation, such as VT100, but how to inform the java app of such capability, on unix I would set the TERM envvar.

On C I would do the following:

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>

static pthread_t workers[2];

static void *_worker(void *file)
{
    int c;
    if(!file) pthread_exit(NULL);

    while((c=fgetc(file))!=EOF) {
        // Sync and put C on the screen
    }

    pthread_exit(NULL);
}

int initConsole()
{
    int stdin_pipe[2], stdout_pipe[2], stderr_pipe[2];

    if(!(pipe(stdin_pipe)||pipe(stdout_pipe)||pipe(stderr_pipe))) {
        if(dup2(stdin_pipe[0], STDIN_FILENO)<0) return -1;
        if(dup2(stdout_pipe[1], STDOUT_FILENO)<0) return -1;
        if(dup2(stderr_pipe[1], STDERR_FILENO)<0) return -1;

        pthread_create(&workers[0], NULL, _worker, fdopen(stdout_pipe[0], "r"));
        pthread_create(&workers[1], NULL, _worker, fdopen(stderr_pipe[0], "r"));

        // Register a handler within the toolkit to push chars into the stdin_pipe

        return 0;
    }

    return -1;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

预谋 2024-10-17 10:58:18

您可以通过子类化 PrintStream 并将您的类简单地写入 JTextArea,将 System.out 定向到 JTextArea。然后简单地创建类的实例并调用 System.setOut(yourInstance);

您可以通过子类化 InputStream 并通过从 JTextArea 返回数据来实现 read() 方法,对 System.in 执行非常类似的操作。

You can direct System.out to a JTextArea by subclassing PrintStream and getting your class to simply write to the JTextArea. Then simple create an instance of your class and call System.setOut(yourInstance);

You can do a pretty similar thing with System.in by subclassing InputStream and implementing the read() method by returning data from the JTextArea.

蔚蓝源自深海 2024-10-17 10:58:18

System.err/out 和 in 在 java 中应该做同样的事情。另外,您继承了通道 [System.inheritedChanne()]

我一开始就误解了您的问题,所以如果您需要在线程中读取 System.in 并使用 EventQueue.invokeLater() 附加到文本区域中。

System.err/out and in should do the same in java. Also you have inherited channel [System.inheritedChanne()]

I misunderstood your question at 1st, so if you need to just read System.in in a thread and use EventQueue.invokeLater() to append into a text area.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文