Javafx java中的FXML访问按钮ID

Javafx java中的FXML访问按钮ID,javafx,fxml,Javafx,Fxml,我给了一个网格窗格一个fxml文件中定义的fx:id的值,然后用getId函数在java代码中访问thid id,这很好。但是,当我尝试使用按钮执行相同操作时,getId返回null。我想做的事情可能吗?如果可能,我怎么能做类似的事情 这是fxml文件: <?xml version="1.0" encoding="UTF-8"?> <?import javafx.scene.control.Button?> <?import javafx.scene.control

我给了一个网格窗格一个fxml文件中定义的
fx:id
的值,然后用
getId
函数在java代码中访问thid id,这很好。但是,当我尝试使用按钮执行相同操作时,
getId
返回null。我想做的事情可能吗?如果可能,我怎么能做类似的事情

这是fxml文件:

<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.HBox?>

<?import javafx.scene.layout.VBox?>

<GridPane alignment="center" hgap="40" vgap="40" xmlns:fx="http://javafx.com/fxml/1"
          fx:controller="Tills.Controllers.MoviePageController">
    <GridPane fx:id="movie1Grid" alignment="center" hgap="10" vgap="10" GridPane.columnIndex="0" GridPane.rowIndex="0">
        <HBox alignment="center" GridPane.columnIndex="0" GridPane.rowIndex="0">
            <Label fx:id="movie1" alignment="center" text="Movie 1"/>
        </HBox>
        <HBox alignment="center" GridPane.columnIndex="0" GridPane.rowIndex="1" spacing="10">
            <VBox alignment="center">
                <Button fx:id="button0" text="17:00" onAction="#submitMovieChoice"/>
                <Label text="test screen"/>
            </VBox>
            <VBox alignment="center">
                <Button fx:id="button1" text="13:15" onAction="#submitMovieChoice"/>
                <Label text="test screen"/>
            </VBox>
            <VBox alignment="center">
                <Button fx:id="button2" text="13:30" onAction="#submitMovieChoice"/>
                <Label text="test screen"/>
            </VBox>
        </HBox>
    </GridPane>

    <GridPane fx:id="movie2Grid" alignment="center" hgap="10" vgap="10" GridPane.columnIndex="0" GridPane.rowIndex="1">
        <HBox alignment="center" GridPane.columnIndex="0" GridPane.rowIndex="0">
            <Label fx:id="movie2" alignment="center" text="Movie 1"/>
        </HBox>
        <HBox alignment="center" GridPane.columnIndex="0" GridPane.rowIndex="1" spacing="10">
            <VBox alignment="center">
                <Button fx:id="button3" text="13:00" onAction="#submitMovieChoice"/>
                <Label text="test screen"/>
            </VBox>
            <VBox alignment="center">
                <Button fx:id="button4" text="13:15" onAction="#submitMovieChoice"/>
                <Label text="test screen"/>
            </VBox>
            <VBox alignment="center">
                <Button fx:id="button5" text="13:30" onAction="#submitMovieChoice"/>
                <Label text="test screen"/>
            </VBox>
        </HBox>
    </GridPane>

    <GridPane fx:id="movie3Grid" alignment="center" hgap="10" vgap="10" GridPane.columnIndex="0" GridPane.rowIndex="2">
        <HBox alignment="center" GridPane.columnIndex="0" GridPane.rowIndex="0">
            <Label fx:id="movie3" alignment="center" text="Movie 1"/>
        </HBox>
        <HBox alignment="center" GridPane.columnIndex="0" GridPane.rowIndex="1" spacing="10">
            <VBox alignment="center">
                <Button fx:id="button6" text="13:00" onAction="#submitMovieChoice"/>
                <Label text="test screen"/>
            </VBox>
            <VBox alignment="center">
                <Button fx:id="button7" text="13:15" onAction="#submitMovieChoice"/>
                <Label text="test screen"/>
            </VBox>
            <VBox alignment="center">
                <Button fx:id="button8" text="13:30" onAction="#submitMovieChoice"/>
                <Label text="test screen"/>
            </VBox>
        </HBox>
    </GridPane>

    <GridPane fx:id="movie4Grid" alignment="center" hgap="10" vgap="10" GridPane.columnIndex="1" GridPane.rowIndex="0">
        <HBox alignment="center" GridPane.columnIndex="0" GridPane.rowIndex="0">
            <Label fx:id="movie4" alignment="center" text="Movie 1"/>
        </HBox>
        <HBox alignment="center" GridPane.columnIndex="0" GridPane.rowIndex="1" spacing="10">
            <VBox alignment="center">
                <Button fx:id="button9" text="13:00" onAction="#submitMovieChoice"/>
                <Label text="test screen"/>
            </VBox>
            <VBox alignment="center">
                <Button fx:id="button10" text="13:15" onAction="#submitMovieChoice"/>
                <Label text="test screen"/>
            </VBox>
            <VBox alignment="center">
                <Button fx:id="button11" text="13:30" onAction="#submitMovieChoice"/>
                <Label text="test screen"/>
            </VBox>
        </HBox>
    </GridPane>

    <GridPane fx:id="movie5Grid" alignment="center" hgap="10" vgap="10" GridPane.columnIndex="1" GridPane.rowIndex="1">
        <HBox alignment="center" GridPane.columnIndex="0" GridPane.rowIndex="0">
            <Label fx:id="movie5" alignment="center" text="Movie 1"/>
        </HBox>
        <HBox alignment="center" GridPane.columnIndex="0" GridPane.rowIndex="1" spacing="10">
            <VBox alignment="center">
                <Button fx:id="button12" text="13:00" onAction="#submitMovieChoice"/>
                <Label text="test screen"/>
            </VBox>
            <VBox alignment="center">
                <Button fx:id="button13" text="13:15" onAction="#submitMovieChoice"/>
                <Label text="test screen"/>
            </VBox>
            <VBox alignment="center">
                <Button fx:id="button14" text="13:30" onAction="#submitMovieChoice"/>
                <Label text="test screen"/>
            </VBox>
        </HBox>
    </GridPane>

    <GridPane fx:id="movie6Grid" alignment="center" hgap="10" vgap="10" GridPane.columnIndex="1" GridPane.rowIndex="2">
        <HBox alignment="center" GridPane.columnIndex="0" GridPane.rowIndex="0">
            <Label fx:id="movie6" alignment="center" text="Movie 1"/>
        </HBox>
        <HBox alignment="center" GridPane.columnIndex="0" GridPane.rowIndex="1" spacing="10">
            <VBox alignment="center">
                <Button fx:id="button15" text="13:00" onAction="#submitMovieChoice"/>
                <Label text="test screen"/>
            </VBox>
            <VBox alignment="center">
                <Button fx:id="button16" text="13:15" onAction="#submitMovieChoice"/>
                <Label text="test screen"/>
            </VBox>
            <VBox alignment="center">
                <Button fx:id="button17" text="13:30" onAction="#submitMovieChoice"/>
                <Label text="test screen"/>
            </VBox>
        </HBox>
    </GridPane>
