我有这个 JList
,我将其用作 System.out
的显示。我正在使用 JFrame
底部的这个 JList
创建一个 IRC 客户端。似乎每当 2 个或更多元素同时添加到 JLists
ListModel
时,整个 JList
就会变成白色且不可交互,直到有一个元素为止是自己添加的。同时添加多个元素的一个示例是异常打印堆栈跟踪时。
这是我设置为System.out
的OutputStream
类...
public class LogOutputStream extends OutputStream {
String sentence = "";
boolean writing = false;
private DefaultListModel subject;
public LogOutputStream(DefaultListModel logListModel) {
this.subject = logListModel;
}
public void write(final int b) {
try {
sentence = sentence + (char) b;
if (sentence.endsWith("\n") && !sentence.isEmpty() && !sentence.equals("\t") && !sentence.equals("\r\n") && !sentence.equals("\n")) {
if (writing == false) {
writing = true;
subject.addElement(sentence.replaceAll("\n", "").replaceAll("\r", "").trim());
}
sentence = "";
writing = false;
}
}
catch (Exception e) {
e.printStackTrace(Boot.stdErr);
}
}
}
有谁知道这里发生了什么以及如何解决它?
最佳答案
这可能是 Swing 并发问题,因为您正在将项目添加到事件线程之外的 JList 模型中。这可能会占用线程并阻止它执行绘制 GUI 或允许用户交互有效卡住 Swing GUI 的必要操作。
尝试确保仅在 EDT(Swing 事件调度线程)上写入 JList。像这样的事情会将 Swing 事件线程上的 addElement(...)
调用排队:
public void write(final int b) {
try {
sentence = sentence + (char) b;
if (sentence.endsWith("\n") && !sentence.isEmpty()
&& !sentence.equals("\t") && !sentence.equals("\r\n")
&& !sentence.equals("\n")) {
if (writing == false) {
writing = true;
final String text = sentence.replaceAll("\n", "")
.replaceAll("\r", "").trim();
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
subject.addElement(text);
}
});
}
sentence = "";
writing = false;
}
} catch (Exception e) {
e.printStackTrace(Boot.stdErr);
}
}
编辑 1
这更接近于我过去使用 StringBuilder 所做的事情:
import java.io.IOException;
import java.io.OutputStream;
import javax.swing.DefaultListModel;
import javax.swing.SwingUtilities;
public class JListOutputStream extends OutputStream {
private DefaultListModel logListModel;
private StringBuilder sb = new StringBuilder();
public JListOutputStream(DefaultListModel logListModel) {
this.logListModel = logListModel;
}
@Override
public void write(int b) throws IOException {
if (b == '\r')
return;
if (b == '\n') {
final String text = sb.toString().trim();
sb.setLength(0);
if (text.isEmpty()) {
return;
}
SwingUtilities.invokeLater(new Runnable() {
public void run() {
logListModel.addElement(text);
}
});
return;
}
sb.append((char) b);
}
}
编辑2
根据这篇题为 Writing Your Own Java I/O Stream Classes 的文章,如果您要扩展 OutputStream,请不要忘记为 flush()
和 close()
方法提供自定义实现。
关于java - JList 变为空白 [我认为输出流缓冲问题],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11181918/