Javafx - 确定鼠标右键单击时光标相对于网格窗格的位置
Javafx - Determine position of cursor on right click relative to gridpane
我有一个显示地图的 40x40 网格窗格。目前,我有以下监听右键单击的方法:
//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());
}
}
});
我想实现的是:
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.
关于如何着手做这件事有什么建议吗?
提前致谢
// 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);
}
}
我有一个显示地图的 40x40 网格窗格。目前,我有以下监听右键单击的方法:
//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());
}
}
});
我想实现的是:
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.
关于如何着手做这件事有什么建议吗?
提前致谢
// 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);
}
}