Events 从menuItem获取源场景

Events 从menuItem获取源场景,events,javafx,scene,Events,Javafx,Scene,我在旁边找到了相关的问题,但是如果不使用FXML,MenuItem没有一个超类,我可以使用它来获得场景。当我在一个按钮实例中发现同样的问题时,我使用下面的方法 (Scene) ((Node) event.getSource()).getScene(); 如果您有任何关于如何解决这个问题的想法,我将不胜感激。 提前谢谢 这是窗户的视图 /** * @author Jose Gonzalez * */ public class Transaction extends TempletePa

我在旁边找到了相关的问题,但是如果不使用FXML,
MenuItem
没有一个超类,我可以使用它来获得场景。当我在一个按钮实例中发现同样的问题时,我使用下面的方法

(Scene) ((Node) event.getSource()).getScene();
如果您有任何关于如何解决这个问题的想法,我将不胜感激。 提前谢谢

这是窗户的视图

/**
 * @author Jose Gonzalez
 *
 */
 public class Transaction  extends TempletePattern{
  private ImageView viewImage;
  private Button button;
  private TransactionController controller;
  private TableView<Saving> table;
  private TableColumn dateColum;
  private TableColumn descriptionColum;
  private TableColumn amountColum;
  private TableColumn valanceColum;
  /**
   * 
   * @param controller
   */
  public Transaction(TransactionController controller)
  {
    this.controller = controller;

  }

/**
 * main method all private methods in the class and set them up on the        borderpane
 * @return pane fully setup to be mount on the scene
 */
public BorderPane setScreen() 
{

    BorderPane trans = new BorderPane();
    trans.setStyle("-fx-background: #FFFFFF;");
    VBox topBox = new VBox ();
    topBox.getChildren().addAll( setMenu(),setTop() );
    trans.setTop(topBox );
    trans.setBottom(processUpdate(process) );
    trans.setCenter(setCenter() );


    return trans;
}
/**
 * 
 * @return vbox holding all note pertaining to the center of the borderpane
 */
private VBox setCenter()
{

    VBox center = new VBox();
    center.setPadding(new Insets(30, 20, 20, 20) );
    table = new TableView<>();
    table.setEditable(true);

    dateColum = new TableColumn("Date");
    dateColum.setCellValueFactory( new PropertyValueFactory<>("firstName"));
    dateColum.prefWidthProperty().bind(table.widthProperty().divide(4));
    dateColum.setResizable(false);

    descriptionColum = new TableColumn("Description");
    descriptionColum.prefWidthProperty().bind(table.widthProperty().divide(4));
    descriptionColum.setResizable(false);
    descriptionColum.setCellValueFactory(new PropertyValueFactory<>("lastName") );

    amountColum = new TableColumn("Amount");
    amountColum.prefWidthProperty().bind(table.widthProperty().divide(4));
    amountColum.setResizable(false);
    amountColum.setCellValueFactory( new PropertyValueFactory<>("transaction") );

    valanceColum = new TableColumn("Availble Valance");
    valanceColum.prefWidthProperty().bind(table.widthProperty().divide(4));
    valanceColum.setResizable(false);
    valanceColum.setCellValueFactory( new PropertyValueFactory<>("valance"));

    table.getColumns().addAll(dateColum, descriptionColum, amountColum,valanceColum );
    mockInfo();
    center.getChildren().add(table);

    return center;
}

/**
 * 
 * @return the screen's menu fully set up
 */
private MenuBar setMenu()
{

    MenuBar menubar = new MenuBar();
     final Menu UserMenu = new Menu("User");
     UserMenu.setId("user");
     UserMenu.setOnAction(controller);
     MenuItem itemLog = new MenuItem("log out");
     itemLog.setId("logout");
     itemLog.setOnAction(controller);
     MenuItem itemAcount = new MenuItem("new acount");
     itemAcount.setId("newAccount");
     UserMenu.getItems().addAll(itemLog, itemAcount);

     final Menu acctMenu = new Menu("Accounts");
     MenuItem itemsavis = new MenuItem("Savings");
     MenuItem itemCredit = new MenuItem("Credit");
     MenuItem itemChecking = new MenuItem("Checking");
     acctMenu.getItems().addAll(itemsavis, itemCredit, itemChecking);


     final Menu aboutMenu = new Menu("about");
     MenuItem itemHelp = new MenuItem("Help");
     aboutMenu.getItems().addAll(itemHelp);


     menubar.getMenus().addAll(UserMenu,  acctMenu, aboutMenu);

    return menubar;
}

/**
 * @param receive constumer info from model through controller and set it on table.
 */
public void  tableDataSetter(ObservableList<Saving> costumerInfo)
{
    table.setItems(costumerInfo);
}

/**
 * insert mock data to be displayed as a place holder 
 */
private void  mockInfo()
{

    ObservableList<Saving> data =
            FXCollections.observableArrayList(
                    new Saving("11/10/16", "Deposit", 123, "123" ),
                    new Saving("11/11/16", "Withdraw", 5, "123" ),
                    new Saving("11/12/16", "Deposit", 24, "123" ),
                    new Saving("11/13/16", "Withdraw", 62, "123" ),
                    new Saving("11/14/16", "Deposit", 134, "123" ),
                    new Saving("11/15/16", "Deposit", 134, "123" ), 
                    new Saving("11/10/16", "Withdraw", 123, "123" ),
                    new Saving("11/11/16", "Deposit", 5, "123" ),
                    new Saving("11/12/16", "Withdraw", 24, "123" ),
                    new Saving("11/13/16", "Deposit", 62, "123" ),
                    new Saving("11/14/16", "Withdraw", 134, "123" ),
                    new Saving("11/15/16", "Deposit", 134, "123" ) 
                    );

    table.setItems(  data  );
 }



}