</GridPane>

直接回答您的问题:如果未明确设置
id
,则
fxmloader
将任何节点的
id
设置为与其
fx:id
相同。因此,在您发布的代码中,按钮将具有
id
“button0”到
button17
,正如预期的那样

我简化了您的代码以便可以运行它,如下所示:

application/Test.fxml
(此处唯一的更改是控制器名称,因为我只是将所有内容放入不同的包中):


application/MoviePageController.java
(通过删除其他依赖项简化):

和一个测试用例:

application/Test.java

package application;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class Test extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception {
        Scene scene = new Scene(FXMLLoader.load(getClass().getResource("Test.fxml")));
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}
这一切都完全按照预期进行,并打印出相应的消息等


我只是不推荐你的方法。它引入了各种附加的字符串绑定,这很容易受到未检查(由编译器)输入错误的攻击,并且有大量重复代码。此外,您将数据存储在UI元素中(例如,您似乎唯一表示电影名称的地方是标签中)。这不是一个好方法:您应该将数据独立于UI,并考虑UI控件简单的数据视图。(有关这方面的更多信息,请阅读“模型-视图-控制器”类型的体系结构。)

例如,考虑将所有重复的FXML放在一个FXML文件中:


使用具有值的控制器,您可以设置:

package application;

import java.io.IOException;

import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.stage.Stage;

public class MovieController {

    private String firstShowing ;
    private String secondShowing ;
    private String thirdShowing ;

    private int baseID ;


    @FXML
    private Label movie ;
    @FXML
    private Button firstShowingButton ;
    @FXML
    private Button secondShowingButton ;
    @FXML
    private Button thirdShowingButton ;


