How can I redirect the STDIO to a GUI component on a java app?
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.
精彩评论