XistenZ XistenZ - 7 months ago 22
Java Question

JScrollPane automagically scrolls down to lowest component in JPanel

In my JPanel (which is in a JScrollPane) I have several JTextArea. When launching the program these areas are populated by JTextArea.setText("text");

The problem is that the JScrollPane scrolls down to the JTextArea with the lowest Y-position as if the user would have focus on the JTextArea, no matter when it was populated with text. I thought that I could work around the problem by populating the JTextArea at the bottom first, if the JScrollPane maybe want to scroll to the "current" JTextArea that's being used. It didn't work so I'm assuming it just remembers the lowest point it's been and then just stays there for some reason.

Setting the view like this doesn't make any difference.

JScrollPane.getViewPort().scrollRectToVisible(new Rectangle(0,0,1,1));


I've tested by neglecting to populate the last JTextAreas and the JScrollPane is then viewing the top of the JPanel, as I want.
What's happening, and why is it ignoring my code?

Update, answer selected
You have to set the viewport a tad later when the GUI is ready

SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
scrollPane.getViewport().setViewPosition(new Point(0, 0));
}
});

Answer
JScrollPane.getViewPort().scrollRectToVisible(new Rectangle(0,0,1,1));

The scrollRectToVisible() method is meant to be used on the component added to the viewport (the panel containing the text areas), not the viewport itself. Not sure what happens when you invoke it directly on the viewport.

Instead I would do the following:

scrollPane.getViewPort().setViewPosition( new Point(0, 0) );

Note, you may need to wrap that statement in a SwingUtilities.invokeLater() to make sure the code is executed on the EDT after all the components have been positioned on the panel by the layout manager.

Comments