views:

401

answers:

2

I have a JScrollpane which contains a scrollable client that changes its size dynamically while using the application. I want the JScrollPane to be aware of the changes without moving the viewport when the client size changes.

To clarify what I mean: Refer to the Java Webstart example ScrollDemo2 from the article How to use scroll panes by Sun. When clicking at the bottom of the window, a circle appears partly outside the window and the scrollbars move. It's the latter behavior I want to avoid.

My guess is that it's just a matter of setting a simple flag in one of the many components that are involved in a scroll pane solution, but I just can't find where it is. Does anyone know?

A: 

I would try something like:

Point p = scrollPane.getViewport().getViewportPosition();
revalidate();
scrollPane.getViewport().setViewportPosition(p);

You may need to wrap the last line of code in a SwingUtilities.invokeLater.

If that doesn't work then maybe you can disable/enable the viewport before and after the revalidate()?

camickr
This could possibly work under certain circumstances, but the problem in my case is that the JScrollPane the class that contains my JScrollPane isn't aware of the size changes in the client. This means that I can't reach the scrollpane from where the changes occur. At least not without searching for it upwards in the hierarchy, which I want to avoid. Moreover, I really think that there is a simple and straightforward solution to this, but that I just don't know about it :).
Bulgur
In the example you refer to the solution is to simply remove the scrollRectToVisible() method. Otherwise, searching upwards is easy because the panel will be added to the viewport so you just need to get the parent of the panel you are changing the preferred size of. I have noticed that when you add a JTextArea to a panel on a scrollpane the viewport tends to scroll to the text area. Unless you post a SSCCE showing the real problem I don't know how else we can help.
camickr
I see that the ScrollDemo2 was an unfortunate example. Just as you point out, the behavior is explicitly set with the scrollRectToVisible() method. Unfortunately, it's very hard to provide an SSCCEE for my problem, because it's part of a pretty big and complex GUI. Likely, the problem is because of something stupid I do in one of the many nested component classes. However, your post kinda pointed me in the right direction anyway and helped me to solve the problem. I'm posting the solution below.
Bulgur
+1  A: 

I managed to solve this problem by overriding the standard behavior of the viewport in my JScrollPane. This might be a solution that is not suitable for all, but in my GUI this works like a charm.

JScrollPane pane = new JScrollPane();
pane.setViewport(
  new JViewport(){
    /**
     * An empty override implementation to prevent undesired scrolling on
     * size changes of the client.
     */
     @Override
     public void scrollRectToVisible(Rectangle rect){}
  });
Bulgur