Как синхронно перекрасить пользовательскую консоль с помощью потоков? - PullRequest
1 голос
/ 03 октября 2011

У меня есть JScrollPane (упакованный с текстовой областью), который действует как пользовательская консоль для моего приложения Swing. Вот код для моей консоли

    class InternalConsoleFrame{
    static JTextArea outArea    
    static JScrollPane consoleHolder

    static setUpStreams(){
        outArea = new javax.swing.JTextArea(10,100)
        System.setErr(new PrintStream(new JTextAreaOutputStream(outArea)));
        System.setOut(new PrintStream(new JTextAreaOutputStream(outArea)));
        WriterAppender logAppender = new WriterAppender(new PatternLayout(), new JTextAreaOutputStream(outArea));
        Logger.getRootLogger().addAppender(logAppender);        
    }

    public InternalConsoleFrame(){

        DefaultCaret caret = (DefaultCaret)outArea.getCaret();
        caret.setUpdatePolicy(DefaultCaret.OUT_BOTTOM);

        outArea.setBackground(new Color(255,250,205));
        outArea.setForeground(Color.BLACK);
        outArea.setLineWrap(true);
        outArea.setWrapStyleWord(true);
        outArea.setFont(new Font(null, Font.PLAIN, 13));
        outArea.addMouseListener(new ConsolePopup());
        consoleHolder = new JScrollPane(outArea);

    }    

}

public class JTextAreaOutputStream extends OutputStream {
    JTextArea ta;

    JTextAreaOutputStream(javax.swing.JTextArea t) {
        super();
        ta = t;
    }

    public synchronized void write(int i) {
        ta.append(Character.toString((char)i));

    }

    public synchronized void write(char[] buf, int off, int len) {
        String s = new String(buf, off, len);
        ta.append(s);

    }

}

Сервер API на внутреннем сервере постоянно печатает состояние (используя println / lo4j из внутреннего интерфейса), но моя пользовательская консоль не может синхронно захватывать операторы log4j / print и перерисовывать себя.

Он отбрасывает весь набор операторов log4j из серверной части только после полного завершения вызова API. Я хочу, чтобы моя консоль перехватывала операторы backend log4j / println во время вызова API и перерисовывалась сама. Как этого достичь?

Я предполагаю, что созданный объект InternalConsoleFrame () блокируется собственным потоком колебания awt до полного выполнения вызова API. Если это так, я думаю, что мне нужно запустить приведенный выше фрагмент кода в новый поток. Если да, то в какой части приведенного выше кода я должен реализовать многопоточность. Я в замешательстве .. Пожалуйста, помогите ..

1 Ответ

1 голос
/ 04 октября 2011

Согласен, похоже, что вы блокируете поток отправки событий (EDT) , нарушая базовое правило потоков для Swing: доступ ко всем компонентам должен происходить в EDT.Для этого реализуйте SwingWorker, в его API есть несколько примеров, другой недавно обсужденный здесь

...