Как отключить контекстное меню по умолчанию в текстовом поле

По умолчанию 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, встроенным в контекстное меню, и это сработало для меня.

Редактировать текст и др.; ИзображениеИв 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