我在JScrollPane上嵌入了一个JTextArea,并使用该JTextArea进行输出.
我想,只要在输出中超出的JTextArea的大小,JTextArea中自动滚动,这样用户就不必做手工向下滚动查看最近的输出.
我怎样才能做到这一点?
我已经将JTextArea和JScrollPane的autoscroll属性设置为true.
我有下一个代码:
listModel = new DefaultListModel();
listModel.addElement(dateFormat.format(new Date()) + ": Msg1");
messageList = new JList(listModel);
messageList.setLayoutOrientation(JList.VERTICAL);
messageScrollList = new JScrollPane(messageList);
messageScrollList.setPreferredSize(new Dimension(500, 200));
messageScrollList.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() {
public void adjustmentValueChanged(AdjustmentEvent e) {
e.getAdjustable().setValue(e.getAdjustable().getMaximum());
}
});
Run Code Online (Sandbox Code Playgroud)
它会自动向下滚动.但是,如果我尝试向上滚动以重新阅读消息,则会强制向下滚动.我怎样才能解决这个问题?
我试图模仿Adium和我见过的大多数其他聊天客户端的功能,其中当新消息进入时滚动条会向前移动,但前提是你已经在那里.换句话说,如果您向上滚动了几行并正在阅读,当有新消息进入时它不会将您的位置跳到屏幕底部; 这会很烦人.但是如果您滚动到底部,程序会正确地假设您希望始终查看最新的消息,因此会相应地自动滚动.
我有一段时间试图模仿这个; 该平台似乎不惜一切代价来对抗这种行为.我能做的最好的事情如下:
在构造函数中:
JTextArea chatArea = new JTextArea();
JScrollPane chatAreaScrollPane = new JScrollPane(chatArea);
// We will manually handle advancing chat window
DefaultCaret caret = (DefaultCaret) chatArea.getCaret();
caret.setUpdatePolicy(DefaultCaret.NEVER_UPDATE);
Run Code Online (Sandbox Code Playgroud)
在处理新文本的方法中:
boolean atBottom = isViewAtBottom();
// Append the text using styles etc to the chatArea
if (atBottom) {
scrollViewportToBottom();
}
public boolean isAtBottom() {
// Is the last line of text the last line of text visible?
Adjustable sb = chatAreaScrollPane.getVerticalScrollBar();
int val = sb.getValue();
int lowest = val + sb.getVisibleAmount(); …Run Code Online (Sandbox Code Playgroud)