Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaFX 2.0 Activating a Menu like a MenuItem

I'm making a MenuBar, and I wan't the functionality to press a Menu like: "File" and then execute a action. Such like opening an other fxml, or an example where some output is written.

I want the functionality of a MenuItem (lie "About") in a Menu like "File".

package model;

import static java.lang.System.out;

import javafx.application.Application;
import javafx.beans.property.ReadOnlyDoubleProperty;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.geometry.Side;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyCodeCombination;
import javafx.scene.input.KeyCombination;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

/**
 * Example of creating menus in JavaFX.
 * 
 * @author Dustin
 */
public class JavaFxMenus extends Application
{
   /**
    * Build menu bar with included menus for this demonstration.
    * 
    * @param menuWidthProperty Width to be bound to menu bar width.
    * @return Menu Bar with menus included.
    */
   private MenuBar buildMenuBarWithMenus(final ReadOnlyDoubleProperty menuWidthProperty)
   {
      final MenuBar menuBar = new MenuBar();

      // Prepare left-most 'File' drop-down menu
      final Menu fileMenu = new Menu("File");

      menuBar.getMenus().add(fileMenu);
      //menuBar.getOnMouseClicked().handle(this);


      // Prepare 'Examples' drop-down menu
      final Menu examplesMenu = new Menu("JavaFX 2.0 Examples");
      examplesMenu.getItems().add(new MenuItem("Text Example"));
      examplesMenu.getItems().add(new MenuItem("Objects Example"));
      examplesMenu.getItems().add(new MenuItem("Animation Example"));
      menuBar.getMenus().add(examplesMenu);

      // Prepare 'Help' drop-down menu
      final Menu helpMenu = new Menu("Help");
      helpMenu.setOnAction(null);

      final MenuItem searchMenuItem = new MenuItem("Search");
      searchMenuItem.setDisable(true);
      helpMenu.getItems().add(searchMenuItem);
      final MenuItem onlineManualMenuItem = new MenuItem("Online Manual");
      onlineManualMenuItem.setVisible(false);
      helpMenu.getItems().add(onlineManualMenuItem);
      helpMenu.getItems().add(new SeparatorMenuItem());
      final MenuItem aboutMenuItem =
         MenuItemBuilder.create()
                        .text("About")
                        .onAction(
                            new EventHandler<ActionEvent>()
                            {
                               @Override public void handle(ActionEvent e)
                               {
                                  out.println("You clicked on About!");
                               }
                            })
                        .accelerator(
                            new KeyCodeCombination(
                               KeyCode.A, KeyCombination.CONTROL_DOWN))
                        .build();             
      helpMenu.getItems().add(aboutMenuItem);
      menuBar.getMenus().add(helpMenu);

      // bind width of menu bar to width of associated stage
      menuBar.prefWidthProperty().bind(menuWidthProperty);

      return menuBar;
   }

   /**
    * Start of JavaFX application demonstrating menu support.
    * 
    * @param stage Primary stage.
    */
   @Override
   public void start(final Stage stage)
   {
      stage.setTitle("Creating Menus with JavaFX 2.0");
      final Group rootGroup = new Group();
      final Scene scene = new Scene(rootGroup, 800, 400, Color.WHEAT);



      final MenuBar menuBar = buildMenuBarWithMenus(stage.widthProperty());
      rootGroup.getChildren().add(menuBar);
      stage.setScene(scene);
      stage.show();
   }

   /**
    * Main executable function for running examples.
    * 
    * @param arguments Command-line arguments: none expected.
    */
   public static void main(final String[] arguments)
   {
      Application.launch(arguments);
   }
}
like image 779
haakonlu Avatar asked Apr 25 '12 12:04

haakonlu


People also ask

Which root control contains all the menus and Menultems?

control. Menu class provides all the methods to deal with menus. This class needs to be instantiated to create a Menu. The following sample of code shows the implementation of JavaFX menu.

What is context menu in JavaFX?

Class ContextMenu. A popup control containing an ObservableList of menu items. The items ObservableList allows for any MenuItem type to be inserted, including its subclasses Menu , MenuItem , RadioMenuItem , CheckMenuItem and CustomMenuItem .

What is primaryStage in JavaFX?

The JavaFX Stage class is the top level JavaFX container. The primary Stage is constructed by the platform. Additional Stage objects may be constructed by the application. Stage objects must be constructed and modified on the JavaFX Application Thread.


2 Answers

AFAIK, A Menu, if has not any added submenu or Menuitems, does not fire events neither on click, on shown nor on hide. However the workaround is to set its graphic where this graphic node will handle mouse clicks for example,

Label menuLabel = new Label("File");
menuLabel.setOnMouseClicked(new EventHandler<MouseEvent>() {
    @Override
    public void handle(MouseEvent event) {

        Stage myDialog = new Stage();
        myDialog.initModality(Modality.WINDOW_MODAL);

        Scene myDialogScene = new Scene(VBoxBuilder.create()
            .children(new Text("Hello! it's My Dialog."))
            .alignment(Pos.CENTER)
            .padding(new Insets(10))
            .build());

        myDialog.setScene(myDialogScene);
        myDialog.show();
    }
});
Menu fileMenuButton = new Menu();
fileMenuButton.setGraphic(menuLabel);
menuBar.getMenus().add(fileMenuButton);

A drawback of this approach is that the label do not cover all spaces of the menu resulting clicking on edges of menu is not triggering the mouse event. See this by uncommenting menuLabel.setStyle line above. But this can be resolved by playing with CSS styles I think.
Code is partially taken from Create Dialog using Stage. You can also load an FXML file into the myDialog stage using the FXMLLoader. There are lots of examples about it on the net.

like image 166
Uluk Biy Avatar answered Oct 13 '22 15:10

Uluk Biy


Recently i had the same problem, this is what i did

@FXML private Menu myMenu;

@Override
public void initialize(URL url, ResourceBundle rb) {

    myMenu.setGraphic(
        ButtonBuilder.create()
            .text("btnText")
            .onAction(new EventHandler<ActionEvent>(){
                @Override public void handle(ActionEvent t) {
                    //TODO
             } })
            .build()
    );
}
like image 27
Hugo Avatar answered Oct 13 '22 16:10

Hugo