    public void setMovieName(String movieName) {
        movie.setText(movieName);
    }

    public String getMovieName() {
        return movie.getText() ;
    }

    public int getBaseID() {
        return baseID ;
    }

    public void setBaseID(int baseID) {
        this.baseID = baseID ;
    }

    public String getFirstShowing() {
        return firstShowing;
    }
    public void setFirstShowing(String firstShowing) {
        this.firstShowing = firstShowing;
        firstShowingButton.setText(firstShowing);
    }
    public String getSecondShowing() {
        return secondShowing;
    }
    public void setSecondShowing(String secondShowing) {
        this.secondShowing = secondShowing;
        secondShowingButton.setText(secondShowing);
    }
    public String getThirdShowing() {
        return thirdShowing;
    }
    public void setThirdShowing(String thirdShowing) {
        this.thirdShowing = thirdShowing;
        thirdShowingButton.setText(thirdShowing);
    }

    public void setShowings(String firstShowing, String secondShowing, String thirdShowing) {
        setFirstShowing(firstShowing);
        setSecondShowing(secondShowing);
        setThirdShowing(thirdShowing);
    }

    private void submitChoice(String showing, int id) {
        try {

            int screeningID = baseID * 3 + id ;
            int age =  0 ;
            //Load the ticket page with the selected name and time
            FXMLLoader loader = new FXMLLoader(getClass().getResource("../ticketType.fxml"));
            TicketPageController controller = new TicketPageController(showing, getMovieName(), screeningID, age);
            loader.setController(controller);
            Parent parent = loader.load();
            Stage window = (Stage) movie.getScene().getWindow();
            window.setScene(new Scene(parent));
            window.show();
        } catch (IOException e) {
            System.err.println("Could not load page");
        }
    }

    @FXML
    private void submitFirstChoice() {
        submitChoice(firstShowing, 0);
    }

    @FXML
    private void submitSecondChoice() {
        submitChoice(secondShowing, 1);
    }

    @FXML
    private void submitThirdChoice() {
        submitChoice(thirdShowing, 2);
    }
}
现在,您可以在代码中组装以下内容:

package application;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Pos;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;

public class Main extends Application {

    private final String[] times = {"17:00", "13:15", "13:30", "13:00", "13:15", "13:30", 
            "13:00", "13:15", "13:30", "13:00", "13:15", "13:30", "13:00", "13:15", "13:30", "13:00", "13:15", "13:30"} ;

