I have the following code for a JMenuBar. How would I add my key listener CustomKeyListener
to the entire JMenuBar?
package UI;
import javax.swing.*;
import java.awt.event.*;
import javax.swing.event.*;
import java.awt.Dimension;
import java.awt.Color;
import java.awt.*;
import java.awt.Point;
import java.awt.font.*;
import UI.*;
public class GuiDMenuBar extends JMenuBar
{
JMenu m_file,m_code;
JMenuItem mi_f_new,mi_f_open;
public GuiDMenuBar()
{
setBorderPainted(true);
makeFileMenu();
makeCodeButton();
}
void makeFileMenu()
{
m_file = new JMenu("File");
m_file.setMnemonic('F');
mi_f_new = new JMenuItem("New");
mi_f_new.setMnemonic('N');
mi_f_open = new JMenuItem("Open");
mi_f_open.setMnemonic('O');
mi_f_new.setAccelerator(KeyStroke.getKeyStroke("control N"));
mi_f_open.setAccelerator(KeyStroke.getKeyStroke("control O"));
m_file.add(mi_f_new);
m_file.add(mi_f_open);
add(m_file);
}
void makeCodeButton()
{
m_code = new JMenu("Code");
m_code.setMnemonic('C');
add(m_code);
}
public void addListeners(ActionListener al)
{
mi_f_new.addActionListener(al);
mi_f_open.addActionListener(al);
}
class CustomKeyListener implements KeyListener
{
@Override
public void keyTyped(KeyEvent e)
{
System.out.println("Type");
}
@Override
public void keyPressed(KeyEvent e)
{
System.out.println("Press");
}
@Override
public void keyReleased(KeyEvent e)
{
System.out.println("Release");
}
}
}
I have tried adding
m_code.setFocusable(true);
m_code.addKeyListener(new CustomKeyListener());
to the void
makeCodeButton
however that did not pick up when anything was typed for that one JMenu. This is why I want it added to the whole JMenuBar instead.
Edit to show full CustomKeyListener
class CustomKeyListener implements KeyListener
{
Robot Roby = null;
@Override
public void keyTyped(KeyEvent e)
{
char c = e.getKeyChar();
if(c==KeyEvent.VK_ENTER)
{
if(m_code.isSelected())
{
try
{
Roby = new Robot();
}
catch(AWTException awte)
{
awte.printStackTrace();
}
clcikComponent(m_file);
}
}
System.out.println("Type");
}
@Override
public void keyPressed(KeyEvent e)
{
System.out.println("Press");
}
@Override
public void keyReleased(KeyEvent e)
{
System.out.println("Release");
}
public void clcikComponent(Component comp)
{
Point p = comp.getLocationOnScreen();
System.out.println(p);
Roby.mouseMove(p.x,p.y);
Roby.mousePress(MouseEvent.BUTTON1_MASK);
Roby.mouseRelease(MouseEvent.BUTTON1_MASK);
}
}
I still think this is a bad idea. As a user I would find it very confusing to find out that using the Enter key on one menu invokes an Action, while it doesn't do anything on other menus. The suggestion I gave in my comment is a far better solution.
However, I was curious why it didn't work and I found out that focus is actually on the JRootPane when the menu is displayed (and events are only dispatched to the component with focus). So you could add the KeyListener to the root pane.
However, there is an easier approach. You can use the JMenu.addMenuKeyListener(...)
method. The interface is the same as a KeyListener except all methods include "menu" in the name.