TableView JavaFX中的上下文菜单可见性
我正在用JavaFX创建TableView JavaFX中的上下文菜单可见性,java,contextmenu,tableview,javafx-2,javafx,Java,Contextmenu,Tableview,Javafx 2,Javafx,我正在用JavaFX创建TableView。在其中,我想在tableView中用鼠标右键单击来显示上下文菜单。因此,我在表中添加了一个EventHandler,如下所示: TableView tableView=new TableView(); EventHandler event = new EventHandler<MouseEvent>() { @Override public void handle(MouseEvent me
TableView
。在其中,我想在tableView中用鼠标右键单击来显示上下文菜单
。因此,我在表中添加了一个EventHandler,如下所示:
TableView tableView=new TableView();
EventHandler event = new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent me) {
if (me.getButton() == MouseButton.SECONDARY) {
tableView.getContextMenu().show(tableView, me.getSceneX(), me.getSceneY());
}
}
};
tableView.addEventHandler(MouseEvent.MOUSE_CLICKED, event);
TableView TableView=newtableview();
EventHandler事件=新的EventHandler(){
@凌驾
公共无效句柄(MouseEvent me){
if(me.getButton()==MouseButton.SECONDARY){
tableView.getContextMenu().show(tableView,me.getSceneX(),me.getSceneY());
}
}
};
tableView.addEventHandler(MouseEvent.MOUSE_单击,事件);
但我的问题是,上下文菜单
在我右键单击表的任何部分时都可见
我想这样做,上下文菜单
应该只有在我点击了TableView
中的任何行时才可见
i、 e.如何在特定点获取TableView中的行号,以便我的
上下文菜单
仅在单击TableView
的任何行时才可见,而不是在整个表格中使用CellFactory
将上下文菜单添加到特定单元格中
例如,使用以下表格:
TableColumn firstNameCol=newtableColumn();
firstNameCol.setText(“第一”);
firstNameCol.setCellValueFactory(新属性ValueFactory(“firstName”));
firstNameCol.setCellFactory(新回调(){
@凌驾
公共TableCell调用(最终TableColumn参数){
最终TableCell单元格=新TableCell(){
@凌驾
public void updateItem(对象项,布尔值为空){
super.updateItem(项,空);
if(空){
setText(空);
}否则{
if(isEditing()){
setText(空);
}否则{
setText(getItem().toString());
设置图形(空);
}
}
}
};
//这样,我将只有特定列的上下文菜单
cell.setContextMenu(ContextMenuBuilder.create().items(MenuItemBuilder.create().text(“菜单”).build()).build());
返回单元;
}
});
可能是较老的问题。有一个解决方案,比如获取表的鼠标事件的目标,检查例如类TableCellSkin,并将上下文菜单显示为
table.addEventHandler(MouseEvent.MOUSE_CLICKED,
new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent e) {
if (e.getButton() == MouseButton.SECONDARY
&& !isRowEmpty) {
EventTarget target = e.getTarget();
if (target instanceof TableCellSkin
|| ((Node) target).getParent() instanceof TableCellSkin) {
// do your stuff. Context menu will be displayed by default
} else {
// hide the context menu when click event is outside table row
table.getContextMenu().hide();
}
}
}
});
table.addEventHandler(MouseEvent.MOUSE_单击,
新的EventHandler(){
@凌驾
公共无效句柄(MouseEvent e){
如果(例如getButton()==MouseButton.SECONDARY
&&!IsRowepty){
EventTarget=e.getTarget();
if(TableCellSkin的目标实例)
||((节点)target.getParent()TableCellSkin实例){
//完成你的任务。默认情况下将显示上下文菜单
}否则{
//当单击事件位于表行之外时隐藏关联菜单
table.getContextMenu().hide();
}
}
}
});
我找到的最佳解决方案是检查y坐标是否超出列标题的边界,然后显式显示菜单
ContextMenu visibleMenu = null;
tableView.setOnMouseClicked((MouseEvent e) -> {
if (visibleMenu !=null) {
visibleMenu.hide();
visibleMenu = null;
}
if (e.getButton()==MouseButton.SECONDARY) {
double columnHeaderHeight = tableView.lookup(".column-header-background").getBoundsInLocal().getHeight();
if (e.getY()>columnHeaderHeight) {
visibleMenu = getContextMenu(); // build on the fly or use a prebuild menu
visibleMenu.show(tableView, e.getScreenX(), e.getScreenY());
} else {
// you could show a header specific context menu here
}
}
});
附加的好处是,您可以使用上下文敏感项动态构建上下文菜单(例如,仅当选择了特定类型的单元格时才会显示),或者只需像setContextMenu那样重用预构建上下文菜单,具体取决于您 配音。我看到tableView.getContextMenu()所以在其他地方您正在设置contextmenu。如果您设置它,即使您没有显式添加事件处理程序,它也将始终显示。我的意思是如果你想控制contextmenu的显示,不要通过tableView.setContextMenu(),IMHO设置它。
ContextMenu visibleMenu = null;
tableView.setOnMouseClicked((MouseEvent e) -> {
if (visibleMenu !=null) {
visibleMenu.hide();
visibleMenu = null;
}
if (e.getButton()==MouseButton.SECONDARY) {
double columnHeaderHeight = tableView.lookup(".column-header-background").getBoundsInLocal().getHeight();
if (e.getY()>columnHeaderHeight) {
visibleMenu = getContextMenu(); // build on the fly or use a prebuild menu
visibleMenu.show(tableView, e.getScreenX(), e.getScreenY());
} else {
// you could show a header specific context menu here
}
}
});