JAVA javaFX menuBar,多个项目,一个方法(场景生成器)
JAVA javaFX menuBar, multiple items, one method (scene Builder)
我有一个 window 使用带有菜单栏的场景生成器构建的。
在 menuBar 中有几个只能打开其他 windows 的菜单项。
所以我只想写一个可以被那些menuItem中的每一个使用的函数,并打开相应的window。
我尝试为每个菜单项提供一个 id,并使用此功能
public void openWindow(ActionEvent event){
System.out.println( event);
}
我可以看到该 ID(例如:客户菜单项),
javafx.event.ActionEvent[source=MenuItem[id=customers, styleClass=[menu-item]]]
但是我不知道如何获取它来打开客户window。
为了从 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());
}
一个选项是获取事件源(MenuItem
)并从中检索一些适当的数据(例如 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
s 而这是有问题的,你可能会考虑在 Java 代码而不是 FXML 中定义它们。
如果所有东西都有一个 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
}
}
我有一个 window 使用带有菜单栏的场景生成器构建的。 在 menuBar 中有几个只能打开其他 windows 的菜单项。
所以我只想写一个可以被那些menuItem中的每一个使用的函数,并打开相应的window。
我尝试为每个菜单项提供一个 id,并使用此功能
public void openWindow(ActionEvent event){
System.out.println( event);
}
我可以看到该 ID(例如:客户菜单项),
javafx.event.ActionEvent[source=MenuItem[id=customers, styleClass=[menu-item]]]
但是我不知道如何获取它来打开客户window。
为了从 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());
}
一个选项是获取事件源(MenuItem
)并从中检索一些适当的数据(例如 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
s 而这是有问题的,你可能会考虑在 Java 代码而不是 FXML 中定义它们。
如果所有东西都有一个 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
}
}