您可以通过菜单层次结构向上移动,直到到达带有弹出窗口的菜单,并获得此弹出窗口的所有者窗口,即打开上下文菜单的窗口

@Override
public void start(Stage primaryStage) {
    MenuItem menuItem = new MenuItem("Something");
    Menu menuInner = new Menu("menu", null, menuItem);
    Menu menuOuter = new Menu("menu", null, menuInner);
    MenuBar menuBar = new MenuBar(menuOuter);

    StackPane root = new StackPane();
    root.setAlignment(Pos.TOP_LEFT);
    root.getChildren().add(menuBar);

    Scene scene = new Scene(root);

    menuItem.setOnAction(evt -> {
        MenuItem m = (MenuItem) evt.getSource();
        while (m.getParentPopup() == null) {
            m = m.getParentMenu();
        }

        Scene s = m.getParentPopup().getOwnerWindow().getScene();
        System.out.println(s == scene);
    });

    primaryStage.setScene(scene);
    primaryStage.show();
}

一般来说,我认为把有关所讨论的场景的信息简单地写在<代码> EventHandler <代码>的<代码> MenuItem <代码>:

final Scene scene = ...

menuItem.setOnAction(evt -> {
    // do something with scene
});

(有效地)
final
局部变量的替代方法是使用一个字段…

您可以在菜单层次结构中向上移动,直到到达一个带有弹出窗口的菜单,并获得该弹出窗口的所有者窗口,该窗口是打开上下文菜单的窗口

@Override
public void start(Stage primaryStage) {
    MenuItem menuItem = new MenuItem("Something");
    Menu menuInner = new Menu("menu", null, menuItem);
    Menu menuOuter = new Menu("menu", null, menuInner);
    MenuBar menuBar = new MenuBar(menuOuter);

    StackPane root = new StackPane();
    root.setAlignment(Pos.TOP_LEFT);
    root.getChildren().add(menuBar);

    Scene scene = new Scene(root);

    menuItem.setOnAction(evt -> {
        MenuItem m = (MenuItem) evt.getSource();
        while (m.getParentPopup() == null) {
            m = m.getParentMenu();
        }

        Scene s = m.getParentPopup().getOwnerWindow().getScene();
        System.out.println(s == scene);
    });

    primaryStage.setScene(scene);
    primaryStage.show();
}

一般来说,我认为把有关所讨论的场景的信息简单地写在<代码> EventHandler <代码>的<代码> MenuItem <代码>:

final Scene scene = ...

menuItem.setOnAction(evt -> {
    // do something with scene
});

(有效地)
final
局部变量的替代方法是使用一个字段…

很难想象这样一种场景,即在无法轻松获取场景或场景中至少一个节点的上下文中向菜单项添加处理程序。你能给出一些上下文吗,例如,显示为什么你需要从事件中获取场景?在我的应用程序中,我想让用户能够添加一个新帐户。计划是让用户进入另一个屏幕/窗格,而不创建新的舞台或场景。但这并不能回答我的问题。在注册处理程序的代码中,必须能够获取对场景或场景中某个对象的引用。你能回答你的问题并发布一些有足够上下文的代码来说明问题吗?我为没有提前发布示例而道歉。在这一点上,是的,您希望能够从偶数中获得某种类型的有用参考,但我一直没有成功。很难想象在无法轻松获取场景或场景中的节点的上下文中向菜单项添加处理程序的场景。你能给出一些上下文吗,例如,显示为什么你需要从事件中获取场景?在我的应用程序中,我想让用户能够添加一个新帐户。计划是让用户进入另一个屏幕/窗格,而不创建新的舞台或场景。但这并不能回答我的问题。在注册处理程序的代码中,必须能够获取对场景或场景中某个对象的引用。你能回答你的问题并发布一些有足够上下文的代码来说明问题吗?我为没有提前发布示例而道歉。说到这一点,是的,你希望能从偶数中得到一些有用的参考资料,但我没有成功。谢谢你,费边。你的回答肯定有效。我尝试了几次向上提升菜单层次结构,但我的方法不正确。我故意不把这场戏传出去。我想避免耦合问题,或者只是简单地看看程序是否可以在不经过现场的情况下完成。谢谢你,费边。你的回答肯定有效。我尝试了几次向上提升菜单层次结构,但我的方法不正确。我故意不把这场戏传出去。我想避免耦合问题,或者只是简单地看看程序是否可以在不经过场景的情况下完成。