2017-01-12 2 views
1

J'ai trouvé des questions connexes sur le côté, mais non sans utiliser FXML, MenuItem n'a pas une super classe que je peux lancer pour obtenir la scène. J'utilise l'approche ci-dessous quand j'ai trouvé le même problème avec une instance de bouton.Obtenir la scène source de menuItem

(Scene) ((Node) event.getSource()).getScene(); 

Des idées sur la façon de résoudre ce problème seront très appréciées. Merci à l'avance

ici est la vue de la fenêtre

/** 
* @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 ); 
} 



} 

et est le contrôleur ici. ps Je viens de commencer à travailler dessus.

public class TransactionController implements EventHandler{ 


    //private LoginModel model ; 
    private Transaction view; 


    public TransactionController() 
    { 
    // model = new LoginModel(); 
     view = new Transaction(this); 
    } 

    @Override 
    public void handle(Event event) { 

     if(( event.getSource() instanceof MenuItem)) 
     { 
      System.out.println("afe " + (((Object)event.getTarget())) ); 
      if( ((MenuItem) (event.getSource()) ).getId().equals("logout") ) 
      { 

       System.err.println("from inside logout"); 
      /// this.goTologInt(event); 
      }else if(((MenuItem) (event.getSource()) ).getId().equals("newAccount") ) 
      { 
      // this.goToNewAct(event); 

      } 


     } 

    } 

    private void goToNewAct(Event event) 
    { 
     Scene scene = (Scene) ((Control) event.getSource()).getScene(); 
    // Stage stage = (Stage) ((Node) event.getSource()).getScene().getWindow(); 
     NewCustomerView newAcct = new NewCustomerView(); 
     scene.setRoot(newAcct.newCustomerScreen()); 
    } 


    private void goTologInt(Event event) 
    { 
     Scene scene = (Scene) ((Node)event.getSource()).getScene() ; 
     //Scene scene = (Scene) ((Control) event.getSource()).getScene(); 
     // Stage stage = (Stage) ((Node) event.getSource()).getScene().getWindow(); 
     LoginView newAcct = new LoginView(new LoginController()); 
     scene.setRoot(newAcct.loginScreen()); 
    } 

} 
+0

Il est difficile d'imaginer un scénario où vous ajoutez un gestionnaire à un élément de menu dans un cont ext où vous ne pouvez pas obtenir la scène, ou au moins un noeud dans la scène, raisonnablement facilement. Pouvez-vous donner un contexte pour cela, par ex. un [MCVE] montrant pourquoi vous devez obtenir la scène * uniquement * de l'événement? –

+0

sur mon application Je veux donner à l'utilisateur la possibilité d'ajouter un nouveau compte. Le plan pour amener l'utilisateur à un autre écran/volet sans créer une nouvelle scène ou scène. –

+1

Cela ne répond pas à ma question cependant. Dans le code où vous enregistrez le gestionnaire, vous devez être en mesure d'obtenir une référence à la scène ou à quelque chose dans la scène. Pouvez-vous [modifier] votre question et poster un code * avec suffisamment de contexte * pour montrer le problème? –

Répondre

0

Vous pouvez aller dans la hiérarchie de menu jusqu'à ce que vous atteignez un menu avec un pop-up et obtenir la fenêtre propriétaire de ce pop-up, ce qui est la fenêtre du menu contextuel a été ouvert à partir.

@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(); 
} 

En général je considère qu'il est une meilleure idée que de faire simplement les informations sur la scène en question à la disposition du EventHandler du MenuItem:

final Scene scene = ... 

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

L'alternative à une (effectivement) final variable locale serait l'utilisation d'un champ ...

+0

Merci, Fabian, votre réponse fonctionne certainement. J'ai essayé de remonter la hiérarchie des menus plusieurs fois, mais mon approche était incorrecte. Je ne fais délibérément pas le tour de la scène. Je veux éviter les problèmes de couplage ou simplement voir si le programme peut être fait sans passer la scène. –