如何使用GridPane和HBox使javafx表单中的所有字段都可单击?

如何使用GridPane和HBox使javafx表单中的所有字段都可单击?,java,javafx,gridpane,pane,hbox,Java,Javafx,Gridpane,Pane,Hbox,我想制作一个有三个部分的表单,两个有字段,一个有按钮 public class Form extends Application{ public static void main(String[] args) { launch(args); } @Override public void start(Stage stage) throws Exception { StackPane r

我想制作一个有三个部分的表单,两个有字段,一个有按钮

public class Form extends Application{
    
    public static void main(String[] args) {
        launch(args);
    }   
    
    @Override
    public void start(Stage stage) throws Exception {           
        StackPane root = new StackPane();
        GridPane fp = new GridPane();
        fp.setAlignment(Pos.TOP_CENTER);
        fp.setHgap(6);
        fp.setVgap(6);
        fp.add(new Label("Name: "), 0, 0);
        
        TextField name = new TextField();
        name.setPrefWidth(450);
        fp.add(name, 1, 0);
        
        GridPane sp = new GridPane();
        sp.setAlignment(Pos.CENTER);
        sp.setHgap(6);
        sp.setVgap(6);
        sp.add(new Label("Another Name: "), 1, 0);
        
        TextField anothername = new TextField();
        anothername.setPrefWidth(120);
        sp.add(anothername, 2, 0);
        HBox hbox = new HBox();
    
        hbox.setAlignment(Pos.BOTTOM_CENTER);
        Button btn1 = new Button("Button 1");
        hbox.getChildren().add(btn1);
    
        Scene scene = new Scene(root, 500, 500);
        root.getChildren().addAll(fp, sp, hbox);
        stage.setScene(scene);
        stage.show();
    }
}
格式化和一些文本可能会关闭,但这是我的一般解决方案。我制作了一个根堆栈窗格来保存表单的所有部分。然后,我制作了两个网格窗格来容纳文本字段,并在底部制作了一个
hbox
来容纳我的按钮


我的问题是,只能单击名称字段。如果我尝试单击另一个名称字段,它将不起作用。我可以按tab键在字段和按钮之间循环,但我希望能够单独单击每个字段。有没有更好的方法来创建一个具有多个窗格或HBox的场景?我也愿意只使用一个网格窗格,但我认为使用两个网格窗格会更容易格式化,因为我想分离不同的字段。谢谢大家!

您面临的问题是使用
StackPane
作为场景的根元素造成的

顾名思义,
StackPane
,将其子项一个叠在另一个上。放置在顶部的任何子项都将是接收事件的子项(例如单击
另一个名称
字段)

您已经添加了3个节点作为
堆栈窗格的子节点

  • 网格窗格#1
    fp
  • 网格窗格#2
    sp
  • HBox
    HBox
  • 由于上次添加了
    HBox
    ,因此它是唯一可以接收单击事件的节点

    使用您的示例,我为上述3项中的每一项添加了边框,以说明JavaFX是如何布置它们的:

    如您所见,
    StackPane
    的每个子项都会调整大小以填充整个区域(我对边框使用了不同的宽度,因此您可以看到所有边框)

    在显示阶段之前,您可以通过添加以下代码来尝试此操作:

    fp.setStyle("-fx-border-color: green; -fx-border-width: 15px");
    sp.setStyle("-fx-border-color: blue; -fx-border-width: 10px");
    hbox.setStyle("-fx-border-color: red; -fx-border-width: 5px");
    
    要解决这个问题,你需要重新考虑你的布局;在您的案例中,
    StackPane
    肯定不是正确的布局窗格


    我强烈建议您仔细阅读Oracle教程中的示例,以便更好地掌握如何最佳地布局场景。

    您所面临的问题是由于您使用
    堆栈窗格作为场景的根元素造成的

    顾名思义,
    StackPane
    ,将其子项一个叠在另一个上。放置在顶部的任何子项都将是接收事件的子项(例如单击
    另一个名称
    字段)

    您已经添加了3个节点作为
    堆栈窗格的子节点

  • 网格窗格#1
    fp
  • 网格窗格#2
    sp
  • HBox
    HBox
  • 由于上次添加了
    HBox
    ,因此它是唯一可以接收单击事件的节点

    使用您的示例,我为上述3项中的每一项添加了边框,以说明JavaFX是如何布置它们的:

    如您所见,
    StackPane
    的每个子项都会调整大小以填充整个区域(我对边框使用了不同的宽度,因此您可以看到所有边框)

    在显示阶段之前,您可以通过添加以下代码来尝试此操作:

    fp.setStyle("-fx-border-color: green; -fx-border-width: 15px");
    sp.setStyle("-fx-border-color: blue; -fx-border-width: 10px");
    hbox.setStyle("-fx-border-color: red; -fx-border-width: 5px");
    
    要解决这个问题,你需要重新考虑你的布局;在您的案例中,
    StackPane
    肯定不是正确的布局窗格

    我强烈建议您阅读Oracle教程中的示例,以便更好地掌握如何优化场景布局