Как да деактивирате контекстното меню по подразбиране в текстово поле

По подразбиране JavaFX TextField има вграден ContextMenu с опции 'отмяна', 'копиране', 'изрязване' и т.н. ComboBox също има същото ContextMenu, когато е зададено като редактируемо (ComboBox всъщност е част от редактора, който е TextField).

Искам да заменя този ContextMenu с персонализиран, но имам проблем с деактивирането на този по подразбиране.

Опитах да използвам събитията ContextMenu и щракване с мишката, но ComboBox и ComboBox.getEditor() и двете имат null ContextMenu.

Изпускам ли нещо?


person Chechulin    schedule 26.11.2012    source източник


Отговори (3)


Както вече посочихте, извикването на GetContextMenu() връща null (което е голямата улика, че това по подразбиране е детайл от изпълнението) и ако добавите допълнителен ContextMenu, той се появява над този по подразбиране.

Опитвате се да замените контекстното меню със следния код:

ContextMenu cm = new ContextMenu();
cm.getItems().add(new MenuItem("Test"));

textbox.setContextMenu(cm);

Получава следния резултат.

въведете описание на изображението тук

Замяната на събитието, щракнато с мишката, също няма да работи, защото все пак ще трябва да получите достъп до контекстното меню по подразбиране чрез някакво свойство, което не изглежда възможно.

Проверих също препратката към CSS, за да видя дали ContextMenu може да се насочва чрез една от подструктурите на контролите, но отново това не върна резултати.

Въз основа на тази информация изглежда, че ContextMenu по подразбиране е детайл от изпълнението на TextField контролата (или може би е родителски класTextInputControl) и в момента не може да бъде променен.

Актуализация

Свързах се с Джонатан Джайлс (техническият ръководител в Oracle в екипа за управление на потребителския интерфейс на JavaFX), който ми каза да подам доклад за грешка.

Търсих в базата данни за грешки и намерих някои съществуващи доклади (RT-23213 & RT-24823), така че изглежда, че това е известен проблем. Към днешна дата проблемът все още е отворен и се счита за среден приоритет, но очевидно ще бъде коригиран за FX 8.0.

От коментарите в доклада за грешка:

Контекстното меню по подразбиране се създава от кожата на контролата, която в момента не е публичен API. Трябва да решим дали и кога контекстното меню трябва да бъде достъпно чрез публичния API, но вероятно ще трябва да изчака по-широката работа, за да направи кожите по-публични.

person Benjamin Gale    schedule 26.11.2012
comment
да, изглежда, че нищо не можем да направим с него. - person Chechulin; 29.11.2012
comment
Поне до следващото издание. - person Benjamin Gale; 29.11.2012
comment
'14 и грешката все още не е коригирана - person ITurchenko; 09.01.2014
comment
Изглежда, че все още е повреден в 8u45. - person davidrmcharles; 24.06.2015
comment
В случай на желание да деактивирам напълно контекстното меню, имах успех с настройката на контекстното меню на ново, празно ContextMenu: field.setContextMenu(new ContextMenu()); - person pulse0ne; 20.11.2015

Намерих начин да деактивирам изскачащото меню по подразбиране. След това можете да добавите свои собствени, без да получавате ефекта на двойното меню.

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());
    }
});
person user2163960    schedule 13.03.2013
comment
Не работи при мен, поне не на TextField. Можете да добавите този код, но също така имайте предвид, че събитието се задейства многократно (предполагам, че при натискане на мишката, отпускане на мишката и какво имате). Така или иначе, контекстното меню все още се появява. - person Warkst; 06.04.2017

надявам се, че ще помогне, имах същия проблем с 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);
}
person Lena    schedule 08.02.2015