3

I am doing a project in javafx using Netbeans IDE. I am new to javafx. I have a menu bar in my project. I need to open a new page on the same windows when clicked on each menu item(not new scene). The code is given below :

private VBox addVBox1() {

    final VBox vbox = new VBox();
    vbox.setPadding(new Insets(20,40,30,4)); 
    vbox.setSpacing(10);

    MenuBar menuBar = new MenuBar();

    Menu menuFile1 = new Menu("ADD");
    Menu menuFile2 = new Menu("EDIT");
    Menu menuFile3 = new Menu("VIEW");
    Menu menuFile4 = new Menu("HELP");

    MenuItem add1 = new MenuItem("ENTER STUDENT DETAILS");
    MenuItem add2 = new MenuItem("ENTER C-MARK");
    MenuItem add3 = new MenuItem("ENTER ATTENDANCE");

    MenuItem add4 = new MenuItem("EDIT STUDENT DETAILS");
    MenuItem add6 = new MenuItem("EDIT C-MARK");
    MenuItem add8 = new MenuItem("EDIT ATTENDANCE");

    MenuItem add10 = new MenuItem("STUDENT DETAILS");
    MenuItem add11 = new MenuItem("C-MARK");
    MenuItem add12 = new MenuItem("ATTENDANCE");

    MenuItem add13 = new MenuItem("VIEW HELP"); 

    add1.setOnAction(new EventHandler<ActionEvent>() {
        public void handle(ActionEvent t) {
            //...WHAT TO INCLUDE HERE ?
        }
    });

    menuFile1.getItems().addAll(add1,add2,add3);
    menuFile2.getItems().addAll(add4,add6,add8);
    menuFile3.getItems().addAll(add10,add11,add12);
    menuFile4.getItems().addAll(add13);
    menuBar.getMenus().addAll(menuFile1,menuFile2,menuFile3,menuFile4);

    vbox.getChildren().addAll(menuBar);

    return vbox;
   }

In my project, I open new pages when clicking on buttons. Its code is:

btn2.setOnAction(new EventHandler<ActionEvent>() {
    @Override
    public void handle(ActionEvent e) {
    ((Stage)btn2.getScene().getWindow()).setScene(new Scene(new Login()));
     }
    });

Is it possible to implement this code in case of menu item ? How should I edit this code to perform an action when clicked on a menu item ?

TomJ
  • 1,803
  • 14
  • 37
  • 57
  • You've done it right (if strange). Try adding `System.out.println("hi from add1 in vbox")' in the ActionEvent. You're just setting the vbox visible, which it already is. – brian Feb 26 '14 at 15:22
  • @brian I want to open a new page in the same window when clicked on a menu item. I don't know how to do it. That's why I leaved a line above setVisible(). How can I do it ? – TomJ Feb 26 '14 at 15:25
  • A new page or a new scene? I think you mean a popup window, which is a new scene. You should edit the question so it says what you want to do. – brian Feb 26 '14 at 15:34

2 Answers2

5

I don't know exactly what you mean by a new page. There is a Pagination control, but I don't think you mean that. Here's how to add a TextArea but you have to design the UI and choose your own controls.

add1.setOnAction(new EventHandler<ActionEvent>() {
    public void handle(ActionEvent t) {
        vbox.getChildren().add(new TextArea());
    }
});

This is how to make a new window but you may want to ask a question about designing dialog boxes. Here's a SO answer https://stackoverflow.com/a/14168238/2855515

add1.setOnAction(new EventHandler<ActionEvent>() {
    public void handle(ActionEvent t) {
        Stage stage = new Stage();
        Scene scene = new Scene(new VBox());
        stage.setTitle("popup");
        stage.setScene(scene);
        stage.show();
    }
});
Community
  • 1
  • 1
brian
  • 10,619
  • 4
  • 21
  • 79
  • Hey... Just post the previous code. I need it. I will try new Scene. I think it will be better. – TomJ Feb 26 '14 at 15:52
1

I think this question has not been answered correctly and the question has been misinterpreted.

TomJ asked:

Is it possible to implement this code in case of menu item?

When he says "menu item", Does he mean Menu or MenuItem? He's clearing showing the correct code for how to do it for a MenuItem. I think he's asking about how to do that same thing for a Menu. I tried doing this for a Menu, and the code for invoking a handler on a Menu is slightly different than doing it for a MenuItem.

