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

JavaFx GridPane中的相对大小

叶浩荡
2023-03-14

如何使用< code>GridPane上的权重设置行/列大小?

例如,如果我想要五行,其中三行是未知的固定大小,一行占用剩余空间的三分之一,另一行占用剩余空间的三分之二(见下图),我该如何实现呢?

我查看了使用RowConstraint,其中两个有row.setVgrow(Priority.ALWAYS);但这只允许平均共享剩余空间。

我尝试使用百分比,因为我在文档< code >中看到,如果widthPercent(或heightPercent)值的总和大于100,这些值将被视为权重。例如,如果3列的宽度百分比都为50,那么每一列都将被分配gridpane可用宽度的1/3(50/(50 50 50))。

问题是,当我尝试这样做时,我丢失了部分应用程序

我想这也是因为文档中说< code >应用程序可以自由混合行/列的大小类型(根据内容、固定或百分比计算)。百分比行/列总是首先根据它们在gridpane的可用空间中所占的百分比(大小减去insets和gap)来分配空间。剩余空间将分配给行/列,给定它们的最小、首选和最大大小以及增长优先级。

JavaFx MCVE

package sample;

import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Priority;
import javafx.scene.layout.RowConstraints;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

public class Main extends Application {
    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) {
        GridPane root = new GridPane();
        root.setGridLinesVisible(true);

        ColumnConstraints columnOneConstraints = new ColumnConstraints();
        columnOneConstraints.setHgrow(Priority.ALWAYS);
        root.getColumnConstraints().addAll(columnOneConstraints);

        RowConstraints rowOneConstraints = new RowConstraints();
        RowConstraints rowTwoConstraints = new RowConstraints();
        rowTwoConstraints.setVgrow(Priority.ALWAYS);
        rowTwoConstraints.setPercentHeight(2000);
        RowConstraints rowThreeConstraints = new RowConstraints();
        RowConstraints rowFourConstraints = new RowConstraints();
        rowFourConstraints.setVgrow(Priority.ALWAYS);
        rowFourConstraints.setPercentHeight(1000);
        RowConstraints rowFiveConstraints = new RowConstraints();
        root.getRowConstraints().addAll(
                rowOneConstraints,
                rowTwoConstraints,
                rowThreeConstraints,
                rowFourConstraints,
                rowFiveConstraints
        );

        Background red = new Background(new BackgroundFill(Color.RED, null, null));
        Background blue = new Background(new BackgroundFill(Color.BLUE, null, null));

        Label rowOne = new Label("R1: Unknown Fixed Size");
        rowOne.backgroundProperty().set(red);
        rowOne.setMaxWidth(Double.MAX_VALUE);
        rowOne.setAlignment(Pos.CENTER);
        rowOne.setTextFill(Color.WHITE);
        rowOne.setMaxHeight(Double.MAX_VALUE);
        root.add(rowOne, 0, 0, 1, 1);

        Label rowTwo = new Label("R2: Grow 2 parts of the remaining space");
        rowTwo.backgroundProperty().set(blue);
        rowTwo.setTextFill(Color.WHITE);
        rowTwo.setAlignment(Pos.CENTER);
        rowTwo.setMaxWidth(Double.MAX_VALUE);
        rowTwo.setMaxHeight(Double.MAX_VALUE);
        root.add(rowTwo, 0, 1, 1, 1);

        Label rowThree = new Label("R3: Unknown Fixed Size");
        rowThree.backgroundProperty().set(red);
        rowThree.setTextFill(Color.WHITE);
        rowThree.setAlignment(Pos.CENTER);
        rowThree.setMaxWidth(Double.MAX_VALUE);
        rowThree.setMaxHeight(Double.MAX_VALUE);
        root.add(rowThree, 0, 2, 1, 1);

        Label rowFour = new Label("R4: Grow 1 part of the remaining space");
        rowFour.backgroundProperty().set(blue);
        rowFour.setTextFill(Color.WHITE);
        rowFour.setAlignment(Pos.CENTER);
        rowFour.setMaxWidth(Double.MAX_VALUE);
        rowFour.setMaxHeight(Double.MAX_VALUE);
        root.add(rowFour, 0, 3, 1, 1);

        Label rowFive = new Label("R5: Unknown Fixed Size");
        rowFive.backgroundProperty().set(red);
        rowFive.setTextFill(Color.WHITE);
        rowFive.setAlignment(Pos.CENTER);
        rowFive.setMaxWidth(Double.MAX_VALUE);
        rowFive.setMaxHeight(Double.MAX_VALUE);
        root.add(rowFive, 0, 4, 1, 1);

        primaryStage.setScene(new Scene(root));
        primaryStage.sizeToScene();
        primaryStage.show();
        primaryStage.setMinHeight(primaryStage.getHeight());
        primaryStage.setMinWidth(primaryStage.getWidth());
    }
}

