JAVA javaFX菜单栏,多项,一种方法(场景生成器)

JAVA javaFX菜单栏,多项,一种方法(场景生成器),java,javafx,scenebuilder,Java,Javafx,Scenebuilder,我有一个用带有菜单栏的场景生成器构建的窗口。 在菜单栏中有几个菜单项只打开其他窗口 因此,我只想编写一个可以由这些菜单项中的每个菜单项使用的函数,并打开相应的窗口 我尝试为每个menuItem提供一个id,并使用此函数 public void openWindow(ActionEvent event){ System.out.println( event); } 我可以看到该id(例如:customer menuItem) 但是我不知道如何使用它来打开客户窗口。为了从ActionEv

我有一个用带有菜单栏的场景生成器构建的窗口。 在菜单栏中有几个菜单项只打开其他窗口

因此,我只想编写一个可以由这些菜单项中的每个菜单项使用的函数,并打开相应的窗口

我尝试为每个menuItem提供一个id,并使用此函数

public void openWindow(ActionEvent event){ 
    System.out.println( event);
}
我可以看到该id(例如:customer menuItem)


但是我不知道如何使用它来打开客户窗口。

为了从ActionEvent获取id,您应该将其源代码转换为MenuItem:

public void openWindow(ActionEvent event){
    MenuItem source = (MenuItem) event.getSource();
    System.out.println(source.getId());
}
请注意,如果您不确定事件源的类型是否为MenuItem,可以这样检查:

if (event.getSource() instanceof MenuItem) {
     MenuItem source = (MenuItem) event.getSource();
     System.out.println(source.getId());
}

为了从ActionEvent获取id,您应该将其源强制转换为MenuItem:

public void openWindow(ActionEvent event){
    MenuItem source = (MenuItem) event.getSource();
    System.out.println(source.getId());
}
请注意,如果您不确定事件源的类型是否为MenuItem,可以这样检查:

if (event.getSource() instanceof MenuItem) {
     MenuItem source = (MenuItem) event.getSource();
     System.out.println(source.getId());
}

一个选项是获取事件源(菜单项
并从中检索一些适当的数据(例如
id
userData
),如其他答案所示。这会起作用,但感觉有点脆弱,因为您依赖于字符串绑定,并且必须对所有类型执行强制转换

在这种情况下,我更愿意定义一个单独的方法来处理每个菜单项。显然,您仍然可以按照通常的方式将公共功能重构为单独的方法

public class MyController {

    @FXML
    private void openCustomersWindow() {
        openWindow("/path/to/customers.fxml");
    }

    @FXML
    private void openOrdersWindow() {
        openWindow("/path/to/orders.fxml");
    }

    // ...

    private void openWindow(String resource) {
        try {
            FXMLLoader loader = new FXMLLoader(getClass().getResource(resource));
            Scene scene = new Scene(loader.load());
            Stage newWindow = new Stage();
            newWindow.setScene(scene);
            newWindow.show();
        } catch (Exception exc) {
            // handle errors....
        }
    }

}
然后只需对一个菜单项使用
onAction=“#openCustomersWindow”
,对另一个菜单项使用
onAction=“#openOrdersWindow”
,以此类推


很明显,这里有一些重复的代码,但并不坏(当然也不比FXML中的重复量差)。如果你有足够的<代码> MenuItem < /C> > S,这是有问题的,你可能会考虑考虑用java代码来代替FXML来定义它们。< /P> < P>一个选项是获取事件的源(<代码> MenuItem < /C> >)并从中检索一些适当的数据(例如<代码> ID <代码>或<代码> USEDATABAS/COD>)如其他答案所示。这会起作用,但感觉有点脆弱,因为您依赖于字符串绑定,并且必须对所有类型执行强制转换

在这种情况下,我更愿意定义一个单独的方法来处理每个菜单项。显然,您仍然可以按照通常的方式将公共功能重构为单独的方法

public class MyController {

    @FXML
    private void openCustomersWindow() {
        openWindow("/path/to/customers.fxml");
    }

    @FXML
    private void openOrdersWindow() {
        openWindow("/path/to/orders.fxml");
    }

    // ...

    private void openWindow(String resource) {
        try {
            FXMLLoader loader = new FXMLLoader(getClass().getResource(resource));
            Scene scene = new Scene(loader.load());
            Stage newWindow = new Stage();
            newWindow.setScene(scene);
            newWindow.show();
        } catch (Exception exc) {
            // handle errors....
        }
    }

}
然后只需对一个菜单项使用
onAction=“#openCustomersWindow”
,对另一个菜单项使用
onAction=“#openOrdersWindow”
,以此类推


很明显,这里有一些重复的代码,但并不坏(当然也不比FXML中的重复量差)。如果你有足够的代码< MenuItem > /CODEXS,这是个问题,你可能想考虑用java代码来定义它们,而不是用FXML来定义。

< P>如果所有的东西都有ID,你可以试试这个。p>
@FXML void openWindow(ActionEvent event){
    try 
    {
        MenuItem tempMenuItem = (MenuItem)event.getSource();                   
        System.out.println(tempMenuItem.getId());


        switch(tempMenuItem.getId())
        {
            case "yourFirstID":
                //open your first window here
                break;
            case "yourSecondID":
                //open your second window here
                break;
        }
    } 
    catch (IOException ex) 
    {
         //catch errors here
    }
}

如果所有东西都有ID,你可以试试这个

@FXML void openWindow(ActionEvent event){
    try 
    {
        MenuItem tempMenuItem = (MenuItem)event.getSource();                   
        System.out.println(tempMenuItem.getId());


        switch(tempMenuItem.getId())
        {
            case "yourFirstID":
                //open your first window here
                break;
            case "yourSecondID":
                //open your second window here
                break;
        }
    } 
    catch (IOException ex) 
    {
         //catch errors here
    }
}

我真的很喜欢你的方法。对于严肃的商业应用,我肯定会使用这个。另一方面,对于小应用程序,我会坚持使用我的)无论如何,meI的+1非常喜欢你的方法。对于严肃的商业应用,我肯定会使用这个。另一方面,对于小型应用程序,我会坚持使用我的)无论如何,+1来自我,如果JavaFX的更高版本更改控件的
toString()
方法的格式会发生什么?他们会指出,
toString()的实现有任何保证,而且从来没有保证过
将在不同版本之间保持不变。建议您使用
toString()
方法作为事实上的API(特别是当所有值实际上都可以通过真实的API调用使用时)是完全错误的。我解决了这个问题。现在我的答案与另一个人一样。如果JavaFX的更高版本更改
toString()的格式会发生什么
控制方法?他们会指出,
toString()
的实现从一个版本到另一个版本都将保持不变,这是没有任何保证的。建议您使用
toString()
方法作为事实上的API(特别是当所有值实际上都可以通过实际API调用使用时),这是完全错误的。我解决了这个问题。现在我的答案与另一个人一样。