Центрировать JavaFX ContextMenu в середине экрана? - PullRequest
0 голосов
/ 15 декабря 2018

Я пытаюсь создать ContextMenu, которое появляется в середине экрана при каждом нажатии клавиши выхода с клавиатуры.Я хочу использовать его для загрузки, сохранения и выхода в моей игре.Он будет вызываться из классов за пределами Main.

Проблема в том, что я не уверен, как узнать высоту и ширину ContextMenu в пикселях.Итак, я в растерянности относительно того, как центрировать его в окне.Я пытаюсь использовать Rectangle2D, чтобы найти центр, но он все еще немного выключен.

Как я могу отобразить свое ContextMenu в середине экрана?

Отображает мое ContextMenu:

/**
 * Returns the Pane object so it can be made into a Scene object.
 * Each Scene has it's own class
 * Each class uses this method to create a Pane object for it.
 * @return Pane 
 */
public Pane getPane() {
   // create a GridPane object
   grid = new GridPane();

   // create ContextMenu and set anchor points.
   ContextMenu cm = Main.Org.createPopUpMenu();
   cm.setOnShowing(event -> {
      event.consume();
      cm.setAnchorX(cm.getAnchorX() - cm.getWidth() / 2.0);
      cm.setAnchorY(cm.getAnchorY() - cm.getHeight() / 2.0);
   });
   Rectangle2D bounds = Screen.getPrimary().getVisualBounds();

   // show ContextMenu if escape key is pressed.
   grid.setOnKeyReleased( event -> {
      if(event.getCode() == KeyCode.ESCAPE) {
         cm.show(grid, bounds.getWidth() / 2.0, bounds.getHeight() / 2.0);
      }
   });

   return grid;
}

Класс организатора createPopUpMenu() Метод:

/**
 * Creates a pop-up menu for saving, loading, and exiting the game
 * @return ContextMenu 
 */
public ContextMenu createPopUpMenu() {
   ContextMenu contextMenu = new ContextMenu();

   MenuItem menuItem = new MenuItem();

   //create ImageViews
   image = new ImageView("/images/PopUpMenu_Exit.png");

   // add ImageViews to MenuItems
   menuItem.setGraphic(image);

   contextMenu.getItems().add(menuItem);

   menuItem.setOnAction( a -> {
      // quit the game
      Platform.exit();
      System.exit(0);
   });

   return contextMenu;
}

1 Ответ

0 голосов
/ 15 декабря 2018

Вот небольшой пример (некоторые пояснения есть в комментариях к коду):

import javafx.application.Application;
import javafx.geometry.Rectangle2D;
import javafx.scene.Scene;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.Label;
import javafx.scene.control.MenuItem;
import javafx.scene.control.SeparatorMenuItem;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.StackPane;
import javafx.stage.Screen;
import javafx.stage.Stage;
import javafx.stage.Window;

public class Main extends Application {

  private ContextMenu menu;

  @Override
  public void start(Stage primaryStage) {
    primaryStage.addEventHandler(KeyEvent.KEY_PRESSED, event -> {
      if (event.getCode() == KeyCode.ESCAPE) {
        event.consume();
        showContextMenu(primaryStage);
      }
    });

    Label label = new Label("Press ESC to show ContextMenu.");
    primaryStage.setScene(new Scene(new StackPane(label), 500, 300));
    primaryStage.show();
  }

  private void showContextMenu(Window owner) {
    if (menu == null) {
      menu = new ContextMenu(
          new MenuItem("Copy"),
          new MenuItem("Cut"),
          new MenuItem("Paste"),
          new SeparatorMenuItem(),
          new MenuItem("Delete")
      );

      /*
       * Adjusts the ContextMenu's position once shown so that the center
       * of the ContextMenu is at the center of the screen (rather than
       * the top left corner). Do this here because the ContextMenu needs
       * to have been displayed in order to know the dimensions.
       *
       * Since the top left corner is already centered on the screen we don't need
       * to know the dimensions of the screen. We only need to move the ContextMenu
       * relative to itself.
       */
      menu.setOnShown(event -> {
        event.consume();
        menu.setAnchorX(menu.getAnchorX() - menu.getWidth() / 2.0);
        menu.setAnchorY(menu.getAnchorY() - menu.getHeight() / 2.0);
      });
    }

    /*
     * Displays the ContextMenu on the primary screen. The top left corner
     * of the ContextMenu will be at the center of the screen. Will need
     * to adjust the ContextMenu's position after it's shown.
     */
    Rectangle2D bounds = Screen.getPrimary().getVisualBounds();
    menu.show(owner, bounds.getWidth() / 2.0, bounds.getHeight() / 2.0);
  }

}
...