我试图模仿Adium和我见过的大多数其他聊天客户端的功能,其中滚动条在新消息进入时前进到底部,但仅限于如果你已经在那里。换句话说,如果你已经滚动了几行并正在阅读,当新消息进入时,它不会将你的位置跳到屏幕的底部;那会很烦人。但是,如果您滚动到底部,则该程序正确地假定您想要始终查看最新的消息,并相应地自动滚动。Swing:滚动到JScrollPane的底部,以当前视口位置为条件
我有一阵熊熊的时间试图模仿这个;该平台似乎不惜一切代价对抗这种行为。我能做的最好的是如下:
在构造函数中:
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);
在处理新文本方法来:
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();
int maxVal = sb.getMaximum();
boolean atBottom = maxVal == lowest;
return atBottom;
}
private void scrollToBottom() {
chatArea.setCaretPosition(chatArea.getDocument().getLength());
}
现在,这个工作,但它janky并不理想有两个原因。
- 通过设置插入位置,用户可能在聊天区中进行的任何选择都将被删除。我可以想象,如果他试图复制/粘贴,这将是非常恼人的。
- 由于滚动窗格的前进发生在插入文本之后,因此滚动条位置错误时会出现一秒钟,然后视觉上跳到最后。这并不理想。
在你问,是的,我已阅读Text Area Scrolling这篇博文,但默认的滚动到底部行为是不是我想要的。
其他相关的(但在我看来,在这方面没有完全有用)问题: Setting scroll bar on a jscrollpane Making a JScrollPane automatically scroll all the way down.
在这方面的任何帮助将是非常赞赏。
编辑:
按Devon_C_Miller的建议,我有滚动到页面底部,解决问题#1的改进方式。
private void scrollToBottom() {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
int endPosition = chatArea.getDocument().getLength();
Rectangle bottom = chatArea.modelToView(endPosition);
chatArea.scrollRectToVisible(bottom);
}
catch (BadLocationException e) {
System.err.println("Could not scroll to " + e);
}
}
});
}
我还有问题#2。
你可以有检查我的答案是: http://stackoverflow.com/questions/4045722/how-to-make-jtextpane-autoscroll-only-when-scroll-bar-is - 底部和滚动 - 罗/ 23654546#23654546 – 2014-05-14 12:21:02