KeyStroke Accelerator не работи след деактивиране на JMenuItem

В рамките на малка самостоятелна програма на Java със Swing GUI използвам JMenuItem с Accelerator - най-вече без никакви проблеми:

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

Проблемът ми е, че когато деактивирам елемента с

item.setEnabled(false);  

и го активирайте по-късно с

item.setEnabled(true);

Не мога да използвам повече ускорителя. JMenuItem е правилно показан като активиран в менюто и мога да щракна върху него с мишката (и моят ActionListener работи правилно), но ускорителят ми не работи - така че не мога да стартирам "Свързване" с Ctrl+C повече.

Някой от вас знае ли какъв е този проблем или как мога да го избегна?


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

item.getAccelerator();

след извикване на item.setEnabled(true) получавам предишния зададен KeyStroke.

Работи с натискане на клавиш Ctrl+U, но не и с Ctrl+C. Струва ми се, че при деактивиране на елемента от менюто операцията за копиране по подразбиране се регистрира отново с Ctrl+C и след повторно активиране на елемента от менюто вече няма връзка между натискането на клавиша и елемента от менюто.

Докато се опитвах да създам малко копие на моята програма, за да демонстрирам проблема, го получих:
Направих две неща заедно - активирах JMenuItem (с натискане на клавиш 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 и след повторно активиране на елемента от менюто вече няма връзка между натискането на клавиша и елемента от менюто. :-/ - person Niklas P; 19.03.2014