Этот вопрос является продолжением this question.JMenuItem ускоритель не работает, когда строка меню скрыта
У меня есть JMenuBar
, поведение которого похоже на панели меню в Firefox и iTunes. То есть строка меню сначала скрыта, но когда вы нажимаете Alt
, появляется строка меню.
Ответ на другой вопрос решается задача достижения этой функциональности, но это привело к другому вопроса: В JMenuItem
Ускорителях не работает, когда JMenuBar
не виден. Другими словами, вы должны нажать Alt
до CTRL+F
(установленный ускоритель).
Это не должно быть, однако, так как метод setAccelerator()
гласит следующее:
общественной ничтожной setAccelerator (KeyStroke KeyStroke)
Устанавливает комбинацию клавиш, которая вызывающую действие пункта меню слушателей без навигации по иерархии меню. Ответственность за установку правильного действия лежит на пользовательском интерфейсе. Обратите внимание, что когда клавиатурный ускоритель вводится, он будет работать независимо от того, отображается ли в данный момент меню.
Итак, мне интересно, если это еще одна ошибка Java?
SSCCE (чтобы получить меню появится, вы нажимаете Alt
и установлен ускоритель CTRL+F
для «Найти», который воспитывает фиктивная JOptionPane
для входа):
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.KeyStroke;
import javax.swing.MenuElement;
import javax.swing.MenuSelectionManager;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.WindowConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class MenuBarTest extends JFrame {
public MenuBarTest() {
JMenu jMenu1 = new JMenu();
JMenu jMenu2 = new JMenu();
final JMenuBar jMenuBar1 = new JMenuBar();
JMenuItem jMenuItem1 = new JMenuItem();
JMenuItem jMenuItem2 = new JMenuItem();
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
jMenu1.setText("File");
jMenuItem1.setText("jMenuItem1");
jMenu1.add(jMenuItem1);
jMenuBar1.add(jMenu1);
jMenu2.setText("Edit");
jMenuItem2.setText("Find");
jMenu2.add(jMenuItem2);
jMenuBar1.add(jMenu2);
setJMenuBar(jMenuBar1);
jMenuBar1.setVisible(false);
ChangeListener listener = new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
MenuElement[] elements = MenuSelectionManager.defaultManager().getSelectedPath();
jMenuBar1.setVisible(elements.length > 0 && elements[0] == jMenuBar1);
}
};
MenuSelectionManager.defaultManager().addChangeListener(listener);
jMenuItem2.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F, java.awt.event.InputEvent.CTRL_MASK));
jMenuItem2.setText("Find");
jMenuItem2.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
String what = JOptionPane.showInputDialog(MenuBarTest.this, "Search for what?");
System.out.println(what);
}
});
pack();
setSize(500,500);
setLocationRelativeTo(null);
setVisible(true);
}
public static void main(String args[]) {
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new MenuBarTest();
}
});
}
}
мое дело в том, что это проблема с документацией: здесь отображается «отображается», что означает нормальное состояние, что меню/элемент под панелью меню скрыто (потому что мы видим только строку меню). Тем не менее, это _showing_ (потому что это видно, и все его предки показывают), таким образом позволяя привязки работать. – kleopatra