Che*_*lin 6 default contextmenu textedit javafx-2
默认情况下,JavaFX TextField内置ContextMenu了"撤消","复制","剪切"等选项.该ComboBox也具有同样的ContextMenu,当它被设置为可编辑(的ComboBox其实是这是一个编辑器的一部分TextField).
我想ContextMenu用自定义替换它,但我遇到了禁用默认问题的问题.
我试图消耗ContextMenu和鼠标点击事件,但ComboBox并ComboBox.getEditor()都有空ContextMenu.
我错过了什么吗?
我找到了一种方法来禁用默认弹出菜单.然后你可以添加自己的,而不会得到双菜单效果.
ComboBox<String> cb_ = new ComboBox<>();
final EventDispatcher initial = cb_.getEditor().getEventDispatcher();
cb_.getEditor().setEventDispatcher(new EventDispatcher()
{
@Override
public Event dispatchEvent(Event event, EventDispatchChain tail)
{
if (event instanceof MouseEvent)
{
//shot in the dark guess for OSX, might not work
MouseEvent mouseEvent = (MouseEvent)event;
if (mouseEvent.getButton() == MouseButton.SECONDARY ||
(mouseEvent.getButton() == MouseButton.PRIMARY && mouseEvent.isControlDown()))
{
event.consume();
}
}
return initial.dispatchEvent(event, tail);
}
});
Run Code Online (Sandbox Code Playgroud)
注意 - 我不是通过组合框上的菜单添加我自己的菜单,我不确定它是否可行(可能).
如果你将组合框包装在Hbox中,并向hbox添加一个菜单 - 我知道这样可行.
HBox hbox = new HBox();
ContextMenu contextMenu = new ContextMenu();
....
hbox.setOnContextMenuRequested(new EventHandler<ContextMenuEvent>()
{
@Override
public void handle(ContextMenuEvent event)
{
contextMenu.show(hbox, event.getScreenX(), event.getScreenY());
}
});
Run Code Online (Sandbox Code Playgroud)
正如您已经说过的,对返回 null 的调用GetContextMenu()(这是默认值是实现细节的重要线索),如果您添加一个附加值,ContextMenu它会显示在默认值之上。
尝试用以下代码替换上下文菜单:
ContextMenu cm = new ContextMenu();
cm.getItems().add(new MenuItem("Test"));
textbox.setContextMenu(cm);
Run Code Online (Sandbox Code Playgroud)
产生以下结果。

覆盖鼠标单击事件也不起作用,因为您仍然需要通过某些属性访问默认的上下文菜单,这似乎是不可能的。
我还检查了 CSS 参考,看看是否可以ContextMenu通过控件子结构之一作为目标,但同样没有返回任何结果。
根据此信息,默认值似乎ContextMenu是控件的实现细节TextField(或者可能是父类TextInputControl),并且当前无法更改。
更新
我联系了 Jonathan Giles(Oracle JavaFX UI 控制团队的技术主管),他让我提交一份错误报告。
我搜索了错误数据库并发现了一些现有报告(RT-23213 和 RT-24823),因此看来这是一个已知问题。截至今天,该问题仍然悬而未决,被认为是中等优先级,但显然它将在 FX 8.0 中得到修复。
来自错误报告评论:
默认上下文菜单是由控件的皮肤创建的,目前不是公共 API。我们需要决定是否以及何时可以通过公共 API 访问上下文菜单,但可能需要等待更广泛的工作以使皮肤更加公开。