Here's a simple code example where the execute method is called when the Execute Menu is clicked:

Menu viewMenu = new Menu("View");
MenuItem viewJobs = new MenuItem("Jobs");
viewJobs.setOnAction(viewJobsAction);
MenuItem viewFileSelection = new MenuItem("File Selection");
viewFileSelection.setOnAction(e->{viewFileSelection());
viewMenu.getItems().addAll(viewJobs, viewFileSelection);

Menu execute = new Menu("Execute");
execute.onShownProperty().setValue(e->{execute());
// if the following line is not added, the onShownProperty event handler
// will never be called!
execute.getItems().addAll(new MenuItem());


Menu help = new Menu("Help");
MenuItem helpItem = new MenuItem("Help");
helpItem.setOnAction(e->{showHelp()}
MenuItem aboutItem = new MenuItem("About");
aboutItem.setOnAction(e->{showAbout()}
help.getItems().addAll(helpItem,aboutItem);
menubar.getMenus().addAll(viewMenu, execute, help);

It's necessary to have a bogus MenuItem added to the Execute Menu for this to work. For Menu, it's better to use the onShownProperty or onShowingProperty rather than using the setOnAction. Any of them will work, but the setOnAction will require a second click before the handler will be called.

The JavaDoc for onShowingProperty for Menu says:

Called just prior to the ContextMenu being shown, even if the menu has no items to show. Note however that this won't be called if the menu does not have a valid anchor node.

It sounds like the code should work without any MenuItems added, but it doesn't. It says however that the call won't be made if the menu doesn't have a valid anchor node. I'm not sure what an anchor node is, and I couldn't find any documentation about how to add an anchor node to a menu. Adding the bogus empty MenuItem clearly made the Execute Menu have a valid anchor node. If someone knows more about anchor nodes, please reply and explain it, but the code example I gave works acceptably.

jewelsea
  • 150,031
  • 14
  • 366
  • 406
Tom Rutchik
  • 1,183
  • 1
  • 12
  • 15
  • FYI, `anchor`s can be set when `ContextMenu`s are [shown](https://openjfx.io/javadoc/16/javafx.controls/javafx/scene/control/ContextMenu.html#show(javafx.scene.Node,double,double)) – jewelsea Jul 20 '21 at 20:31
  • I don't quite understand the relationship of Menu or MenuItem to ContextMenu. ContextMenu is neither a sub or super class of either Menu or MenuItem. Is there some kind of association between them. And the big problem is that the event doesn't happen if Menu already doesn't have an anchor! – Tom Rutchik Jul 21 '21 at 18:12
  • Okay, I looked at the Menu and MenuItem implementation and see that MenuItem has a parent that is a ContextMenu. Menu is a subclass of MenuItem, so it too has a parent that is a ContextMenu. That makes sense that both those classes are just wrap ContentMenu. Menu and MenuItem alleviate the user from the detail concerning the positioning placement for ContextMenu. Thanks jewelsea, that was the pointer I needed! – Tom Rutchik Jul 21 '21 at 19:02
  • Yeah, the menu stuff is pretty complex, especially if you start looking at the implementations. But a lot of the complexity is in the implementation rather than the public API, so quite a bit of it is hidden. Unlike lots of other JavaFX controls, menus aren't JavaFX nodes, (I think because sometimes they need to use popup windows to display and windows aren't nodes). Internally they have a bridge to nodes (and sometimes popup windows). – jewelsea Jul 21 '21 at 19:28
  • As you note, internally, the regular menus and menu items rely on context menu implementations to show menu popups when needed, though that detail is mainly hidden in the public API. I think all of that complexity, especially that the menus aren't nodes, leads to some anomalies and inconsistencies in the APIs. Things like events need to be bridged in the framework implementation from the underlying nodes, to be exposed in the public class API. – jewelsea Jul 21 '21 at 19:32
  • 1
    I played around with it, It's only top level menus in a menubar that you must have at least one MenuItem to have a ContextMenu. It's perfectly fine to have top level menus contain child menus and those menus don't need to have any MenuItems. That's because their parent is the ContextMenu. The MenuBar doesn't act as a ContextMenu, so that's why you have to do the trick of adding at least one dummy MenuItem. – Tom Rutchik Jul 21 '21 at 20:59