开发者

How can I redirect the STDIO to a GUI component on a java app?

开发者 https://www.devze.com 2023-02-02 21:07 出处:网络
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

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, fd开发者_StackOverflow中文版open(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;
}


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.


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消