KeyStroke Accelerator не работает после отключения JMenuItem

В небольшой автономной программе Java с графическим интерфейсом Swing я использую JMenuItem с ускорителем - в основном без проблем:

JMenuItem item = new JMenuItem("Connect", 'C');
KeyStroke ks = KeyStroke.getKeyStroke('C', Event.CTRL_MASK);
item.setAccelerator(ks);
item.addActionListener(this);

Моя проблема в том, что когда я отключаю item с помощью

item.setEnabled(false);  

и включить его позже с помощью

item.setEnabled(true);

Я больше не могу использовать ускоритель. JMenuItem правильно отображается как включенный в меню, и я могу щелкнуть его мышью (и мой ActionListener работает правильно), но мой ускоритель не работает, поэтому я не могу запустить «Подключение» с помощью Ctrl+C больше.

Кто-нибудь из вас знает, что это за проблема или как ее избежать?


Другие пункты меню, ускорители которых (но без временного отключения) работают. При звонке

item.getAccelerator();

после вызова item.setEnabled(true) я получаю ранее установленный KeyStroke.

Он работает с клавишей Ctrl+U, но не с Ctrl+C. Мне кажется, что при отключении пункта меню операция копирования по умолчанию снова регистрируется с помощью Ctrl + C, и после повторного включения пункта меню связи между KeyStroke и пунктом меню больше нет.

При попытке построить уменьшенную копию моей программы, чтобы продемонстрировать проблему, я обнаружил ее:
я сделал две вещи одновременно: включил JMenuItem (с помощью KeyStroke Ctrl+C) И запросил фокус для JTextField.
>


Вот небольшой код программы, которая не реагирует на нажатие клавиши Ctrl+C, связанное с пунктом меню:

public class ProblemDemo extends JFrame implements ActionListener {

public ProblemDemo() {
    super("ProblemDemo");
    setSize(500,500);
    setLocation(500,300);

    setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    JMenuBar menubar = new JMenuBar();
    JMenuItem menuItem = new JMenuItem("JMenuItem", 'C');
    menuItem.setAccelerator(KeyStroke.getKeyStroke('C', Event.CTRL_MASK));
    menuItem.addActionListener(this);
    JMenu menu = new JMenu("Actions");
    menu.add(menuItem);
    menubar.add(menu);
    setJMenuBar(menubar);

    JTextArea textarea = new JTextArea();
    getContentPane().setLayout(new BorderLayout());
    getContentPane().add(textarea, BorderLayout.CENTER);

    setVisible(true);
}

@Override
public void actionPerformed(ActionEvent event) {
    if ("JMenuItem".equals(event.getActionCommand())) {
        System.out.println("JMenuItem clicked");
    }
}

public static void main(String[] args) {
    new ProblemDemo();
}

}


person Niklas P    schedule 19.03.2014    source источник
comment
должно работать - вы, возможно, наткнулись на но, тем не менее. Покажите SSCCE, чтобы воспроизвести проблему, и добавьте версию JDK/OS, которую вы используете.   -  person kleopatra    schedule 19.03.2014
comment
-1 за то, что не показан код для его воспроизведения... повторяю: это может быть ошибка в вашем конкретном коде или ошибка в ядре. В обоих вариантах без компилируемого/запускаемого кода помочь не получится.   -  person kleopatra    schedule 19.03.2014
comment
Ctrl+C используется в текстовых компонентах для копирования текста. Возможно, основное внимание уделяется текстовому компоненту, поэтому вместо действия подключения вызывается действие копирования. Без надлежащего SSCCE мы не можем помочь.   -  person camickr    schedule 19.03.2014


Ответы (2)


У меня была та же проблема, когда я пытался включить элементы меню копирования/вырезания (а также кнопки на панели инструментов), только если что-то выбрано в JTable, вызвав setEnabled (true) в ListSelectionListener.

Я решаю свою проблему, вызывая requestFocusInWindow для JMenuBar, содержащего элементы, каждый раз, когда вызывается setEnable (true).

Кажется, что выбор чего-то в таблице направляет Ctrl+C / Ctrl+x к таблице...

Может быть, это поможет

person panounou    schedule 28.07.2014

Попробуйте создать следующий метод:

private KeyStroke getNewKeyStroke(){

 KeyStroke ks = KeyStroke.getKeyStroke('C', Event.CTRL_MASK);
 return KeyStroke;

}   

то вы можете вызвать следующий метод следующим образом:

 item.setEnabled(true);
 item.setAccelerator(this.getNewKeyStroke());
person Anto    schedule 19.03.2014
comment
Я пытался вставить ваш код (до и после item.setEnabled(true);) - безуспешно. Даже в сочетании с удалением и повторным добавлением ActionListener поведение не меняется. - person Niklas P; 19.03.2014
comment
Он работает с клавишей Ctrl+U, но не с Ctrl+C. Мне кажется, что при отключении пункта меню операция копирования по умолчанию снова регистрируется с помощью Ctrl + C, и после повторного включения пункта меню связи между KeyStroke и пунктом меню больше нет. :-/ - person Niklas P; 19.03.2014