繁体   English   中英

将文本追加到JTextPane时,JTextPane的滚动条不可见

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM