我有一个项目,它在控制台中逐行打印数字,并且我成功地将其重定向到我用于此应用程序的GUI Jframe。但是,当数字被打印到TextArea中时,它们不会像滚动列表一样很好地一一显示。相反,我看到整个TextArea闪烁并反复打印。阅读完成后,TextArea中的所有内容看起来都正确。是否有一种方法可以正确地进行设置,以便打印出的效果就像在控制台中看到的一样?]
非常感谢您提供帮助!
为了重定向system.out,我有以下代码:
package ibanchecker03;
import java.io.IOException;
import java.io.OutputStream;
import javax.swing.JTextArea;
public class CustomOutputStream extends OutputStream {
private JTextArea textArea;
public CustomOutputStream(JTextArea textArea){
this.textArea=textArea;
}
@Override
public void write(int b) throws IOException {
// redirects data to the text area
textArea.append(String.valueOf((char)b));
// scrolls the text area to the end of data
textArea.setCaretPosition(textArea.getDocument().getLength());
// keeps the textArea up to date
textArea.update(textArea.getGraphics());
}
}
然后在应用程序类内部,我有这个重定向输出:
PrintStream printStream = new PrintStream(new CustomOutputStream(display));
System.setOut(printStream);
System.setErr(printStream);
而不是写每个字符(并更新每个字符的textArea
),我建议您实现一个缓冲区(使用StringBuilder
)并附加到该缓冲区。仅更新textArea
上的flush()
,并在单独的线程中进行。类似,
public class CustomOutputStream extends OutputStream {
private StringBuilder sb = new StringBuilder();
private JTextArea textArea;
public CustomOutputStream(JTextArea textArea) {
this.textArea = textArea;
}
@Override
public void write(int b) throws IOException {
sb.append((char) b);
}
@Override
public void flush() {
if (sb.length() > 0) {
final String toWrite = sb.toString();
sb.setLength(0);
SwingUtilities.invokeLater(() -> {
textArea.append(toWrite);
textArea.setCaretPosition(textArea.getDocument().getLength());
textArea.update(textArea.getGraphics());
});
}
}
@Override
public void close() {
flush();
sb = null;
}
}