Как я могу перенаправить STDIO в компонент GUI в Java-приложении? - PullRequest
0 голосов
/ 05 января 2011

В CI просто создать пару каналов и использовать dup2 для перезаписи дескриптора файла std, а на другом конце я бы создал поток для каждого канала вывода (sdtout, sdterr) в бесконечном цикле, используя преимущества блокировка ввода / вывода каналов для обновления текстовой области / холста, соответствующей предложению консоли. Что касается стандартного ввода, я бы слушал ключевые события в таком компоненте и записывал их в канал.

Но как я могу выполнить это на Java с помощью Swing?

Я не могу смешивать нативный код как директиву проекта. Я уже нарушил многие директивы проекта, так что я не могу настаивать на этом ...

Также было бы неплохо обеспечить некоторый уровень эмуляции терминала, такой как VT100, но как сообщить java-приложению о такой возможности, в unix я установил бы TERM envvar.

На C я бы сделал следующее:

#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;
}

Ответы [ 2 ]

1 голос
/ 05 января 2011

Вы можете направить System.out в JTextArea, создав подкласс PrintStream и заставив свой класс просто записать в JTextArea.Затем просто создайте экземпляр своего класса и вызовите System.setOut(yourInstance);

. С System.in вы можете сделать довольно похожую вещь, создав подкласс InputStream и реализовав метод read(), возвращая данные из JTextArea.

1 голос
/ 05 января 2011

System.err / out и in должны делать то же самое в Java.Также вы унаследовали канал [System.inheritedChanne ()]

Я неправильно понял ваш вопрос на 1-м, поэтому, если вам нужно просто прочитать System.in в потоке и использовать EventQueue.invokeLater () для добавления в текстобласть.

...