Tôi đang cố gắng bắt chước chức năng của Adium và hầu hết các ứng dụng trò chuyện khác mà tôi đã thấy, trong đó thanh cuộn tiến xuống phía dưới khi có tin nhắn mới, nhưng chỉ nếu bạn đã ở đó. Nói cách khác, nếu bạn đã cuộn một vài dòng lên và đang đọc, khi một tin nhắn mới đến trong nó sẽ không nhảy vị trí của bạn vào dưới cùng của màn hình; điều đó sẽ gây phiền nhiễu. Nhưng nếu bạn được cuộn xuống dưới cùng, chương trình sẽ giả định rằng bạn muốn xem các thư gần đây nhất mọi lúc, và vì vậy tự động cuộn tương ứng.Swing: Cuộn xuống dưới cùng của JScrollPane, có điều kiện trên vị trí chế độ xem hiện tại
Tôi đã có một khoảng thời gian cố bắt chước điều này; nền tảng dường như chống lại hành vi này bằng mọi giá. Điều tốt nhất tôi có thể làm là như sau:
Trong constructor:
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);
Trong phương pháp để xử lý văn bản mới sắp tới trong:
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());
}
Bây giờ, làm việc này, nhưng đó là janky và không lý tưởng Vì hai lý do.
- Bằng cách đặt vị trí dấu mũ, bất kỳ lựa chọn nào người dùng có thể có trong khu vực trò chuyện sẽ bị xóa. Tôi có thể tưởng tượng điều này sẽ rất khó chịu nếu anh ta cố gắng sao chép/dán.
- Vì sự tiến bộ của ngăn di chuyển xảy ra sau khi văn bản được chèn vào, có một giây thứ hai nơi thanh cuộn ở vị trí sai, và sau đó nó nhảy về phía cuối. Đây không phải là lý tưởng.
Trước khi bạn hỏi, có Tôi đã đọc bài đăng trên blog này trên Text Area Scrolling, nhưng cuộn mặc định cho hành vi dưới cùng không phải là những gì tôi muốn.
(nhưng tâm trí của tôi, chứ không phải hoàn toàn hữu ích trong vấn đề này) câu hỏi liên quan khác: Setting scroll bar on a jscrollpane Making a JScrollPane automatically scroll all the way down.
Bất kỳ sự giúp đỡ trong vấn đề này sẽ được rất nhiều đánh giá cao.
Edit:
Theo lời khuyên Devon_C_Miller, tôi có một cách cải tiến di chuyển xuống phía dưới, giải quyết vấn đề # 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);
}
}
});
}
Tôi vẫn gặp sự cố # 2.
Bạn có thể kiểm tra câu trả lời của tôi ở đó: http://stackoverflow.com/questions/4045722/how-to-make-jtextpane-autoscroll-only-when-scroll-bar-is -at-bottom-and-scroll-lo/23654546 # 23654546 –