1 Reply Latest reply: Jan 15, 2013 8:32 AM by 984080 RSS

    ScrollPane and scaled content

    l2p
      I have a Problem with a ScrollPane not adjusting properly to its scaled content. According to the ScrollPane documentation I wrapped the scaled node into a Group. This does work for all transformations that are executed before the first stage.show(). Everything that happens after that does not get recognized by the ScrollPane.
      import javafx.application.Application;
      import javafx.event.ActionEvent;
      import javafx.event.EventHandler;
      import javafx.scene.Group;
      import javafx.scene.GroupBuilder;
      import javafx.scene.Scene;
      import javafx.scene.SceneBuilder;
      import javafx.scene.control.Button;
      import javafx.scene.control.ButtonBuilder;
      import javafx.scene.control.ScrollPane;
      import javafx.scene.control.ScrollPaneBuilder;
      import javafx.scene.control.SplitPane;
      import javafx.scene.control.SplitPaneBuilder;
      import javafx.scene.image.Image;
      import javafx.scene.image.ImageView;
      import javafx.scene.image.ImageViewBuilder;
      import javafx.scene.layout.AnchorPane;
      import javafx.scene.layout.AnchorPaneBuilder;
      import javafx.scene.layout.BorderPane;
      import javafx.scene.layout.BorderPaneBuilder;
      import javafx.scene.layout.Pane;
      import javafx.scene.layout.VBox;
      import javafx.scene.layout.VBoxBuilder;
      import javafx.scene.shape.Rectangle;
      import javafx.scene.shape.Shape;
      import javafx.scene.transform.Scale;
      import javafx.stage.Stage;
      
      public class test extends Application
      {
           //~ Methods ----------------------------------------------------------------
      
           @Override
           public void start(final Stage stage) throws Exception
           {
                final ImageView imageView =
                    ImageViewBuilder.create()
                                    .image(new Image("http://www.google.com/intl/en_ALL/images/logos/images_logo_lg.gif"))
                                    .build();
                final Shape overlayRectangle = new Rectangle(100, 100, 200, 200);
                final AnchorPane anchorPane = AnchorPaneBuilder.create().children(imageView, overlayRectangle).build();
                overlayRectangle.toFront();
      
                final Group wrapperGroup = GroupBuilder.create().children(anchorPane).build();
                final VBox box = VBoxBuilder.create().children(wrapperGroup).build();
                final ScrollPane scroll = ScrollPaneBuilder.create().content(box).build();
                final SplitPane split = SplitPaneBuilder.create().items(scroll, new Pane()).build();
                final Button button =
                    ButtonBuilder.create().text("1/2 scale").onAction(new EventHandler<ActionEvent>() {
                               @Override
                               public void handle(final ActionEvent event)
                               {
                                    anchorPane.getTransforms().add(new Scale(0.5, 0.5));
                               }
                          }).build();
      
                final BorderPane border = BorderPaneBuilder.create().center(split).bottom(button).build();
                final Scene scene = SceneBuilder.create().root(border).build();
                
                anchorPane.getTransforms().add(new Scale(0.5, 0.5));
                
                stage.setScene(scene);
                stage.show();
           }
      
           public static void main(final String[] args)
           {
                launch();
           }
      }
      If your run the code above you can see what i mean. You can move the splitter to the right of the (already scaled) image and see the scrollbar disappear. Then click on the scale button and move the splitter close tho the nor smaller image. You will see the scroll bar appear even though the splitter is not over the image yet.

      You can achieve the same effect if you move the "anchorPane.getTransforms().add(new Scale(0.5, 0.5));" line below the stage.show().

      I would like the ScrollPane to dynamically adjust to the visual bounds of the AncorPane (containing image and overlays). Somehow the FX environment does this implicitly during the first stage.show(). How do I do this?

      Regards
      l2p

      Edited by: 981912 on Jan 15, 2013 2:34 PM
      Upon further investigation the problem seems to be related to the VBox. It does not shrink when its content shrinks and therefore keeps the scroll bar from disappearing.
      How do I configure the VBox to resize itself? Or do I really need to recreate a custom made VBox by subclassing a node or something similar?
        • 1. Re: ScrollPane and scaled content
          984080
          Hi,

          to make the scollbar dissapear, you just can add 1 line:
          anchorPane.getTransforms().add(new Scale(0.5, 0.5));
          
          //new line --> this will request that the anchorPane will re-render.
          anchorPane.requestLayout();
          At the other side, normally you shouldn't worry about resizing. JavaFX does it for you!
          Use, setMinSize(..,..) setPrefSize(..,..) and setMaxSize(..,..) --> This will define the size range of the element itself.

          The Container element, can also determine the size. Like with the method: setVGrow = ALLWAYS or NEVER.

          Tip! Use the JavaFX Scene Builder to have a better understandment of the components. ;)


          Good luck!