Мне нужно было сделать то же самое для области ввода текста. Решения, которые я нашел в Интернете, не работали для меня (они либо прекращали автоматическую прокрутку при быстрой записи большого количества сообщений, либо блокировали полосу прокрутки внизу, даже если вы прокручивали вверх с помощью колесика мыши).
Я сделал это так:
public static void makeTextAreaAutoScroll(JTextArea textArea) {
// Get the text area's scroll pane :
final JScrollPane scrollPane = (JScrollPane) (textArea.getParent().getParent());
// Disable the auto scroll :
((DefaultCaret)textArea.getCaret()).setUpdatePolicy(DefaultCaret.NEVER_UPDATE);
// Add a listener to the vertical scroll bar :
scrollPane.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() {
private int _val = 0;
private int _ext = 0;
private int _max = 0;
private final BoundedRangeModel _model = scrollPane.getVerticalScrollBar().getModel();
@Override
public void adjustmentValueChanged(AdjustmentEvent e) {
// Get the new max :
int newMax = _model.getMaximum();
// If the new max has changed and if we were scrolled to bottom :
if (newMax != _max && (_val + _ext == _max) ) {
// Scroll to bottom :
_model.setValue(_model.getMaximum() - _model.getExtent());
}
// Save the new values :
_val = _model.getValue();
_ext = _model.getExtent();
_max = _model.getMaximum();
}
});
}
Просто используйте это так:
makeTextAreaAutoScroll(yourTextArea);
Вы можете протестировать этот код:
new Timer().schedule(new TimerTask() {
@Override
public void run() {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
String line = "test " + Math.random();
yourTextArea.append(yourTextArea.getText().isEmpty() ? line : "\n" + line);
}
});
}
}, 0, 5);
Теперь ваша текстовая область должна автоматически прокручиваться, если полоса прокрутки находится внизу, прекратить автоматическую прокрутку, если вы перемещаете полосу прокрутки (перетаскивая полосу или используя колесо), и снова автоматически прокручивать, если вы устанавливаете полосу прокрутки снова дно.