How to synchronously repaint custom console using threads?
I have a JScrollPane(packed with text area) that acts as a custom console for my swing application. Here is the code for my console
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);
}
}
The API server at the back end is continuously printing status (using println/lo4j from backend) but my custom console is not able to synchronously capture the log4j/print statements and repaint itself.
It drops the whole set of log4j statements from the backend only after the total completion of the API call. I want my console to capture the backend log4j/println statements During the API call and repaint itself. How can this be achieved?
My guess is that the InternalConsoleFrame() object created is being blocked by the native swing awt thread until the complete execution of the API call. If this is the case, I think that I need to launch the above code snippet onto a new Thread. If so, in which portion of the above code should I implement threading. I am quite confused..Please help..
Agreed, it looks like you're blocking the event dispatch thread(EDT) by violating the base threading rule for Swing: all component access must happen on the EDT. Implement a SwingWorker to achieve that, its api doc has some examples, another recently discussed here
精彩评论