【发布时间】:2019-10-25 18:25:19
【问题描述】:
我在 JScrollPane 中有一个 JTextPane(水平策略 NEVER 和垂直策略 ALWAYS)。我已经编写了一种在此 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 的可见性上。
任何帮助将不胜感激。
【问题讨论】:
-
在您的情况下,以下改进可能会有所帮助:
SwingUtilities.invokeLater(() -> appendToPanel(this.txt_message, "dummy text "+i, TextType.SUCCESS))。但最好阅读concurrency in Swing。 -
上述方法试过了,还是不行。
-
在这种情况下,您必须阅读Concurrency in Swing 并按照该页面中的示例进行操作。