您的代码无法运行的原因有两个:
Rectangle
个(以及所有Shape
个)实例不是resizable个.这意味着父 node (例如AnchorPane
)不能调整这些 node 的大小(具体地说,Rectangle.resize()
是无操作的).
- 您正在拨打
centerPane.getHeight()
,而面板还没有布置好.这意味着届时其height
(和width
)将为零.当宽度和高度改变时,你真的需要重新做布局.
JavaFX支持Pane
个子类的集合,这些子类管理布局.(例如,请参见this tutorial或API docs)以了解详细信息.)通常,如果您需要的布局策略不受这些布局窗格之一的支持,则您应该通过将Region
或Pane
子类化来定义您自己的布局策略.您至少应该覆盖layoutChildren()
方法,以及计算最小/最小/最大宽度和高度的方法.
您的问题并不清楚您的实际用例是否保证了完成此操作所需的编码量.然而,这里有一个容器窗格的快速示例,它将其内容居中,并具有一个可配置的值,用于确定其内容应占据其大小的(线性)比例.
package org.jamesd.examples.centeringpane;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.geometry.Orientation;
import javafx.scene.Node;
import javafx.scene.layout.Region;
public class CenteringPane extends Region {
private final Node content ;
private DoubleProperty sizeProportion = new SimpleDoubleProperty(1);
public CenteringPane(Node content) {
this.content = content;
getChildren().add(content);
sizeProportion.addListener(obs -> requestLayout());
}
@Override
protected void layoutChildren() {
if (content.isManaged()) {
double w = getWidth();
double h = getHeight();
double targetWidth = (w - snappedLeftInset() - snappedRightInset()) * getSizeProportion();
double targetHeight = (h - snappedTopInset() - snappedBottomInset()) * getSizeProportion();
double x = (w - targetWidth) / 2;
double y = (h - targetHeight) / 2;
content.resizeRelocate(snapPositionX(x), snapPositionY(y), snapSizeX(targetWidth), snapSizeY(targetHeight));
}
}
public double getSizeProportion() {
return sizeProportion.get();
}
public DoubleProperty sizeProportionProperty() {
return sizeProportion;
}
public void setSizeProportion(double sizeProportion) {
this.sizeProportion.set(sizeProportion);
}
@Override
protected double computePrefWidth(double height) {
return snappedLeftInset() + snappedRightInset() + content.prefWidth(height) / getSizeProportion();
}
@Override
protected double computePrefHeight(double width) {
return snappedTopInset() + snappedBottomInset() + content.prefHeight(width) / getSizeProportion();
}
@Override
protected double computeMinWidth(double height) {
return snappedLeftInset() + snappedRightInset() + content.minWidth(height) / getSizeProportion();
}
@Override
protected double computeMinHeight(double width) {
return snappedTopInset() + snappedBottomInset() + content.minHeight(width) / getSizeProportion();
}
@Override
protected double computeMaxWidth(double height) {
return snappedLeftInset() + snappedRightInset() + content.maxWidth(height) / getSizeProportion();
}
@Override
protected double computeMaxHeight(double width) {
return snappedTopInset() + snappedBottomInset() + content.maxHeight(width) / getSizeProportion();
}
@Override
public Orientation getContentBias() {
return content.getContentBias();
}
}
以下是一个快速测试 case :
package org.jamesd.examples.centeringpane;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Slider;
import javafx.scene.layout.Background;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
public class HelloApplication extends Application {
@Override
public void start(Stage stage) {
Pane pane = new Pane();
pane.setBackground(Background.fill(Color.BLUE));
CenteringPane centeringPane = new CenteringPane(pane);
BorderPane root = new BorderPane(centeringPane);
Slider slider = new Slider(0, 1, 0.5);
centeringPane.sizeProportionProperty().bind(slider.valueProperty());
HBox controls = new HBox(5, slider);
controls.setPadding(new Insets(10));
controls.setAlignment(Pos.CENTER);
root.setTop(controls);
Scene scene = new Scene(root, 800, 500);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
}