我目前正在尝试使用此代码来实现此目的:
public class HelloApplication extends Application {
@Override
public void start(Stage stage) throws IOException {
AnchorPane centerPane = new AnchorPane();
Rectangle rect = new Rectangle();
rect.setFill(Color.BLUE);
AnchorPane.setTopAnchor(rect, .25 * centerPane.getHeight());
AnchorPane.setBottomAnchor(rect, .25 * centerPane.getHeight());
AnchorPane.setLeftAnchor(rect, .25 * centerPane.getHeight());
AnchorPane.setRightAnchor(rect, .25 * centerPane.getHeight());
Scene scene = new Scene(centerPane, 320, 240);
stage.setTitle("Anchor Pane Scaling test");
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
}
但是我没有显示矩形。
我想知道是否有办法解决这种方法,或者是否有更好的方法来缩放窗格内的节点,我应该尝试。
您的代码不起作用有两个原因:
Rectangle
(以及所有 Shape
)实例是 非托管。这意味着父节点(例如AnchorPane
)不会调整这些节点的大小或重新定位这些节点。centerPane.getHeight()
。这意味着此时它的 height
(和 width
)将为零。每当宽度和高度发生变化时,您确实需要重新进行布局。JavaFX 支持一组管理布局的
Pane
子类。 (例如,请参阅本教程或API文档)了解详细信息。)通常,如果您需要这些布局窗格之一不支持的布局策略,那么您应该通过子类化来定义自己的布局策略 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();
}
}
这是一个快速测试用例:
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();
}
}