Question

I was wondering why Nimbus would be conflicting somehow with Virtual keys. Check out the sample I made below:

    public class buttontest implements ActionListener {

    JMenuItem close =new JMenuItem("Close");

    public static void main (String[] args){

    try {
        for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
            if ("Nimbus".equals(info.getName())) {
                UIManager.setLookAndFeel(info.getClassName());
                break;
            }
        }
    } catch (UnsupportedLookAndFeelException e) {
        // handle exception
    } catch (ClassNotFoundException e) {
        // handle exception
    } catch (InstantiationException e) {
        // handle exception
    } catch (IllegalAccessException e) {
        // handle exception
    }

    }

    public buttontest(){

    JFrame test = new JFrame();
    JMenuBar bar=new JMenuBar();
    JMenu file=new JMenu("File");

    close.setMnemonic(KeyEvent.VK_C);
    file.setMnemonic(KeyEvent.VK_F);

    test.setExtendedState(test.getExtendedState() | test.MAXIMIZED_BOTH); // Maximized Window or setSize(getMaximumSize())
    test.setDefaultCloseOperation(1);

    bar.add(file);
    file.add(close);
    test.setJMenuBar(bar);
    test.setVisible(true);  
}

public void actionPerformed(ActionEvent e){

    if(e.getSource()==close){
        System.exit(0);
    }
}

}

The way its wrote, you can try to use the Virtual keys. You will see that Alt F works to open the File menu but Alt C doesnt close the application. In other way, if you comment the Nimbus code both virtual Keys will work.

I made one research regarding to this "bug" (or maybe something wrong Im doing that Im not aware) but until now I found nothing. Has someone ever passed through this?

Was it helpful?

Solution

You have to use setAccelerator() method for JMenuItem:

close.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, InputEvent.ALT_MASK ));

From Javadoc:
JMenuItem#setAccelerator(KeyStroke)

Sets the key combination which invokes the menu item's action listeners without navigating the menu hierarchy. It is the UI's responsibility to install the correct action. Note that when the keyboard accelerator is typed, it will work whether or not the menu is currently displayed.


Additional note:

  1. Replace LookAndFeelInfo to UIManager.LookAndFeelInfo as it's an inner class inside UIManager.

  2. Call the constructor in the main method.

  3. Change the parameter of setDefaultCloseOperation(1) to 3 as 3 = JFrame.EXIT_ON_CLOSE, but 1=JFrame.HIDE_ON_CLOSE which hides the frame, personally, I hate it, because close button created for closing frame, not hiding it, like Skype.

  4. Add actionListener to close button :close.addActionListener(this);

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top