JavaFx GridPane中的相对大小

问题描述

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

例如,如果我要五行,其中三行是未知的固定大小,其中一行占据了剩余空间的三分之一,而另一行则占据了剩余空间的三分之二(请参见下图),我如何实现呢? / p>

What I want

我看过使用RowConstraints的情况,其中两个有row.setVgrow(Priority.ALWAYS);,但这只允许剩余的空间被平均分配。

我尝试使用百分比,正如我在文档that if the sum of the widthPercent (or heightPercent) values total greater than 100,the values will be treated as weights. e.g. if 3 columns are each given a widthPercent of 50,then each will be allocated 1/3 of the gridpane's available width (50/(50+50+50)).中看到的那样

问题是,当我尝试此操作时,我丢失了部分应用程序

Application missing

我认为这也是文档An application may freely mix the size-types of rows/columns (computed from content,fixed,or percentage). The percentage rows/columns will always be allocated space first based on their percentage of the gridpane's available space (size minus insets and gaps). The remaining space will be allocated to rows/columns given their minimum,preferred,and maximum sizes and grow priorities.

中的一部分

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));

        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,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,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,2,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,3,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,4,1);

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

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

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);
    }
}

解决方法

据我所知,仅使用默认的JavaFX GridPane就无法实现您的示例所显示的内容。该论坛中专业人士的标准答案是:创建您自己的自定义(类似于GridBag)布局。 ;-P

如果要使用JavaFX给出的默认选项,可以组合使用e。 G。 BorderPaneGridPane。这与您的示例所显示的不完全相同,但是也许与之接近。您需要确定是否足够满足您的需求。

以下是示例:

当第一行和最后一行应具有固定的高度值时,可以使用BorderPane作为根。对于中心,您可以有一个GridPane,其中两行具有基于百分比的值。然后,它的第二行可以包含e。 G。 BorderPane(顶部节点的固定高度)等等。

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>

preview

,

如果您能够使用第三方库,就我而言,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));

        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,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>

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...