I\'m currently writing a simple chat in Java and currently I\'m stuck on this problem: I want my output JTextPane to behave like you would expect it to from a good chat, ie
If you're only wanting to scroll when you're at the bottom then this should help.
Use this method to check and see if the scrollbar is at the end (or bottom), and if so, scroll down automatically using setCaretPosition(Component.getDocument().getLength());
:
public boolean shouldScroll() {
int minimumValue = scrollPane.getVerticalScrollBar().getValue() + scrollPane.getVerticalScrollBar().getVisibleAmount();
int maximumValue = scrollPane.getVerticalScrollBar().getMaximum();
return maximumValue == minimumValue;
}
I found similar results when using Google which led me to a method similar to this one which worked as requested.
Edit: Make sure that it is done within invokeLater()
as it needs to be updated before scrolling is done.
A full example of what I use:
public class ScrollTest extends Thread {
private JFrame frame;
private JTextArea textArea;
private JScrollPane scrollPane;
public static void main(String[] arguments) {
new ScrollTest().run();
}
public ScrollTest() {
textArea = new JTextArea(20, 20);
scrollPane = new JScrollPane(textArea);
frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(scrollPane);
frame.pack();
frame.setVisible(true);
}
public void run() {
while (true) {
textArea.append("" + Math.random() + "\n");
if (shouldScroll()) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
scrollPane.getVerticalScrollBar().setValue(scrollPane.getVerticalScrollBar().getMaximum());
}
});
}
try {
Thread.sleep(500);
} catch (Exception exception) {
exception.printStackTrace();
}
}
}
public boolean shouldScroll() {
int minimumValue = scrollPane.getVerticalScrollBar().getValue() + scrollPane.getVerticalScrollBar().getVisibleAmount();
int maximumValue = scrollPane.getVerticalScrollBar().getMaximum();
return maximumValue == minimumValue;
}
}
You can use an AdjustmentListener to condtion scrolling, as shown in this example.
JScrollBar has getValue() method. Just warp it in SwingUtilities.invokeLater() to be called after text appending.