我需要使用3个标签在JavaFX中创建布局。每个标签应该水平居中。第一个应放置在窗户下方1/4的位置,第二个应位于一半的下方(即垂直居中),第三个应位于下方3/4处。基于窗口大小百分比的JavaFX布局
如果窗口调整大小,标签应该保持它们的相对位置。
这似乎很简单,但我不知道该怎么做。我尝试过使用VBox,但似乎没有办法对垂直位置进行精确控制。然后,我看着AnchorPane,但看不到如何做到这一点。
有人可以告诉我一个简单的方法来做到这一点与FXML或编程?
我需要使用3个标签在JavaFX中创建布局。每个标签应该水平居中。第一个应放置在窗户下方1/4的位置,第二个应位于一半的下方(即垂直居中),第三个应位于下方3/4处。基于窗口大小百分比的JavaFX布局
如果窗口调整大小,标签应该保持它们的相对位置。
这似乎很简单,但我不知道该怎么做。我尝试过使用VBox,但似乎没有办法对垂直位置进行精确控制。然后,我看着AnchorPane,但看不到如何做到这一点。
有人可以告诉我一个简单的方法来做到这一点与FXML或编程?
您可以使用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);
}
}
的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>
这应该是一个更灵活的解决方案。
我尝试过使用VBox,但我认为比例出错了。每个“标签”都是“VBox”高度的1/3,并且标签居中,因此顶部标签在屏幕下方为1/6,而不是1/4(同样,底部标签为5/6)。 –
你可能是对的。在这种情况下,您需要在'Label'周围使用'Region'作为“间隔符”。我会相应地更新我的答案并添加此选项。 – dzim
下面的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);
}
}
使用GridPane我还没有考虑过,但现在回想起来,这是显而易见的选择。谢谢你的帮助。 –
这是布局窗格,可以让您对定位进行最好的控制:如果您使用了Swing,JavaFX就相当于Swing的'GridBagLayout'。 –