我有一个使用TreeView用JavaFX编写的应用程序,ContextMenu依赖于所选的TreeItem,我的TreeCell实现使用setOnContextMenuRequested()来显示ContextMenu,每当我右键单击一个节点时,这都可以正常工作。我现在想要在使用键盘导航树并使用Windows上下文菜单的标准快捷键(SHIFT + F10)时实现相同的目标,我几乎设法做到了,它显示了ContextMenu但是当我尝试使用导航时用于选择菜单中的项目的键,它会显示主应用程序窗口的上下文菜单并在其中导航,同时我想显示靠近所选单元格的上下文菜单,我该怎么做?下面是一个展示我的问题的小应用程序
import javafx.application.Application;
import javafx.geometry.Bounds;
import javafx.geometry.Point2D;
import javafx.scene.Scene;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.MenuItem;
import javafx.scene.control.TreeCell;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.input.ContextMenuEvent;
import javafx.scene.input.PickResult;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class Main extends Application
{
@Override
public void start(Stage primaryStage)
{
try
{
BorderPane root = new BorderPane();
TreeView<String> treeView = new TreeView<>();
TreeItem<String> treeRoot = new TreeItem<>("Root");
for (int i = 1; i <= 5; i++)
{
TreeItem<String> child = new TreeItem<>("Item " + i);
child.getChildren().addAll(new TreeItem<>("Item " + i + "A"), new TreeItem<>("Item " + i + "B"));
treeRoot.getChildren().add(child);
}
treeView.setRoot(treeRoot);
root.setCenter(treeView);
ContextMenu contextMenu = new ContextMenu();
for (int i = 1; i <= 3; i++)
{
String text = "Choice " + i;
MenuItem menuItem = new MenuItem(text);
menuItem.setOnAction(event -> System.out.println(text));
contextMenu.getItems().add(menuItem);
}
treeView.addEventHandler(ContextMenuEvent.CONTEXT_MENU_REQUESTED, event ->
{
PickResult pickResult = event.getPickResult();
if (pickResult != null && pickResult.getIntersectedNode() != null)
{
TreeCell<String> cell = (TreeCell<String>) pickResult.getIntersectedNode();
Bounds bounds = cell.getBoundsInParent();
double x = bounds.getMinX() + (bounds.getWidth() / 2);
double y = bounds.getMinY() + (bounds.getHeight() / 2);
Point2D loc = cell.getParent().localToScreen(x, y);
contextMenu.show(cell, loc.getX(), loc.getY());
}
});
Scene scene = new Scene(root, 400, 400);
primaryStage.setScene(scene);
primaryStage.show();
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
public static void main(String[] args)
{
launch(args);
}
}