如何在javaFX中使上下文菜单在树视图上工作?
我想要一个树状视图项目的上下文菜单。 我希望事件处理程序的ActionEvent会提供有关单击哪个TreeView项的信息,但我发现getSource和getTarget返回一个菜单项。我如何才能找到已单击的TreeView项目?我可以在单独的选项卡中有多个TreeView如何在javaFX中使上下文菜单在树视图上工作?,java,javafx,treeview,contextmenu,Java,Javafx,Treeview,Contextmenu,我想要一个树状视图项目的上下文菜单。 我希望事件处理程序的ActionEvent会提供有关单击哪个TreeView项的信息,但我发现getSource和getTarget返回一个菜单项。我如何才能找到已单击的TreeView项目?我可以在单独的选项卡中有多个TreeView FileContextMenu cm = new FileContextMenu(new EventHandler<ActionEvent>() { public void handle(
FileContextMenu cm = new FileContextMenu(new EventHandler<ActionEvent>() {
public void handle(ActionEvent e) {
System.out.println("Open File");
//MenuItem mi = (MenuItem)e.getSource();
EventTarget et = e.getTarget();
//File editorFile = new File(mi.getId());
System.out.println(et);
//mainWindowController.openEditor(editorFile);
}
}, new EventHandler<ActionEvent>() {
public void handle(ActionEvent e) {
System.out.println("Create Project From Template");
}
});
我现在尝试使用cellfactory,但我不知道如何使用p参数来查找单元格值。我的代码是:
this.fileTreeView.setCellFactory(new Callback<TreeView<FileShort>,TreeCell<FileShort>>(){
@Override
public TreeCell<FileShort> call(TreeView<FileShort> p) {
TreeCell<FileShort> cell = new TreeCell<FileShort>();
cell.setContextMenu(cm);
return cell;
}
});
this.fileTreeView.setCellFactory(新回调(){
@凌驾
公共TreeCell呼叫(TreeView p){
TreeCell单元=新的TreeCell();
cell.setContextMenu(cm);
返回单元;
}
});
您必须为每个单元格创建不同的上下文菜单:
this.fileTreeView.setCellFactory(new Callback<TreeView<FileShort>,TreeCell<FileShort>>(){
@Override
public TreeCell<FileShort> call(TreeView<FileShort> p) {
TreeCell<FileShort> cell = new TreeCell<FileShort>() {
@Override
protected void updateItem(FileShort file, boolean empty) {
super.updateItem(file, empty);
if (empty) {
setText(null);
} else {
// maybe use a more appropriate string for display here
// e.g. if you were using a regular java.io.File you would
// likely want file.getName()
setText(file.toString());
}
}
};
ContextMenu cm = createContextMenu(cell);
cell.setContextMenu(cm);
return cell;
}
});
private ContextMenu createContextMenu(TreeCell<FileShort> cell) {
ContextMenu cm = new ContextMenu();
MenuItem openItem = new MenuItem("Open File");
openItem.setOnAction(event -> {
FileShort file = cell.getItem();
if (file != null) {
// open the file...
}
});
cm.getItems().add(openItem);
// other menu items...
return cm ;
}
this.fileTreeView.setCellFactory(新回调(){
@凌驾
公共TreeCell呼叫(TreeView p){
TreeCell单元=新的TreeCell(){
@凌驾
受保护的void updateItem(FileShort文件,布尔值为空){
super.updateItem(文件,空);
if(空){
setText(空);
}否则{
//可能使用更合适的字符串在此处显示
//例如,如果您使用的是常规的java.io.File,您会
//可能需要文件.getName()
setText(file.toString());
}
}
};
ContextMenu cm=createContextMenu(单元格);
cell.setContextMenu(cm);
返回单元;
}
});
私有上下文菜单createContextMenu(TreeCell单元格){
ContextMenu cm=新建ContextMenu();
MenuItem openItem=新MenuItem(“打开文件”);
openItem.setOnAction(事件->{
FileShort file=cell.getItem();
如果(文件!=null){
//打开文件。。。
}
});
cm.getItems().add(openItem);
//其他菜单项。。。
返回cm;
}
您是在向树单元注册上下文菜单吗?您的意思是让createNode为每个节点创建一个包含文件名的派生类的菜单项?也就是说,每个项目都有单独的上下文菜单?嗯,没有。我真的不理解那个评论。您发布的代码只是展示了如何构造上下文菜单。您没有显示您在哪里使用它,即您在哪里做something.setContextMenu(cm)
或something.setOnContextMenuRequested(事件->cm.show(…)代码>或类似的东西。如果something
是相关的树单元,则可以从该单元获取树项并执行所需操作。(但是每个单元格(不是项目)都有单独的上下文菜单,是的。)我正在将上下文菜单附加到树视图。。我不知道如何将单独的元素附加到树元素,因为treeview元素是动态生成的。是的,您需要将一个上下文菜单附加到每个TreeCell
s,如果您在树上设置一个单元格工厂,您可以这样做。谢谢,这看起来可以工作。但是我有一个问题:树中的所有项目都显示为空白,即我只看到没有文件名和目录名的箭头。@Adder听起来好像您没有覆盖updateItem(…)
方法。(为了简洁起见,我假设您只是在问题的代码中省略了它。)在答案中添加了一个示例实现代码>缺少cm.getItems().addAll(openItem)代码>
public void setContextMenu(ContextMenu cm)
{
fileTreeView.setContextMenu(cm);
}
this.fileTreeView.setCellFactory(new Callback<TreeView<FileShort>,TreeCell<FileShort>>(){
@Override
public TreeCell<FileShort> call(TreeView<FileShort> p) {
TreeCell<FileShort> cell = new TreeCell<FileShort>();
cell.setContextMenu(cm);
return cell;
}
});
this.fileTreeView.setCellFactory(new Callback<TreeView<FileShort>,TreeCell<FileShort>>(){
@Override
public TreeCell<FileShort> call(TreeView<FileShort> p) {
TreeCell<FileShort> cell = new TreeCell<FileShort>() {
@Override
protected void updateItem(FileShort file, boolean empty) {
super.updateItem(file, empty);
if (empty) {
setText(null);
} else {
// maybe use a more appropriate string for display here
// e.g. if you were using a regular java.io.File you would
// likely want file.getName()
setText(file.toString());
}
}
};
ContextMenu cm = createContextMenu(cell);
cell.setContextMenu(cm);
return cell;
}
});
private ContextMenu createContextMenu(TreeCell<FileShort> cell) {
ContextMenu cm = new ContextMenu();
MenuItem openItem = new MenuItem("Open File");
openItem.setOnAction(event -> {
FileShort file = cell.getItem();
if (file != null) {
// open the file...
}
});
cm.getItems().add(openItem);
// other menu items...
return cm ;
}