Given:
package pkg;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Border;
import javafx.scene.layout.BorderStroke;
import javafx.scene.layout.BorderStrokeStyle;
import javafx.scene.layout.BorderWidths;
import javafx.scene.layout.CornerRadii;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
public class App extends Application {
@Override
public void start(Stage stage) {
var scene = new Scene(getView(), 640, 480);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
private Pane getView() {
Pane pane = new Pane();
Rectangle r = new Rectangle(0, 0, 300, 200);
r.setFill(Color.RED);
r.setStroke(Color.YELLOW);
r.setStrokeWidth(10);
pane.getChildren().add(r);
pane.setBorder(new Border(new BorderStroke(Color.BLACK, BorderStrokeStyle.SOLID, CornerRadii.EMPTY,
new BorderWidths(2))));
AnchorPane ap = new AnchorPane();
ap.getChildren().add(pane);
return ap;
}
}
Why is the rectangle stomping the border of its container? It appears the pane is sized to the size of the rectangle plus the stroke width.
This appears to be the expected result of the "absolute positioning of children" offered by Pane
, which "does not perform layout beyond resizing resizable children to their preferred sizes." In particular,
The red rectangle's top left corner is at (0, 0).
The strokeType
defaults to CENTERED
, placing its top left corner at (0, 0), clipped to the left and above.
The black border shows the computed size, absent any layout.
For comparison, the example below adds the rectangle and border to a StackPane
, which lays out its children with Pos.CENTER
alignment by default.
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.Border;
import javafx.scene.layout.BorderStroke;
import javafx.scene.layout.BorderStrokeStyle;
import javafx.scene.layout.BorderWidths;
import javafx.scene.layout.CornerRadii;
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 App extends Application {
@Override
public void start(Stage stage) {
stage.setScene(new Scene(getView()));
stage.show();
}
private Pane getView() {
Rectangle r = new Rectangle(0, 0, 300, 200);
r.setFill(Color.RED);
r.setStroke(Color.YELLOW);
r.setStrokeWidth(10);
StackPane sp = new StackPane();
sp.setBorder(new Border(new BorderStroke(Color.BLACK,
BorderStrokeStyle.SOLID, CornerRadii.EMPTY, new BorderWidths(2))));
sp.getChildren().add(r);
return sp;
}
public static void main(String[] args) {
launch();
}
}