默认情况下,JavaFX TextField
内置ContextMenu
,其中包含“撤消”,“复制”,“剪切”等选项。 ComboBox
设置为可编辑时ContextMenu
也具有相同的ComboBox
(TextField
实际上是编辑器的一部分ContextMenu
)。
我想将此ContextMenu
替换为自定义的ComboBox
,但我遇到了禁用默认值的问题。
我已尝试使用ComboBox.getEditor()
和鼠标点击事件,但ContextMenu
和{{1}}都有空{{1}}。
我错过了什么吗?
答案 0 :(得分:6)
我找到了一种禁用默认弹出菜单的方法。然后你可以添加自己的,而不会得到双重菜单效果。
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);
}
});
注意 - 我没有通过组合框中的菜单添加我自己的菜单,我不确定它是否有用(可能)。
如果你将组合框包装在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());
}
});
答案 1 :(得分:2)
正如您已经说过的,对GetContextMenu()
的调用返回null(这是默认的一个实现细节的大线索),如果您添加一个额外的ContextMenu
,它将显示在默认值上
尝试使用以下代码替换上下文菜单:
ContextMenu cm = new ContextMenu();
cm.getItems().add(new MenuItem("Test"));
textbox.setContextMenu(cm);
产生以下结果。
覆盖鼠标单击事件也不起作用,因为您仍然需要通过某些似乎不可能的属性访问默认的上下文菜单。
我还检查了CSS引用,看看ContextMenu
是否可以通过其中一个控件子结构进行目标验证,但这又没有返回任何结果。
根据此信息,它看起来好像默认ContextMenu
是TextField
控件(或者它的父类TextInputControl
)的实现细节,并且当前无法更改。
<强>更新强>
我联系了Jonathan Giles(JavaFX UI控制团队的Oracle技术主管),他告诉我提交错误报告。
我搜索了错误数据库并找到了一些现有报告(RT-23213和RT-24823),所以看来这是一个已知问题。截至今天,该问题仍然是开放的,被认为是中等优先级,但显然它将在FX 8.0中得到修复。
从错误报告评论:
默认上下文菜单由控件的外观创建,即 目前不是公共API。我们需要决定上下文是否以及何时 菜单应该可以通过公共API访问,但它可能会 需要等待更广泛的工作才能使皮肤更加公开。
答案 2 :(得分:0)
我希望它会有所帮助,我在上下文菜单中构建了editText也遇到了同样的问题,这对我有用..
EditText et; ImageView iv;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et=(EditText) findViewById(R.id.et1);
iv=(ImageView) findViewById(R.id.iv1);
registerForContextMenu(et);
registerForContextMenu(iv);
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo)
{
menu.clear();
if(v==et)
getMenuInflater().inflate(R.menu.editmemu, menu);
if(v==iv)
getMenuInflater().inflate(R.menu.imagemenu, menu);super.onCreateContextMenu(menu, v, menuInfo);
}