Issue
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.
Solution
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 toCENTERED
, 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();
}
}
Answered By - trashgod
Answer Checked By - Terry (JavaFixing Volunteer)