Изменить ключ мнемонического модификатора в Java/Swing

Настроить горячие клавиши фокусировки в Swing очень просто:

  tfldPlantsNeeded = new JTextField( FIELD_LEN_MED );
  lblPlantsNeeded = new JLabel( "Plants Needed" );
  lblPlantsNeeded.setDisplayedMnemonic( 'p' );
  lblPlantsNeeded.setLabelFor( tfldPlantsNeeded );

Это даст фокус tfldPlantsNeeded JTextField, когда пользователь нажмет ALT+p. Он также выделяет/отображает символ, который вызовет изменение фокуса. (В этом случае при нажатии ALT буква «Р» в «Растениях» подчеркнута.)

Это здорово... ну, вроде. На Mac, когда пользователь нажимает ALT (что также является Option на клавиатуре Mac), мнемоника подсвечивается, но изменение фокуса не срабатывает при нажатии p. Однако если пользователь нажимает Control + Option + p, то он работает как "ожидаемый" и фокус меняется. (Кроме того, если пользователь ДЕЙСТВИТЕЛЬНО нажимает Option + p, в текущее выделенное текстовое поле будут вставлены забавные символы.)

Я знаю, что могу сделать это сам, указав пользовательские сочетания клавиш с помощью getInputMap и getActionMap, но есть ли способ изменить глобальный мнемонический модификатор приложения, чтобы мы могли использовать автоматические сочетания клавиш и запускать подсветку символов? (В моем случае я хотел бы использовать Command или Meta в качестве клавиши мнемонического модификатора.)


person Clayton    schedule 11.03.2014    source источник
comment
да (никогда не пробовал) эти ускорители - 1. TextAction или 2 UIManager   -  person mKorbel    schedule 11.03.2014


Ответы (1)


Очевидно, это не так просто, как вы думаете, но есть способ.

Прежде всего, для меню (JMenu) есть свойство, которое управляется внешним видом и поведением, называемое Menu.shortcutKeys, которое вы можете установить вручную. Это устанавливает мнемонический модификатор для меню в определенном внешнем виде. Если вам нужна дополнительная информация об этом, не стесняйтесь спрашивать.

Чтобы установить мнемонический модификатор для всего, вам нужно переопределить набор инструментов по умолчанию (Toolkit). Прежде всего, запустите основной метод, чтобы узнать, что это такое, со следующими строками.

System.out.println(System.getProperty("java.awt.headless"));
System.out.println(System.getProperty("awt.toolkit"));

Если первая строка null из false (см. java.awt.Toolkit getDefaultToolkit()), то вторая строка даст вам имя класса, которое используется в качестве набора инструментов по умолчанию для вашей системы. Я использую Windows, и вторая строка дает вывод sun.awt.windows.WToolkit. Теперь создайте класс, который переопределяет getFocusAcceleratorKeyMask в вашем наборе инструментов по умолчанию. Для меня это выглядит так

public class MyToolkit extends WToolkit {

    @Override
    public int getFocusAcceleratorKeyMask() {
        return InputEvent.CTRL_DOWN_MASK;
    }
}

Наконец, мы должны сказать системе использовать его. В своем приложении поместите строку

System.setProperty("awt.toolkit", "packagename.MyToolkit");

где вам нужно установить правильный путь пакета к вашему классу. Убедитесь, что эта строка размещена перед запуском любого кода, связанного с графическим интерфейсом, желательно в первых строках main. Теперь это должно установить CONTROL в качестве глобального мнемонического модификатора (или использовать META_DOWN_MASK, если это то, что вы хотите. Посмотрите на java.awt.event.InputEvent для списка MASK.).

person user1803551    schedule 24.03.2014
comment
WToolkit является окончательным и не может быть расширен. - person Paul Erlenmeyer; 25.03.2020