This discussion is archived
8 Replies Latest reply: Jan 14, 2013 1:43 AM by 983777 RSS

prevent Group from lapping out of it's parent Pane

983777 Newbie
Currently Being Moderated
I added a group into a pane beside another. How can I prevent that a group laps out of it's parent pane.

Example Screenshot (Button is in another pane than the group):
http://imageshack.us/photo/my-images/62/groupv.jpg/

Example code :
-----
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package javafxapplication1;

import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.CircleBuilder;
import javafx.stage.Stage;

/**
*
* @author DSE
*/
public class JavaFXApplication1 extends Application {

@Override
public void start(Stage primaryStage) {

BorderPane root = new BorderPane();

Button btn = new Button();
btn.setText("Why??");
root.setLeft(btn);

Group group = new Group();
root.setCenter(group);

Circle circle = CircleBuilder.create()
.centerX(0)
.centerY(0)
.radius(170)
.fill(Color.RED)
.build();

group.getChildren().add(circle);
Scene scene = new Scene(root, 300, 250);
primaryStage.setScene(scene);
primaryStage.show();
}


public static void main(String[] args) {
launch(args);
}
}
-----

Edited by: 980774 on 09.01.2013 04:44
  • 1. Re: prevent Group from lapping out of it's parent Pane
    jsmith Guru
    Currently Being Moderated
    It's a quirk of BorderPane, see the JavaDoc =>
    http://docs.oracle.com/javafx/2/api/javafx/scene/layout/BorderPane.html
    "BorderPane does not clip its content by default, so it is possible that childrens' bounds may extend outside its own bounds if a child's min size prevents it from being fit within it space."

    I'm not such a big fan of JavaFX 2's BorderPane due to it's strange sizing behaviour for it's children.

    A quick work around this quirk is to add the center content first so that it will be layered underneath the other panes in the BorderPane and have the root of the other child panes of your border pane be unbounded resizable Panes which fill their available area with an opaque color which will paint over the overflowing center pane.
    import javafx.application.Application;
    import javafx.scene.*;
    import javafx.scene.control.Button;
    import javafx.scene.layout.*;
    import javafx.scene.paint.Color;
    import javafx.scene.shape.Circle;
    import javafx.scene.shape.CircleBuilder;
    import javafx.stage.Stage;
    
    public class JavaFXApplication1 extends Application {
      @Override public void start(Stage stage) {
        BorderPane root = new BorderPane();
    
        Group group = new Group();
        root.setCenter(group);
    
        Button btn = new Button();
        btn.setText("Why??");
        root.setLeft(btn);
    
        VBox leftPane = new VBox();
        leftPane.setStyle("-fx-background-color: white;");
        leftPane.getChildren().add(btn);
        root.setLeft(leftPane);
    
        Circle circle = CircleBuilder.create()
                .centerX(0)
                .centerY(0)
                .radius(170)
                .fill(Color.RED)
                .build();
    
        group.getChildren().add(circle);
        stage.setScene(new Scene(root, 300, 250));
        stage.show();
      }
    
      public static void main(String[] args) { launch(args); }
    }
    Perhaps somebody has an alternate or better solution?

    Perhaps there is a related jira issue to make this simpler or more intuitive?
    http://javafx-jira.kenai.com/browse/RT-17441 "add boolean clipContent property to Region to make it easier to turn clipping on/off for layout containers"
  • 2. Re: prevent Group from lapping out of it's parent Pane
    983777 Newbie
    Currently Being Moderated
    Thanks. So this means, I can get rid of this problem by using HBoxes and VBoxes instead?

    This is already good news.
  • 3. Re: prevent Group from lapping out of it's parent Pane
    jsmith Guru
    Currently Being Moderated
    I can get rid of this problem by using HBoxes and VBoxes instead?
    Yes, your sample using a HBox instead of a BorderPane works more the way I would expect it to:
    import javafx.application.Application;
    import javafx.scene.*;
    import javafx.scene.control.Button;
    import javafx.scene.layout.*;
    import javafx.scene.paint.Color;
    import javafx.scene.shape.Circle;
    import javafx.scene.shape.CircleBuilder;
    import javafx.stage.Stage;
    
    public class HBoxSample extends Application {
      @Override public void start(Stage stage) {
        Button btn = new Button();
        btn.setText("Why??");
        btn.setMinWidth(Button.USE_PREF_SIZE);
    
        Circle circle = CircleBuilder.create()
            .centerX(0)
            .centerY(0)
            .radius(170)
            .fill(Color.RED)
            .build();
    
        Group group = new Group();
        group.getChildren().add(circle);
    
        HBox hbox = new HBox();
        hbox.getChildren().addAll(btn, group);
        stage.setScene(new Scene(hbox, 300, 250));
        stage.show();
      }
    
      public static void main(String[] args) { launch(args); }
    }
  • 4. Re: prevent Group from lapping out of it's parent Pane
    983777 Newbie
    Currently Being Moderated
    Thanks a lot.

    Edited by: 980774 on 10.01.2013 04:20
  • 5. Re: prevent Group from lapping out of it's parent Pane
    983777 Newbie
    Currently Being Moderated
    When I translate the group, it again overlaps other Panels.
    Is there a way to keep it only within that panel?

    I also tried the toFront() and toBack() functions on all, the group, the panel and the button, however there was no difference.
    --------
    package javafxapplication1;

    import javafx.application.Application;
    import javafx.scene.Group;
    import javafx.scene.Scene;
    import javafx.scene.control.Button;
    import javafx.scene.layout.HBox;
    import javafx.scene.paint.Color;
    import javafx.scene.shape.Circle;
    import javafx.scene.shape.CircleBuilder;
    import javafx.stage.Stage;

    /**
    *
    * @author DSE
    */
    public class JavaFXApplication1 extends Application {

    @Override public void start(Stage stage) {
    Button btn = new Button();
    btn.setText("Why??");
    btn.setMinWidth(Button.USE_PREF_SIZE);

    Circle circle = CircleBuilder.create()
    .centerX(0)
    .centerY(0)
    .radius(170)
    .fill(Color.RED)
    .build();

    Group group = new Group();
    group.getChildren().add(circle);

    HBox hbox = new HBox();
    hbox.getChildren().add(btn);
    hbox.getChildren().add(group);
    group.setTranslateX(-100);
    stage.setScene(new Scene(hbox, 300, 250));
    stage.show();
    }


    public static void main(String[] args) {
    launch(args);
    }
    }
  • 6. Re: prevent Group from lapping out of it's parent Pane
    983777 Newbie
    Currently Being Moderated
    after translating the group it overlaps again
  • 7. Re: prevent Group from lapping out of it's parent Pane
    jsmith Guru
    Currently Being Moderated
    after translating the group it overlaps again
    Yep, that's the original feature request I linked:
    http://javafx-jira.kenai.com/browse/RT-17441 "add boolean clipContent property to Region to make it easier to turn clipping on/off for layout containers"

    The overlap occurs because by default all of the JavaFX panes don't clip transformed content.

    Normally the transformation properties such as scaleX or translateX are used when animating a node, and often when doing animations you don't want to clip the transformed node to a container (at least I think that's the reasoning?).

    Rather than translating the group, you can use a method like group.relocate which will adjust the group's layoutX and layoutY values, in which case it won't spill outside the bounds of the layout bounds (because you are adjusting the layout bounds).

    http://docs.oracle.com/javafx/2/api/javafx/scene/Node.html#relocate%28double,%20double%29
    http://docs.oracle.com/javafx/2/api/javafx/scene/Node.html#boundsInParentProperty%28%29
    http://docs.oracle.com/javafx/2/api/javafx/scene/Node.html#layoutBoundsProperty%28%29

    If you can't just relocate the Group and need to perform animations or adjust transforms like translate on the Group and you need to keep the Group within reasonable layout bounds, then you can do one of three things:

    1. Wrap the Group in another Group - the outer group will then have the layoutBounds of the boundsInParent of the child group, thus the layoutBounds of the outer group will include the transforms applied to the child group.
    2. Place the Group in a ScrollPane - then it can take on it's own independent self-contained co-ordinate system which will never overlap any parent nodes.
    3. Set a clip on the Group (as the linked issue suggests), so that any portion of the transformed node which falls outside of it's layout bounds is clipped.

    You have very good questions . . .
  • 8. Re: prevent Group from lapping out of it's parent Pane
    983777 Newbie
    Currently Being Moderated
    Thanks for this detailed answer. I overlooked your last link to the setclip.

    Firstly i tried the ScrollPane, however this didn't look that good. (For some reason the pane didn't use the whole VBOX space left).

    Then I tried the setClip method and this looked better. In this case I'm using a Rectangle with it's width bound the the vBox (the parent) width minus the first panels' width. I assume that there might be a better way, but at least in this case I understand totally what I'm doing ;-) .

    Edited by: skauf on 14.01.2013 01:41

    Edited by: skauf on 14.01.2013 01:42

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points