2016-04-04 57 views
3

我需要使用3个标签在JavaFX中创建布局。每个标签应该水平居中。第一个应放置在窗户下方1/4的位置,第二个应位于一半的下方(即垂直居中),第三个应位于下方3/4处。基于窗口大小百分比的JavaFX布局

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

这似乎很简单,但我不知道该怎么做。我尝试过使用VBox,但似乎没有办法对垂直位置进行精确控制。然后,我看着AnchorPane,但看不到如何做到这一点。

有人可以告诉我一个简单的方法来做到这一点与FXML或编程?

回答

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

+0

使用GridPane我还没有考虑过,但现在回想起来,这是显而易见的选择。谢谢你的帮助。 –

+0

这是布局窗格,可以让您对定位进行最好的控制:如果您使用了Swing,JavaFX就相当于Swing的'GridBagLayout'。 –

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作为您的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> 

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

+0

我尝试过使用VBox,但我认为比例出错了。每个“标签”都是“VBox”高度的1/3,并且标签居中,因此顶部标签在屏幕下方为1/6,而不是1/4(同样,底部标签为5/6)。 –

+0

你可能是对的。在这种情况下,您需要在'Label'周围使用'Region'作为“间隔符”。我会相应地更新我的答案并添加此选项。 – dzim

1

下面的ConstrainedGridPane类有助于做到这一点。 在你的四个标签情况下,你扩展它像这样:

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