我想要的东西可以用Swing的GridBagLayout生成,但显然这不能与<code>GridPane</code>一起使用。

package sample;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.WindowConstants;

import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

public class Main {

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        JPanel panel = new JPanel(new GridBagLayout());

        GridBagConstraints constraints = new GridBagConstraints();
        constraints.fill = GridBagConstraints.BOTH;
        constraints.weightx = 1;

        JLabel rowOne = new JLabel("R1: Unknown Fixed Size", SwingConstants.CENTER);
        rowOne.setBackground(Color.RED);
        rowOne.setForeground(Color.WHITE);
        rowOne.setOpaque(true);
        constraints.gridy = 0;
        constraints.weighty = 0;
        panel.add(rowOne, constraints);

        JLabel rowTwo = new JLabel("R2: Grow 2 parts of remaining space", SwingConstants.CENTER);
        rowTwo.setBackground(Color.BLUE);
        rowTwo.setForeground(Color.WHITE);
        rowTwo.setOpaque(true);
        constraints.gridy = 1;
        constraints.weighty = 2;
        panel.add(rowTwo, constraints);

        JLabel rowThree = new JLabel("R3: Unknown Fixed Size", SwingConstants.CENTER);
        rowThree.setBackground(Color.RED);
        rowThree.setForeground(Color.WHITE);
        rowThree.setOpaque(true);
        constraints.gridy = 2;
        constraints.weighty = 0;
        panel.add(rowThree, constraints);

        JLabel rowFour = new JLabel("R4: Grow 1 part of the remaining space", SwingConstants.CENTER);
        rowFour.setBackground(Color.BLUE);
        rowFour.setForeground(Color.WHITE);
        rowFour.setOpaque(true);
        constraints.gridy = 3;
        constraints.weighty = 1;
        panel.add(rowFour, constraints);

        JLabel rowFive = new JLabel("R5: Unknown Fixed Size", SwingConstants.CENTER);
        rowFive.setBackground(Color.RED);
        rowFive.setForeground(Color.WHITE);
        rowFive.setOpaque(true);
        constraints.gridy = 4;
        constraints.weighty = 0;
        panel.add(rowFive, constraints);

        frame.getContentPane().add(panel);
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.pack();
        frame.setMinimumSize(frame.getSize());
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}

共有2个答案

郑俊弼
2023-03-14

如果你能使用第三方库,在我的例子中,MigLayout是一个不错的选择。

它使实现我想要的布局变得简单,并且它还支持FXML。

package sample;

import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import org.tbee.javafx.scene.layout.MigPane;

public class Main extends Application {
    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) {
        MigPane root = new MigPane(
                "fill, debug, wrap, gap 0, insets 0",
                "[fill, grow]",
                "[fill][fill, grow 2][fill][fill, grow 1][fill]"
        );

        Background red = new Background(new BackgroundFill(Color.RED, null, null));
        Background blue = new Background(new BackgroundFill(Color.BLUE, null, null));

        Label rowOne = new Label("R1: Unknown Fixed Size");
        rowOne.backgroundProperty().set(red);
        rowOne.setAlignment(Pos.CENTER);
        rowOne.setTextFill(Color.WHITE);
        root.add(rowOne);

        Label rowTwo = new Label("R2: Grow 2 parts of the remaining space");
        rowTwo.backgroundProperty().set(blue);
        rowTwo.setTextFill(Color.WHITE);
        rowTwo.setAlignment(Pos.CENTER);
        root.add(rowTwo);

        Label rowThree = new Label("R3: Unknown Fixed Size");
        rowThree.backgroundProperty().set(red);
        rowThree.setTextFill(Color.WHITE);
        rowThree.setAlignment(Pos.CENTER);
        root.add(rowThree);

        Label rowFour = new Label("R4: Grow 1 part of the remaining space");
        rowFour.backgroundProperty().set(blue);
        rowFour.setTextFill(Color.WHITE);
        rowFour.setAlignment(Pos.CENTER);
        root.add(rowFour);

        Label rowFive = new Label("R5: Unknown Fixed Size");
        rowFive.backgroundProperty().set(red);
        rowFive.setTextFill(Color.WHITE);
        rowFive.setAlignment(Pos.CENTER);
        root.add(rowFive);

        primaryStage.setScene(new Scene(root));
        primaryStage.sizeToScene();
        primaryStage.show();
        primaryStage.setMinHeight(primaryStage.getHeight());
        primaryStage.setMinWidth(primaryStage.getWidth());
    }
}
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Label?>
<?import org.tbee.javafx.scene.layout.fxml.MigPane?>

<MigPane layout="fill, gap 10 10, debug, wrap"
         cols="fill, grow"
         rows="[][grow 2][][grow 1][]">

    <Label text="Row One"
           alignment="CENTER" />

    <Label text="Row Two"
           alignment="CENTER" />

    <Label text="Row Three"
           alignment="CENTER" />

    <Label text="Row Four"
           alignment="CENTER" />

    <Label text="Row Five"
           alignment="CENTER" />