    @Override
    public void start(Stage primaryStage) throws Exception {
        GridPane root = new GridPane();
        root.setAlignment(Pos.CENTER);
        root.setHgap(40);
        root.setVgap(40);

        for (int i = 0 ; i < 6; i++) {
            FXMLLoader loader = new FXMLLoader(getClass().getResource("MovieView.fxml"));
            Parent movieView = loader.load();
            MovieController controller = loader.getController() ;
            controller.setMovieName("Movie "+(i+1));
            controller.setShowings(times[i*3], times[i*3+1], times[i*3+2]);
            root.add(movieView, i / 3, i % 3);
        }

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

    public static void main(String[] args) {
        launch(args);
    }
}
包应用;
导入javafx.application.application;
导入javafx.fxml.fxmloader;
导入javafx.geometry.Pos;
导入javafx.scene.Parent;
导入javafx.scene.scene;
导入javafx.scene.layout.GridPane;
导入javafx.stage.stage;
公共类主扩展应用程序{
私有最终字符串[]次={“17:00”、“13:15”、“13:30”、“13:00”、“13:15”、“13:30”,
"13:00", "13:15", "13:30", "13:00", "13:15", "13:30", "13:00", "13:15", "13:30", "13:00", "13:15", "13:30"} ;
@凌驾
public void start(Stage primaryStage)引发异常{
GridPane root=新的GridPane();
根部设置对齐(位置中心);
根.setHgap(40);
根.setVgap(40);
对于(int i=0;i<6;i++){
FXMLLoader=newFXMLLoader(getClass().getResource(“MovieView.fxml”);
父movieView=loader.load();
MovieController controller=loader.getController();
controller.setMovieName(“电影”+(i+1));
控制器设置显示(次数[i*3],次数[i*3+1],次数[i*3+2]);
root.add(电影视图,i/3,i%3);
}
场景=新场景(根);
初级阶段。场景(场景);
primaryStage.show();
}
公共静态void main(字符串[]args){
发射(args);
}
}

除了摆脱所有“场景导航”(使用调用
getParent()
getChildren()
来查找其他控件)之外,如果您试图更改UI的外观,这些“场景导航”将完全中断,这也就消除了许多重复代码(特别是在FXML中)。在现实生活中,您可能正在数据库中查找这里的数据,您可以将其检索到一个对象中,并将其传递给所有控制器等。这种方法有多种多样,例如,请参见FXML文档或。您还可以进一步细分,并使用三个按钮避免重复代码(尽管这可能有些过分)。

要直接回答您的问题:
fxmloader
将任何节点的
id
设置为与其
fx:id
相同,如果没有明确设置
id
。因此,在您发布的代码中,按钮将具有
id
“button0”到
button17
,正如预期的那样

我简化了您的代码以便可以运行它,如下所示:

application/Test.fxml
package application;

import java.io.IOException;

import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.stage.Stage;

public class MovieController {

    private String firstShowing ;
    private String secondShowing ;
    private String thirdShowing ;

    private int baseID ;


    @FXML
    private Label movie ;
    @FXML
    private Button firstShowingButton ;
    @FXML
    private Button secondShowingButton ;
    @FXML
    private Button thirdShowingButton ;


    public void setMovieName(String movieName) {
        movie.setText(movieName);
    }

    public String getMovieName() {
        return movie.getText() ;
    }

    public int getBaseID() {
        return baseID ;
    }

    public void setBaseID(int baseID) {
        this.baseID = baseID ;
    }

    public String getFirstShowing() {
        return firstShowing;
    }
    public void setFirstShowing(String firstShowing) {
        this.firstShowing = firstShowing;
        firstShowingButton.setText(firstShowing);
    }
    public String getSecondShowing() {
        return secondShowing;
    }
    public void setSecondShowing(String secondShowing) {
        this.secondShowing = secondShowing;
        secondShowingButton.setText(secondShowing);
    }
    public String getThirdShowing() {
        return thirdShowing;
    }
    public void setThirdShowing(String thirdShowing) {
        this.thirdShowing = thirdShowing;
        thirdShowingButton.setText(thirdShowing);
    }

    public void setShowings(String firstShowing, String secondShowing, String thirdShowing) {
        setFirstShowing(firstShowing);
        setSecondShowing(secondShowing);
        setThirdShowing(thirdShowing);
    }

    private void submitChoice(String showing, int id) {
        try {

            int screeningID = baseID * 3 + id ;
            int age =  0 ;
            //Load the ticket page with the selected name and time
            FXMLLoader loader = new FXMLLoader(getClass().getResource("../ticketType.fxml"));
            TicketPageController controller = new TicketPageController(showing, getMovieName(), screeningID, age);
            loader.setController(controller);
            Parent parent = loader.load();
            Stage window = (Stage) movie.getScene().getWindow();
            window.setScene(new Scene(parent));
            window.show();
        } catch (IOException e) {
            System.err.println("Could not load page");
        }
    }

    @FXML
    private void submitFirstChoice() {
        submitChoice(firstShowing, 0);
    }

    @FXML
    private void submitSecondChoice() {
        submitChoice(secondShowing, 1);
    }

    @FXML
    private void submitThirdChoice() {
        submitChoice(thirdShowing, 2);
    }
}
package application;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Pos;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;

public class Main extends Application {

    private final String[] times = {"17:00", "13:15", "13:30", "13:00", "13:15", "13:30", 
            "13:00", "13:15", "13:30", "13:00", "13:15", "13:30", "13:00", "13:15", "13:30", "13:00", "13:15", "13:30"} ;

    @Override
    public void start(Stage primaryStage) throws Exception {
        GridPane root = new GridPane();
        root.setAlignment(Pos.CENTER);
        root.setHgap(40);
        root.setVgap(40);

        for (int i = 0 ; i < 6; i++) {
            FXMLLoader loader = new FXMLLoader(getClass().getResource("MovieView.fxml"));
            Parent movieView = loader.load();
            MovieController controller = loader.getController() ;
            controller.setMovieName("Movie "+(i+1));
            controller.setShowings(times[i*3], times[i*3+1], times[i*3+2]);
            root.add(movieView, i / 3, i % 3);
        }

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

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