我已经尝试了一切。我认为他们犯了很大的错误,没有在任何事情上提供索引单元格。
我可以拿到我的菜单,但不是在正确的地方。右键单击即可。
在我的TreeView中,我可以使用get KeyReleased,但我不知道将菜单放在哪里。
setOnKeyReleased((KeyEvent t) -> {
switch (t.getCode()) {
case CONTEXT_MENU:
getSelectionModel().getSelectedItem().setGraphic(new Label("hi"));
//showMenu just calls show on my ContextMenu of my subclass TreeNode
((TreeNode)getSelectionModel().getSelectedItem()).showMenu(
getSelectionModel().getSelectedItem().getGraphic().getLocalToSceneTransform());
break;
}
});
没有布局方法会给我TreeCell的坐标
答案 0 :(得分:2)
根本不可能为给定项目提供对单元格的API访问。并非每个项目都有与之关联的单元格。最重要的是,由单元格表示的项目可能随时更改,因此即使您可以提供对单元格的访问,API也可能会非常混乱。
这样的基本技巧是创建一个单元工厂,并向单元注册适当的监听器。你的情况有点棘手,但可能。以下工作来获取表示所选项的单元格(您可能需要稍微修改代码以处理单元格从屏幕滚动的情况)。
(请注意,我随意使用了Z键,因为我的笔记本电脑上没有ContextMenu键。)
import javafx.application.Application;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ChangeListener;
import javafx.geometry.Bounds;
import javafx.geometry.Point2D;
import javafx.scene.Node;
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.KeyCode;
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);
ObjectProperty<TreeCell<String>> selectedCell = new SimpleObjectProperty<>();
treeView.setCellFactory(tree -> {
TreeCell<String> cell = new TreeCell<>();
cell.textProperty().bind(cell.itemProperty());
ChangeListener<TreeItem<String>> listener = (obs, oldItem, newItem) -> {
TreeItem<String> selectedItem = treeView.getSelectionModel().getSelectedItem();
if (selectedItem == null) {
selectedCell.set(null);
} else {
if (selectedItem == cell.getTreeItem()) {
selectedCell.set(cell);
}
}
};
cell.treeItemProperty().addListener(listener);
treeView.getSelectionModel().selectedItemProperty().addListener(listener);
return cell ;
});
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.setOnKeyReleased(event -> {
if (event.getCode() == KeyCode.Z) {
if (selectedCell.get() != null) {
Node anchor = selectedCell.get();
// figure center of cell in screen coords:
Bounds anchorBounds = anchor.getBoundsInParent();
double x = anchorBounds.getMinX() + anchorBounds.getWidth() / 2 ;
double y = anchorBounds.getMinY() + anchorBounds.getHeight() / 2 ;
Point2D screenLoc = anchor.getParent().localToScreen(x, y);
contextMenu.show(selectedCell.get(), screenLoc.getX(), screenLoc.getY());
}
}
});
Scene scene = new Scene(root,400,400);
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}