我想为右键单击+ ALT事件提供特殊的上下文菜单。
到目前为止,我可以将该事件的菜单设置为我的自定义菜单。但我无法在常规右键单击时将其重置为默认值(没有ALT关闭)。
我尝试通过textarea.getContextualMenu()存储默认菜单,并使用该菜单进行常规右键单击,但它仍然显示我的自定义菜单,包括有和没有ALT的两个事件。
关于如何重置菜单的任何想法?
//store default menu
defaultMenu = controller.txtArea.getContextMenu();
//check if alt is down
controller.txtArea.addEventHandler(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent keyEvent) {
if (keyEvent.getCode().equals(ALT)) {
System.out.println("alt typed---" + controller.txtArea.getCaretPosition());
//check if right click is performed
controller.txtArea.addEventFilter(MouseEvent.MOUSE_PRESSED, new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent mouseEvent) {
if (mouseEvent.getButton().equals(MouseButton.SECONDARY)) {
//override default menu by custom one
ContextMenu customMenu = new ContextMenu(new MenuItem("testing"));
controller.txtArea.setContextMenu(customMenu);
}
}
});
}
else{
//reset menu to default
controller.txtArea.setContextMenu(defaultMenu);
}
}
});
答案 0 :(得分:2)
我根据具体情况做这样的事情来构建菜单。不完全是您的情况,但您可以在事件处理程序中设置不同的菜单。它是Node的一种方法,因此您可以将它用于TextArea。
private static final class TextFieldTreeCellImpl extends TreeCell<String> {
private TextField textField;
public TextFieldTreeCellImpl() {
setOnContextMenuRequested((ContextMenuEvent event) -> {
setContextMenu(getCtxMenu());
});
}
private ContextMenu getCtxMenu() {
ContextMenu ctxMenu = new ContextMenu();
((TreeNode)getTreeItem()).addMenuItems(ctxMenu);
return ctxMenu;
}
...
答案 1 :(得分:1)
你的问题非常有趣。虽然您尚未提交应用程序代码以便我们可以精确地分析问题,但我可以向您介绍另一种解决方案(可能更好)。
我很少次使用上下文菜单。也许你可以做一些更有趣的事情。例如,您可以仅使用JavaFX组件的联结创建上下文菜单。为此,您可以在程序中定义一个区域,该区域将保留用于上下文菜单的外观。该区域可能是JavaFX组件(控件),例如文本区域。您可以从此控件上应用鼠标事件开始。用户点击鼠标后,您可以显示自己的上下文菜单。
您可以创建Parent类的扩展,该扩展可用作放置JavaFX控件的区域。使用new CSS API,您可以通过CSS为这个控件放置区域设置样式。将所有控件放在该区域之后,您将拥有上下文菜单。当您在文本区域中单击鼠标时,在上下文菜单中使用控件,您可以显示自己的上下文菜单。
要正确完成此操作,您可以在应用程序的开头通过将opacity property设置为零并将mouseTransparent设置为true来在文本区域的同一集合中添加上下文菜单。当用户点击时,触发的事件必须更改这些属性,并使用layoutXY properties正确定位上下文菜单。或者你不能使用opacity和mouseTransparent。您可以在必要时添加和删除上下文菜单。
为了让您的程序变得更好,您可以使用Timeline添加不透明度动画,逐渐显示您的自定义上下文菜单。您还可以添加着色效果,例如DropShadow,这会使您的上下文菜单明显高于文本区域。
这将为您提供更多灵活性和自定义,使您的应用程序更具吸引力。 ;)
答案 2 :(得分:0)
这是解决方案!感谢您的意见。 有两个问题:第一个是由setOnContextMenuRequested解决的上下文菜单。第二个是ALT被“按下”的事实,我不得不在没有按下时再发射一个事件......重新启动菜单。所以以下组合起作用:
//add custom menu actions..
controller.inLineCSSTextArea.addEventFilter(MouseEvent.MOUSE_PRESSED, new EventHandler<MouseEvent>() {//check for mouse click
@Override
public void handle(MouseEvent mouseEvent) {//handle event this way...
if (mouseEvent.getButton().equals(MouseButton.SECONDARY)) {//if right mouse button
controller.inLineCSSTextArea.setOnContextMenuRequested(new EventHandler<ContextMenuEvent>() {//check for context menu request
@Override
public void handle(ContextMenuEvent arg0) {//handle event this way...
//set a custom menu based on key event
controller.inLineCSSTextArea.addEventHandler(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>() {//check for key event...
@Override
public void handle(KeyEvent keyEvent) {//handle event this way...
if (keyEvent.getCode().equals(CONTROL)) {//if control key is pressed
controller.inLineCSSTextArea.setContextMenu(CNTRLmenu);
}
if (keyEvent.getCode().equals(ALT) ) {//if alt key is pressed
controller.inLineCSSTextArea.setContextMenu(ALTmenu);
}
}
});
}
});
}
}
});
//reset the context menu when any key is released. this is needed, otherwise default menu will not be set again on right click.
controller.inLineCSSTextArea.addEventHandler(KeyEvent.KEY_RELEASED, new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent keyEvent) {
controller.inLineCSSTextArea.setContextMenu(DEFAULTmenu);
}
});