Griva
Griva

Reputation: 1738

Allow only visual overflow of JavaFX node

I got quite simple question but I can't find answer to my case. My goal is to "allow" only visual overflow of node and prevent resize of parent node like this:

enter image description here

I want to allow visual overflow of child (right) but I want to prevent resize of parent and clip it as black rectangle (left). I am aware of setClip method but this way I get situation (#1) where child is clipped visually.

Is it possible in JavaFX to allow visual overflow?

I need it becauase I can't deal with centering of node in StackPane when nested children overflow but would be good to avoid clipping them. I want to get first situation but now i get second one: enter image description here

Is there other solution to my problem?

Upvotes: 3

Views: 1555

Answers (2)

fabian
fabian

Reputation: 82461

If you set the absulute position and size of the children yourself, you can make the parent layout ignore a child by setting the managed property to false. Unmanaged nodes are not repositioned/resized by the parent and are ignored when calculating the layout bounds of the parent.

child.setManaged(false); 

Upvotes: 3

Slaw
Slaw

Reputation: 45806

This is standard behavior for JavaFX Regions:

Every Region has its layout bounds, which are specified to be (0, 0, width, height). A Region might draw outside these bounds. The content area of a Region is the area which is occupied for the layout of its children. This area is, by default, the same as the layout bounds of the Region, but can be modified by either the properties of a border (either with BorderStrokes or BorderImages), and by padding. The padding can be negative, such that the content area of a Region might extend beyond the layout bounds of the Region, but does not affect the layout bounds.

Here's a short example:

import javafx.application.Application;
import javafx.geometry.Point2D;
import javafx.scene.Scene;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

public class Main extends Application {

  @Override
  public void start(Stage primaryStage) {
    Pane pane = new Pane();
    pane.setBackground(new Background(new BackgroundFill(Color.BLACK, null, null)));
    pane.setMaxSize(500, 300);

    Rectangle rect = new Rectangle(100, 100, Color.FIREBRICK);
    rect.setOnMousePressed(this::handleMousePressed);
    rect.setOnMouseDragged(this::handleMouseDragged);
    pane.getChildren().add(rect);

    StackPane root = new StackPane(pane);

    primaryStage.setScene(new Scene(root, 600, 400));
    primaryStage.show();
  }

  private Point2D origin;

  private void handleMousePressed(MouseEvent event) {
    origin = new Point2D(event.getX(), event.getY());
    event.consume();
  }

  private void handleMouseDragged(MouseEvent event) {
    Rectangle rect = (Rectangle) event.getSource();
    rect.setTranslateX(rect.getTranslateX() + event.getX() - origin.getX());
    rect.setTranslateY(rect.getTranslateY() + event.getY() - origin.getY());
    event.consume();
  }

}

This has a Rectangle whose parent is a Pane but allows you to drag the Rectangle anywhere, even outside the bounds of the Pane.

Upvotes: 1

Related Questions