It took some experimenting, but here is a solution.
import java.awt.Adjustable;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
/**
*
*/
public class Test extends JFrame implements ActionListener, AdjustmentListener {
private JTextArea text;
private JScrollPane scroll;
private JButton addText;
private int value;
private int appended = 0;
private boolean max = false;
public Test() {
JPanel panel = new JPanel(new BorderLayout());
setContentPane(panel);
text = new JTextArea();
scroll = new JScrollPane(text);
panel.add(scroll, BorderLayout.CENTER);
scroll.getVerticalScrollBar().addAdjustmentListener(this);
addText = new JButton("Add Text");
panel.add(addText, BorderLayout.SOUTH);
addText.addActionListener(this);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(400, 200);
setVisible(true);
}
public void actionPerformed(ActionEvent e) {
if(e.getSource().equals(addText)) {
JScrollBar bar = scroll.getVerticalScrollBar();
value = bar.getValue();
if(value + bar.getVisibleAmount() >= bar.getMaximum()) {
max = true;
}
else {
max = false;
}
//value needs to be set to 2 because the adjustmentValueChanged gets called twice for some reason
appended = 2;
text.append("This is a test string to add\r\n");
}
}
public void adjustmentValueChanged(AdjustmentEvent arg0) {
Adjustable adj = arg0.getAdjustable();
if(appended > 0) {
if(max) {
adj.setValue(adj.getMaximum());
}
else {
adj.setValue(value);
}
}
appended--;
}
public static void main(String[] args) {
Test t = new Test();
}
}