基于窗口大小百分比的JavaFX布局

时间:2016-04-04 01:03:37

标签: javafx javafx-8

我需要在JavaFX中创建一个带有3个标签的Layout。每个标签应水平居中。第一个应该放在窗口的1/4处,第二个应该是中间的一半(即垂直居中),第三个应该是向下的3/4。

如果调整窗口大小,标签应保持相对位置。

看起来很简单,但我无法弄清楚如何去做。我尝试使用VBox,但似乎没有办法对垂直放置进行精细控制。然后我看了看AnchorPane,但看不出怎么做。

有人可以通过FXML或以编程方式向我展示一种简单的方法吗?

3 个答案:

答案 0 :(得分:3)

您可以使用GridPane执行此操作(可能还有其他方法)。填充四行一列,并使用RowConstraints使每行具有相同的高度,并对齐每行底部的标签。使用ColumnConstraints对象水平居中标签。

SSCCE:

import javafx.application.Application;
import javafx.geometry.HPos;
import javafx.geometry.VPos;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.RowConstraints;
import javafx.stage.Stage;

public class LayoutExample extends Application {

    @Override
    public void start(Stage primaryStage) {
        GridPane root = new GridPane();
        int numRows = 4 ;
        for (int i = 0 ; i < numRows ; i++) {
            RowConstraints rc = new RowConstraints();
            rc.setPercentHeight(100.0 / numRows);
            rc.setValignment(VPos.BOTTOM);
            root.getRowConstraints().add(rc);
        }
        ColumnConstraints cc = new ColumnConstraints();
        cc.setHalignment(HPos.CENTER);
        cc.setPercentWidth(100);
        root.getColumnConstraints().add(cc);

        for (int row = 0; row < 3 ; row++) {
            Label label = new Label("Label "+(row+1));
            root.add(label, 0, row);
        }

        Scene scene = new Scene(root, 400, 400);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

enter image description here

答案 1 :(得分:1)

下面的ConstrainedGridPane类有助于实现此目的。 在您的4个标签案例中,您可以像这样扩展它:

 public class LabelPane extends ConstrainedGridPane() {
   public LabelPane() {
     // ... setup you labels
     // hgap=0 - 1 column using 100%
     super.fixColumnSizes(0,100);
     // vgap=5 - 4 columns using 25% each ...
     super.fixRowSizes(5, 25,25,25,25);
   }
 }

ConstrainedGridPane源代码

import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Region;
import javafx.scene.layout.RowConstraints;

/**
 * a GridPane with Column and RowConstraints
 * @author wf
 *
 */
public class ConstrainedGridPane extends GridPane {


  /**
   * fix the columnSizes to the given column Width
   * @param colWidths
   */
  public void fixColumnSizes(int hGap,int... colWidths) {
    this.setHgap(hGap);
    // Setting columns size in percent
    for (int colWidth : colWidths) {
      ColumnConstraints column = new ColumnConstraints();
      column.setPercentWidth(colWidth);
      getColumnConstraints().add(column);
    }
  }

  /**
   * fix the rowSizes to the given rowHeights
   * @param rowHeights
   */
  public void fixRowSizes(int vGap,int... rowHeight) {
    this.setVgap(vGap);
    for (int rowWidth : rowHeight) {
      RowConstraints rowc = new RowConstraints();
      rowc.setPercentHeight(rowWidth);
      getRowConstraints().add(rowc);
    }

    // grid.setPrefSize(WINDOW_WIDTH, WINDOW_HEIGHT); // Default width and
    // height
    this.setMaxSize(Region.USE_COMPUTED_SIZE, Region.USE_COMPUTED_SIZE);
  }
}

答案 2 :(得分:0)

基于FXML的方法并使用VBox代替GridPane看起来像这样:

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

<?import java.lang.*?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.VBox?>

<VBox xmlns:fx="http://javafx.com/fxml" alignment="CENTER">

    <Label text="Label 1" VBox.vgrow="ALWAYS"> 
        <maxHeight><Double fx:constant="MAX_VALUE" /></maxHeight>
    </Label>
    <Label text="Label 2" VBox.vgrow="ALWAYS"> 
        <maxHeight><Double fx:constant="MAX_VALUE" /></maxHeight>
    </Label>
    <Label text="Label 3" VBox.vgrow="ALWAYS"> 
        <maxHeight><Double fx:constant="MAX_VALUE" /></maxHeight>
    </Label>
</VBox>

这个代码在SceneBuilder生成时可能不喜欢这样,因为我使用e(fx)clipse内部DSL FXGraph来生成它。

<强> 修改

正如@James_D建议的那样(见下面的评论),这可能不是随时适合的解决方案。所以。对上述FXML的一个小修改是使用Region作为&#34;间隔符&#34;围绕Label

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

<?import java.lang.*?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.Region?>
<?import javafx.scene.layout.VBox?>

<VBox xmlns:fx="http://javafx.com/fxml" alignment="CENTER">
    <Region VBox.vgrow="ALWAYS"> 
        <maxHeight><Double fx:constant="MAX_VALUE" /></maxHeight>
    </Region>
    <Label text="Label 1"/> 
    <Region VBox.vgrow="ALWAYS"> 
        <maxHeight><Double fx:constant="MAX_VALUE" /></maxHeight>
    </Region>
    <Label text="Label 2"/> 
    <Region VBox.vgrow="ALWAYS"> 
        <maxHeight><Double fx:constant="MAX_VALUE" /></maxHeight>
    </Region>
    <Label text="Label 3"/> 
    <Region VBox.vgrow="ALWAYS"> 
        <maxHeight><Double fx:constant="MAX_VALUE" /></maxHeight>
    </Region>
</VBox>

这应该是一个更灵活的解决方案。