JTextArea添加到JScrollPane无法显示滚动条

哈得撸泽 2020-08-21 11:02:51
各位大佬,小弟遇到一个问题,好几天解决不掉,特来寻找大佬的帮助。
实现需求:只要产生新的String就到实时打印到JTextArea(JTextArea添加到JScrollPane),并且需要实时显示滚动条。
我的实现:,每次产生新的String就要启动一个新的线程(Thread_update)进行打印,部分代码如下。
问题:JScrollPane的滚动条只有在结束完成才会一次显示,中间String都超过JScrollPane的可视域了但是进度条都没有显示。
求大佬们帮助。

//初始化JTextArea()和JScrollPane()
return_text = new JTextArea();
//return全局输出编辑框不可编辑
return_text.setEditable(false);
//设置自动换行
return_text.setLineWrap(true);
// 设置断行不断字
return_text.setWrapStyleWord(true);
//return输出界面(带进度条)初始化
return_scrollpane = new JScrollPane();
return_scrollpane.setViewportView(return_text);
return_scrollpane.setAutoscrolls(true);
return_scrollpane.setBounds(10, 40, 570, 408);
container.add(return_scrollpane);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);



//每次产生新的sth就要启动一个线程进行打印
updateThread(sth);



//启动打印线程
private void updateThread(String sth) {
Thread_update thread_update = new Thread_update(sth);
thread_update.start();
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
}



//子线程的实现
private class Thread_update extends Thread {
private String sth;

public Thread_update(String sth) {
this.sth = sth;
}

@Override
public void run() {
return_text.setText(return_text.getText() + sth);
return_text.paintImmediately(return_text.getBounds());
return_text.setCaretPosition(return_text.getDocument().getLength());
return_scrollpane.revalidate();
try {
Thread.sleep(100);
} catch (Exception e) {
e.printStackTrace();
}
}
}
...全文
8278 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
哈得撸泽 2020-08-24
  • 打赏
  • 举报
回复
引用 8 楼 sunyiz 的回复:
[quote=引用 7 楼 哈得撸泽 的回复:] 嗯,试了下把listener里边的sleep全部去掉是可以能正常打印的,滚动条也可以实时显示,但是因为listener里边涉及到网络数据的读取,也不知道可以读取的字节数,我现在实现是设计等待时间去读取,如果不使用sleep可以使用什么去做这个延时又不会影响到UI的绘制?大佬。
你这样的需求,应该在你的那个 Thread_update 线程中做类似于网络数据读取的耗时任务 然后再任务做完之后,根据结果再去刷新界面 注意 SwingUtilities.invokeLater 中的任务会在EDT中执行,所以这个里面只能执行UI刷新的代码 所有耗时代码也不能放到 SwingUtilities.invokeLater 里做[/quote]大佬,完美解决,非常感谢🙏太感谢了🙏
sunyiz 2020-08-23
  • 打赏
  • 举报
回复
引用 5 楼 哈得撸泽 的回复:
嗯,是的,这个update_Thread我是放在ActionEvent的监听器中,然后使用按钮添加了这个监听器。大佬的意思是我使这个监听器所在线程睡眠了,影响了UI的绘制?
嗯,是这意思。 你之前能让文字刷新,是因为你强制调用了文本控件的 paintImmediately ,但是这样做并不合适
sunyiz 2020-08-23
  • 打赏
  • 举报
回复
引用 7 楼 哈得撸泽 的回复:
嗯,试了下把listener里边的sleep全部去掉是可以能正常打印的,滚动条也可以实时显示,但是因为listener里边涉及到网络数据的读取,也不知道可以读取的字节数,我现在实现是设计等待时间去读取,如果不使用sleep可以使用什么去做这个延时又不会影响到UI的绘制?大佬。
你这样的需求,应该在你的那个 Thread_update 线程中做类似于网络数据读取的耗时任务 然后再任务做完之后,根据结果再去刷新界面 注意 SwingUtilities.invokeLater 中的任务会在EDT中执行,所以这个里面只能执行UI刷新的代码 所有耗时代码也不能放到 SwingUtilities.invokeLater 里做
哈得撸泽 2020-08-23
  • 打赏
  • 举报
回复
引用 6 楼 sunyiz 的回复:
[quote=引用 5 楼 哈得撸泽 的回复:] 嗯,是的,这个update_Thread我是放在ActionEvent的监听器中,然后使用按钮添加了这个监听器。大佬的意思是我使这个监听器所在线程睡眠了,影响了UI的绘制?
嗯,是这意思。 你之前能让文字刷新,是因为你强制调用了文本控件的 paintImmediately ,但是这样做并不合适[/quote]嗯,试了下把listener里边的sleep全部去掉是可以能正常打印的,滚动条也可以实时显示,但是因为listener里边涉及到网络数据的读取,也不知道可以读取的字节数,我现在实现是设计等待时间去读取,如果不使用sleep可以使用什么去做这个延时又不会影响到UI的绘制?大佬。
哈得撸泽 2020-08-22
  • 打赏
  • 举报
回复
引用 4 楼 sunyiz 的回复:
无法实时显示应该和你的 updateThread 方法中 sleep 有关 这个方法你应该是在某个 Listener 中调用的, Swing 所有控件的 listener 都是在 EDT 中执行的 而 EDT 负责 UI 绘制 你把 sleep 在 EDT 中执行,会阻碍界面的正常刷新
嗯,是的,这个update_Thread我是放在ActionEvent的监听器中,然后使用按钮添加了这个监听器。大佬的意思是我使这个监听器所在线程睡眠了,影响了UI的绘制?
sunyiz 2020-08-22
  • 打赏
  • 举报
回复
无法实时显示应该和你的 updateThread 方法中 sleep 有关 这个方法你应该是在某个 Listener 中调用的, Swing 所有控件的 listener 都是在 EDT 中执行的 而 EDT 负责 UI 绘制 你把 sleep 在 EDT 中执行,会阻碍界面的正常刷新
哈得撸泽 2020-08-21
  • 打赏
  • 举报
回复
哈得撸泽 2020-08-21
  • 打赏
  • 举报
回复
@Override
public void run() {
// return_text.setText(return_text.getText() + sth);
// return_text.paintImmediately(return_text.getBounds());
// return_text.setCaretPosition(return_text.getDocument().getLength());
// return_scrollpane.revalidate();
// try {
// Thread.sleep(100);
// } catch (Exception e) {
// e.printStackTrace();
// }
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
return_text.append(sth);
}
});
try {
Thread.sleep(100);
} catch (Exception e) {
e.printStackTrace();
}
}
}
大佬,run()实现复制你的现在JTextArea都不会实时显示了
sunyiz 2020-08-21
  • 打赏
  • 举报
回复
把你的线程改成这样试试:

	//子线程的实现
	private static class Thread_update extends Thread {
		private String sth;

		public Thread_update(String sth) {
			this.sth = sth;
		}

		@Override
		public void run() {
			SwingUtilities.invokeLater(new Runnable() {
				@Override
				public void run() {
					return_text.append(sth);
				}
			});
			try {
				Thread.sleep(100);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

62,625

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