Есть ли способ получить доступ к стрелкам прокрутки ContextMenu (полоса прокрутки)? JavaFX - PullRequest
0 голосов
/ 10 января 2020

Я реализую автозаполнение текстового поля на основе этого ответа здесь:

{ ссылка }

Я использую ContextMenu, высота которого достаточно велика, так что ~ 15 элементов могут быть видны в время, когда доступно больше элементов, стрелки показывают внизу и вверху контекстного меню.

Проблема, с которой я столкнулся, заключается в том, что при прокрутке элементов вниз и вводе некоторых других слов мое контекстное меню остается прокручиваемым вниз, и мне приходится прокручивать его вверх вручную, чтобы отображать элементы, даже если есть только 1 item.

Я пробовал разные способы доступа к полосе прокрутки ContextMenu, поэтому я могу прокручивать ее вверх каждый раз, когда я вводю новый символ в поле, но я не мог придумать, как это сделать. ..

Есть ли способ прокрутить контекстное меню или установить фокус на первый элемент (вверху) всякий раз, когда я вводю что-то в поле для автозаполнения?

Надеюсь, мне удалось чтобы объяснить мою проблему правильно, и я благодарен за ответы заранее ..

1 Ответ

0 голосов
/ 11 января 2020

ContextMenu содержит стрелки вверх и вниз как особый тип MenuItem, называемый ArrowMenuItem. Структура выглядит следующим образом:

ContextMenu > ContextMenuSkin > ContextMenuContent > ArrowMenuItem

ArrowMenuItem - это не приватный c закрытый пакетный класс. У ContextMenuContent есть два экземпляра этого класса: upArrow и downArrow, и эти два экземпляра отображаются только тогда, когда элементы не могут поместиться в ContextMenu. ContextMenuContent использует Timeline для прокрутки ContextMenu, поэтому, когда ENTERED type MouseEvent запускается по любому из этих элементов стрелки, Timeline начинает прокручивать содержимое вверх или вниз на основе зависания ArrowMenuItem. Timeline останавливается, когда мышь покидает эту область. У ContextMenuContent есть метод scroll, который вам нужен, но, к сожалению, этот метод не опубликован c.

Возможные решения:

  1. Расширьте ContextMenuSkin, ContextMenuContent, чтобы раскрыть метод scroll. Таким образом, вы можете вызвать lookup ContextMenuContent со скина и использовать этот метод для прокрутки полностью вверх или вниз.

  2. Используйте классы стиля menu-up-arrow и menu-down-arrow для ищите узлы стрелок. Как только вы получите узел стрелки, вы можете стимулировать событие мыши ENTERED, чтобы сделать прокрутку ContextMenu вверх или вниз. Обратите внимание, что таким образом пользователь должен дождаться окончания прокрутки, поскольку Timeline имеет фиксированную скорость прокрутки. Затем вам нужно использовать это событие после завершения прокрутки. Пример кода:

ContextMenuSkin skin = (ContextMenuSkin) contextMenu.getSkin();
Node up = skin.getNode().lookup(".menu-up-arrow");
Node down = skin.getNode().lookup(".menu-down-arrow");
MouseEvent enteredEvent = new MouseEvent(MouseEvent.MOUSE_ENTERED, ...); // the remaining parameters
if (shouldScrollUp) {
    up.fireEvent(enteredEvent);
} else {
    down.fireEvent(enteredEvent);
}
// consume the event after scroll is over
Использование отражения:
private static void scrollContextMenuUp(ContextMenu contextMenu) {
    try {
        ContextMenuSkin skin = (ContextMenuSkin) contextMenu.getSkin();
        ContextMenuContent content = (ContextMenuContent) skin.getNode();
        Method method = content.getClass().getDeclaredMethod("scroll", double.class);
        method.setAccessible(true);
        method.invoke(content, 12.0); // change this double value to scroll more
    } catch (Exception e) {
        System.err.println("Unable to scroll due to: " + e.getMessage());
    }
}
...