12 Replies Latest reply: Mar 28, 2013 6:07 AM by wzberger RSS

    Annoying problems with ScrollPane and scaling. Any workarounds?

    ibibby
      I'm having some annoying ScrollPane issues. I've got a scrollPane, which has a Group as its content, and that Group has other children, one of which is an ImageView that can be scaled. I'm finding that often, when I scale the image down, thereby making the ScrollPane's content smaller, the ScrollPane bars fail to adjust accordingly. The remain too large, allowing you to scroll the content off the screen altogether! If you actually click on the ScrollPane's content after scaling down, the scrollbars will suddenly adjust to the right size, but I have not been able to figure out any way to make this happen programmatically.

      Anybody else got any ideas? Also, is this considered a bug, and if so, are there any plans to fix it already?
        • 1. Re: Annoying problems with ScrollPane and scaling. Any workarounds?
          jsmith
          Please post code to replicate this (http://sscce.org/)
          • 2. Re: Annoying problems with ScrollPane and scaling. Any workarounds?
            ibibby
            I haven't yet figured out how to write a simple program that reproduces the exact issue I'm having. However, this program will create a similar issue, and illustrates the bugginess of ScrollPane when scaling children in general. Note how after scaling down, the scrollbars don't adjust accordingly, until you you actually click on them. Also, note how if you're already scrolled all the way to the bottom right of the image when you scale it down, it results in the ScrollPane's content being scrolled completely out of view, and then snapping back into view when you click on the scrollbars:
            public class ScaleError extends Application {
                
                @Override
                public void start(Stage primaryStage) {
                    
                    final Group scaledGroup = new Group();
                    scaledGroup.getChildren().add(new Ellipse(1500, 1500));
                    
                    Group scaledGroupContainer = new Group(scaledGroup);
                    
                    Group scrollContent = new Group(scaledGroupContainer);
                    
                    ScrollPane scrollPane = new ScrollPane();
                    scrollPane.setContent(scrollContent);
                    scrollPane.setPrefHeight(600);
                    
                    Button scaleButton = new Button();
                    scaleButton.setText("Scale to 50%");
                    scaleButton.setOnAction(new EventHandler<ActionEvent>() {
                        @Override
                        public void handle(ActionEvent event) {
                            scaledGroup.setScaleX(.5);
                            scaledGroup.setScaleY(.5);
                            scaledGroup.requestLayout();
                        }
                    });
                    
                    VBox root = new VBox();
                    root.getChildren().addAll(scaleButton, scrollPane);
                    
                    
                    Scene scene = new Scene(root, 600, 600);
                    
                    primaryStage.setTitle("ScrollPane problem illustration");
                    primaryStage.setScene(scene);
                    primaryStage.show();
                }
            
                public static void main(String[] args) {
                    launch(args);
                }
            }
            Edited by: ibibby on Mar 26, 2013 12:49 PM
            • 3. Re: Annoying problems with ScrollPane and scaling. Any workarounds?
              James_D
              If you change
              Group scaledGroupContainer = new Group(scaledGroup);
              to
              Group scaledGroupContainer = new Group();
              scaledGroupContainer.getChildren().add(scaledGroup);
              the problem seems to go away.

              So it looks like Nodes passed into the Group's constructor aren't properly observed for changes in their bounds?

              Edited by: James_D on Mar 26, 2013 1:30 PM

              Update: I can't reproduce this behavior, though I'm certain it's what I saw happen earlier.
              • 4. Re: Annoying problems with ScrollPane and scaling. Any workarounds?
                ibibby
                Now that's bizarre. The two really should be identical. My own app, in which I'm having a similar problem, doesn't actually use the Group's constructor to pass in the children like my sample does. I just did it here for brevity's sake. The bottom line, I think, is that ScrollPane has a lot of issues when it comes to adjusting to changes in content size caused by children of its content. I'd still be interested to know if there are any bugs reported for this kind of thing at JIRA.

                Edit: Actually, I just tried what you said for myself, and it didn't make any difference.

                Edited by: ibibby on Mar 26, 2013 2:11 PM
                • 5. Re: Annoying problems with ScrollPane and scaling. Any workarounds?
                  shakir.gusaroff
                  It is a bug: Runtime RT-11253
                  ScrollPane : scrollbars not updated for transforms....
                  • 6. Re: Annoying problems with ScrollPane and scaling. Any workarounds?
                    ibibby
                    Hi, shakir. Here's the direct link to the ticket: https://javafx-jira.kenai.com/browse/RT-11253

                    However, I see that it's listed as being withdrawn as of July 27 of last year. There's a comment by Mick Fleming that says "ScrollPane just doesn't work this way, and this will probably never work. The correct way to do this is documented in the javadocs."

                    Does anybody have a clue what he's talking about? I didn't see anything helpful for this issue in the javadoc for ScrollPane.
                    • 7. Re: Annoying problems with ScrollPane and scaling. Any workarounds?
                      James_D
                      Wel, I swear that's what happened earlier. I can't reproduce it now. Go figure. (I was experimenting with changing the outer Group to a Pane, which doesn't allow passing the nodes to the constructor; that didn't work, but changing it back and calling getChildren().add() seemed to make a difference.)

                      Still, seems buggy, as you say, and the comment section on the referenced JIRA are just weird.
                      • 8. Re: Annoying problems with ScrollPane and scaling. Any workarounds?
                        ibibby
                        I've found that setting the content of the ScrollPane to null after scaling and then changing it back works, but that's a ridiculous kludge. I can't believe there's no better way to make this happen!
                        • 9. Re: Annoying problems with ScrollPane and scaling. Any workarounds?
                          shakir.gusaroff
                          Here is another workaround: scrollPane.setFitToWidth(true);
                              scaleButton.setOnAction(new EventHandler<ActionEvent>() {
                                      @Override
                                      public void handle(ActionEvent event) {
                                          scaledGroup.setScaleX(.5);
                                          scaledGroup.setScaleY(.5);
                                          scaledGroup.requestLayout();
                                          scrollPane.setFitToWidth(true);
                                      }
                                  });
                          • 10. Re: Annoying problems with ScrollPane and scaling. Any workarounds?
                            ibibby
                            Yeah, that does seem to work for this case, and you don't need the requestLayout() call either. It's weird, because setFitToWidth() should have no effect on this issue, at least going by the Javadoc for that method, which states that it is ignored if the content is not resizable.

                            Also, if fitToWidth is already set to true, it has no effect when you set it to true again in the button's handler method. In that case you need to set it to false to make the scrollbars adjust.

                            I have found that the following code works in either case, and also gets you back to whatever fitToWidth value you started with. Of course, like setting the ScrollPane content to null and back again, this is a ridiculous kludge to compensate for what appears to be a buggy control:
                            scaleButton.setOnAction(new EventHandler<ActionEvent>() {
                                        @Override
                                        public void handle(ActionEvent event) {
                                            scaledGroup.setScaleX(.5);
                                            scaledGroup.setScaleY(.5);
                                            scrollPane.setFitToWidth(!scrollPane.isFitToWidth());
                                            scrollPane.setFitToWidth(!scrollPane.isFitToWidth());
                                        }
                                    });
                            • 11. Re: Annoying problems with ScrollPane and scaling. Any workarounds?
                              ibibby
                              Also, in my own app, which has a related problem (only the opposite - the scrollbars don't adjust until I click on the image rather than the scrollbars themselves, which stay the same size and even let you scroll the image off the visible screen completely!), the method of removing and re-adding the ScrollPane content is the only thing that works. The fitToWidth method doesn't have any effect in that case.
                              • 12. Re: Annoying problems with ScrollPane and scaling. Any workarounds?
                                wzberger
                                Using scrollPane.requestLayout() instead of scaledGroup.requestLayout() seems to fix the issue.