java - 将 JavaFX ContextMenu 置于屏幕中央?

标签 java javafx javafx-8 contextmenu gridpane

我正在尝试创建一个上下文菜单,每当按下键盘的转义按钮时,该菜单就会出现在屏幕中间。我想用它来处理游戏中的加载、保存和退出。它将从 Main 之外的类中调用。

问题是我不确定如何找出 ContextMenu 的高度和宽度(以像素为单位)。所以,我不知道如何将它放在窗口的中心。我正在尝试使用 Rectangle2D 来找到中心,但它仍然略有偏差。

如何在屏幕中间显示我的上下文菜单?

显示我的上下文菜单:

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

最佳答案

这是一个小例子(一些解释在代码注释中):

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

}

关于java - 将 JavaFX ContextMenu 置于屏幕中央?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53788456/

相关文章:

java - 为什么要在抽象方法前加abstract关键字

java - Hibernate 4 中的编程模式更新

java - 我如何在这里使用多态性来改进我的代码?

canvas - 如何以不锯齿的方式绘制由多条线段组成的曲线

java - 如何增加JavaFX中ScrollPane的滚动效果?

JavaFx:检查鼠标是否位于节点的子节点上

java - 将 POJO 转换为 JavaFX 属性

javafx - 如何在 JavaFX 中渲染 3D 文本?

java - @Autowired 对象中的 Spring 空指针异常

JavaFX开启新场景