Reputation: 1497
I am designing a program that has a JEditorPane
where users can enter and compile Java code. They can then run their program in a new process, and then their output will be displayed in a JTextArea
. I accomplish this by extending JTextArea
and adding this as a member:
private OutputStream writer = new OutputStream() {
public void write(int b) {
Console.this.append(String.valueOf((char) b));
}
};
I then have a simple getStream()
method that returns this OutputStream
wrapped in a PrintWriter
, and call System.setOut()
and System.setErr()
with the PrintWriter
.
Now here comes the issue: if the user compiles a program where a lot of output is sent to the Console at once (e.g., infinite loop of System.out.println()
calls), the entire GUI hangs. I have attempted to fix this by using a SwingWorker
to handle the append()
calls but nothing seems to work.
Is there a way to keep the GUI responsive even if massive amounts of text are being written to the JTextArea
? I'm assuming part of the issue is the amount of time time that is taken to update the GUI after an append()
call. Is there maybe a way to delay writing to the JTextArea
by a small amount so that a user can click the button to terminate the process?
Upvotes: 0
Views: 533
Reputation: 285405
I wonder if your problem is the way you're writing in your OutputStream. Perhaps you should write to a StringBuilder object off of the EDT, and then when a "\n" comes along, append the String on the EDT to the JTextArea.
Something like this:
// this is all called in a background thread
public void write(int b) throws IOException {
if (b == '\r')
return;
if (b == '\n') {
final String text = sb.toString() + "\n";
SwingUtilities.invokeLater(new Runnable() {
// except this is queued onto the event thread.
public void run() {
textArea.append(text);
}
});
sb.setLength(0);
return;
}
sb.append((char) b);
}
Upvotes: 4