当前位置: 首页 > 知识库问答 >
问题:

如何布局一个用一定比例的可用空间填充的JavaFX节点?

白吕恭
2023-03-14

共有1个答案

越福
2023-03-14

您可以按照James_D的建议,使用带有适当约束的gridpane来完成此任务。这里有一个例子:

import javafx.application.Application;
import javafx.geometry.HPos;
import javafx.geometry.Pos;
import javafx.geometry.VPos;
import javafx.scene.Scene;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Region;
import javafx.scene.layout.RowConstraints;
import javafx.stage.Stage;

public class App extends Application {

  @Override
  public void start(Stage primaryStage) {
    Region region = new Region();
    region.setStyle("-fx-background-color: firebrick;");

    GridPane grid = new GridPane();
    grid.setAlignment(Pos.CENTER);
    grid.add(region, 0, 0);

    ColumnConstraints cc = new ColumnConstraints(0, Region.USE_COMPUTED_SIZE, Double.MAX_VALUE);
    cc.setPercentWidth(75);
    cc.setHgrow(Priority.ALWAYS);
    cc.setHalignment(HPos.CENTER);
    grid.getColumnConstraints().add(cc);

    RowConstraints rr = new RowConstraints(0, Region.USE_COMPUTED_SIZE, Double.MAX_VALUE);
    rr.setPercentHeight(100);
    rr.setVgrow(Priority.ALWAYS);
    rr.setValignment(VPos.CENTER);
    grid.getRowConstraints().add(rr);

    primaryStage.setScene(new Scene(grid, 500, 300));
    primaryStage.show();
  }
}

另一个选择是创建自己的布局,假设我没有犯错,这并不太难:

import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.geometry.HPos;
import javafx.geometry.VPos;
import javafx.scene.Node;
import javafx.scene.layout.Pane;

public class CustomPane extends Pane {

  // value should be between 0.0 (0%) and 1.0 (100%)
  private final DoubleProperty widthRatio =
      new SimpleDoubleProperty(this, "widthRatio", 0.75) {

        @Override
        protected void invalidated() {
          requestLayout();
        }
      };
  public final void setWidthRatio(double widthRatio) { this.widthRatio.set(widthRatio); }
  public final double getWidthRatio() { return widthRatio.get(); }
  public final DoubleProperty widthRatioProperty() { return widthRatio; }

  public CustomPane() {}

  public CustomPane(double widthRatio) {
    setWidthRatio(widthRatio);
  }

  @Override
  protected void layoutChildren() {
    double ratio = getWidthRatioClamped();
    double x = snappedLeftInset();
    double y = snappedTopInset();
    double w = getWidth() - snappedRightInset() - x;
    double h = getHeight() - snappedBottomInset() - y;

    // could do the same thing with the height if you want
    x = snapPositionX(x + ((w - w * ratio) / 2.0));
    w = snapSizeX(w * ratio);

    for (Node child : getManagedChildren()) {
      layoutInArea(child, x, y, w, h, -1.0, HPos.CENTER, VPos.CENTER);
    }
  }

  private double getWidthRatioClamped() {
    return Math.max(0.0, Math.min(1.0, getWidthRatio()));
  }
}

请注意,这两个解决方案都将考虑子节点的最小/最大/最大宽度和高度。如果子节点的大小不可调整(例如ImageViewMediaView等),那么它将不能按预期工作。当然,您也可以为不可调整大小的节点创建变通方法。例如,下面是我的另一个答案,它创建了一个“可调整的ImageView”。

 类似资料:
  • 当Admob中没有可用广告时(例如,如果用户没有internet连接),是否可以用其他视图填充剩余空间?也就是说,是否有可能根据广告的可用性来调整Android的布局? 我尝试过使用Android:layout_weight,但似乎Android会考虑Admob视图的空间,即使当时没有任何可用的广告(我在模拟器中使用ads:loadadoncreate=“false”来模拟这种情况)。 你知道吗?

  • 我对荡秋千很陌生。我有一个基于外部输入动态生成UI的应用程序。在面板的顶部,有一个带有一些标题文本的JLabel,然后是一个按钮(告诉应用程序重新加载动态生成的内容),然后在下面是一个JScrollPane,其中包含所有动态生成的内容。我希望标签和按钮只占用所需的垂直空间,然后滚动窗格来填充所有剩余的可用空间。 我正在使用GridBagLayout,并在添加滚动窗格之前设置gbc.fill=BOT

  • 问题内容: 我试图为javafx创建一个自定义组件,所以我让我的类扩展javafx.scene.control.Control并在构造函数上绘制其内容。 我的疑问是:如何使其“增长”以填充其父布局上的所有可用空间?就像当我放置一个TextArea时一样… 这是我正在做的精简示例: 在此示例中,TextArea将获得布局为其提供的所有空间。我希望我的组件也一样! 我已经尝试做的所有事情:-更改属性s

  • 问题内容: 我有一个包含标签的页面,这些标签包含在div中,标签具有一个变量,并且我想用字符,点或“-”填充两者之间的空格。 例如。 我的标签文本1 -----------这里有些文本。 我的文字2 -----------------------另一个文字。 如果您发现两个文本都是合理的(或至少我尝试过),可能是计算字符数时遇到的问题,但是字符宽度可能有所不同,那么任何人都知道在Asp.Net,c

  • 问题内容: 我在Pandas DataFrame中有一列具有连续数字的列。 我想将所有这些值更改为一个简单的字符串,例如“ foo”,导致 问题答案: 只需选择该列并像往常一样分配: 分配标量值会将所有行设置为相同的标量值