JavaFX 2.0 Активация меню, как MenuItem

Я создаю MenuBar, и я не хочу использовать функцию Menu как: "Файл", а затем выполнить действие. Такие, как открытие другого fxml, или пример, где записывается какой-то вывод.

Я хочу функциональность MenuItem (ложь "О" ) в Menu как "Файл".

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

Ответ 1

AFAIK, A Menu, если не добавлено подменю или Menuitem s, не запускает события ни по щелчку, ни по показанному, ни по экрану. Однако обходным путем является установка его графического изображения, где этот графический node будет обрабатывать щелчки мыши, например,

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 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);

Недостатком этого подхода является то, что метка не охватывает все пробелы меню, в результате щелчка по краям меню не вызывает событие мыши. См. Это, раскомментируя строку menuLabel.setStyle выше. Но это можно решить, играя с стилями CSS, которые я думаю.
Код частично взят из Создать диалог с использованием этапа. Вы также можете загрузить файл FXML на этапе myDialog с помощью FXMLLoader. В сети есть много примеров.

Ответ 2

Недавно у меня была та же проблема, вот что я сделал

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

Ответ 3

Недавно я столкнулся с той же проблемой, это был мой выход:

У меня было меню меню в меню, которое должно было вести себя так, как если бы щелкнул элемент menuItem (в вашем случае File). Итак, что вы можете сделать, это иметь функцию menuItem Dummy_menuItem

final Menu fileMenu = new Menu("File");
fileMenu.getItems().add(new MenuItem("Dummy_menuItem"));
menuBar.getMenus().add(fileMenu);

а затем щелкнув меню File, запустите пункт меню Dummy_menuItem или любую функцию, которую вы хотите использовать. Чтобы определить, какое меню должно иметь это свойство, я использовал numberOfMenuItems, чтобы получить количество элементов меню в меню в меню

if (numberOfMenuItems == 1) {
    menu.showingProperty().addListener(
        (observableValue, oldValue, newValue) -> {
            if (newValue) {
                // the first menuItem is triggered
                menu.getItems().get(0).fire();
            }
        }
    );
}

результат заключается в том, что Dummy_menuItem запускается без контекста, отображающего элемент меню при щелчке меню File или в любом меню с одним элементом меню. Таким образом, кажется, что вы нажали на меню File и были перенаправлены на другую страницу или что-то еще.

Надеюсь, это поможет!

Ответ 4

В сочетании с ответом от нашего друга @Dota2 я создал вспомогательный класс для запуска события Menu onAction(Menu menu), даже если он не имеет никаких MenuItem внутри. Вот статический вспомогательный метод:

public static void onAction(Menu menu)
{
    final MenuItem menuItem = new MenuItem();

    menu.getItems().add(menuItem);
    menu.addEventHandler(Menu.ON_SHOWN, event -> menu.hide());
    menu.addEventHandler(Menu.ON_SHOWING, event -> menu.fire());
}

Затем вы вызываете:

YourHelperClass.onAction(myMenu);

И готов! Надеюсь, это поможет.

Ответ 5

Я думаю, вы не можете разрешить какие-либо действия на ярлыке основного меню.

Однако вы можете создать стек стека и заполнить его текстом и панелью меню.