Details
-
Bug
-
Resolution: Fixed
-
P4
-
8
-
Windows 7 64-bit
JavaFX 8b119
Description
Minimum size is not used properly in layout, but it is in rendering. The result is that parent bounds appear to be miscalculated.
Try the following:
package layoutbounds;
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.geometry.Bounds;
import javafx.geometry.Point2D;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
/**
* Resize the child by dragging the green square. JavaFX 2.2 and JavaFX 8
* behave very differently.
* @author scott.palmer
*/
public class LayoutBounds extends Application {
static class Widget extends AnchorPane {
private final VBox vbox;
private final BorderPane contentPane;
private final AnchorPane contentStack;
private final StackPane contentWrapper;
private final AnchorPane childrenGroup;
private final AnchorPane connectionGroup;
private final HBox bottomPane;
public Widget(String title) {
vbox = new VBox();
vbox.setFillWidth(true);
vbox.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
AnchorPane.setTopAnchor(vbox, 0.0);
AnchorPane.setRightAnchor(vbox, 0.0);
AnchorPane.setBottomAnchor(vbox, 0.0);
AnchorPane.setLeftAnchor(vbox, 0.0);
getChildren().add(vbox);
Label titleBar = new Label(title);
titleBar.setAlignment(Pos.CENTER);
titleBar.setMaxWidth(Double.MAX_VALUE);
titleBar.setTextFill(Color.WHITE);
titleBar.setStyle("-fx-background-color: BLUE;");
vbox.getChildren().add(titleBar);
contentStack = new AnchorPane();
contentWrapper = new StackPane();
bottomPane = new HBox();
bottomPane.getChildren().add(new Label("resize->"));
contentPane = new BorderPane();
contentPane.setBottom(bottomPane);
contentPane.setPickOnBounds(false);
childrenGroup = new AnchorPane();
contentWrapper.getChildren().add(childrenGroup);
contentPane.setCenter(contentWrapper);
connectionGroup = new AnchorPane();
AnchorPane.setTopAnchor(contentPane, 0.0);
AnchorPane.setRightAnchor(contentPane, 0.0);
AnchorPane.setBottomAnchor(contentPane, 0.0);
AnchorPane.setLeftAnchor(contentPane, 0.0);
contentStack.getChildren().add(connectionGroup);
contentStack.getChildren().add(contentPane);
contentStack.setMaxHeight(Double.MAX_VALUE);
VBox.setVgrow(contentStack, Priority.ALWAYS);
vbox.getChildren().add(contentStack);
Rectangle sizer = new Rectangle(16, 16);
sizer.setFill(Color.GREENYELLOW);
AnchorPane.setRightAnchor(sizer, 0.0);
AnchorPane.setBottomAnchor(sizer, 0.0);
getChildren().add(sizer);
sizer.setOnMouseDragged(resizeDragHandler);
setStyle("-fx-background-color: SKYBLUE; -fx-border-color: YELLOW; -fx-border-width: 3px;");
}
void addComponent(Widget child) {
childrenGroup.getChildren().add(child);
}
private EventHandler<MouseEvent> resizeDragHandler = new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent me) {
Point2D dragPoint = Widget.this.sceneToLocal(new Point2D(me.getSceneX(), me.getSceneY()));
sizeToPoint(dragPoint);
me.consume();
}
};
private void sizeToPoint(Point2D dragPoint) {
Bounds bounds = getBoundsInLocal();
setMinSize(Math.max(0, dragPoint.getX()-bounds.getMinX()),
Math.max(0, dragPoint.getY()-bounds.getMinY()));
}
}
@Override
public void start(Stage primaryStage) {
Widget rectA = new Widget("Parent");
Widget rectB = new Widget("Child");
rectA.addComponent(rectB);
AnchorPane root = new AnchorPane();
root.getChildren().add(rectA);
Scene scene = new Scene(root, 400, 300);
primaryStage.setTitle("Layout Bounds Issues");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Try the following:
package layoutbounds;
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.geometry.Bounds;
import javafx.geometry.Point2D;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
/**
* Resize the child by dragging the green square. JavaFX 2.2 and JavaFX 8
* behave very differently.
* @author scott.palmer
*/
public class LayoutBounds extends Application {
static class Widget extends AnchorPane {
private final VBox vbox;
private final BorderPane contentPane;
private final AnchorPane contentStack;
private final StackPane contentWrapper;
private final AnchorPane childrenGroup;
private final AnchorPane connectionGroup;
private final HBox bottomPane;
public Widget(String title) {
vbox = new VBox();
vbox.setFillWidth(true);
vbox.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
AnchorPane.setTopAnchor(vbox, 0.0);
AnchorPane.setRightAnchor(vbox, 0.0);
AnchorPane.setBottomAnchor(vbox, 0.0);
AnchorPane.setLeftAnchor(vbox, 0.0);
getChildren().add(vbox);
Label titleBar = new Label(title);
titleBar.setAlignment(Pos.CENTER);
titleBar.setMaxWidth(Double.MAX_VALUE);
titleBar.setTextFill(Color.WHITE);
titleBar.setStyle("-fx-background-color: BLUE;");
vbox.getChildren().add(titleBar);
contentStack = new AnchorPane();
contentWrapper = new StackPane();
bottomPane = new HBox();
bottomPane.getChildren().add(new Label("resize->"));
contentPane = new BorderPane();
contentPane.setBottom(bottomPane);
contentPane.setPickOnBounds(false);
childrenGroup = new AnchorPane();
contentWrapper.getChildren().add(childrenGroup);
contentPane.setCenter(contentWrapper);
connectionGroup = new AnchorPane();
AnchorPane.setTopAnchor(contentPane, 0.0);
AnchorPane.setRightAnchor(contentPane, 0.0);
AnchorPane.setBottomAnchor(contentPane, 0.0);
AnchorPane.setLeftAnchor(contentPane, 0.0);
contentStack.getChildren().add(connectionGroup);
contentStack.getChildren().add(contentPane);
contentStack.setMaxHeight(Double.MAX_VALUE);
VBox.setVgrow(contentStack, Priority.ALWAYS);
vbox.getChildren().add(contentStack);
Rectangle sizer = new Rectangle(16, 16);
sizer.setFill(Color.GREENYELLOW);
AnchorPane.setRightAnchor(sizer, 0.0);
AnchorPane.setBottomAnchor(sizer, 0.0);
getChildren().add(sizer);
sizer.setOnMouseDragged(resizeDragHandler);
setStyle("-fx-background-color: SKYBLUE; -fx-border-color: YELLOW; -fx-border-width: 3px;");
}
void addComponent(Widget child) {
childrenGroup.getChildren().add(child);
}
private EventHandler<MouseEvent> resizeDragHandler = new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent me) {
Point2D dragPoint = Widget.this.sceneToLocal(new Point2D(me.getSceneX(), me.getSceneY()));
sizeToPoint(dragPoint);
me.consume();
}
};
private void sizeToPoint(Point2D dragPoint) {
Bounds bounds = getBoundsInLocal();
setMinSize(Math.max(0, dragPoint.getX()-bounds.getMinX()),
Math.max(0, dragPoint.getY()-bounds.getMinY()));
}
}
@Override
public void start(Stage primaryStage) {
Widget rectA = new Widget("Parent");
Widget rectB = new Widget("Child");
rectA.addComponent(rectB);
AnchorPane root = new AnchorPane();
root.getChildren().add(rectA);
Scene scene = new Scene(root, 400, 300);
primaryStage.setTitle("Layout Bounds Issues");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}