本文是小编为大家收集整理的关于Javafx确定鼠标右键单击时相对于网格窗格的位置的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。
问题描述
我有一个40x40 Gridpane,显示地图.目前,我有以下方法收听右键单击:
//detect right click + display menu, select if you want to place item 1 or item 2 final ContextMenu cm = new ContextMenu(); cm.addEventFilter(MouseEvent.MOUSE_RELEASED, new EventHandler<MouseEvent>() { @Override public void handle(MouseEvent event) { if (event.getButton() == MouseButton.SECONDARY) event.consume(); } }); cm.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { System.out.println("Following item selected: "+ ((MenuItem)event.getTarget()).getText()); } }); //two placeable items MenuItem item1Place = new MenuItem("Item 1"); MenuItem item2Place = new MenuItem("Item 2"); cm.getItems().addAll(item1Place, item2Place); primaryStage.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() { @Override public void handle(MouseEvent e) { if (e.getButton() == MouseButton.SECONDARY) { cm.show(primaryStage, e.getScreenX(), e.getScreenY()); } } });
我想实现的是以下内容:
如果在右键单击后选择菜单项,我想保存 右键单击变量
的位置,例如[32,12]如果 右键单击是横跨格里彭的32个街区,向上12个街区.
关于如何执行此操作的任何建议?
预先感谢
// first edit code entered below. I realise the indentation is very off however fixing it seemed to turn it back to plain text placeItem1.setOnAction(evt -> System.out.println("Item 1 placed ["+col+", "+row+"]")); placeItem2.setOnAction(evt -> System.out.println(Item 2 placed["+col+", "+row+"]")); menu.show(cell, e.getScreenX(), e.getScreenY()); }); root.add(cell, x, y);
推荐答案
在网格中的每个单元格中添加一个侦听器,而不是将一个鼠标侦听器添加到舞台上.用于上下文菜单处理的适当听众是contextMenuRequested处理程序:
import javafx.application.Application; import javafx.scene.Scene; import javafx.scene.control.ContextMenu; import javafx.scene.control.MenuItem; import javafx.scene.input.MouseButton; import javafx.scene.layout.GridPane; import javafx.scene.layout.Pane; import javafx.stage.Stage; public class ClicksInGridPane extends Application { @Override public void start(Stage primaryStage) { GridPane root = new GridPane(); final int NUM_ROWS = 40 ; final int NUM_COLS = 40 ; ContextMenu menu = new ContextMenu(); MenuItem menuItem1 = new MenuItem("Item 1"); MenuItem menuItem2 = new MenuItem("Item 2"); menu.getItems().addAll(menuItem1, menuItem2); for (int x = 0 ; x < NUM_COLS ; x++) { for (int y = 0 ; y < NUM_ROWS ; y++) { Pane cell = new Pane(); cell.setPrefSize(20, 20); // add style just to draw grid: cell.setStyle("-fx-background-color: black, white; -fx-background-insets: 0, 0 0 1 1;"); // context menu listener: final int col = x ; final int row = y ; cell.setOnContextMenuRequested(e -> { menuItem1.setOnAction(evt -> System.out.println("Item 1 selected in cell ["+col+", "+row+"]")); menuItem2.setOnAction(evt -> System.out.println("Item 2 selected in cell ["+col+", "+row+"]")); menu.show(cell, e.getScreenX(), e.getScreenY()); }); root.add(cell, x, y); } } primaryStage.setScene(new Scene(root)); primaryStage.show(); } public static void main(String[] args) { launch(args); } }
问题描述
I have a 40x40 gridpane, displaying a map. Currently, i have the following methods listening for a right click:
//detect right click + display menu, select if you want to place item 1 or item 2 final ContextMenu cm = new ContextMenu(); cm.addEventFilter(MouseEvent.MOUSE_RELEASED, new EventHandler<MouseEvent>() { @Override public void handle(MouseEvent event) { if (event.getButton() == MouseButton.SECONDARY) event.consume(); } }); cm.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { System.out.println("Following item selected: "+ ((MenuItem)event.getTarget()).getText()); } }); //two placeable items MenuItem item1Place = new MenuItem("Item 1"); MenuItem item2Place = new MenuItem("Item 2"); cm.getItems().addAll(item1Place, item2Place); primaryStage.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() { @Override public void handle(MouseEvent e) { if (e.getButton() == MouseButton.SECONDARY) { cm.show(primaryStage, e.getScreenX(), e.getScreenY()); } } });
What I'd like to implement is the following:
If a menu item is selected after a right click, i'd like to save the position of the right click in a variable
e.g. [32,12] if right click was 32 blocks of the gridpane across, and 12 blocks up.
Any suggestions on how to go about doing this?
Thanks in advance
// first edit code entered below. I realise the indentation is very off however fixing it seemed to turn it back to plain text placeItem1.setOnAction(evt -> System.out.println("Item 1 placed ["+col+", "+row+"]")); placeItem2.setOnAction(evt -> System.out.println(Item 2 placed["+col+", "+row+"]")); menu.show(cell, e.getScreenX(), e.getScreenY()); }); root.add(cell, x, y);
推荐答案
Add a listener to each cell in the grid, instead of adding one mouse listener to the stage. The proper listener to use for context menu handling is a contextMenuRequested handler:
import javafx.application.Application; import javafx.scene.Scene; import javafx.scene.control.ContextMenu; import javafx.scene.control.MenuItem; import javafx.scene.input.MouseButton; import javafx.scene.layout.GridPane; import javafx.scene.layout.Pane; import javafx.stage.Stage; public class ClicksInGridPane extends Application { @Override public void start(Stage primaryStage) { GridPane root = new GridPane(); final int NUM_ROWS = 40 ; final int NUM_COLS = 40 ; ContextMenu menu = new ContextMenu(); MenuItem menuItem1 = new MenuItem("Item 1"); MenuItem menuItem2 = new MenuItem("Item 2"); menu.getItems().addAll(menuItem1, menuItem2); for (int x = 0 ; x < NUM_COLS ; x++) { for (int y = 0 ; y < NUM_ROWS ; y++) { Pane cell = new Pane(); cell.setPrefSize(20, 20); // add style just to draw grid: cell.setStyle("-fx-background-color: black, white; -fx-background-insets: 0, 0 0 1 1;"); // context menu listener: final int col = x ; final int row = y ; cell.setOnContextMenuRequested(e -> { menuItem1.setOnAction(evt -> System.out.println("Item 1 selected in cell ["+col+", "+row+"]")); menuItem2.setOnAction(evt -> System.out.println("Item 2 selected in cell ["+col+", "+row+"]")); menu.show(cell, e.getScreenX(), e.getScreenY()); }); root.add(cell, x, y); } } primaryStage.setScene(new Scene(root)); primaryStage.show(); } public static void main(String[] args) { launch(args); } }