</MigPane>
张心水
2023-03-14

据我所知,仅使用默认的JavaFXGridPane是不可能实现示例中显示的功能的。本论坛专业人士的标准答案是:创建自己的自定义(网格状)布局-P

如果你想使用JavaFX提供的默认选项,你可以使用<code>BorderPane</code>和<code>GridPane

这里的例子:

当第一行和最后一行应该具有固定的高度值时,可以使用边框窗格作为根。对于中心,您可以有一个网格窗格,其中有两行具有基于百分比的值。然后,它的第二行可以包含例如<code>边框窗格</code>(顶部节点的固定高度),等等。

FXML:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.RowConstraints?>

<BorderPane prefHeight="600.0" prefWidth="400.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1">
   <top>
      <HBox alignment="CENTER" style="-fx-background-color: lightgreen;" BorderPane.alignment="CENTER">
         <children>
            <Label text="&quot;R1&quot;" />
         </children>
      </HBox>
   </top>
   <bottom>
      <HBox alignment="CENTER" style="-fx-background-color: lightgreen;" BorderPane.alignment="CENTER">
         <children>
            <Label text="&quot;R5&quot;" />
         </children>
      </HBox>
   </bottom>
   <center>
      <GridPane BorderPane.alignment="CENTER">
        <columnConstraints>
          <ColumnConstraints halignment="CENTER" hgrow="SOMETIMES" />
        </columnConstraints>
        <rowConstraints>
          <RowConstraints percentHeight="60.0" vgrow="SOMETIMES" />
          <RowConstraints percentHeight="40.0" vgrow="SOMETIMES" />
        </rowConstraints>
         <children>
            <HBox alignment="CENTER" style="-fx-background-color: tomato;">
               <children>
                  <Label text="&quot;R2&quot;" />
               </children>
            </HBox>
            <BorderPane GridPane.rowIndex="1">
               <center>
                  <HBox alignment="CENTER" style="-fx-background-color: tomato;">
                     <children>
                        <Label text="&quot;R4&quot;" />
                     </children>
                  </HBox>
               </center>
               <top>
                  <HBox alignment="CENTER" style="-fx-background-color: lightgreen;" BorderPane.alignment="CENTER">
                     <children>
                        <Label text="&quot;R3&quot;" />
                     </children>
                  </HBox>
               </top>
            </BorderPane>
         </children>
      </GridPane>
   </center>
</BorderPane>

 类似资料:
  • 在SVG元素中添加属性(width,height,viewBox)时,有没有人能解释一下rect和text的相对大小的变化?(在Linux x86_64上的Firefox 30中测试) 根据需要显示: 将svg元素更改为 给出了以下结果:

  • 所以我是一个计算机科学的学生,我已经完成了我的第一年。我想创建一个简单的程序,我意识到我已经厌倦了使用无布局; 给每一个单独的组件添加界限是如此的烦人。嗯,我一直在大量使用组件和,这使我的工作变得更容易了。但我已经厌倦了。 我非常关心我制作的GUI的外观,在开始添加代码的功能之前,我几乎用了一半的时间来编程使GUI看起来很好。通过不使用布局并添加边界,我被迫使用,因为如果更改JFrame的大小,这

  • 我不能处理230m边的图形。我克隆了Apache.Spark,构建了它,然后在Cluster上试用。 而且,收集所有的顶点和边来计算它们也不是一个好主意。这样做很容易:和

  • 问题内容: 免责声明: 我不相信这是重复的,因为我使用相对尺寸来生成全屏网格布局而不使用。 问题: 在这个jsFiddle中,我有四个等比例的框。它们旨在跨越屏幕宽度并保持正方形。其中包含一些示例方形DIV(40%x40%)。我正在努力使文本标签在水平方向和垂直方向居中。 我看过(并尝试过)的所有示例都不起作用,因为它们要求我知道标签的高度,或者它们使用了受浏览器限制的技巧。我需要按照小提琴使用所

  • 本文向大家介绍在C ++中生成相同总和的对的最大数量,包括了在C ++中生成相同总和的对的最大数量的使用技巧和注意事项,需要的朋友参考一下 给我们一个整数数组。目的是在数组中找到最大对数,相加后将产生相同的总和。我们必须找到此类对的最大数量。 输入值 输出结果 说明-数字对的总和- 输入值 输出结果 说明-数字对的总和- 以下程序中使用的方法如下 整数数组Arr []用于存储整数。 整数“大小”存

  • 我在使用React-Native的文本输入模块时遇到了问题 https://facebook.github.io/react-native/docs/textinput.html 在Android上,这很好也很简单,你创建TextInput,给它一个字体大小,它就相应地设置TextInput控件的高度。 另一方面,对于iOS,除非您在样式中为TextInput提供明确的高度,否则它将是0。 这通常