[英]Scrollbars not visible for JTextPane when appending text into JTextPane
我在JScrollPane中有一个JTextPane(始终使用水平策略,而始终使用垂直策略)。 我已经编写了一种在此JTextPane中附加文本的方法。 现在有一个按钮,单击该按钮,动作侦听器正在运行以进行一些数据操作并更新JTextPane上的数据。 我正在使用JScrollPane.update()方法刷新附加的文本。 文本正确更新,直到达到JTextPane的高度。 添加更多文本时,它应显示垂直滚动条并更新文本。 但是,这没有发生。 相反,当流程从动作侦听器方法中流出时,整个文本将显示。
我尝试过同时更新JTextPane和JScrollPane。 但这似乎不起作用。
JTextPane txt_message = new JTextPane();
txt_message.setPreferredSize(new Dimension(300,300));
JScrollPane sPane = new JScrollPane(txt_message);
sPane.setHorizontalScrollBarPolicy
(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
sPane.setVerticalScrollBarPolicy
(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
sPane.setPreferredSize(new Dimension(320,320));
pnl_messagePane.add(sPane);
txt_message.setEditable(false);
DefaultCaret caret = (DefaultCaret) txt_message.getCaret();
caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);
//some other GUI elements
.....
btn_Run.addActionListener(e->{
for(int i=1; i<100; i++){
appendToPanel(this.txt_message, "dummy text "+i, TextType.SUCCESS);
}
//TextType is an enum defined in code whose value can be SUCCESS, ERROR
});
// Method for appending JTextPanel Text
private void appendToPane(JTextPane tp, String msg, TextType type)
{
Color c = null;
switch(type) {
case ERROR:
c = Color.RED;
break;
case SUCCESS:
c=Color.GREEN;
break;
default:
c = Color.BLACK;
}
StyledDocument doc = tp.getStyledDocument();
SimpleAttributeSet keyWord = new SimpleAttributeSet();
StyleConstants.setForeground(keyWord, c);
StyleConstants.setBold(keyWord, true);
try
{
doc.insertString(doc.getLength(), "\n"+msg, keyWord );
}
catch(Exception e) {
System.out.println(e);
}
tp.update(tp.getGraphics());
this.sPane.update(this.sPane.getGraphics());
}
在循环运行时,应将JTextPane中的文本更新为
虚拟文字1
虚拟文字2
虚拟文字3
。 。 。
假设在伪文本10之后,它达到了JScrollPane的高度。
现在预期的行为是-
它应该继续更新新文本,例如
虚拟文字11
虚拟文字12
..和垂直滚动条应出现。
但是实际行为是-
它可以正常工作,直到伪文本10(假设JScrollPane的高度可以容纳10行)。 之后,JTextPane闪烁但没有任何反应,并且在循环完成时,它使用垂直滚动条一次显示了剩余的90行。
虚拟文字11
虚拟文字12
。
。
。
我猜这个问题是在我添加越来越多的行时JScrollBar可见性的某个地方。
任何帮助,将不胜感激。
相反,当流程从动作侦听器方法中流出时,整个文本将显示。
从侦听器调用的代码在Event Dispatch Thread (EDT)
。
因此,如前所述,您的循环代码正在EDT
上执行。 EDT
负责重新绘制GUI,但是直到主循环执行完成后才能这样做。
它可以正常工作,直到伪文本10(假设JScrollPane的高度可以容纳10行)。 之后,JTextPane闪烁但没有任何反应
它似乎仅能正常工作,因为您未正确使用Swing:
tp.update(tp.getGraphics());
this.sPane.update(this.sPane.getGraphics());
您不应该直接调用update(...)方法。 需要重绘组件时,Swing将在内部调用此方法。 强制更新会导致闪烁。 不要这样!
代替更新文本区域,您需要在单独的Thread
上执行代码,以免阻塞EDT
。
一种方法是使用SwingWorker
。 它为您创建了线程,并允许您根据需要publish()
结果publish()
到文本窗格,以便随后在EDT上正确更新文本窗格。
在注释部分获得的Concurrency
链接包含有关How to Use a SwingWorker
以及相关工作示例的部分,以帮助您入门。 本教程还介绍了EDT
工作原理。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.